Bug 948238 - Read browser.tabs.remote once at startup and never again (r=bsmedberg)
authorBill McCloskey <wmccloskey@mozilla.com>
Thu, 12 Dec 2013 14:13:20 -0800
changeset 160280 c25c364ce89ca5c4910f43588a579c4dd1bd09c1
parent 160279 52e299230d268bc0d733b9dc951b77ec4001ac68
child 160281 edc7514508f033fab9fefff868535c4fe1551703
push id25827
push userkwierso@gmail.com
push dateFri, 13 Dec 2013 03:13:04 +0000
treeherdermozilla-central@1bc33fa19b24 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs948238
milestone29.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 948238 - Read browser.tabs.remote once at startup and never again (r=bsmedberg)
accessible/src/windows/msaa/nsWinUtils.cpp
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
browser/components/nsBrowserGlue.js
browser/components/sessionstore/src/SessionStore.jsm
browser/metro/base/content/browser.js
dom/ipc/ContentParent.cpp
dom/ipc/TabChild.cpp
gfx/thebes/gfxPlatform.cpp
layout/forms/nsListControlFrame.cpp
toolkit/components/satchel/nsFormAutoComplete.js
toolkit/xre/nsAppRunner.cpp
widget/xpwidgets/nsBaseWidget.cpp
xpcom/system/nsIXULRuntime.idl
--- a/accessible/src/windows/msaa/nsWinUtils.cpp
+++ b/accessible/src/windows/msaa/nsWinUtils.cpp
@@ -53,17 +53,17 @@ nsWinUtils::GetComputedStyleDeclaration(
 
 bool
 nsWinUtils::MaybeStartWindowEmulation()
 {
   // Register window class that'll be used for document accessibles associated
   // with tabs.
   if (Compatibility::IsJAWS() || Compatibility::IsWE() ||
       Compatibility::IsDolphin() ||
-      Preferences::GetBool("browser.tabs.remote")) {
+      BrowserTabsRemote()) {
     RegisterNativeWindow(kClassNameTabContent);
     sHWNDCache = new nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible>(4);
     return true;
   }
 
   return false;
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -737,17 +737,17 @@ const gFormSubmitObserver = {
     this.panel.openPopup(element, position, offset, 0);
   }
 };
 
 var gBrowserInit = {
   delayedStartupFinished: false,
 
   onLoad: function() {
-    gMultiProcessBrowser = gPrefService.getBoolPref("browser.tabs.remote");
+    gMultiProcessBrowser = Services.appinfo.browserTabsRemote;
 
     var mustLoadSidebar = false;
 
     if (!gMultiProcessBrowser) {
       // There is a Content:Click message manually sent from content.
       Cc["@mozilla.org/eventlistenerservice;1"]
         .getService(Ci.nsIEventListenerService)
         .addSystemEventListener(gBrowser, "click", contentAreaClick, true);
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3032,17 +3032,17 @@
             this._waitForInitialContentDocument();
           }
 
           this.style.backgroundColor =
             Services.prefs.getBoolPref("browser.display.use_system_colors") ?
               "-moz-default-background-color" :
               Services.prefs.getCharPref("browser.display.background_color");
 
-          if (Services.prefs.getBoolPref("browser.tabs.remote")) {
+          if (Services.appinfo.browserTabsRemote) {
             messageManager.addMessageListener("DOMTitleChanged", this);
             messageManager.addMessageListener("contextmenu", this);
           }
         ]]>
       </constructor>
 
       <method name="_generateUniquePanelID">
         <body><![CDATA[
@@ -3098,17 +3098,17 @@
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
             this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
           }
           document.removeEventListener("keypress", this, false);
           window.removeEventListener("sizemodechange", this, false);
 
-          if (Services.prefs.getBoolPref("browser.tabs.remote")) {
+          if (Services.appinfo.browserTabsRemote) {
             messageManager.removeMessageListener("DOMTitleChanged", this);
             messageManager.removeMessageListener("contextmenu", this);
           }
         ]]>
       </destructor>
 
       <!-- Deprecated stuff, implemented for backwards compatibility. -->
       <method name="enterTabbedMode">
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -476,17 +476,17 @@ BrowserGlue.prototype = {
 #ifdef NIGHTLY_BUILD
     ShumwayUtils.init();
 #endif
     webrtcUI.init();
     AboutHome.init();
     SessionStore.init();
     BrowserUITelemetry.init();
 
-    if (Services.prefs.getBoolPref("browser.tabs.remote"))
+    if (Services.appinfo.browserTabsRemote)
       ContentClick.init();
 
     Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
   },
 
   _checkForOldBuildUpdates: function () {
     // check for update if our build is old
     if (Services.prefs.getBoolPref("app.update.enabled") &&
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -384,17 +384,17 @@ let SessionStoreInternal = {
   /**
    * Initialize the sessionstore service.
    */
   init: function () {
     if (this._initialized) {
       throw new Error("SessionStore.init() must only be called once!");
     }
 
-    this._disabledForMultiProcess = Services.prefs.getBoolPref("browser.tabs.remote");
+    this._disabledForMultiProcess = Services.appinfo.browserTabsRemote;
     if (this._disabledForMultiProcess) {
       this._deferredInitialized.resolve();
       return;
     }
 
     TelemetryTimestamps.add("sessionRestoreInitialized");
     OBSERVING.forEach(function(aTopic) {
       Services.obs.addObserver(this, aTopic, true);
--- a/browser/metro/base/content/browser.js
+++ b/browser/metro/base/content/browser.js
@@ -1424,17 +1424,17 @@ Tab.prototype = {
     let notification = this._notification = document.createElement("notificationbox");
 
     let browser = this._browser = document.createElement("browser");
     browser.id = "browser-" + this._id;
     this._chromeTab.linkedBrowser = browser;
 
     browser.setAttribute("type", "content");
 
-    let useRemote = Services.prefs.getBoolPref("browser.tabs.remote");
+    let useRemote = Services.appinfo.browserTabsRemote;
     let useLocal = Util.isLocalScheme(aURI);
     browser.setAttribute("remote", (!useLocal && useRemote) ? "true" : "false");
 
     // Append the browser to the document, which should start the page load
     let stack = document.createElementNS(XUL_NS, "stack");
     stack.className = "browserStack";
     stack.appendChild(browser);
     stack.setAttribute("flex", "1");
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -74,16 +74,17 @@
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIRemoteBlob.h"
 #include "nsIScriptError.h"
 #include "nsIStyleSheet.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIURIFixup.h"
 #include "nsIWindowWatcher.h"
+#include "nsIXULRuntime.h"
 #include "nsMemoryReporterManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
 #include "nsThreadUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
 #include "PreallocatedProcessManager.h"
 #include "ProcessPriorityManager.h"
@@ -3108,17 +3109,17 @@ ContentParent::RecvKeywordToURI(const ns
   return true;
 }
 
 bool
 ContentParent::ShouldContinueFromReplyTimeout()
 {
   // The only time ContentParent sends blocking messages is for CPOWs, so
   // timeouts should only ever occur in electrolysis-enabled sessions.
-  MOZ_ASSERT(Preferences::GetBool("browser.tabs.remote", false));
+  MOZ_ASSERT(BrowserTabsRemote());
   return false;
 }
 
 bool
 ContentParent::ShouldSandboxContentProcesses()
 {
 #ifdef MOZ_CONTENT_SANDBOX
   return !PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX");
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -50,16 +50,17 @@
 #include "nsIDocShell.h"
 #include "nsIURI.h"
 #include "nsIURIFixup.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIWebBrowser.h"
 #include "nsIWebBrowserFocus.h"
 #include "nsIWebBrowserSetup.h"
 #include "nsIWebProgress.h"
+#include "nsIXULRuntime.h"
 #include "nsInterfaceHashtable.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsLayoutUtils.h"
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "nsWeakReference.h"
 #include "PermissionMessageUtils.h"
@@ -2309,18 +2310,18 @@ TabChild::InitRenderingState()
         observerService->AddObserver(this,
                                      BROWSER_ZOOM_TO_RECT,
                                      false);
         observerService->AddObserver(this,
                                      BEFORE_FIRST_PAINT,
                                      false);
     }
 
-    // This state can't really change during the lifetime of the child.
-    sCpowsEnabled = Preferences::GetBool("browser.tabs.remote", false);
+    // This state can't change during the lifetime of the child.
+    sCpowsEnabled = BrowserTabsRemote();
     if (Preferences::GetBool("dom.ipc.cpows.force-enabled", false))
       sCpowsEnabled = true;
 
     return true;
 }
 
 void
 TabChild::SetBackgroundColor(const nscolor& aColor)
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -80,16 +80,17 @@
 #endif
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 
 #include "nsIGfxInfo.h"
+#include "nsIXULRuntime.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 
 gfxPlatform *gPlatform = nullptr;
 static bool gEverInitialized = false;
 
 static Mutex* gGfxPlatformPrefsLock = nullptr;
@@ -2070,17 +2071,17 @@ InitLayersAccelerationPrefs()
     sPrefLayersAccelerationDisabled = Preferences::GetBool("layers.acceleration.disabled", false);
     sPrefLayersPreferOpenGL = Preferences::GetBool("layers.prefer-opengl", false);
     sPrefLayersPreferD3D9 = Preferences::GetBool("layers.prefer-d3d9", false);
     sPrefLayersDump = Preferences::GetBool("layers.dump", false);
     sPrefLayersScrollGraph = Preferences::GetBool("layers.scroll-graph", false);
     sPrefLayoutFrameRate = Preferences::GetInt("layout.frame_rate", -1);
     sBufferRotationEnabled = Preferences::GetBool("layers.bufferrotation.enabled", true);
     sComponentAlphaEnabled = Preferences::GetBool("layers.componentalpha.enabled", true);
-    sPrefBrowserTabsRemote = Preferences::GetBool("browser.tabs.remote", false);
+    sPrefBrowserTabsRemote = BrowserTabsRemote();
 
 #ifdef XP_WIN
     if (sPrefLayersAccelerationForceEnabled) {
       sLayersSupportsD3D9 = true;
     } else {
       nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
       if (gfxInfo) {
         int32_t status;
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -11,16 +11,17 @@
 #include "nsGkAtoms.h"
 #include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsComboboxControlFrame.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIPresShell.h"
 #include "nsEventStateManager.h"
 #include "nsIDOMMouseEvent.h"
+#include "nsIXULRuntime.h"
 #include "nsFontMetrics.h"
 #include "nsIScrollableFrame.h"
 #include "nsCSSRendering.h"
 #include "nsIDOMEventListener.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 #include "nsContentUtils.h"
 #include "mozilla/Attributes.h"
@@ -1801,18 +1802,17 @@ nsListControlFrame::MouseDown(nsIDOMEven
       HandleListSelection(aMouseEvent, selectedIndex); // might destroy us
     if (!weakFrame.IsAlive()) {
       return NS_OK;
     }
     mChangesSinceDragStart = change;
   } else {
     // NOTE: the combo box is responsible for dropping it down
     if (mComboboxFrame) {
-      if (XRE_GetProcessType() == GeckoProcessType_Content &&
-          Preferences::GetBool("browser.tabs.remote", false)) {
+      if (XRE_GetProcessType() == GeckoProcessType_Content && BrowserTabsRemote()) {
         nsContentUtils::DispatchChromeEvent(mContent->OwnerDoc(), mContent,
                                             NS_LITERAL_STRING("mozshowdropdown"), true,
                                             false);
         return NS_OK;
       }
 
       if (!IgnoreMouseEventForSelection(aMouseEvent)) {
         return NS_OK;
--- a/toolkit/components/satchel/nsFormAutoComplete.js
+++ b/toolkit/components/satchel/nsFormAutoComplete.js
@@ -483,19 +483,18 @@ FormAutoCompleteResult.prototype = {
           this.formHistory.update({ op: "remove",
                                     fieldname: this.fieldName,
                                     value: removedEntry.text });
         }
     }
 };
 
 
-if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT &&
-    Services.prefs.prefHasUserValue("browser.tabs.remote") &&
-    Services.prefs.getBoolPref("browser.tabs.remote")) {
+let remote = Services.appinfo.browserTabsRemote;
+if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT && remote) {
   // Register the stub FormAutoComplete module in the child which will
   // forward messages to the parent through the process message manager.
   let component = [FormAutoCompleteChild];
   this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);
 } else {
   let component = [FormAutoComplete];
   this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);
 }
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -784,16 +784,26 @@ static_assert(GeckoProcessType_IPDLUnitT
 NS_IMETHODIMP
 nsXULAppInfo::GetProcessType(uint32_t* aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = XRE_GetProcessType();
   return NS_OK;
 }
 
+static bool gBrowserTabsRemote = false;
+static bool gBrowserTabsRemoteInitialized = false;
+
+NS_IMETHODIMP
+nsXULAppInfo::GetBrowserTabsRemote(bool* aResult)
+{
+  *aResult = BrowserTabsRemote();
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsXULAppInfo::EnsureContentProcess()
 {
   if (XRE_GetProcessType() != GeckoProcessType_Default)
     return NS_ERROR_NOT_AVAILABLE;
 
   nsRefPtr<ContentParent> unused = ContentParent::GetNewOrUsed();
   return NS_OK;
@@ -4363,16 +4373,27 @@ XRE_DeinitCommandLine()
 }
 
 GeckoProcessType
 XRE_GetProcessType()
 {
   return mozilla::startup::sChildProcessType;
 }
 
+bool
+mozilla::BrowserTabsRemote()
+{
+  if (!gBrowserTabsRemoteInitialized) {
+    gBrowserTabsRemote = Preferences::GetBool("browser.tabs.remote", false);
+    gBrowserTabsRemoteInitialized = true;
+  }
+
+  return gBrowserTabsRemote;
+}
+
 void
 SetupErrorHandling(const char* progname)
 {
 #ifdef XP_WIN
   /* On Windows XPSP3 and Windows Vista if DEP is configured off-by-default
      we still want DEP protection: enable it explicitly and programmatically.
      
      This function is not available on WinXPSP2 so we dynamically load it.
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -930,17 +930,17 @@ nsBaseWidget::GetPreferredCompositorBack
 }
 
 static void
 CheckForBasicBackends(nsTArray<LayersBackend>& aHints)
 {
   for (size_t i = 0; i < aHints.Length(); ++i) {
     if (aHints[i] == LAYERS_BASIC &&
         !Preferences::GetBool("layers.offmainthreadcomposition.force-basic", false) &&
-        !Preferences::GetBool("browser.tabs.remote", false)) {
+        !BrowserTabsRemote()) {
       // basic compositor is not stable enough for regular use
       aHints[i] = LAYERS_NONE;
     }
   }
 }
 
 void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
 {
--- a/xpcom/system/nsIXULRuntime.idl
+++ b/xpcom/system/nsIXULRuntime.idl
@@ -1,22 +1,31 @@
 /* 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/. */
 
 #include "nsISupports.idl"
 
+%{C++
+
+namespace mozilla {
+// Simple C++ getter for nsIXULRuntime::browserTabsRemote
+bool BrowserTabsRemote();
+}
+
+%}
+
 /**
  * Provides information about the XUL runtime.
  * @status UNSTABLE - This interface is not frozen and will probably change in
  *                    future releases. If you need this functionality to be
  *                    stable/frozen, please contact Benjamin Smedberg.
  */
 
-[scriptable, uuid(cb0b8eda-4c83-4d0e-a63c-d3b65714bc85)]
+[scriptable, uuid(33bd1630-611e-11e3-949a-0800200c9a66)]
 interface nsIXULRuntime : nsISupports
 {
   /**
    * Whether the application was launched in safe mode.
    */
   readonly attribute boolean inSafeMode;
 
   /**
@@ -63,16 +72,22 @@ interface nsIXULRuntime : nsISupports
   const unsigned long PROCESS_TYPE_IPDLUNITTEST = 3;
 
   /**
    * The type of the caller's process.  Returns one of the values above.
    */
   readonly attribute unsigned long processType;
 
   /**
+   * If true, browser tabs may be opened in a different process from the main
+   * browser UI.
+   */
+  readonly attribute boolean browserTabsRemote;
+
+  /**
    * Signal the apprunner to invalidate caches on the next restart.
    * This will cause components to be autoregistered and all
    * fastload data to be re-created.
    */
   void invalidateCachesOnRestart();
 
   /**
    * Starts a child process. This method is intented to pre-start a