Bug 1248619 - Part 3: Restore the previous viewport size, user agent, display pixel ratio and touch simultation properties. r=rcaliman
☠☠ backed out by fb0c2bcc9bc6 ☠ ☠
authorGabriel Luong <gabriel.luong@gmail.com>
Tue, 09 Oct 2018 14:53:29 -0400
changeset 440249 fb2a9e0b7538881fbe1c526d961338108ca4c967
parent 440248 ae15dbcedd8a73fc2a53b231354c49321da74ee1
child 440250 e8214c1232867528c2a3956ace751ed3ba8f384b
push id108767
push usergabriel.luong@gmail.com
push dateTue, 09 Oct 2018 18:55:25 +0000
treeherdermozilla-inbound@fb2a9e0b7538 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrcaliman
bugs1248619
milestone64.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 1248619 - Part 3: Restore the previous viewport size, user agent, display pixel ratio and touch simultation properties. r=rcaliman We also provided reasonable defaults to all our SErvices.prefs getter in case an user's profile is somehow missing those prefs.
devtools/client/preferences/devtools-client.js
devtools/client/responsive.html/manager.js
devtools/client/responsive.html/reducers/ui.js
devtools/client/responsive.html/reducers/viewports.js
devtools/client/responsive.html/test/browser/browser.ini
devtools/client/responsive.html/test/browser/browser_state_restore.js
devtools/client/responsive.html/test/browser/head.js
--- a/devtools/client/preferences/devtools-client.js
+++ b/devtools/client/preferences/devtools-client.js
@@ -302,24 +302,35 @@ pref("devtools.hud.loglimit", 10000);
 pref("devtools.editor.tabsize", 2);
 pref("devtools.editor.expandtab", true);
 pref("devtools.editor.keymap", "default");
 pref("devtools.editor.autoclosebrackets", true);
 pref("devtools.editor.detectindentation", true);
 pref("devtools.editor.enableCodeFolding", true);
 pref("devtools.editor.autocomplete", true);
 
+// The width of the viewport.
+pref("devtools.responsive.viewport.width", 320);
+// The height of the viewport.
+pref("devtools.responsive.viewport.height", 480);
+// The pixel ratio of the viewport.
+pref("devtools.responsive.viewport.pixelRatio", 0);
 // Whether or not the viewports are left aligned.
 pref("devtools.responsive.leftAlignViewport.enabled", false);
 // Whether to reload when touch simulation is toggled
 pref("devtools.responsive.reloadConditions.touchSimulation", false);
 // Whether to reload when user agent is changed
 pref("devtools.responsive.reloadConditions.userAgent", false);
 // Whether to show the notification about reloading to apply emulation
 pref("devtools.responsive.reloadNotification.enabled", true);
+// Whether or not touch simulation is enabled.
+pref("devtools.responsive.touchSimulation.enabled", false);
+// The user agent of the viewport.
+pref("devtools.responsive.userAgent", "");
+
 // Whether to show the settings onboarding tooltip only in release or beta builds.
 #if defined(RELEASE_OR_BETA)
 pref("devtools.responsive.show-setting-tooltip", true);
 #else
 pref("devtools.responsive.show-setting-tooltip", false);
 #endif
 // Show the custom user agent input in Nightly builds.
 #if defined(NIGHTLY_BUILD)
--- a/devtools/client/responsive.html/manager.js
+++ b/devtools/client/responsive.html/manager.js
@@ -2,35 +2,36 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Ci } = require("chrome");
 const promise = require("promise");
 const Services = require("Services");
+const asyncStorage = require("devtools/shared/async-storage");
 const EventEmitter = require("devtools/shared/event-emitter");
 
