Bug 1257242 - Split the ::BrowserTabsRemoteAutostart() function into two parts, to allow for the blocking policies to be checked independently from the prefs checks. r=jimm draft
authorFelipe Gomes <felipc@gmail.com>
Wed, 16 Mar 2016 14:08:18 -0300
changeset 341118 66c12a2665dbbbc7086a378faffb5e9d7d054f71
parent 339874 f0c0480732d36153e8839c7f17394d45f679f87d
child 341119 a75671e7da0ad72faacbd08cbb673c756430368c
push id13153
push userfelipc@gmail.com
push dateWed, 16 Mar 2016 17:08:54 +0000
reviewersjimm
bugs1257242
milestone48.0a1
Bug 1257242 - Split the ::BrowserTabsRemoteAutostart() function into two parts, to allow for the blocking policies to be checked independently from the prefs checks. r=jimm The behavior of ::BrowserTabsRemoteAutostart() shouldn't change, meaning that every result remains the same. The new getter can be accessed by JS through Services.appinfo.multiprocessBlockPolicy MozReview-Commit-ID: EI68awp2cGg
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsAppRunner.h
xpcom/system/nsIXULRuntime.idl
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -956,16 +956,19 @@ nsXULAppInfo::GetProcessID(uint32_t* aRe
 #endif
   return NS_OK;
 }
 
 static bool gBrowserTabsRemoteAutostart = false;
 static uint64_t gBrowserTabsRemoteStatus = 0;
 static bool gBrowserTabsRemoteAutostartInitialized = false;
 
