Bug 1366823 - add Scratchpad manager APIs to DevToolsShim;r=ochameau
authorJulian Descottes <jdescottes@mozilla.com>
Mon, 29 May 2017 14:50:07 +0200
changeset 409226 4d8182ea2319cc481a3d74dded1dcd02d0fc48cb
parent 409225 958633822c0969edd7796117e741984c13b29354
child 409227 f39ea1fb1be510633bca4cfe7cf57b9506831e39
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1366823
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1366823 - add Scratchpad manager APIs to DevToolsShim;r=ochameau MozReview-Commit-ID: 5JsSu9Spkgn
devtools/client/framework/devtools.js
devtools/shim/DevToolsShim.jsm
devtools/shim/tests/unit/test_devtools_shim.js
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -9,16 +9,17 @@ const Services = require("Services");
 
 const {DevToolsShim} = Cu.import("chrome://devtools-shim/content/DevToolsShim.jsm", {});
 
 // Load gDevToolsBrowser toolbox lazily as they need gDevTools to be fully initialized
 loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
 loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
 loader.lazyRequireGetter(this, "ToolboxHostManager", "devtools/client/framework/toolbox-host-manager", true);
 loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
+loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
 
 const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} =
   require("devtools/client/definitions");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {JsonView} = require("devtools/client/jsonview/main");
 const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
 const {Task} = require("devtools/shared/task");
 const {getTheme, setTheme, addThemeObserver, removeThemeObserver} =
