Bug 1453519 - Avoid process reselection inside RDM. r=ochameau draft
authorJ. Ryan Stinnett <jryans@gmail.com>
Fri, 13 Apr 2018 11:57:44 -0500
changeset 792287 2ac33c09f47dd71230aa170db7c44bddc696cae1
parent 792286 c3385a8d1b850aebd6daf77aca541acdc53e3b00
push id109067
push userbmo:jryans@gmail.com
push dateTue, 08 May 2018 01:13:33 +0000
reviewersochameau
bugs1453519
milestone61.0a1
Bug 1453519 - Avoid process reselection inside RDM. r=ochameau Use `E10SUtils` to check for cases where browser code would try to force a browser to reselect a new process (such as when it is a preloaded browser) so that we can avoid any process changes once RDM is open. If such a case applies, navigate to about:blank first to trigger the process change before starting RDM. MozReview-Commit-ID: CxspLFXXotF
devtools/client/responsive.html/browser/swap.js
--- a/devtools/client/responsive.html/browser/swap.js
+++ b/devtools/client/responsive.html/browser/swap.js
@@ -1,15 +1,16 @@
 /* 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 { Ci } = require("chrome");
+const { E10SUtils } = require("resource://gre/modules/E10SUtils.jsm");
 const { tunnelToInnerBrowser } = require("./tunnel");
 
 function debug(msg) {
   console.log(`RDM swap: ${msg}`);
 }
 
 /**
  * Swap page content from an existing tab into a new browser within a container
@@ -84,19 +85,42 @@ function swapToInnerBrowser({ tab, conta
     let contentTabId = ourTab.linkedBrowser.frameLoader.tabParent.tabId;
     gBrowser._swapBrowserDocShells(ourTab, otherBrowser);
     if (otherBrowser.frameLoader.tabParent.tabId != contentTabId) {
       // Bug 1408602: Try to unwind to save tab content from being lost.
       throw new Error("Swapping tab content between browsers failed.");
     }
   };
 
+  // Wait for a browser to load into a new frame loader.
+  function loadURIWithNewFrameLoader(browser, uri, options) {
+    return new Promise(resolve => {
+      gBrowser.addEventListener("XULFrameLoaderCreated", resolve, { once: true });
+      browser.loadURI(uri, options);
+    });
+  }
+
   return {
 
     async start() {
+      // In some cases, such as a preloaded browser used for about:newtab, browser code
+      // will force a new frameloader on next navigation to ensure balanced process
+      // assignment.  If this case will happen here, navigate to about:blank first to get
+      // this out of way so that we stay within one process while RDM is open.
+      let { newFrameloader } = E10SUtils.shouldLoadURIInBrowser(
+        tab.linkedBrowser,
+        "about:blank"
+      );
+      if (newFrameloader) {
+        debug(`Tab will force a new frameloader on navigation, load about:blank first`);
+        await loadURIWithNewFrameLoader(tab.linkedBrowser, "about:blank", {
+          flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
+        });
+      }
+
       tab.isResponsiveDesignMode = true;
 
       // Hide the browser content temporarily while things move around to avoid displaying
       // strange intermediate states.
       tab.linkedBrowser.style.visibility = "hidden";
 
       // Freeze navigation temporarily to avoid "blinking" in the location bar.
       freezeNavigationState(tab);