Backed out changeset cf1022433399 (bug 1433574) Linux build bustages on a CLOSED TREE
authorAndreea Pavel <apavel@mozilla.com>
Tue, 24 Apr 2018 04:35:07 +0300
changeset 468715 60cf97933726a504197477aab9f8092cf9fd97b5
parent 468714 1e3173e0ad058647182f3aa2d94b03b30eb0fe4f
child 468716 f63f20404c553366c4724be5b9690b755f7712ef
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1433574
milestone61.0a1
backs outcf1022433399232d089891e4979fced0289b0e7c
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
Backed out changeset cf1022433399 (bug 1433574) Linux build bustages on a CLOSED TREE
mobile/android/app/mobile.js
testing/geckodriver/src/prefs.rs
testing/marionette/client/marionette_driver/geckoinstance.py
testing/marionette/components/marionette.js
testing/mozbase/mozprofile/mozprofile/profile.py
toolkit/locales/en-US/chrome/mozapps/extensions/update.properties
toolkit/locales/jar.mn
toolkit/mozapps/extensions/content/update.css
toolkit/mozapps/extensions/content/update.html
toolkit/mozapps/extensions/content/update.js
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/jar.mn
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -194,16 +194,17 @@ pref("extensions.enabledScopes", 1);
 pref("extensions.autoupdate.enabled", true);
 pref("extensions.autoupdate.interval", 86400);
 pref("extensions.update.enabled", true);
 pref("extensions.update.interval", 86400);
 pref("extensions.dss.enabled", false);
 pref("extensions.ignoreMTimeChanges", false);
 pref("extensions.logging.enabled", false);
 pref("extensions.hideInstallButton", true);
+pref("extensions.showMismatchUI", false);
 pref("extensions.hideUpdateButton", false);
 pref("extensions.strictCompatibility", false);
 pref("extensions.minCompatibleAppVersion", "11.0");
 
 pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
 pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
 
 /* preferences for the Get Add-ons pane */
