Bug 1599360 - Use AppUpdater.jsm in aboutDialog-appUpdater.js when preffed on, and use the current implementation when preffed off r=rstrong a=jcristau
authorDrew Willcoxon <adw@mozilla.com>
Tue, 03 Dec 2019 06:01:32 +0000
changeset 566682 76bfe47a96892f087cc63b184d39e9ff03a573f4
parent 566681 849518df51c9527b9d8bdcd35eadcd5a6fec532f
child 566683 05a20bf0606f6d43549fe2c2e92db504286fd3ea
push id12373
push userccoroiu@mozilla.com
push dateWed, 04 Dec 2019 10:47:12 +0000
treeherdermozilla-beta@b69378d81dcf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrstrong, jcristau
bugs1599360
milestone72.0
Bug 1599360 - Use AppUpdater.jsm in aboutDialog-appUpdater.js when preffed on, and use the current implementation when preffed off r=rstrong a=jcristau Summary of changes: * Copy aboutDialog-appUpdater.js to a new aboutDialog-appUpdater-legacy.js file * Update aboutDialog-appUpdater.js: Rewrite it to use the new AppUpdater.jsm when the `browser.aboutDialogNewAppUpdater` pref is true, and load aboutDialog-appUpdater-legacy.js otherwise * In toolkit/mozapps/update/tests/browser, add new browser.legacy.ini and browser.legacy.bits.ini files that do not set `browser.aboutDialogNewAppUpdater` to true, so that the old implementation is still tested * Update browser.ini and browser.bits.ini files to set `browser.aboutDialogNewAppUpdater` to true so that the new implementation is tested If all this is OK, I'll file another bug for removing the legacy stuff once we merge. Differential Revision: https://phabricator.services.mozilla.com/D54837
browser/base/content/aboutDialog-appUpdater-legacy.js
browser/base/content/aboutDialog-appUpdater.js
browser/base/jar.mn
toolkit/mozapps/update/tests/browser/browser.bits.ini
toolkit/mozapps/update/tests/browser/browser.ini
toolkit/mozapps/update/tests/browser/browser.legacy.bits.ini
toolkit/mozapps/update/tests/browser/browser.legacy.ini
toolkit/mozapps/update/tests/browser/browser_aboutDialog_legacyAppUpdater.js
toolkit/mozapps/update/tests/browser/browser_aboutDialog_newAppUpdater.js
toolkit/mozapps/update/tests/moz.build
copy from browser/base/content/aboutDialog-appUpdater.js
copy to browser/base/content/aboutDialog-appUpdater-legacy.js
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater-legacy.js
@@ -2,36 +2,19 @@
  * 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/. */
 
 // Note: this file is included in aboutDialog.xul and preferences/advanced.xhtml
 // if MOZ_UPDATER is defined.
 
 /* import-globals-from aboutDialog.js */
 
-var { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "DownloadUtils",
-  "resource://gre/modules/DownloadUtils.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "UpdateUtils",
-  "resource://gre/modules/UpdateUtils.jsm"
-);
-
 const PREF_APP_UPDATE_CANCELATIONS_OSX = "app.update.cancelations.osx";
 const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
 
