Bug 1511345 - Fix migration from bug 857456. r=kmag, r=zombie, a=RyanVM
authorAndrew Swan <aswan@mozilla.com>
Fri, 30 Nov 2018 09:05:52 -0800
changeset 508168 bb2815518fc776afaf5e54a3fb4c9d2c5e66ed0e
parent 508167 138f65958545ae296c6742b9a13ca83f8310a0d8
child 508169 b1446de2dd1361ef4996ec6777f8058407523f76
child 508209 8dfebfa481b127c422a703354d3b96d0d5d56ee2
child 508248 2b2ff7f61faf580dcb6f120af2b76e0830844c35
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag, zombie, RyanVM
bugs1511345, 857456
milestone65.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 1511345 - Fix migration from bug 857456. r=kmag, r=zombie, a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D13562
toolkit/mozapps/extensions/internal/XPIDatabase.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -42,22 +42,24 @@ XPCOMUtils.defineLazyModuleGetters(this,
 
 const {nsIBlocklistService} = Ci;
 
 // These are injected from XPIProvider.jsm
 /* globals
  *         BOOTSTRAP_REASONS,
  *         DB_SCHEMA,
  *         XPIStates,
+ *         migrateAddonLoader
  */
 
 for (let sym of [
   "BOOTSTRAP_REASONS",
   "DB_SCHEMA",
   "XPIStates",
+  "migrateAddonLoader",
 ]) {
   XPCOMUtils.defineLazyGetter(this, sym, () => XPIInternal[sym]);
 }
 
 ChromeUtils.import("resource://gre/modules/Log.jsm");
 const LOGGER_ID = "addons.xpi-utils";
 
 const nsIFile = Components.Constructor("@mozilla.org/file/local;1", "nsIFile",
@@ -1313,47 +1315,17 @@ this.XPIDatabase = {
         let error = new Error("Bad JSON file contents");
         error.rebuildReason = "XPIDB_rebuildBadJSON_MS";
         throw error;
       }
 
       if (inputAddons.schemaVersion == 27) {
         // Types were translated in bug 857456.
         for (let addon of inputAddons.addons) {
-          switch (addon.type) {
-            case "extension":
-            case "dictionary":
-            case "locale":
-            case "theme":
-              addon.loader = "bootstrap";
-              break;
-
-            case "webbextension":
-              addon.type = "extension";
-              addon.loader = null;
-              break;
-
-            case "webextension-dictionary":
-              addon.type = "dictionary";
-              addon.loader = null;
-              break;
-
-            case "webextension-langpack":
-              addon.type = "locale";
-              addon.loader = null;
-              break;
-
-            case "webextension-theme":
-              addon.type = "theme";
-              addon.loader = null;
-              break;
-
-            default:
-              logger.warn(`Not converting unknown addon type ${addon.type}`);
-          }
+          migrateAddonLoader(addon);
         }
       } else if (inputAddons.schemaVersion != DB_SCHEMA) {
         // For now, we assume compatibility for JSON data with a
         // mismatched schema version, though we throw away any fields we
         // don't know about (bug 902956)
         this._recordStartupError(`schemaMismatch-${inputAddons.schemaVersion}`);
         logger.debug(`JSON schema mismatch: expected ${DB_SCHEMA}, actual ${inputAddons.schemaVersion}`);
       }
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -349,16 +349,63 @@ function* iterDirectory(aDir) {
   } finally {
     if (dirEnum) {
       dirEnum.close();
     }
   }
 }
 
 /**
+ * Migrate data about an addon to match the change made in bug 857456
+ * in which "webextension-foo" types were converted to "foo" and the
+ * "loader" property was added to distinguish different addon types.
+ *
+ * @param {Object} addon  The addon info to migrate.
+ * @returns {boolean} True if the addon data was converted, false if not.
+ */
+function migrateAddonLoader(addon) {
+  if (addon.hasOwnProperty("loader")) {
+    return false;
+  }
+
+  switch (addon.type) {
+    case "extension":
+    case "dictionary":
+    case "locale":
+    case "theme":
+      addon.loader = "bootstrap";
+      break;
+
+    case "webextension":
+      addon.type = "extension";
+      addon.loader = null;
+      break;
+
+    case "webextension-dictionary":
+      addon.type = "dictionary";
+      addon.loader = null;
+      break;
+
+    case "webextension-langpack":
+      addon.type = "locale";
+      addon.loader = null;
+      break;
+
+    case "webextension-theme":
+      addon.type = "theme";
+      addon.loader = null;
+      break;
+
+    default:
+      logger.warn(`Not converting unknown addon type ${addon.type}`);
+  }
+  return true;
+}
+
+/**
  * The on-disk state of an individual XPI, created from an Object
  * as stored in the addonStartup.json file.
  */
 const JSON_FIELDS = Object.freeze([
   "changed",
   "dependencies",
   "enabled",
   "file",
@@ -1197,16 +1244,31 @@ var XPIStates = {
     let state;
     try {
       state = aomStartup.readStartupData();
     } catch (e) {
       logger.warn("Error parsing extensions state: ${error}",
                   {error: e});
     }
 
+    // When upgrading from a build prior to bug 857456, convert startup
+    // metadata.
+    let done = false;
+    for (let location of Object.values(state)) {
+      for (let data of Object.values(location.addons)) {
+        if (!migrateAddonLoader(data)) {
+          done = true;
+          break;
+        }
+      }
+      if (done) {
+        break;
+      }
+    }
+
     logger.debug("Loaded add-on state: ${}", state);
     return state || {};
   },
 
   /**
    * Walk through all install locations, highest priority first,
    * comparing the on-disk state of extensions to what is stored in prefs.
    *
@@ -2724,16 +2786,17 @@ var XPIInternal = {
   TemporaryInstallLocation,
   XPIStates,
   XPI_PERMISSION,
   awaitPromise,
   canRunInSafeMode,
   getURIForResourceInFile,
   isXPI,
   iterDirectory,
+  migrateAddonLoader,
 };
 
 var addonTypes = [
   new AddonManagerPrivate.AddonType("extension", URI_EXTENSION_STRINGS,
                                     "type.extension.name",
                                     AddonManager.VIEW_TYPE_LIST, 4000,
                                     AddonManager.TYPE_SUPPORTS_UNDO_RESTARTLESS_UNINSTALL),
   new AddonManagerPrivate.AddonType("theme", URI_EXTENSION_STRINGS,