--- a/testing/geckodriver/src/prefs.rs
+++ b/testing/geckodriver/src/prefs.rs
@@ -153,16 +153,18 @@ lazy_static! {
 
         // Disable intalling any distribution extensions or add-ons
         ("extensions.installDistroAddons", Pref::new(false)),
 
         // Make sure Shield doesn't hit the network.
         // Removed in Firefox 60.
         ("extensions.shield-recipe-client.api_url", Pref::new("")),
 
+        ("extensions.showMismatchUI", Pref::new(false)),
+
         // Turn off extension updates so they do not bother tests
         ("extensions.update.enabled", Pref::new(false)),
         ("extensions.update.notifyUser", Pref::new(false)),
 
         // Make sure opening about:addons will not hit the network
         ("extensions.webservice.discoverURL", Pref::new("http://%(server)s/dummy/discoveryURL")),
 
         // Allow the application to have focus even it runs in the
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -63,16 +63,17 @@ class GeckoInstance(object):
         "extensions.enabledScopes": 5,
         # Disable metadata caching for installed add-ons by default
         "extensions.getAddons.cache.enabled": False,
         # Disable intalling any distribution add-ons
         "extensions.installDistroAddons": False,
         # Make sure Shield doesn't hit the network.
         # Removed in Firefox 60.
         "extensions.shield-recipe-client.api_url": "",
+        "extensions.showMismatchUI": False,
         # Turn off extension updates so they don't bother tests
         "extensions.update.enabled": False,
         "extensions.update.notifyUser": False,
         # Make sure opening about:addons won"t hit the network
         "extensions.webservice.discoverURL": "http://%(server)s/dummy/discoveryURL",
 
         # Allow the application to have focus even it runs in the background
         "focusmanager.testmode": True,
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -192,16 +192,18 @@ const RECOMMENDED_PREFS = new Map([
 
   // Disable metadata caching for installed add-ons by default
   ["extensions.getAddons.cache.enabled", false],
 
   // Disable installing any distribution extensions or add-ons.
   // Should be set in profile.
   ["extensions.installDistroAddons", false],
 
+  ["extensions.showMismatchUI", false],
+
   // Turn off extension updates so they do not bother tests
   ["extensions.update.enabled", false],
   ["extensions.update.notifyUser", false],
 
   // Make sure opening about:addons will not hit the network
   [
     "extensions.webservice.discoverURL",
     "http://%(server)s/dummy/discoveryURL",
--- a/testing/mozbase/mozprofile/mozprofile/profile.py
+++ b/testing/mozbase/mozprofile/mozprofile/profile.py
@@ -407,16 +407,18 @@ class FirefoxProfile(Profile):
         # Also ensure that those are not getting disabled.
         # see: https://developer.mozilla.org/en/Installing_extensions
         'extensions.enabledScopes': 5,
         'extensions.autoDisableScopes': 10,
         # Don't send the list of installed addons to AMO
         'extensions.getAddons.cache.enabled': False,
         # Don't install distribution add-ons from the app folder
         'extensions.installDistroAddons': False,
+        # Dont' run the add-on compatibility check during start-up
+        'extensions.showMismatchUI': False,
         # Don't automatically update add-ons
         'extensions.update.enabled': False,
         # Don't open a dialog to show available add-on updates
         'extensions.update.notifyUser': False,
         # Enable test mode to run multiple tests in parallel
         'focusmanager.testmode': True,
         # Enable test mode to not raise an OS level dialog for location sharing
         'geo.provider.testing': True,
new file mode 100644
--- /dev/null
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/update.properties
@@ -0,0 +1,17 @@
+# 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/.
+
+# LOCALIZATION NOTE (addonUpdateTitle)
+# %S will be replace with the localized name of the application
+addonUpdateTitle=%S Update
+
+# LOCALIZATION NOTE (addonUpdateMessage)
+# %S will be replace with the localized name of the application
+addonUpdateMessage=%S is updating your extensions…
+
+addonUpdateCancelMessage=Still updating. Want to wait?
+
+# LOCALIZATION NOTE (addonUpdateCancelButton)
+# %S will be replace with the localized name of the application
+addonUpdateCancelButton=Stop update and launch %S
--- a/toolkit/locales/jar.mn
+++ b/toolkit/locales/jar.mn
@@ -88,16 +88,17 @@
   locale/@AB_CD@/mozapps/downloads/unknownContentType.properties  (%chrome/mozapps/downloads/unknownContentType.properties)
   locale/@AB_CD@/mozapps/downloads/unknownContentType.dtd         (%chrome/mozapps/downloads/unknownContentType.dtd)
   locale/@AB_CD@/mozapps/downloads/settingsChange.dtd             (%chrome/mozapps/downloads/settingsChange.dtd)
   locale/@AB_CD@/mozapps/downloads/downloads.properties           (%chrome/mozapps/downloads/downloads.properties)
   locale/@AB_CD@/mozapps/extensions/extensions.dtd                (%chrome/mozapps/extensions/extensions.dtd)
 #ifndef MOZ_FENNEC
   locale/@AB_CD@/mozapps/extensions/extensions.properties         (%chrome/mozapps/extensions/extensions.properties)
   locale/@AB_CD@/mozapps/extensions/blocklist.dtd                 (%chrome/mozapps/extensions/blocklist.dtd)
+  locale/@AB_CD@/mozapps/extensions/update.properties             (%chrome/mozapps/extensions/update.properties)
 #endif
   locale/@AB_CD@/mozapps/handling/handling.dtd                    (%chrome/mozapps/handling/handling.dtd)
   locale/@AB_CD@/mozapps/handling/handling.properties             (%chrome/mozapps/handling/handling.properties)
   locale/@AB_CD@/mozapps/preferences/changemp.dtd                 (%chrome/mozapps/preferences/changemp.dtd)
   locale/@AB_CD@/mozapps/preferences/removemp.dtd                 (%chrome/mozapps/preferences/removemp.dtd)
   locale/@AB_CD@/mozapps/preferences/preferences.properties       (%chrome/mozapps/preferences/preferences.properties)
   locale/@AB_CD@/mozapps/profile/createProfileWizard.dtd          (%chrome/mozapps/profile/createProfileWizard.dtd)
   locale/@AB_CD@/mozapps/profile/profileSelection.properties      (%chrome/mozapps/profile/profileSelection.properties)
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/content/update.css
@@ -0,0 +1,26 @@
+body {
+  font: message-box;
+  min-width: 480px;
+}
+
+#message {
+  font-size: 14px;
+}
+
+#message, #cancel-section {
+  margin: 10px 5px;
+}
+
+#progress {
+  width: calc(100% - 10px);
+  margin: 0 5px;
+}
+
+#cancel-section {
+  display: flex;
+  justify-content: space-between;
+}
+
+#cancel-message {
+  vertical-align: middle;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/content/update.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <script src="update.js"></script>
+    <link rel="stylesheet"  href="chrome://mozapps/content/extensions/update.css">
+  </head>
+  <body>
+    <div>
+      <div id="message"></div>
+
+      <progress id="progress" val="0" max="1"></progress>
+
+      <div id="cancel-section">
+        <span id="cancel-message"></span>
+        <button id="cancel-btn"></button>
+      </div>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/content/update.js
@@ -0,0 +1,24 @@
+"use strict";
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+let BRAND_PROPS = "chrome://branding/locale/brand.properties";
+let UPDATE_PROPS = "chrome://mozapps/locale/extensions/update.properties";
+
+let appName = Services.strings.createBundle(BRAND_PROPS)
+                      .GetStringFromName("brandShortName");
+let bundle = Services.strings.createBundle(UPDATE_PROPS);
+
+let titleText = bundle.formatStringFromName("addonUpdateTitle", [appName], 1);
+let messageText = bundle.formatStringFromName("addonUpdateMessage", [appName], 1);
+let cancelText = bundle.GetStringFromName("addonUpdateCancelMessage");
+let cancelButtonText = bundle.formatStringFromName("addonUpdateCancelButton", [appName], 1);
+
+document.title = titleText;
+
+window.addEventListener("load", e => {
+  document.getElementById("message").textContent = messageText;
+  document.getElementById("cancel-message").textContent = cancelText;
+  document.getElementById("cancel-btn").textContent = cancelButtonText;
+  window.sizeToContent();
+});
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -330,16 +330,19 @@ var AddonTestUtils = {
     Services.prefs.setIntPref("extensions.autoDisableScopes", 0);
 
     // And scan for changes at startup
     Services.prefs.setIntPref("extensions.startupScanScopes", 15);
 
     // By default, don't cache add-ons in AddonRepository.jsm
     Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", false);
 
+    // Disable the compatibility updates window by default
+    Services.prefs.setBoolPref("extensions.showMismatchUI", false);
+
     // Point update checks to the local machine for fast failures
     Services.prefs.setCharPref("extensions.update.url", "http://127.0.0.1/updateURL");
     Services.prefs.setCharPref("extensions.update.background.url", "http://127.0.0.1/updateBackgroundURL");
     Services.prefs.setCharPref("extensions.blocklist.url", "http://127.0.0.1/blocklistURL");
     Services.prefs.setCharPref("services.settings.server", "http://localhost/dummy-kinto/v1");
 
     // By default ignore bundled add-ons
     Services.prefs.setBoolPref("extensions.installDistroAddons", false);
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -59,16 +59,17 @@ const nsIFile = Components.Constructor("
 const PREF_DB_SCHEMA                  = "extensions.databaseSchema";
 const PREF_XPI_STATE                  = "extensions.xpiState";
 const PREF_BLOCKLIST_ITEM_URL         = "extensions.blocklist.itemURL";
 const PREF_BOOTSTRAP_ADDONS           = "extensions.bootstrappedAddons";
 const PREF_PENDING_OPERATIONS         = "extensions.pendingOperations";
 const PREF_EM_EXTENSION_FORMAT        = "extensions.";
 const PREF_EM_ENABLED_SCOPES          = "extensions.enabledScopes";
 const PREF_EM_STARTUP_SCAN_SCOPES     = "extensions.startupScanScopes";
+const PREF_EM_SHOW_MISMATCH_UI        = "extensions.showMismatchUI";
 const PREF_XPI_ENABLED                = "xpinstall.enabled";
 const PREF_XPI_WHITELIST_REQUIRED     = "xpinstall.whitelist.required";
 const PREF_XPI_DIRECT_WHITELISTED     = "xpinstall.whitelist.directRequest";
 const PREF_XPI_FILE_WHITELISTED       = "xpinstall.whitelist.fileRequest";
 // xpinstall.signatures.required only supported in dev builds
 const PREF_XPI_SIGNATURES_REQUIRED    = "xpinstall.signatures.required";
 const PREF_XPI_SIGNATURES_DEV_ROOT    = "xpinstall.signatures.dev-root";
 const PREF_LANGPACK_SIGNATURES        = "extensions.langpacks.signatures.required";
@@ -1742,16 +1743,19 @@ var XPIProvider = {
   // The value of the minCompatibleAppVersion preference
   minCompatibleAppVersion: null,
   // The value of the minCompatiblePlatformVersion preference
   minCompatiblePlatformVersion: null,
   // A Map of active addons to their bootstrapScope by ID
   activeAddons: new Map(),
   // True if the platform could have activated extensions
   extensionsActive: false,
+  // True if all of the add-ons found during startup were installed in the
+  // application install location
+  allAppGlobal: true,
   // New distribution addons awaiting permissions approval
   newDistroAddons: null,
   // Keep track of startup phases for telemetry
   runPhase: XPI_STARTING,
   // Per-addon telemetry information
   _telemetryDetails: {},
   // Have we started shutting down bootstrap add-ons?
   _closing: false,
@@ -2029,16 +2033,26 @@ var XPIProvider = {
       Services.obs.addObserver(this, NOTIFICATION_TOOLBOX_CONNECTION_CHANGE);
 
 
       let flushCaches = this.checkForChanges(aAppChanged, aOldAppVersion,
                                              aOldPlatformVersion);
 
       AddonManagerPrivate.markProviderSafe(this);
 
+      if (aAppChanged && !this.allAppGlobal &&
+          Services.prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true) &&
+          AddonManager.updateEnabled) {
+        let addonsToUpdate = this.shouldForceUpdateCheck(aAppChanged);
+        if (addonsToUpdate) {
+          this.noLegacyStartupCheck(addonsToUpdate);
+          flushCaches = true;
+        }
+      }
+
       if (flushCaches) {
         Services.obs.notifyObservers(null, "startupcache-invalidate");
         // UI displayed early in startup (like the compatibility UI) may have
         // caused us to cache parts of the skin or locale in memory. These must
         // be flushed to allow extension provided skins and locales to take full
         // effect
         Services.obs.notifyObservers(null, "chrome-flush-skin-caches");
         Services.obs.notifyObservers(null, "chrome-flush-caches");
@@ -2259,16 +2273,165 @@ var XPIProvider = {
           let data = {oldVersion: addon.version};
           let method = callUpdate ? "update" : "install";
           this.callBootstrapMethod(newAddon, file, method, reason, data);
         }
       }
     }
   },
 
+  /**
+   * If the application has been upgraded and there are add-ons outside the
+   * application directory then we may need to synchronize compatibility
+   * information but only if the mismatch UI isn't disabled.
+   *
+   * @returns null if no update check is needed, otherwise an array of add-on
+   *          IDs to check for updates.
+   */
+  shouldForceUpdateCheck(aAppChanged) {
+    AddonManagerPrivate.recordSimpleMeasure("XPIDB_metadata_age", AddonRepository.metadataAge());
+
+    let startupChanges = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
+    logger.debug("shouldForceUpdateCheck startupChanges: " + startupChanges.toSource());
+    AddonManagerPrivate.recordSimpleMeasure("XPIDB_startup_disabled", startupChanges.length);
+
+    let forceUpdate = [];
+    if (startupChanges.length > 0) {
+    let addons = XPIDatabase.getAddons();
+      for (let addon of addons) {
+        if ((startupChanges.includes(addon.id)) &&
+            (addon.permissions() & AddonManager.PERM_CAN_UPGRADE) &&
+            (!addon.isCompatible || isDisabledLegacy(addon))) {
+          logger.debug("shouldForceUpdateCheck: can upgrade disabled add-on " + addon.id);
+          forceUpdate.push(addon.id);
+        }
+      }
+    }
+
+    if (forceUpdate.length > 0) {
+      return forceUpdate;
+    }
+
+    return null;
+  },
+
+  /**
+   * Perform startup check for updates of legacy extensions.
+   * This runs during startup when an app update has made some add-ons
+   * incompatible and legacy add-on support is diasabled.
+   * In this case, we just do a quiet update check.
+   *
+   * @param {Array<string>} ids The ids of the addons to check for updates.
+   *
+   * @returns {Set<string>} The ids of any addons that were updated.  These
+   *                        addons will have been started by the update
+   *                        process so they should not be started by the
+   *                        regular bootstrap startup code.
+   */
+  noLegacyStartupCheck(ids) {
+    let started = new Set();
+    const DIALOG = "chrome://mozapps/content/extensions/update.html";
+    const SHOW_DIALOG_DELAY = 1000;
+    const SHOW_CANCEL_DELAY = 30000;
+
+    // Keep track of a value between 0 and 1 indicating the progress
+    // for each addon.  Just combine these linearly into a single
+    // value for the progress bar in the update dialog.
+    let updateProgress = val => {};
+    let progressByID = new Map();
+    function setProgress(id, val) {
+      progressByID.set(id, val);
+      updateProgress(Array.from(progressByID.values()).reduce((a, b) => a + b) / progressByID.size);
+    }
+
+    // Do an update check for one addon and try to apply the update if
+    // there is one.  Progress for the check is arbitrarily defined as
+    // 10% done when the update check is done, between 10-90% during the
+    // download, then 100% when the update has been installed.
+    let checkOne = async (id) => {
+      logger.debug(`Checking for updates to disabled addon ${id}\n`);
+
+      setProgress(id, 0);
+
+      let addon = await AddonManager.getAddonByID(id);
+      let install = await new Promise(resolve => addon.findUpdates({
+        onUpdateFinished() { resolve(null); },
+        onUpdateAvailable(addon, install) { resolve(install); },
+      }, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED));
+
+      if (!install) {
+        setProgress(id, 1);
+        return;
+      }
+
+      setProgress(id, 0.1);
+
+      let installPromise = new Promise(resolve => {
+        let finish = () => {
+          setProgress(id, 1);
+          resolve();
+        };
+        install.addListener({
+          onDownloadProgress() {
+            if (install.maxProgress != 0) {
+              setProgress(id, 0.1 + 0.8 * install.progress / install.maxProgress);
+            }
+          },
+          onDownloadEnded() {
+            setProgress(id, 0.9);
+          },
+          onDownloadFailed: finish,
+          onInstallFailed: finish,
+          onInstallEnded() {
+            started.add(id);
+            AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED, id);
+            finish();
+          },
+        });
+      });
+      install.install();
+      await installPromise;
+    };
+
+    let finished = false;
+    Promise.all(ids.map(checkOne)).then(() => { finished = true; });
+
+    let window;
+    let timer = setTimeout(() => {
+      const FEATURES = "chrome,dialog,centerscreen,scrollbars=no";
+      window = Services.ww.openWindow(null, DIALOG, "", FEATURES, null);
+
+      let cancelDiv;
+      window.addEventListener("DOMContentLoaded", e => {
+        let progress = window.document.getElementById("progress");
+        updateProgress = val => { progress.value = val; };
+
+        cancelDiv = window.document.getElementById("cancel-section");
+        cancelDiv.setAttribute("style", "display: none;");
+
+        let cancelBtn = window.document.getElementById("cancel-btn");
+        cancelBtn.addEventListener("click", e => { finished = true; });
+      });
+
+      timer = setTimeout(() => {
+        cancelDiv.removeAttribute("style");
+        window.sizeToContent();
+      }, SHOW_CANCEL_DELAY - SHOW_DIALOG_DELAY);
+    }, SHOW_DIALOG_DELAY);
+
+    Services.tm.spinEventLoopUntil(() => finished);
+
+    clearTimeout(timer);
+    if (window) {
+      window.close();
+    }
+
+    return started;
+  },
+
   async updateSystemAddons() {
     let systemAddonLocation = XPIProvider.installLocationsByName[KEY_APP_SYSTEM_ADDONS];
     if (!systemAddonLocation)
       return;
 
     // Don't do anything in safe mode
     if (Services.appinfo.inSafeMode)
       return;
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -1440,16 +1440,20 @@ this.XPIDatabaseReconcile = {
     let previousVisible = this.getVisibleAddons(previousAddons);
     let currentVisible = this.flattenByID(currentAddons, hideLocation);
 
     // Pass over the new set of visible add-ons, record any changes that occurred
     // during startup and call bootstrap install/uninstall scripts as necessary
     for (let [id, currentAddon] of currentVisible) {
       let previousAddon = previousVisible.get(id);
 
+      // Note if any visible add-on is not in the application install location
+      if (currentAddon._installLocation.name != KEY_APP_GLOBAL)
+        XPIProvider.allAppGlobal = false;
+
       let isActive = !currentAddon.disabled && !currentAddon.pendingUninstall;
       let wasActive = previousAddon ? previousAddon.active : currentAddon.active;
 
       if (!previousAddon) {
         // If we had a manifest for this add-on it was a staged install and
         // so wasn't something recovered from a corrupt database
         let wasStaged = !!loadedManifest(currentAddon._installLocation, id);
 
--- a/toolkit/mozapps/extensions/jar.mn
+++ b/toolkit/mozapps/extensions/jar.mn
@@ -9,16 +9,19 @@ toolkit.jar:
   content/mozapps/extensions/extensions.css                     (content/extensions.css)
   content/mozapps/extensions/extensions.js                      (content/extensions.js)
 * content/mozapps/extensions/extensions.xml                     (content/extensions.xml)
   content/mozapps/extensions/updateinfo.xsl                     (content/updateinfo.xsl)
   content/mozapps/extensions/blocklist.xul                      (content/blocklist.xul)
   content/mozapps/extensions/blocklist.js                       (content/blocklist.js)
   content/mozapps/extensions/blocklist.css                      (content/blocklist.css)
   content/mozapps/extensions/blocklist.xml                      (content/blocklist.xml)
+  content/mozapps/extensions/update.html                        (content/update.html)
+  content/mozapps/extensions/update.js                          (content/update.js)
+  content/mozapps/extensions/update.css                         (content/update.css)
   content/mozapps/extensions/eula.xul                           (content/eula.xul)
   content/mozapps/extensions/eula.js                            (content/eula.js)
   content/mozapps/extensions/pluginPrefs.xul                    (content/pluginPrefs.xul)
   content/mozapps/extensions/pluginPrefs.js                     (content/pluginPrefs.js)
   content/mozapps/extensions/OpenH264-license.txt               (content/OpenH264-license.txt)
 #endif
   content/mozapps/xpinstall/xpinstallConfirm.xul                (content/xpinstallConfirm.xul)
   content/mozapps/xpinstall/xpinstallConfirm.js                 (content/xpinstallConfirm.js)