-var gAppUpdater;
-
 function onUnload(aEvent) {
   if (gAppUpdater) {
     if (gAppUpdater.isChecking) {
       gAppUpdater.checker.stopCurrentCheck();
     }
     // Safe to call even when there isn't a download in progress.
     gAppUpdater.removeDownloadListener();
     gAppUpdater = null;
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -2,202 +2,140 @@
  * 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/. */
 
 // Note: this file is included in aboutDialog.xul and preferences/advanced.xhtml
 // if MOZ_UPDATER is defined.
 
 /* import-globals-from aboutDialog.js */
 
+// These two eslint directives should be removed when we remove handling for the
+// legacy app updater.
+/* eslint-disable prettier/prettier */
+/* global AppUpdater, appUpdater, onUnload */
+
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "DownloadUtils",
-  "resource://gre/modules/DownloadUtils.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "UpdateUtils",
-  "resource://gre/modules/UpdateUtils.jsm"
-);
-
-const PREF_APP_UPDATE_CANCELATIONS_OSX = "app.update.cancelations.osx";
-const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
+XPCOMUtils.defineLazyModuleGetters(this, {
+  DownloadUtils: "resource://gre/modules/DownloadUtils.jsm",
+  UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
+});
 
 var gAppUpdater;
 
+(() => {
+
+// If the new app updater is preffed off, load the legacy version.
+if (!Services.prefs.getBoolPref("browser.aboutDialogNewAppUpdater", false)) {
+  Services.scriptloader.loadSubScript(
+    "chrome://browser/content/aboutDialog-appUpdater-legacy.js",
+    this
+  );
+  return;
+}
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  AppUpdater: "resource:///modules/AppUpdater.jsm",
+});
+
 function onUnload(aEvent) {
   if (gAppUpdater) {
-    if (gAppUpdater.isChecking) {
-      gAppUpdater.checker.stopCurrentCheck();
-    }
-    // Safe to call even when there isn't a download in progress.
-    gAppUpdater.removeDownloadListener();
+    gAppUpdater.stopCurrentCheck();
     gAppUpdater = null;
   }
 }
 
 function appUpdater(options = {}) {
-  XPCOMUtils.defineLazyServiceGetter(
-    this,
-    "aus",
-    "@mozilla.org/updates/update-service;1",
-    "nsIApplicationUpdateService"
-  );
-  XPCOMUtils.defineLazyServiceGetter(
-    this,
-    "checker",
-    "@mozilla.org/updates/update-checker;1",
-    "nsIUpdateChecker"
-  );
-  XPCOMUtils.defineLazyServiceGetter(
-    this,
-    "um",
-    "@mozilla.org/updates/update-manager;1",
-    "nsIUpdateManager"
-  );
+  this._appUpdater = new AppUpdater();
+
+  this._appUpdateListener = (status, ...args) => {
+    this._onAppUpdateStatus(status, ...args);
+  };
+  this._appUpdater.addListener(this._appUpdateListener);
 
   this.options = options;
   this.updateDeck = document.getElementById("updateDeck");
-  this.promiseAutoUpdateSetting = null;
 
   this.bundle = Services.strings.createBundle(
     "chrome://browser/locale/browser.properties"
   );
 
   let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
   let manualLink = document.getElementById("manualLink");
   manualLink.textContent = manualURL;
   manualLink.href = manualURL;
   document.getElementById("failedLink").href = manualURL;
 
-  if (this.updateDisabledByPolicy) {
-    this.selectPanel("policyDisabled");
-    return;
-  }
-
-  if (this.isReadyForRestart) {
-    this.selectPanel("apply");
-    return;
-  }
-
-  if (this.aus.isOtherInstanceHandlingUpdates) {
-    this.selectPanel("otherInstanceHandlingUpdates");
-    return;
-  }
-
-  if (this.isDownloading) {
-    this.startDownload();
-    // selectPanel("downloading") is called from setupDownloadingUI().
-    return;
-  }
-
-  if (this.isStaging) {
-    this.waitForUpdateToStage();
-    // selectPanel("applying"); is called from waitForUpdateToStage().
-    return;
-  }
-
-  // We might need this value later, so start loading it from the disk now.
-  this.promiseAutoUpdateSetting = UpdateUtils.getAppUpdateAutoEnabled();
-
-  // That leaves the options
-  // "Check for updates, but let me choose whether to install them", and
-  // "Automatically install updates".
-  // In both cases, we check for updates without asking.
-  // In the "let me choose" case, we ask before downloading though, in onCheckComplete.
-  this.checkForUpdates();
+  this._appUpdater.check();
 }
 
 appUpdater.prototype = {
-  // true when there is an update check in progress.
-  isChecking: false,
-
-  // true when there is an update ready to be applied on restart or staged.
-  get isPending() {
-    if (this.update) {
-      return (
-        this.update.state == "pending" ||
-        this.update.state == "pending-service" ||
-        this.update.state == "pending-elevate"
-      );
-    }
-    return (
-      this.um.activeUpdate &&
-      (this.um.activeUpdate.state == "pending" ||
-        this.um.activeUpdate.state == "pending-service" ||
-        this.um.activeUpdate.state == "pending-elevate")
-    );
+  stopCurrentCheck() {
+    this._appUpdater.removeListener(this._appUpdateListener);
+    this._appUpdater.stop();
   },
 
-  // true when there is an update already staged.
-  get isApplied() {
-    if (this.update) {
-      return (
-        this.update.state == "applied" || this.update.state == "applied-service"
-      );
-    }
-    return (
-      this.um.activeUpdate &&
-      (this.um.activeUpdate.state == "applied" ||
-        this.um.activeUpdate.state == "applied-service")
-    );
+  get update() {
+    return this._appUpdater.update;
   },
 
-  get isStaging() {
-    if (!this.updateStagingEnabled) {
-      return false;
-    }
-    let errorCode;
-    if (this.update) {
-      errorCode = this.update.errorCode;
-    } else if (this.um.activeUpdate) {
-      errorCode = this.um.activeUpdate.errorCode;
+  _onAppUpdateStatus(status, ...args) {
+    switch (status) {
+      case AppUpdater.STATUS.UPDATE_DISABLED_BY_POLICY:
+        this.selectPanel("policyDisabled");
+        break;
+      case AppUpdater.STATUS.READY_FOR_RESTART:
+        this.selectPanel("apply");
+        break;
+      case AppUpdater.STATUS.OTHER_INSTANCE_HANDLING_UPDATES:
+        this.selectPanel("otherInstanceHandlingUpdates");
+        break;
+      case AppUpdater.STATUS.DOWNLOADING:
+        if (!args.length) {
+          this.downloadStatus = document.getElementById("downloadStatus");
+          this.downloadStatus.textContent = DownloadUtils.getTransferTotal(
+            0,
+            this.update.selectedPatch.size
+          );
+          this.selectPanel("downloading");
+        } else {
+          let [progress, max] = args;
+          this.downloadStatus.textContent = DownloadUtils.getTransferTotal(
+            progress,
+            max
+          );
+        }
+        break;
+      case AppUpdater.STATUS.STAGING:
+        this.selectPanel("applying");
+        break;
+      case AppUpdater.STATUS.CHECKING:
+        this.selectPanel("checkingForUpdates");
+        break;
+      case AppUpdater.STATUS.NO_UPDATES_FOUND:
+        this.selectPanel("noUpdatesFound");
+        break;
+      case AppUpdater.STATUS.UNSUPPORTED_SYSTEM:
+        if (this.update.detailsURL) {
+          let unsupportedLink = document.getElementById("unsupportedLink");
+          unsupportedLink.href = this.update.detailsURL;
+        }
+        this.selectPanel("unsupportedSystem");
+        break;
+      case AppUpdater.STATUS.MANUAL_UPDATE:
+        this.selectPanel("manualUpdate");
+        break;
+      case AppUpdater.STATUS.DOWNLOAD_AND_INSTALL:
+        this.selectPanel("downloadAndInstall");
+        break;
+      case AppUpdater.STATUS.DOWNLOAD_FAILED:
+        this.selectPanel("downloadFailed");
+        break;
     }
-    // If the state is pending and the error code is not 0, staging must have
-    // failed.
-    return this.isPending && errorCode == 0;
-  },
-
-  // true when an update ready to restart to finish the update process.
-  get isReadyForRestart() {
-    if (this.updateStagingEnabled) {
-      let errorCode;
-      if (this.update) {
-        errorCode = this.update.errorCode;
-      } else if (this.um.activeUpdate) {
-        errorCode = this.um.activeUpdate.errorCode;
-      }
-      // If the state is pending and the error code is not 0, staging must have
-      // failed and Firefox should be restarted to try to apply the update
-      // without staging.
-      return this.isApplied || (this.isPending && errorCode != 0);
-    }
-    return this.isPending;
-  },
-
-  // true when there is an update download in progress.
-  get isDownloading() {
-    if (this.update) {
-      return this.update.state == "downloading";
-    }
-    return this.um.activeUpdate && this.um.activeUpdate.state == "downloading";
-  },
-
-  // true when updating has been disabled by enterprise policy
-  get updateDisabledByPolicy() {
-    return Services.policies && !Services.policies.isAllowed("appUpdate");
-  },
-
-  // true when updating in background is enabled.
-  get updateStagingEnabled() {
-    return !this.updateDisabledByPolicy && this.aus.canStageUpdates;
   },
 
   /**
    * Sets the panel of the updateDeck.
    *
    * @param  aChildID
    *         The id of the deck's child to select, e.g. "apply".
    */
@@ -237,35 +175,25 @@ appUpdater.prototype = {
       this.updateDeck.selectedPanel = panel;
     }
   },
 
   /**
    * Check for updates
    */
   checkForUpdates() {
-    // Clear prefs that could prevent a user from discovering available updates.
-    if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CANCELATIONS_OSX)) {
-      Services.prefs.clearUserPref(PREF_APP_UPDATE_CANCELATIONS_OSX);
-    }
-    if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ELEVATE_NEVER)) {
-      Services.prefs.clearUserPref(PREF_APP_UPDATE_ELEVATE_NEVER);
-    }
-    this.selectPanel("checkingForUpdates");
-    this.isChecking = true;
-    this.checker.checkForUpdates(this.updateCheckListener, true);
-    // after checking, onCheckComplete() is called
+    this._appUpdater.checkForUpdates();
   },
 
   /**
    * Handles oncommand for the "Restart to Update" button
    * which is presented after the download has been downloaded.
    */
   buttonRestartAfterDownload() {
-    if (!this.isReadyForRestart) {
+    if (!this._appUpdater.isReadyForRestart) {
       return;
     }
 
     gAppUpdater.selectPanel("restarting");
 
     // Notify all windows that an application quit has been requested.
     let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
       Ci.nsISupportsPRBool
@@ -289,224 +217,19 @@ appUpdater.prototype = {
     }
 
     Services.startup.quit(
       Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart
     );
   },
 
   /**
-   * Implements nsIUpdateCheckListener. The methods implemented by
-   * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload
-   * to make it clear which are used by each interface.
-   */
-  updateCheckListener: {
-    /**
-     * See nsIUpdateService.idl
-     */
-    onCheckComplete(aRequest, aUpdates) {
-      gAppUpdater.isChecking = false;
-      gAppUpdater.update = gAppUpdater.aus.selectUpdate(aUpdates);
-      if (!gAppUpdater.update) {
-        gAppUpdater.selectPanel("noUpdatesFound");
-        return;
-      }
-
-      if (gAppUpdater.update.unsupported) {
-        if (gAppUpdater.update.detailsURL) {
-          let unsupportedLink = document.getElementById("unsupportedLink");
-          unsupportedLink.href = gAppUpdater.update.detailsURL;
-        }
-        gAppUpdater.selectPanel("unsupportedSystem");
-        return;
-      }
-
-      if (!gAppUpdater.aus.canApplyUpdates) {
-        gAppUpdater.selectPanel("manualUpdate");
-        return;
-      }
-
-      if (!gAppUpdater.promiseAutoUpdateSetting) {
-        gAppUpdater.promiseAutoUpdateSetting = UpdateUtils.getAppUpdateAutoEnabled();
-      }
-      gAppUpdater.promiseAutoUpdateSetting.then(updateAuto => {
-        if (updateAuto) {
-          // automatically download and install
-          gAppUpdater.startDownload();
-        } else {
-          // ask
-          gAppUpdater.selectPanel("downloadAndInstall");
-        }
-      });
-    },
-
-    /**
-     * See nsIUpdateService.idl
-     */
-    onError(aRequest, aUpdate) {
-      // Errors in the update check are treated as no updates found. If the
-      // update check fails repeatedly without a success the user will be
-      // notified with the normal app update user interface so this is safe.
-      gAppUpdater.isChecking = false;
-      gAppUpdater.selectPanel("noUpdatesFound");
-    },
-
-    /**
-     * See nsISupports.idl
-     */
-    QueryInterface: ChromeUtils.generateQI(["nsIUpdateCheckListener"]),
-  },
-
-  /**
-   * Shows the applying UI until the update has finished staging
-   */
-  waitForUpdateToStage() {
-    if (!this.update) {
-      this.update = this.um.activeUpdate;
-    }
-    this.update.QueryInterface(Ci.nsIWritablePropertyBag);
-    this.update.setProperty("foregroundDownload", "true");
-    this.selectPanel("applying");
-    this.updateUIWhenStagingComplete();
-  },
-
-  /**
    * Starts the download of an update mar.
    */
   startDownload() {
-    if (!this.update) {
-      this.update = this.um.activeUpdate;
-    }
-    this.update.QueryInterface(Ci.nsIWritablePropertyBag);
-    this.update.setProperty("foregroundDownload", "true");
-
-    let state = this.aus.downloadUpdate(this.update, false);
-    if (state == "failed") {
-      this.selectPanel("downloadFailed");
-      return;
-    }
-
-    this.setupDownloadingUI();
+    this._appUpdater.startDownload();
   },
-
-  /**
-   * Switches to the UI responsible for tracking the download.
-   */
-  setupDownloadingUI() {
-    this.downloadStatus = document.getElementById("downloadStatus");
-    this.downloadStatus.textContent = DownloadUtils.getTransferTotal(
-      0,
-      this.update.selectedPatch.size
-    );
-    this.selectPanel("downloading");
-    this.aus.addDownloadListener(this);
-  },
-
-  removeDownloadListener() {
-    if (this.aus) {
-      this.aus.removeDownloadListener(this);
-    }
-  },
-
-  /**
-   * See nsIRequestObserver.idl
-   */
-  onStartRequest(aRequest) {},
+};
 
-  /**
-   * See nsIRequestObserver.idl
-   */
-  onStopRequest(aRequest, aStatusCode) {
-    switch (aStatusCode) {
-      case Cr.NS_ERROR_UNEXPECTED:
-        if (
-          this.update.selectedPatch.state == "download-failed" &&
-          (this.update.isCompleteUpdate || this.update.patchCount != 2)
-        ) {
-          // Verification error of complete patch, informational text is held in
-          // the update object.
-          this.removeDownloadListener();
-          this.selectPanel("downloadFailed");
-          break;
-        }
-        // Verification failed for a partial patch, complete patch is now
-        // downloading so return early and do NOT remove the download listener!
-        break;
-      case Cr.NS_BINDING_ABORTED:
-        // Do not remove UI listener since the user may resume downloading again.
-        break;
-      case Cr.NS_OK:
-        this.removeDownloadListener();
-        if (this.updateStagingEnabled) {
-          this.selectPanel("applying");
-          this.updateUIWhenStagingComplete();
-        } else {
-          this.selectPanel("apply");
-        }
-        break;
-      default:
-        this.removeDownloadListener();
-        this.selectPanel("downloadFailed");
-        break;
-    }
-  },
-
-  /**
-   * See nsIProgressEventSink.idl
-   */
-  onStatus(aRequest, aContext, aStatus, aStatusArg) {},
+this.onUnload = onUnload;
+this.appUpdater = appUpdater;
 
-  /**
-   * See nsIProgressEventSink.idl
-   */
-  onProgress(aRequest, aContext, aProgress, aProgressMax) {
-    this.downloadStatus.textContent = DownloadUtils.getTransferTotal(
-      aProgress,
-      aProgressMax
-    );
-  },
-
-  /**
-   * This function registers an observer that watches for the staging process
-   * to complete. Once it does, it updates the UI to either request that the
-   * user restarts to install the update on success, request that the user
-   * manually download and install the newer version, or automatically download
-   * a complete update if applicable.
-   */
-  updateUIWhenStagingComplete() {
-    let observer = (aSubject, aTopic, aData) => {
-      // Update the UI when the background updater is finished
-      let status = aData;
-      if (
-        status == "applied" ||
-        status == "applied-service" ||
-        status == "pending" ||
-        status == "pending-service" ||
-        status == "pending-elevate"
-      ) {
-        // If the update is successfully applied, or if the updater has
-        // fallen back to non-staged updates, show the "Restart to Update"
-        // button.
-        this.selectPanel("apply");
-      } else if (status == "failed") {
-        // Background update has failed, let's show the UI responsible for
-        // prompting the user to update manually.
-        this.selectPanel("downloadFailed");
-      } else if (status == "downloading") {
-        // We've fallen back to downloading the complete update because the
-        // partial update failed to get staged in the background.
-        // Therefore we need to keep our observer.
-        this.setupDownloadingUI();
-        return;
-      }
-      Services.obs.removeObserver(observer, "update-staged");
-    };
-    Services.obs.addObserver(observer, "update-staged");
-  },
-
-  /**
-   * See nsISupports.idl
-   */
-  QueryInterface: ChromeUtils.generateQI([
-    "nsIProgressEventSink",
-    "nsIRequestObserver",
-  ]),
-};
+})();
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -1,15 +1,16 @@
 # 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/.
 browser.jar:
 %  content browser %content/browser/ contentaccessible=yes
 
         content/browser/aboutDialog-appUpdater.js     (content/aboutDialog-appUpdater.js)