-const TOOL_URL = "chrome://devtools/content/responsive.html/index.xhtml";
-
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 loader.lazyRequireGetter(this, "throttlingProfiles", "devtools/client/shared/components/throttling/profiles");
 loader.lazyRequireGetter(this, "SettingOnboardingTooltip", "devtools/client/responsive.html/setting-onboarding-tooltip");
 loader.lazyRequireGetter(this, "swapToInnerBrowser", "devtools/client/responsive.html/browser/swap", true);
 loader.lazyRequireGetter(this, "startup", "devtools/client/responsive.html/utils/window", true);
 loader.lazyRequireGetter(this, "message", "devtools/client/responsive.html/utils/message");
 loader.lazyRequireGetter(this, "showNotification", "devtools/client/responsive.html/utils/notification", true);
 loader.lazyRequireGetter(this, "l10n", "devtools/client/responsive.html/utils/l10n");
 loader.lazyRequireGetter(this, "EmulationFront", "devtools/shared/fronts/emulation", true);
 loader.lazyRequireGetter(this, "PriorityLevels", "devtools/client/shared/components/NotificationBox", true);
 loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
 loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
 loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
 
+const TOOL_URL = "chrome://devtools/content/responsive.html/index.xhtml";
+
 const RELOAD_CONDITION_PREF_PREFIX = "devtools.responsive.reloadConditions.";
 const RELOAD_NOTIFICATION_PREF = "devtools.responsive.reloadNotification.enabled";
 const SHOW_SETTING_TOOLTIP_PREF = "devtools.responsive.show-setting-tooltip";
 
 function debug(msg) {
   // console.log(`RDM manager: ${msg}`);
 }
 
@@ -356,16 +357,19 @@ ResponsiveUI.prototype = {
     // Notify the inner browser to start the frame script
     debug("Wait until start frame script");
     await message.request(this.toolWindow, "start-frame-script");
 
     // Get the protocol ready to speak with emulation actor
     debug("Wait until RDP server connect");
     await this.connectToServer();
 
+    // Restore the previous state of RDM.
+    await this.restoreState();
+
     // Show the settings onboarding tooltip
     if (Services.prefs.getBoolPref(SHOW_SETTING_TOOLTIP_PREF)) {
       this.settingOnboardingTooltip =
         new SettingOnboardingTooltip(ui.toolWindow.document);
     }
 
     // Non-blocking message to tool UI to start any delayed init activities
     message.post(this.toolWindow, "post-init");
@@ -530,17 +534,17 @@ ResponsiveUI.prototype = {
         break;
       case "content-resize":
         this.onContentResize(event);
         break;
       case "exit":
         this.onExit();
         break;
       case "remove-device-association":
-        this.onRemoveDeviceAssociation(event);
+        this.onRemoveDeviceAssociation();
         break;
       case "viewport-resize":
         this.onViewportResize(event);
         break;
     }
   },
 
   async onChangeDevice(event) {
@@ -599,17 +603,17 @@ ResponsiveUI.prototype = {
     });
   },
 
   onExit() {
     const { browserWindow, tab } = this;
     ResponsiveUIManager.closeIfNeeded(browserWindow, tab);
   },
 
