Bug 1345515 - Add notifications advertising new RDM. r=ochameau
authorJ. Ryan Stinnett <jryans@gmail.com>
Mon, 20 Mar 2017 16:06:54 -0500
changeset 354058 00401ba00247d6ef3aa185792648234ce0d75d05
parent 354057 139362080b7637983672ed9379cea55b3dd39e85
child 354059 e6cd1cb7eaa9dbafeb921209d1f710ff387e67a9
push id31685
push userkwierso@gmail.com
push dateThu, 20 Apr 2017 21:45:29 +0000
treeherdermozilla-central@5e3dc7e1288a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1345515
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 1345515 - Add notifications advertising new RDM. r=ochameau New RDM can be disabled because the user flipped a pref or because e10s is disabled. For each of these cases, add notifications to old RDM pushing users to switch to the new version and provide feedback, since the old RDM will eventually be removed. MozReview-Commit-ID: EOQ0FkuRmY0
devtools/client/locales/en-US/responsiveUI.properties
devtools/client/responsivedesign/responsivedesign.jsm
--- a/devtools/client/locales/en-US/responsiveUI.properties
+++ b/devtools/client/locales/en-US/responsiveUI.properties
@@ -6,17 +6,16 @@
 # which is available from the Web Developer sub-menu -> 'Responsive Mode'.
 #
 # The correct localization of this file might be to keep it in
 # English, or another language commonly spoken among web developers.
 # You want to make that choice consistent across the developer tools.
 # A good criteria is the language in which you'd find the best
 # documentation on web development on the web.
 
-
 # LOCALIZATION NOTE  (responsiveUI.rotate2): tooltip of the rotate button.
 responsiveUI.rotate2=Rotate
 
 # LOCALIZATION NOTE  (responsiveUI.screenshot): tooltip of the screenshot button.
 responsiveUI.screenshot=Screenshot
 
 # LOCALIZATION NOTE  (responsiveUI.userAgentPlaceholder): placeholder for the user agent input.
 responsiveUI.userAgentPlaceholder=Custom User Agent
@@ -62,8 +61,18 @@ responsiveUI.resizerTooltip=Use the Cont
 
 # LOCALIZATION NOTE (responsiveUI.needReload): notification that appears
 # when touch events are enabled
 responsiveUI.needReload=If touch event listeners have been added earlier, the page needs to be reloaded.
 responsiveUI.notificationReload=Reload
 responsiveUI.notificationReload_accesskey=R
 responsiveUI.dontShowReloadNotification=Never show again
 responsiveUI.dontShowReloadNotification_accesskey=N