+        content/browser/aboutDialog-appUpdater-legacy.js     (content/aboutDialog-appUpdater-legacy.js)
 *       content/browser/aboutDialog.xul               (content/aboutDialog.xul)
         content/browser/aboutDialog.js                (content/aboutDialog.js)
         content/browser/aboutDialog.css               (content/aboutDialog.css)
         content/browser/aboutRestartRequired.js       (content/aboutRestartRequired.js)
         content/browser/aboutRestartRequired.xhtml    (content/aboutRestartRequired.xhtml)
         content/browser/aboutRobots.xhtml             (content/aboutRobots.xhtml)
         content/browser/aboutRobots.js                (content/aboutRobots.js)
         content/browser/aboutRobots.css               (content/aboutRobots.css)
--- a/toolkit/mozapps/update/tests/browser/browser.bits.ini
+++ b/toolkit/mozapps/update/tests/browser/browser.bits.ini
@@ -8,16 +8,17 @@ support-files =
   ../data/shared.js
   ../data/sharedUpdateXML.js
   app_update.sjs
   downloadPage.html
   testConstants.js
 
 prefs =
   app.update.BITS.enabled=true
+  browser.aboutDialogNewAppUpdater=true
 
 # BITS Download Tests
 #####################
 
 # About Dialog Application Update Tests
 [browser_aboutDialog_bc_downloading.js]
 [browser_aboutDialog_bc_downloading_staging.js]
 [browser_aboutDialog_bc_downloaded.js]
