Bug 1314429 - Bump XPIProvider's schema version to re-read info about multiprocessCompatible. Store information about whether that is false in a new field in the DB to avoid conflicts with any existing code. r=rhelmer, a=gchang
authorFelipe Gomes <felipc@gmail.com>
Mon, 28 Nov 2016 17:05:46 -0200
changeset 352746 38176b5357f07869d8d7bf718cfd34fc2696cfd5
parent 352745 ada06e30b71f989b148be443ad65bfc87d98c813
child 352747 e8ad14b973ac729dbc57869f1b690f6b78713242
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhelmer, gchang
bugs1314429
milestone52.0a2
Bug 1314429 - Bump XPIProvider's schema version to re-read info about multiprocessCompatible. Store information about whether that is false in a new field in the DB to avoid conflicts with any existing code. r=rhelmer, a=gchang MozReview-Commit-ID: 5Ip4UjuAult
browser/extensions/e10srollout/bootstrap.js
toolkit/mozapps/extensions/internal/E10SAddonsRollout.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/test/xpcshell/test_multiprocessCompatible.js
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/e10srollout/bootstrap.js
@@ -12,17 +12,17 @@ Cu.import("resource://gre/modules/Update
 
  // The amount of people to be part of e10s
 const TEST_THRESHOLD = {
   "beta"    : 0.5,  // 50%
   "release" : 1.0,  // 100%
 };
 
 const ADDON_ROLLOUT_POLICY = {
-  "beta"    : "51alladdons", // Any WebExtension or addon with mpc = true
+  "beta"    : "51alladdons", // Any WebExtension or addon except with mpc = false
   "release" : "50allmpc", // Any WebExtension or addon with mpc = true
 };
 
 const PREF_COHORT_SAMPLE       = "e10s.rollout.cohortSample";
 const PREF_COHORT_NAME         = "e10s.rollout.cohort";
 const PREF_E10S_OPTED_IN       = "browser.tabs.remote.autostart";
 const PREF_E10S_FORCE_ENABLED  = "browser.tabs.remote.force-enable";
 const PREF_E10S_FORCE_DISABLED = "browser.tabs.remote.force-disable";
--- a/toolkit/mozapps/extensions/internal/E10SAddonsRollout.jsm
+++ b/toolkit/mozapps/extensions/internal/E10SAddonsRollout.jsm
@@ -140,17 +140,17 @@ Object.defineProperty(this, "isAddonPart
 
     if (blocklist && blocklist.indexOf(aAddon.id) > -1) {
       return false;
     }
 
     let policy = RolloutPolicy[policyId];
 
     if (policy.alladdons) {
-      if (aAddon.multiprocessCompatible === false) {
+      if (aAddon.mpcOptedOut == true) {
         return false;
       }
 
       return true;
     }
 
     if (policy.webextensions && aAddon.type == "webextension") {
       return true;
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -173,17 +173,17 @@ const XPI_PERMISSION                  = 
 
 const RDFURI_INSTALL_MANIFEST_ROOT    = "urn:mozilla:install-manifest";
 const PREFIX_NS_EM                    = "http://www.mozilla.org/2004/em-rdf#";
 
 const TOOLKIT_ID                      = "toolkit@mozilla.org";
 
 const XPI_SIGNATURE_CHECK_PERIOD      = 24 * 60 * 60;
 
-XPCOMUtils.defineConstant(this, "DB_SCHEMA", 18);
+XPCOMUtils.defineConstant(this, "DB_SCHEMA", 19);
 
 const NOTIFICATION_TOOLBOXPROCESS_LOADED      = "ToolboxProcessLoaded";
 
 // Properties that exist in the install manifest
 const PROP_METADATA      = ["id", "version", "type", "internalName", "updateURL",
                             "updateKey", "optionsURL", "optionsType", "aboutURL",
                             "iconURL", "icon64URL"];
 const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
@@ -824,16 +824,17 @@ function EM_R(aProperty) {
 }
 
 function createAddonDetails(id, aAddon) {
   return {
     id: id || aAddon.id,
     type: aAddon.type,
     version: aAddon.version,
     multiprocessCompatible: aAddon.multiprocessCompatible,
+    mpcOptedOut: aAddon.mpcOptedOut,
     runInSafeMode: aAddon.runInSafeMode,
     dependencies: aAddon.dependencies,
     hasEmbeddedWebExtension: aAddon.hasEmbeddedWebExtension,
   };
 }
 
 /**
  * Converts an internal add-on type to the type presented through the API.
@@ -1189,17 +1190,21 @@ let loadManifestFromRDF = Task.async(fun
   }
 
   addon.strictCompatibility = !(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) ||
                               getRDFProperty(ds, root, "strictCompatibility") == "true";
 
   // Only read these properties for extensions.
   if (addon.type == "extension") {
     addon.bootstrap = getRDFProperty(ds, root, "bootstrap") == "true";
-    addon.multiprocessCompatible = getRDFProperty(ds, root, "multiprocessCompatible") == "true";
+
+    let mpcValue = getRDFProperty(ds, root, "multiprocessCompatible");
+    addon.multiprocessCompatible = mpcValue == "true";
+    addon.mpcOptedOut = mpcValue == "false";
+
     addon.hasEmbeddedWebExtension = getRDFProperty(ds, root, "hasEmbeddedWebExtension") == "true";
 
     if (addon.optionsType &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_DIALOG &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_TAB &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE_INFO) {
       throw new Error("Install manifest specifies unknown type: " + addon.optionsType);
@@ -7990,17 +7995,17 @@ function defineAddonWrapperProperty(name
     enumerable: true,
   });
 }
 
 ["id", "syncGUID", "version", "isCompatible", "isPlatformCompatible",
  "providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
  "softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents",
  "strictCompatibility", "compatibilityOverrides", "updateURL", "dependencies",
- "getDataDirectory", "multiprocessCompatible", "signedState",
+ "getDataDirectory", "multiprocessCompatible", "signedState", "mpcOptedOut",
  "isCorrectlySigned"].forEach(function(aProp) {
    defineAddonWrapperProperty(aProp, function() {
      let addon = addonFor(this);
      return (aProp in addon) ? addon[aProp] : undefined;
    });
 });
 
 ["fullDescription", "developerComments", "eula", "supportURL",
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -84,17 +84,17 @@ const PROP_JSON_FIELDS = ["id", "syncGUI
                           "optionsType", "aboutURL", "icons", "iconURL", "icon64URL",
                           "defaultLocale", "visible", "active", "userDisabled",
                           "appDisabled", "pendingUninstall", "descriptor", "installDate",
                           "updateDate", "applyBackgroundUpdates", "bootstrap",
                           "skinnable", "size", "sourceURI", "releaseNotesURI",
                           "softDisabled", "foreignInstall", "hasBinaryComponents",
                           "strictCompatibility", "locales", "targetApplications",
                           "targetPlatforms", "multiprocessCompatible", "signedState",
-                          "seen", "dependencies", "hasEmbeddedWebExtension"];
+                          "seen", "dependencies", "hasEmbeddedWebExtension", "mpcOptedOut"];
 
 // Properties that should be migrated where possible from an old database. These
 // shouldn't include properties that can be read directly from install.rdf files
 // or calculated
 const DB_MIGRATE_METADATA= ["installDate", "userDisabled", "softDisabled",
                             "sourceURI", "applyBackgroundUpdates",
                             "releaseNotesURI", "foreignInstall", "syncGUID"];
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_multiprocessCompatible.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_multiprocessCompatible.js
@@ -48,38 +48,40 @@ function build_test(multiprocessCompatib
     });
 
     let expectedMPC = updateMultiprocessCompatible === undefined ?
                       multiprocessCompatible :
                       updateMultiprocessCompatible;
 
     let xpifile = createTempXPIFile(addonData);
     let install = yield new Promise(resolve => AddonManager.getInstallForFile(xpifile, resolve));
-    do_check_eq(install.addon.multiprocessCompatible, multiprocessCompatible);
+    do_check_eq(install.addon.multiprocessCompatible, !!multiprocessCompatible);
+    do_check_eq(install.addon.mpcOptedOut, multiprocessCompatible === false)
     yield promiseCompleteAllInstalls([install]);
 
     if (!bootstrap) {
       yield promiseRestartManager();
       do_check_true(isExtensionInAddonsList(profileDir, addonData.id));
       do_check_eq(isItemMarkedMPIncompatible(addonData.id), !multiprocessCompatible);
     }
 
     let addon = yield promiseAddonByID(addonData.id);
     do_check_neq(addon, null);
-    do_check_eq(addon.multiprocessCompatible, multiprocessCompatible);
+    do_check_eq(addon.multiprocessCompatible, !!multiprocessCompatible);
+    do_check_eq(addon.mpcOptedOut, multiprocessCompatible === false);
 
     yield promiseFindAddonUpdates(addon);
 
     // Should have applied the compatibility change
-    do_check_eq(addon.multiprocessCompatible, expectedMPC);
+    do_check_eq(addon.multiprocessCompatible, !!expectedMPC);
     yield promiseRestartManager();
 
     addon = yield promiseAddonByID(addonData.id);
     // Should have persisted the compatibility change
-    do_check_eq(addon.multiprocessCompatible, expectedMPC);
+    do_check_eq(addon.multiprocessCompatible, !!expectedMPC);
     if (!bootstrap) {
       do_check_true(isExtensionInAddonsList(profileDir, addonData.id));
       do_check_eq(isItemMarkedMPIncompatible(addonData.id), !multiprocessCompatible);
     }
 
     addon.uninstall();
     yield promiseRestartManager();
 
@@ -88,17 +90,17 @@ function build_test(multiprocessCompatib
 }
 
 /* Builds a set of tests to run the same steps for every combination of:
  *   The add-on being restartless
  *   The initial add-on supporting multiprocess
  *   The update saying the add-on should or should not support multiprocess (or not say anything at all)
  */
 for (let bootstrap of [false, true]) {
-  for (let multiprocessCompatible of [false, true]) {
+  for (let multiprocessCompatible of [undefined, false, true]) {
     for (let updateMultiprocessCompatible of [undefined, false, true]) {
       add_task(build_test(multiprocessCompatible, bootstrap, updateMultiprocessCompatible));
     }
   }
 }
 
 function run_test() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");