+
+# LOCALIZATION NOTE (responsiveUI.newVersionUserDisabled): notification that appears
+# when old RDM is displayed because the user has disabled new RDM.
+responsiveUI.newVersionUserDisabled=A new version of Responsive Design Mode is available, but it appears to be disabled. Please enable it and provide feedback, as this version will be removed.
+# LOCALIZATION NOTE (responsiveUI.newVersionE10sDisabled): notification that appears
+# when old RDM is displayed because e10s is disabled.
+responsiveUI.newVersionE10sDisabled=A new version of Responsive Design Mode is available, but it requires multi-process mode, which is currently disabled. Please enable it and provide feedback, as this version will be removed.
+# LOCALIZATION NOTE (responsiveUI.newVersionEnableAndRestart): button text in notification
+# to enable new RDM itself or e10s as a prerequisite for new RDM.
+responsiveUI.newVersionEnableAndRestart=Enable and Restart
\ No newline at end of file
--- a/devtools/client/responsivedesign/responsivedesign.jsm
+++ b/devtools/client/responsivedesign/responsivedesign.jsm
@@ -9,32 +9,37 @@ const Cu = Components.utils;
 const { loader, require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
 const { LocalizationHelper } = require("devtools/shared/l10n");
 const { Task } = require("devtools/shared/task");
 const Services = require("Services");
 const EventEmitter = require("devtools/shared/event-emitter");
 
 loader.lazyImporter(this, "SystemAppProxy",
                     "resource://gre/modules/SystemAppProxy.jsm");
+loader.lazyImporter(this, "BrowserUtils",
+                    "resource://gre/modules/BrowserUtils.jsm");
 loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
 loader.lazyRequireGetter(this, "showDoorhanger",
                          "devtools/client/shared/doorhanger", true);
 loader.lazyRequireGetter(this, "TouchEventSimulator",
                          "devtools/shared/touch/simulator", true);
 loader.lazyRequireGetter(this, "flags",
                          "devtools/shared/flags");
 loader.lazyRequireGetter(this, "EmulationFront",
                          "devtools/shared/fronts/emulation", true);
 loader.lazyRequireGetter(this, "DebuggerClient",
                          "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "DebuggerServer",
                          "devtools/server/main", true);
+loader.lazyRequireGetter(this, "system", "devtools/shared/system");
 
 this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
 
+const NEW_RDM_ENABLED = "devtools.responsive.html.enabled";
+
 const MIN_WIDTH = 50;
 const MIN_HEIGHT = 50;
 
 const MAX_WIDTH = 10000;
 const MAX_HEIGHT = 10000;
 
 const SLOW_RATIO = 6;
 const ROUND_RATIO = 10;
@@ -131,17 +136,17 @@ var Manager = {
 };
 
 EventEmitter.decorate(Manager);
 
 // If the new HTML RDM UI is enabled and e10s is enabled by default (e10s is required for
 // the new HTML RDM UI to function), delegate the ResponsiveUIManager API over to that
 // tool instead.  Performing this delegation here allows us to contain the pref check to a
 // single place.
-if (Services.prefs.getBoolPref("devtools.responsive.html.enabled") &&
+if (Services.prefs.getBoolPref(NEW_RDM_ENABLED) &&
     Services.appinfo.browserTabsRemoteAutostart) {
   let { ResponsiveUIManager } =
     require("devtools/client/responsive.html/manager");
   this.ResponsiveUIManager = ResponsiveUIManager;
 } else {
   this.ResponsiveUIManager = Manager;
 }
 
@@ -261,16 +266,18 @@ ResponsiveUI.prototype = {
     // Hook to display promotional Developer Edition doorhanger.
     // Only displayed once.
     showDoorhanger({
       window: this.mainWindow,
       type: "deveditionpromo",
       anchor: this.chromeDoc.querySelector("#content")
     });
 
+    this.showNewUINotification();
+
     // Notify that responsive mode is on.
     this._telemetry.toolOpened("responsive");
     ResponsiveUIManager.emit("on", { tab: this.tab });
   }),
 
   connectToServer: Task.async(function* () {
     if (!DebuggerServer.initialized) {
       DebuggerServer.init();
@@ -394,22 +401,24 @@ ResponsiveUI.prototype = {
       this.touchEventSimulator.stop();
     }
 
     yield this.client.close();
     this.client = this.emulationFront = null;
 
     this._telemetry.toolClosed("responsive");
 
-    if (this.tab.linkedBrowser.messageManager) {
+    if (this.tab.linkedBrowser && this.tab.linkedBrowser.messageManager) {
       let stopped = this.waitForMessage("ResponsiveMode:Stop:Done");
       this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
       yield stopped;
     }
 
+    this.hideNewUINotification();
+
     this.inited = null;
     ResponsiveUIManager.emit("off", { tab: this.tab });
   }),
 
   waitForMessage(message) {
     return new Promise(resolve => {
       let listener = () => {
         this.mm.removeMessageListener(message, listener);
@@ -678,16 +687,79 @@ ResponsiveUI.prototype = {
     homeButton.addEventListener("mouseup", () => {
       SystemAppProxy.dispatchKeyboardEvent("keyup", { key: "Home" });
     });
     bottomToolbar.appendChild(homeButton);
     this.bottomToolbar = bottomToolbar;
     this.container.appendChild(bottomToolbar);
   },
 
+  showNewUINotification() {
+    let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
+
+    // One reason we might be using old RDM is that the user explcitly disabled new RDM.
+    // We should encourage them to use the new one, since the old one will be removed.
+    if (Services.prefs.prefHasUserValue(NEW_RDM_ENABLED) &&
+        !Services.prefs.getBoolPref(NEW_RDM_ENABLED)) {
+      let buttons = [{
+        label: this.strings.GetStringFromName("responsiveUI.newVersionEnableAndRestart"),
+        callback: () => {
+          Services.prefs.setBoolPref(NEW_RDM_ENABLED, true);
+          BrowserUtils.restartApplication();
+        },
+      }];
+      nbox.appendNotification(
+        this.strings.GetStringFromName("responsiveUI.newVersionUserDisabled"),
+        "responsive-ui-new-version-user-disabled",
+        null,
+        nbox.PRIORITY_INFO_LOW,
+        buttons
+      );
+      return;
+    }
+
+    // Only show a notification about the new RDM UI on channels where there is an e10s
+    // switch in the preferences UI (Dev. Ed, Nightly).  On other channels, it is less
+    // clear how a user would proceed here, so don't show a message.
+    if (!system.constants.E10S_TESTING_ONLY) {
+      return;
+    }
+
+    let buttons = [{
+      label: this.strings.GetStringFromName("responsiveUI.newVersionEnableAndRestart"),
+      callback: () => {
+        Services.prefs.setBoolPref("browser.tabs.remote.autostart", true);
+        Services.prefs.setBoolPref("browser.tabs.remote.autostart.2", true);
+        BrowserUtils.restartApplication();
+      },
+    }];
+    nbox.appendNotification(
+      this.strings.GetStringFromName("responsiveUI.newVersionE10sDisabled"),
+      "responsive-ui-new-version-e10s-disabled",
+      null,
+      nbox.PRIORITY_INFO_LOW,
+      buttons
+    );
+  },
+
+  hideNewUINotification() {
+    if (!this.mainWindow.gBrowser || !this.mainWindow.gBrowser.getNotificationBox) {
+      return;
+    }
+    let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
+    let n = nbox.getNotificationWithValue("responsive-ui-new-version-user-disabled");
+    if (n) {
+      n.close();
+    }
+    n = nbox.getNotificationWithValue("responsive-ui-new-version-e10s-disabled");
+    if (n) {
+      n.close();
+    }
+  },
+
   /**
    * Validate and apply any user input on the editable menulist
    */
   handleManualInput: function () {
     let userInput = this.menulist.inputField.value;
     let value = INPUT_PARSER.exec(userInput);
     let selectedPreset = this.menuitems.get(this.selectedItem);