--- a/toolkit/mozapps/update/tests/browser/browser.ini
+++ b/toolkit/mozapps/update/tests/browser/browser.ini
@@ -5,16 +5,17 @@ head = head.js
 support-files =
   ../data/shared.js
   ../data/sharedUpdateXML.js
   app_update.sjs
   downloadPage.html
   testConstants.js
 prefs =
   app.update.BITS.enabled=false
+  browser.aboutDialogNewAppUpdater=true
 
 # About Dialog Application Update Tests
 [browser_aboutDialog_bc_downloading.js]
 [browser_aboutDialog_bc_downloading_staging.js]
 [browser_aboutDialog_bc_downloaded.js]
 [browser_aboutDialog_bc_downloaded_staging.js]
 [browser_aboutDialog_bc_downloaded_stagingFailure.js]
 [browser_aboutDialog_bc_downloaded_staged.js]
@@ -30,16 +31,17 @@ prefs =
 skip-if = os != 'win'
 reason = test must be able to prevent file deletion.
 [browser_aboutDialog_fc_check_malformedXML.js]
 [browser_aboutDialog_fc_check_noUpdate.js]
 [browser_aboutDialog_fc_check_otherInstance.js]
 skip-if = os != 'win'
 reason = Windows only feature.
 [browser_aboutDialog_fc_check_unsupported.js]