-  async onRemoveDeviceAssociation(event) {
+  async onRemoveDeviceAssociation() {
     let reloadNeeded = false;
     await this.updateDPPX();
     reloadNeeded |= await this.updateUserAgent() &&
                     this.reloadOnChange("userAgent");
     reloadNeeded |= await this.updateTouchSimulation() &&
                     this.reloadOnChange("touchSimulation");
     if (reloadNeeded) {
       this.getViewportBrowser().reload();
@@ -622,16 +626,50 @@ ResponsiveUI.prototype = {
     const { width, height } = event.data;
     this.emit("viewport-resize", {
       width,
       height,
     });
   },
 
   /**
+   * Restores the previous state of RDM.
+   */
+  async restoreState() {
+    const deviceState = await asyncStorage.getItem("devtools.responsive.deviceState");
+    if (deviceState) {
+      // Return if there is a device state to restore, this will be done when the
+      // device list is loaded after the post-init.
+      return;
+    }
+
+    const pixelRatio =
+      Services.prefs.getIntPref("devtools.responsive.viewport.pixelRatio", 0);
+    const touchSimulationEnabled =
+      Services.prefs.getBoolPref("devtools.responsive.touchSimulation.enabled", false);
+    const userAgent = Services.prefs.getCharPref("devtools.responsive.userAgent", "");
+
+    let reloadNeeded = false;
+
+    await this.updateDPPX(pixelRatio);
+
+    if (touchSimulationEnabled) {
+      reloadNeeded |= await this.updateTouchSimulation(touchSimulationEnabled) &&
+                      this.reloadOnChange("touchSimulation");
+    }
+    if (userAgent) {
+      reloadNeeded |= await this.updateUserAgent(userAgent) &&
+                      this.reloadOnChange("userAgent");
+    }
+    if (reloadNeeded) {
+      this.getViewportBrowser().reload();
+    }
+  },
+
+  /**
    * Set or clear the emulated device pixel ratio.
    *
    * @return boolean
    *         Whether a reload is needed to apply the change.
    *         (This is always immediate, so it's always false.)
    */
   async updateDPPX(dppx) {
     if (!dppx) {
--- a/devtools/client/responsive.html/reducers/ui.js
+++ b/devtools/client/responsive.html/reducers/ui.js
@@ -15,44 +15,48 @@ const {
   TOGGLE_TOUCH_SIMULATION,
   TOGGLE_USER_AGENT_INPUT,
 } = require("../actions/index");
 
 const LEFT_ALIGNMENT_ENABLED = "devtools.responsive.leftAlignViewport.enabled";
 const RELOAD_ON_TOUCH_SIMULATION = "devtools.responsive.reloadConditions.touchSimulation";
 const RELOAD_ON_USER_AGENT = "devtools.responsive.reloadConditions.userAgent";
 const SHOW_USER_AGENT_INPUT = "devtools.responsive.showUserAgentInput";
+const TOUCH_SIMULATION_ENABLED = "devtools.responsive.touchSimulation.enabled";
+const USER_AGENT = "devtools.responsive.userAgent";
 
 const INITIAL_UI = {
   // The pixel ratio of the display.
   displayPixelRatio: 0,
   // Whether or not the viewports are left aligned.
-  leftAlignmentEnabled: Services.prefs.getBoolPref(LEFT_ALIGNMENT_ENABLED),
+  leftAlignmentEnabled: Services.prefs.getBoolPref(LEFT_ALIGNMENT_ENABLED, false),
   // Whether or not to reload when touch simulation is toggled.
-  reloadOnTouchSimulation: Services.prefs.getBoolPref(RELOAD_ON_TOUCH_SIMULATION),
+  reloadOnTouchSimulation: Services.prefs.getBoolPref(RELOAD_ON_TOUCH_SIMULATION, false),
   // Whether or not to reload when user agent is changed.
-  reloadOnUserAgent: Services.prefs.getBoolPref(RELOAD_ON_USER_AGENT),
+  reloadOnUserAgent: Services.prefs.getBoolPref(RELOAD_ON_USER_AGENT, false),
   // Whether or not to show the user agent input in the toolbar.
-  showUserAgentInput: Services.prefs.getBoolPref(SHOW_USER_AGENT_INPUT),
+  showUserAgentInput: Services.prefs.getBoolPref(SHOW_USER_AGENT_INPUT, false),
   // Whether or not touch simulation is enabled.
-  touchSimulationEnabled: false,
+  touchSimulationEnabled: Services.prefs.getBoolPref(TOUCH_SIMULATION_ENABLED, false),
   // The user agent of the viewport.
-  userAgent: "",
+  userAgent: Services.prefs.getCharPref(USER_AGENT, ""),
 };
 
 const reducers = {
 
   [CHANGE_DISPLAY_PIXEL_RATIO](ui, { displayPixelRatio }) {
     return {
       ...ui,
       displayPixelRatio,
     };
   },
 
   [CHANGE_USER_AGENT](ui, { userAgent }) {
+    Services.prefs.setCharPref(USER_AGENT, userAgent);
+
     return {
       ...ui,
       userAgent,
     };
   },
 
   [TOGGLE_LEFT_ALIGNMENT](ui, { enabled }) {
     const leftAlignmentEnabled = enabled !== undefined ?
@@ -86,16 +90,18 @@ const reducers = {
 
     return {
       ...ui,
       reloadOnUserAgent,
     };
   },
 
   [TOGGLE_TOUCH_SIMULATION](ui, { enabled }) {
+    Services.prefs.setBoolPref(TOUCH_SIMULATION_ENABLED, enabled);
+
     return {
       ...ui,
       touchSimulationEnabled: enabled,
     };
   },
 
   [TOGGLE_USER_AGENT_INPUT](ui, { enabled }) {
     const showUserAgentInput = enabled !== undefined ?
--- a/devtools/client/responsive.html/reducers/viewports.js
+++ b/devtools/client/responsive.html/reducers/viewports.js
@@ -1,33 +1,39 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+const Services = require("Services");
+
 const {
   ADD_VIEWPORT,
   CHANGE_DEVICE,
   CHANGE_PIXEL_RATIO,
   REMOVE_DEVICE_ASSOCIATION,
   RESIZE_VIEWPORT,
   ROTATE_VIEWPORT,
 } = require("../actions/index");
 
+const VIEWPORT_WIDTH_PREF = "devtools.responsive.viewport.width";
+const VIEWPORT_HEIGHT_PREF = "devtools.responsive.viewport.height";
+const VIEWPORT_PIXEL_RATIO_PREF = "devtools.responsive.viewport.pixelRatio";
+
 let nextViewportId = 0;
 
 const INITIAL_VIEWPORTS = [];
 const INITIAL_VIEWPORT = {
   id: nextViewportId++,
   device: "",
   deviceType: "",
-  height: 480,
-  width: 320,
-  pixelRatio: 0,
+  height: Services.prefs.getIntPref(VIEWPORT_HEIGHT_PREF, 480),
+  width: Services.prefs.getIntPref(VIEWPORT_WIDTH_PREF, 320),
+  pixelRatio: Services.prefs.getIntPref(VIEWPORT_PIXEL_RATIO_PREF, 0),
   userContextId: 0,
 };
 
 const reducers = {
 
   [ADD_VIEWPORT](viewports, { userContextId }) {
     // For the moment, there can be at most one viewport.
     if (viewports.length === 1) {
@@ -58,16 +64,18 @@ const reducers = {
   },
 
   [CHANGE_PIXEL_RATIO](viewports, { id, pixelRatio }) {
     return viewports.map(viewport => {
       if (viewport.id !== id) {
         return viewport;
       }
 
+      Services.prefs.setIntPref(VIEWPORT_PIXEL_RATIO_PREF, pixelRatio);
+
       return {
         ...viewport,
         pixelRatio,
       };
     });
   },
 
   [REMOVE_DEVICE_ASSOCIATION](viewports, { id }) {
@@ -93,16 +101,19 @@ const reducers = {
       if (!height) {
         height = viewport.height;
       }
 
       if (!width) {
         width = viewport.width;
       }
 
+      Services.prefs.setIntPref(VIEWPORT_WIDTH_PREF, width);
+      Services.prefs.setIntPref(VIEWPORT_HEIGHT_PREF, height);
+
       return {
         ...viewport,
         height,
         width,
       };
     });
   },
 
--- a/devtools/client/responsive.html/test/browser/browser.ini
+++ b/devtools/client/responsive.html/test/browser/browser.ini
@@ -47,16 +47,17 @@ tags = devtools webextensions
 skip-if = true # Bug 1413765
 [browser_network_throttling.js]
 [browser_page_state.js]
 [browser_permission_doorhanger.js]
 tags = devtools geolocation
 skip-if = true # Bug 1413765
 [browser_preloaded_newtab.js]
 [browser_screenshot_button.js]
+[browser_state_restore.js]
 [browser_tab_close.js]
 [browser_tab_remoteness_change.js]
 [browser_target_blank.js]
 [browser_telemetry_activate_rdm.js]
 [browser_toolbox_computed_view.js]
 [browser_toolbox_rule_view.js]
 [browser_toolbox_rule_view_reload.js]
 [browser_toolbox_swap_browsers.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/responsive.html/test/browser/browser_state_restore.js
@@ -0,0 +1,56 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the previous viewport size, user agent, ddppx and touch simulation properties
+// are restored when reopening RDM.
+
+const TEST_URL = "data:text/html;charset=utf-8,";
+const DEFAULT_DPPX = window.devicePixelRatio;
+const NEW_DPPX = DEFAULT_DPPX + 1;
+const NEW_USER_AGENT = "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0";
+
+addRDMTask(TEST_URL, async function({ ui, manager }) {
+  const { store } = ui.toolWindow;
+
+  reloadOnTouchChange(true);
+  reloadOnUAChange(true);
+
+  await waitUntilState(store, state => state.viewports.length == 1);
+
+  info("Checking the default RDM state.");
+  testViewportDeviceMenuLabel(ui, "Responsive");
+  testViewportDimensions(ui, 320, 480);
+  await testUserAgent(ui, DEFAULT_UA);
+  await testDevicePixelRatio(ui, DEFAULT_DPPX);
+  await testTouchEventsOverride(ui, false);
+
+  info("Changing the RDM size, dppx, ua and toggle ON touch simulations.");
+  await setViewportSize(ui, manager, 90, 500);
+  await selectDevicePixelRatio(ui, NEW_DPPX);
+  await toggleTouchSimulation(ui);
+  await changeUserAgentInput(ui, NEW_USER_AGENT);
+
+  reloadOnTouchChange(false);
+  reloadOnUAChange(false);
+});
+
+addRDMTask(TEST_URL, async function({ ui }) {
+  const { store } = ui.toolWindow;
+
+  reloadOnTouchChange(true);
+  reloadOnUAChange(true);
+
+  info("Reopening RDM and checking that the previous device state is restored.");
+
+  await waitUntilState(store, state => state.viewports.length == 1);
+
+  testViewportDimensions(ui, 90, 500);
+  await testUserAgent(ui, NEW_USER_AGENT);
+  await testDevicePixelRatio(ui, NEW_DPPX);
+  await testTouchEventsOverride(ui, true);
+
+  reloadOnTouchChange(false);
+  reloadOnUAChange(false);
+});
--- a/devtools/client/responsive.html/test/browser/head.js
+++ b/devtools/client/responsive.html/test/browser/head.js
@@ -60,16 +60,21 @@ Services.prefs.setBoolPref("devtools.res
 registerCleanupFunction(async () => {
   Services.prefs.clearUserPref("devtools.devices.url");
   Services.prefs.clearUserPref("devtools.responsive.reloadNotification.enabled");
   Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
   Services.prefs.clearUserPref("devtools.responsive.reloadConditions.touchSimulation");
   Services.prefs.clearUserPref("devtools.responsive.reloadConditions.userAgent");
   Services.prefs.clearUserPref("devtools.responsive.show-setting-tooltip");
   Services.prefs.clearUserPref("devtools.responsive.showUserAgentInput");
+  Services.prefs.clearUserPref("devtools.responsive.touchSimulation.enabled");
+  Services.prefs.clearUserPref("devtools.responsive.userAgent");
+  Services.prefs.clearUserPref("devtools.responsive.viewport.height");
+  Services.prefs.clearUserPref("devtools.responsive.viewport.pixelRatio");
+  Services.prefs.clearUserPref("devtools.responsive.viewport.width");
   await asyncStorage.removeItem("devtools.devices.url_cache");
   await asyncStorage.removeItem("devtools.responsive.deviceState");
   await removeLocalDevices();
 });
 
 /**
  * Open responsive design mode for the given tab.
  */