+static bool gMultiprocessBlockPolicyInitialized = false;
+static uint32_t gMultiprocessBlockPolicy = 0;
+
 NS_IMETHODIMP
 nsXULAppInfo::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData) {
   if (!nsCRT::strcmp(aTopic, "getE10SBlocked")) {
     nsCOMPtr<nsISupportsPRUint64> ret = do_QueryInterface(aSubject);
     if (!ret)
       return NS_ERROR_FAILURE;
 
     ret->SetData(gBrowserTabsRemoteStatus);
@@ -978,16 +981,23 @@ nsXULAppInfo::Observe(nsISupports *aSubj
 NS_IMETHODIMP
 nsXULAppInfo::GetBrowserTabsRemoteAutostart(bool* aResult)
 {
   *aResult = BrowserTabsRemoteAutostart();
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsXULAppInfo::GetMultiprocessBlockPolicy(uint32_t* aResult)
+{
+  *aResult = MultiprocessBlockPolicy();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsXULAppInfo::GetAccessibilityEnabled(bool* aResult)
 {
 #ifdef ACCESSIBILITY
   *aResult = GetAccService() != nullptr;
 #else
   *aResult = false;
 #endif
   return NS_OK;
@@ -4631,23 +4641,39 @@ const char* kForceDisableE10sPref = "bro
 static inline uint32_t
 PRTimeToSeconds(PRTime t_usec)
 {
   PRTime usec_per_sec = PR_USEC_PER_SEC;
   return uint32_t(t_usec /= usec_per_sec);
 }
 #endif // XP_WIN
 
-bool
-mozilla::BrowserTabsRemoteAutostart()
-{
-  if (gBrowserTabsRemoteAutostartInitialized) {
-    return gBrowserTabsRemoteAutostart;
+uint32_t
+MultiprocessBlockPolicy() {
+  if (gMultiprocessBlockPolicyInitialized) {
+    return gMultiprocessBlockPolicy;
   }
-  gBrowserTabsRemoteAutostartInitialized = true;
+  gMultiprocessBlockPolicyInitialized = true;
+
+  /**
+   * Avoids enabling e10s if there are add-ons installed.
+   */
+  bool addonsCanDisable = Preferences::GetBool("extensions.e10sBlocksEnabling", false);
+  bool disabledByAddons = Preferences::GetBool("extensions.e10sBlockedByAddons", false);
+
+#ifdef MOZ_CRASHREPORTER
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AddonsShouldHaveBlockedE10s"),
+                                     disabledByAddons ? NS_LITERAL_CSTRING("1")
+                                                      : NS_LITERAL_CSTRING("0"));
+#endif
+
+  if (addonsCanDisable && disabledByAddons) {
+    gMultiprocessBlockPolicy = kE10sDisabledForAddons;
+    return gMultiprocessBlockPolicy;
+  }
 
   bool disabledForA11y = false;
 #ifdef XP_WIN
   /**
    * Avoids enabling e10s if accessibility has recently loaded. Performs the
    * following checks:
    * 1) Checks a pref indicating if a11y loaded in the last session. This pref
    * is set in nsBrowserGlue.js. If a11y was loaded in the last session we
@@ -4669,16 +4695,21 @@ mozilla::BrowserTabsRemoteAutostart()
     if (difference > ONE_WEEK_IN_SECONDS || !a11yRunDate) {
       Preferences::ClearUser(kAccessibilityLastRunDatePref);
     } else {
       disabledForA11y = true;
     }
   }
 #endif // XP_WIN
 
+  if (disabledForA11y) {
+    gMultiprocessBlockPolicy = kE10sDisabledForAccessibility;
+    return gMultiprocessBlockPolicy;
+  }
+
   /**
    * Avoids enabling e10s for certain locales that require bidi selection,
    * which currently doesn't work well with e10s.
    */
   bool disabledForBidi = false;
 
   nsAutoCString locale;
   nsCOMPtr<nsIXULChromeRegistry> registry =
@@ -4694,86 +4725,95 @@ mozilla::BrowserTabsRemoteAutostart()
 
   if (locale.EqualsLiteral("ar") ||
       locale.EqualsLiteral("fa") ||
       locale.EqualsLiteral("he") ||
       locale.EqualsLiteral("ur")) {
     disabledForBidi = true;
   }
 
+  if (disabledForBidi) {
+    gMultiprocessBlockPolicy = kE10sDisabledForBidi;
+    return gMultiprocessBlockPolicy;
+  }
+
+#if defined(XP_MACOSX)
+  // If for any reason we suspect acceleration will be disabled, disable
+  // e10s auto start on mac.
+
+  // Check prefs
+  bool accelDisabled = gfxPrefs::GetSingleton().LayersAccelerationDisabled() &&
+                       !gfxPrefs::LayersAccelerationForceEnabled();
+
+  accelDisabled = accelDisabled || !nsCocoaFeatures::AccelerateByDefault();
+
+  // Check for blocked drivers
+  if (!accelDisabled) {
+    nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+    if (gfxInfo) {
+      int32_t status;
+      if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_OPENGL_LAYERS, &status)) &&
+          status != nsIGfxInfo::FEATURE_STATUS_OK) {
+        accelDisabled = true;
+      }
+    }
+  }
+
+  // Check env flags
+  if (accelDisabled) {
+    const char *acceleratedEnv = PR_GetEnv("MOZ_ACCELERATED");
+    if (acceleratedEnv && (*acceleratedEnv != '0')) {
+      accelDisabled = false;
+    }
+  }
+
+  if (accelDisabled) {
+    gMultiprocessBlockPolicy = kE10sDisabledForMacGfx;
+    return gMultiprocessBlockPolicy;
+  }
+#endif // defined(XP_MACOSX)
+
+  /*
+   * None of the blocking policies matched, so e10s is allowed to run.
+   * Cache the information and return 0, indicating success.
+   */
+  gMultiprocessBlockPolicy = 0;
+  return 0;
+}
+
+bool
+mozilla::BrowserTabsRemoteAutostart()
+{
+  if (gBrowserTabsRemoteAutostartInitialized) {
+    return gBrowserTabsRemoteAutostart;
+  }
+  gBrowserTabsRemoteAutostartInitialized = true;
+
+
   bool optInPref = Preferences::GetBool("browser.tabs.remote.autostart", false);
   bool trialPref = Preferences::GetBool("browser.tabs.remote.autostart.2", false);
   bool prefEnabled = optInPref || trialPref;
   int status;
   if (optInPref) {
     status = kE10sEnabledByUser;
   } else if (trialPref) {
     status = kE10sEnabledByDefault;
   } else {
     status = kE10sDisabledByUser;
   }
 
-  bool addonsCanDisable = Preferences::GetBool("extensions.e10sBlocksEnabling", false);
-  bool disabledByAddons = Preferences::GetBool("extensions.e10sBlockedByAddons", false);
-
-#ifdef MOZ_CRASHREPORTER
-  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AddonsShouldHaveBlockedE10s"),
-                                     disabledByAddons ? NS_LITERAL_CSTRING("1")
-                                                      : NS_LITERAL_CSTRING("0"));
-#endif
-
   if (prefEnabled) {
-    if (disabledForA11y) {
-      status = kE10sDisabledForAccessibility;
-    } else if (disabledForBidi) {
-      status = kE10sDisabledForBidi;
-    } else if (addonsCanDisable && disabledByAddons) {
-      status = kE10sDisabledForAddons;
+    uint32_t blockPolicy = MultiprocessBlockPolicy();
+    if (blockPolicy != 0) {
+      status = blockPolicy;
     } else {
       gBrowserTabsRemoteAutostart = true;
     }
   }
 
-#if defined(XP_MACOSX)
-  // If for any reason we suspect acceleration will be disabled, disabled
-  // e10s auto start on mac.
-  if (gBrowserTabsRemoteAutostart) {
-    // Check prefs
-    bool accelDisabled = gfxPrefs::GetSingleton().LayersAccelerationDisabled() &&
-                         !gfxPrefs::LayersAccelerationForceEnabled();
-
-    accelDisabled = accelDisabled || !nsCocoaFeatures::AccelerateByDefault();
-
-    // Check for blocked drivers
-    if (!accelDisabled) {
-      nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-      if (gfxInfo) {
-        int32_t status;
-        if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_OPENGL_LAYERS, &status)) &&
-            status != nsIGfxInfo::FEATURE_STATUS_OK) {
-          accelDisabled = true;
-        }
-      }
-    }
-
-    // Check env flags
-    if (accelDisabled) {
-      const char *acceleratedEnv = PR_GetEnv("MOZ_ACCELERATED");
-      if (acceleratedEnv && (*acceleratedEnv != '0')) {
-        accelDisabled = false;
-      }
-    }
-
-    if (accelDisabled) {
-      gBrowserTabsRemoteAutostart = false;
-      status = kE10sDisabledForMacGfx;
-    }
-  }
-#endif // defined(XP_MACOSX)
-
   // Uber override pref for manual testing purposes
   if (Preferences::GetBool(kForceEnableE10sPref, false)) {
     gBrowserTabsRemoteAutostart = true;
     prefEnabled = true;
     status = kE10sEnabledByUser;
   }
 
   // Uber override pref for emergency blocking
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -115,9 +115,16 @@ extern GeckoProcessType sChildProcessTyp
 } // namespace mozilla
 
 /**
  * Set up platform specific error handling such as suppressing DLL load dialog
  * and the JIT debugger on Windows, and install unix signal handlers.
  */
 void SetupErrorHandling(const char* progname);
 
+/**
+ * A numeric value indicating whether multiprocess might be blocked.
+ * Possible values can be found at nsAppRunner.cpp. A value of 0
+ * represents not blocking.  
+ */
+uint32_t MultiprocessBlockPolicy();
+
 #endif // nsAppRunner_h__
--- a/xpcom/system/nsIXULRuntime.idl
+++ b/xpcom/system/nsIXULRuntime.idl
@@ -87,16 +87,23 @@ interface nsIXULRuntime : nsISupports
 
   /**
    * If true, browser tabs may be opened by default in a different process
    * from the main browser UI.
    */
   readonly attribute boolean browserTabsRemoteAutostart;
 
   /**
+   * A numeric value indicating whether multiprocess might be blocked.
+   * Possible values can be found at nsAppRunner.cpp. A value of 0
+   * represents not blocking.
+   */
+   readonly attribute unsigned long multiprocessBlockPolicy;
+
+  /**
    * If true, the accessibility service is running.
    */
   readonly attribute boolean accessibilityEnabled;
 
   /**
    * Indicates whether the current Firefox build is 64-bit.
    */
   readonly attribute boolean is64Bit;