+[browser_aboutDialog_newAppUpdater.js]
 
 # about:preferences Application Update Tests
 [browser_aboutPrefs_bc_downloading.js]
 [browser_aboutPrefs_bc_downloading_staging.js]
 [browser_aboutPrefs_bc_downloaded.js]
 [browser_aboutPrefs_bc_downloaded_staging.js]
 [browser_aboutPrefs_bc_downloaded_stagingFailure.js]
 [browser_aboutPrefs_bc_downloaded_staged.js]
copy from toolkit/mozapps/update/tests/browser/browser.bits.ini
copy to toolkit/mozapps/update/tests/browser/browser.legacy.bits.ini
copy from toolkit/mozapps/update/tests/browser/browser.ini
copy to toolkit/mozapps/update/tests/browser/browser.legacy.ini
--- a/toolkit/mozapps/update/tests/browser/browser.ini
+++ b/toolkit/mozapps/update/tests/browser/browser.legacy.ini
@@ -30,16 +30,17 @@ prefs =
 skip-if = os != 'win'
 reason = test must be able to prevent file deletion.
 [browser_aboutDialog_fc_check_malformedXML.js]
 [browser_aboutDialog_fc_check_noUpdate.js]
 [browser_aboutDialog_fc_check_otherInstance.js]
 skip-if = os != 'win'
 reason = Windows only feature.
 [browser_aboutDialog_fc_check_unsupported.js]