@@ -390,16 +391,37 @@ DevTools.prototype = {
         definitions.push(definition);
       }
     }
 
     return definitions.sort(this.ordinalSort);
   },
 
   /**
+   * Get the array of currently opened scratchpad windows.
+   *
+   * @return {Array} array of currently opened scratchpad windows.
+   *         Empty array if the scratchpad manager is not loaded.
+   */
+  getOpenedScratchpads: function () {
+    // Check if the module is loaded to avoid loading ScratchpadManager for no reason.
+    if (!Cu.isModuleLoaded("resource://devtools/client/scratchpad/scratchpad-manager.jsm")) {
+      return [];
+    }
+    return ScratchpadManager.getSessionState();
+  },
+
+  /**
+   * Restore the provided array of scratchpad window states.
+   */
+  restoreScratchpadSession: function (scratchpads) {
+    ScratchpadManager.restoreSession(scratchpads);
+  },
+
+  /**
    * Show a Toolbox for a target (either by creating a new one, or if a toolbox
    * already exists for the target, by bring to the front the existing one)
    * If |toolId| is specified then the displayed toolbox will have the
    * specified tool selected.
    * If |hostType| is specified then the toolbox will be displayed using the
    * specified HostType.
    *
    * @param {Target} target
@@ -535,19 +557,24 @@ DevTools.prototype = {
     }
 
     JsonView.destroy();
 
     gDevTools.unregisterDefaults();
 
     removeThemeObserver(this._onThemeChanged);
 
-    // Notify the DevToolsShim that DevTools are no longer available, particularly if the
-    // destroy was caused by disabling/removing the DevTools add-on.
-    DevToolsShim.unregister();
+    // Do not unregister devtools from the DevToolsShim if the destroy is caused by an
+    // application shutdown. For instance SessionStore needs to save the Scratchpad
+    // manager state on shutdown.
+    if (!shuttingDown) {
+      // Notify the DevToolsShim that DevTools are no longer available, particularly if
+      // the destroy was caused by disabling/removing the DevTools add-on.
+      DevToolsShim.unregister();
+    }
 
     // Cleaning down the toolboxes: i.e.
     //   for (let [target, toolbox] of this._toolboxes) toolbox.destroy();
     // Is taken care of by the gDevToolsBrowser.forgetBrowserWindow
   },
 
   /**
    * Iterator that yields each of the toolboxes.
--- a/devtools/shim/DevToolsShim.jsm
+++ b/devtools/shim/DevToolsShim.jsm
@@ -148,16 +148,40 @@ this.DevToolsShim = {
   unregisterTheme: function (theme) {
     if (this.isInstalled()) {
       this.gDevTools.unregisterTheme(theme);
     } else {
       removeItem(this.themes, t => t === theme);
     }
   },
 
+  /**
+   * Called from SessionStore.jsm in mozilla-central when saving the current state.
+   *
+   * @return {Array} array of currently opened scratchpad windows. Empty array if devtools
+   *         are not installed
+   */
+  getOpenedScratchpads: function () {
+    if (!this.isInstalled()) {
+      return [];
+    }
+    return this.gDevTools.getOpenedScratchpads();
+  },
+
+  /**
+   * Called from SessionStore.jsm in mozilla-central when restoring a state that contained
+   * opened scratchpad windows.
+   */
+  restoreScratchpadSession: function (scratchpads) {
+    if (!this.isInstalled()) {
+      return;
+    }
+    this.gDevTools.restoreScratchpadSession(scratchpads);
+  },
+
   _onDevToolsRegistered: function () {
     // Register all pending event listeners on the real gDevTools object.
     for (let [event, listener] of this.listeners) {
       this.gDevTools.on(event, listener);
     }
 
     for (let tool of this.tools) {
       this.gDevTools.registerTool(tool);
--- a/devtools/shim/tests/unit/test_devtools_shim.js
+++ b/devtools/shim/tests/unit/test_devtools_shim.js
@@ -17,16 +17,18 @@ function createMockDevTools() {
   let methods = [
     "on",
     "off",
     "registerTool",
     "registerTheme",
     "unregisterTool",
     "unregisterTheme",
     "emit",
+    "getOpenedScratchpads",
+    "restoreScratchpadSession",
   ];
 
   let mock = {
     callLog: {}
   };
 
   for (let method of methods) {
     // Create a stub for method, that only pushes its arguments in the inner callLog
@@ -183,16 +185,40 @@ function test_events() {
   DevToolsShim.register(mock);
   checkCalls(mock, "emit", 1, ["devtools-registered"]);
 
   // Check emit is called once with the devtools-unregistered event.
   DevToolsShim.unregister();
   checkCalls(mock, "emit", 2, ["devtools-unregistered"]);
 }
 
+function test_scratchpad_apis() {
+  ok(!DevToolsShim.isInstalled(), "DevTools are not installed");
+
+  // Check that restoreScratchpadSession doesn't crash.
+  DevToolsShim.restoreScratchpadSession([{}]);
+
+  let scratchpads = DevToolsShim.getOpenedScratchpads();
+  equal(scratchpads.length, 0,
+      "getOpenedScratchpads returns [] when DevTools are not installed");
+
+  let mock = createMockDevTools();
+  DevToolsShim.register(mock);
+
+  // Check that calls to restoreScratchpadSession are not held.
+  checkCalls(mock, "restoreScratchpadSession", 0);
+
+  DevToolsShim.getOpenedScratchpads();
+  checkCalls(mock, "getOpenedScratchpads", 1, []);
+
+  let scratchpadSessions = [{}];
+  DevToolsShim.restoreScratchpadSession(scratchpadSessions);
+  checkCalls(mock, "restoreScratchpadSession", 1, [scratchpadSessions]);
+}
+
 function run_test() {
   test_register_unregister();
   DevToolsShim.unregister();
 
   test_on_is_forwarded_to_devtools();
   DevToolsShim.unregister();
 
   test_off_called_before_registering_devtools();
@@ -202,10 +228,13 @@ function run_test() {
   DevToolsShim.unregister();
 
   test_registering_tool();
   DevToolsShim.unregister();
 
   test_registering_theme();
   DevToolsShim.unregister();
 
+  test_scratchpad_apis();
+  DevToolsShim.unregister();
+
   test_events();
 }