+[browser_aboutDialog_legacyAppUpdater.js]
 
 # about:preferences Application Update Tests
 [browser_aboutPrefs_bc_downloading.js]
 [browser_aboutPrefs_bc_downloading_staging.js]
 [browser_aboutPrefs_bc_downloaded.js]
 [browser_aboutPrefs_bc_downloaded_staging.js]
 [browser_aboutPrefs_bc_downloaded_stagingFailure.js]
 [browser_aboutPrefs_bc_downloaded_staged.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/tests/browser/browser_aboutDialog_legacyAppUpdater.js
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// This makes sure the legacy app updater is used when the new one is preffed
+// off.
+add_task(async function aboutDialog_legacyAppUpdater() {
+  let aboutDialog = await waitForAboutDialog();
+  registerCleanupFunction(() => {
+    aboutDialog.close();
+  });
+  await TestUtils.waitForCondition(
+    () => aboutDialog.gAppUpdater,
+    "Wait for gAppUpdater to be set"
+  );
+  Assert.ok(
+    !aboutDialog.gAppUpdater._appUpdater,
+    "gAppUpdater._appUpdater should not be defined when using the legacy app updater"
+  );
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/tests/browser/browser_aboutDialog_newAppUpdater.js
@@ -0,0 +1,20 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// This makes sure the new app updater is used when preffed on.
+add_task(async function aboutDialog_newAppUpdater() {
+  let aboutDialog = await waitForAboutDialog();
+  registerCleanupFunction(() => {
+    aboutDialog.close();
+  });
+  await TestUtils.waitForCondition(
+    () => aboutDialog.gAppUpdater,
+    "Wait for gAppUpdater to be set"
+  );
+  Assert.ok(
+    aboutDialog.gAppUpdater._appUpdater,
+    "gAppUpdater._appUpdater should be defined when using the new app updater"
+  );
+});
--- a/toolkit/mozapps/update/tests/moz.build
+++ b/toolkit/mozapps/update/tests/moz.build
@@ -5,18 +5,20 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 HAS_MISC_RULE = True
 
 FINAL_TARGET = '_tests/xpcshell/toolkit/mozapps/update/tests/data'
 
 if not CONFIG['MOZ_SUITE']:
     BROWSER_CHROME_MANIFESTS += ['browser/browser.ini']
+    BROWSER_CHROME_MANIFESTS += ['browser/browser.legacy.ini']
     if CONFIG['MOZ_BITS_DOWNLOAD']:
         BROWSER_CHROME_MANIFESTS += ['browser/browser.bits.ini']
+        BROWSER_CHROME_MANIFESTS += ['browser/browser.legacy.bits.ini']
 
 XPCSHELL_TESTS_MANIFESTS += [
     'unit_aus_update/xpcshell.ini',
     'unit_base_updater/xpcshell.ini'
 ]
 
 if CONFIG['MOZ_MAINTENANCE_SERVICE']:
     XPCSHELL_TESTS_MANIFESTS += ['unit_service_updater/xpcshell.ini']