Bug 1648815 Don't require builtin certificates for system addon update checks r=rpl,aswan
authorShane Caraveo <scaraveo@mozilla.com>
Wed, 08 Jul 2020 09:04:01 +0000
changeset 539375 9b327379454aa7153111b749f3b4c4724ab95d28
parent 539374 30a3da9f613cabf83e3b5af280229b71580e644a
child 539376 339829507e50bf130c8076977a73b7cab4715cfc
push id121082
push userscaraveo@mozilla.com
push dateWed, 08 Jul 2020 14:13:58 +0000
treeherderautoland@9b327379454a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrpl, aswan
bugs1648815
milestone80.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 1648815 Don't require builtin certificates for system addon update checks r=rpl,aswan Differential Revision: https://phabricator.services.mozilla.com/D81587
toolkit/modules/GMPInstallManager.jsm
toolkit/modules/tests/xpcshell/test_GMPInstallManager.js
toolkit/mozapps/extensions/internal/GMPProvider.jsm
toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/test/browser/browser_gmpProvider.js
toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker.js
toolkit/mozapps/extensions/test/xpcshell/test_gmpProvider.js
--- a/toolkit/modules/GMPInstallManager.jsm
+++ b/toolkit/modules/GMPInstallManager.jsm
@@ -35,22 +35,111 @@ ChromeUtils.defineModuleGetter(
   "resource://gre/modules/CertUtils.jsm"
 );
 ChromeUtils.defineModuleGetter(
   this,
   "UpdateUtils",
   "resource://gre/modules/UpdateUtils.jsm"
 );
 
+ChromeUtils.defineModuleGetter(
+  this,
+  "ServiceRequest",
+  "resource://gre/modules/ServiceRequest.jsm"
+);
+
 function getScopedLogger(prefix) {
   // `PARENT_LOGGER_ID.` being passed here effectively links this logger
   // to the parentLogger.
   return Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP", prefix + " ");
 }
 
+const LOCAL_GMP_SOURCES = [
+  {
+    id: "gmp-gmpopenh264",
+    src: "chrome://global/content/gmp-sources/openh264.json",
+  },
+  {
+    id: "gmp-widevinecdm",
+    src: "chrome://global/content/gmp-sources/widevinecdm.json",
+  },
+];
+
+function downloadJSON(uri) {
+  let log = getScopedLogger("GMPInstallManager.checkForAddons");
+  log.info("fetching config from: " + uri);
+  return new Promise((resolve, reject) => {
+    let xmlHttp = new ServiceRequest({ mozAnon: true });
+
+    xmlHttp.onload = function(aResponse) {
+      resolve(JSON.parse(this.responseText));
+    };
+
+    xmlHttp.onerror = function(e) {
+      reject("Fetching " + uri + " results in error code: " + e.target.status);
+    };
+
+    xmlHttp.open("GET", uri);
+    xmlHttp.overrideMimeType("application/json");
+    xmlHttp.send();
+  });
+}
+
+/**
+ * If downloading from the network fails (AUS server is down),
+ * load the sources from local build configuration.
+ */
+function downloadLocalConfig() {
+  let log = getScopedLogger("GMPInstallManager.checkForAddons");
+  return Promise.all(
+    LOCAL_GMP_SOURCES.map(conf => {
+      return downloadJSON(conf.src).then(addons => {
+        let platforms = addons.vendors[conf.id].platforms;
+        let target = Services.appinfo.OS + "_" + UpdateUtils.ABI;
+        let details = null;
+
+        while (!details) {
+          if (!(target in platforms)) {
+            // There was no matching platform so return false, this addon
+            // will be filtered from the results below
+            log.info("no details found for: " + target);
+            return false;
+          }
+          // Field either has the details of the binary or is an alias
+          // to another build target key that does
+          if (platforms[target].alias) {
+            target = platforms[target].alias;
+          } else {
+            details = platforms[target];
+          }
+        }
+
+        log.info("found plugin: " + conf.id);
+        return {
+          id: conf.id,
+          URL: details.fileUrl,
+          hashFunction: addons.hashFunction,
+          hashValue: details.hashValue,
+          version: addons.vendors[conf.id].version,
+          size: details.filesize,
+        };
+      });
+    })
+  ).then(addons => {
+    // Some filters may not match this platform so
+    // filter those out
+    addons = addons.filter(x => x !== false);
+
+    return {
+      usedFallback: true,
+      addons,
+    };
+  });
+}
+
 /**
  * Provides an easy API for downloading and installing GMP Addons
  */
 function GMPInstallManager() {}
 /**
  * Temp file name used for downloading
  */
 GMPInstallManager.prototype = {
@@ -73,30 +162,36 @@ GMPInstallManager.prototype = {
 
     log.info("Using url (with replacement): " + url);
     return url;
   },
   /**
    * Performs an addon check.
    * @return a promise which will be resolved or rejected.
    *         The promise is resolved with an object with properties:
-   *           gmpAddons: array of GMPAddons
+   *           addons: array of addons
    *           usedFallback: whether the data was collected from online or
    *                         from fallback data within the build
    *         The promise is rejected with an object with properties:
    *           target: The XHR request object
    *           status: The HTTP status code
    *           type: Sometimes specifies type of rejection
    */
   async checkForAddons() {
     let log = getScopedLogger("GMPInstallManager.checkForAddons");
     if (this._deferred) {
       log.error("checkForAddons already called");
       return Promise.reject({ type: "alreadycalled" });
     }
+
+    if (!GMPPrefs.getBool(GMPPrefs.KEY_UPDATE_ENABLED, true)) {
+      log.info("Updates are disabled via media.gmp-manager.updateEnabled");
+      return { usedFallback: true, addons: [] };
+    }
+
     this._deferred = PromiseUtils.defer();
 
     let allowNonBuiltIn = true;
     let certs = null;
     if (!Services.prefs.prefHasUserValue(GMPPrefs.KEY_URL_OVERRIDE)) {
       allowNonBuiltIn = !GMPPrefs.getString(
         GMPPrefs.KEY_CERT_REQUIREBUILTIN,
         true
@@ -107,24 +202,24 @@ GMPInstallManager.prototype = {
     }
 
     let url = await this._getURL();
 
     let addonPromise = ProductAddonChecker.getProductAddonList(
       url,
       allowNonBuiltIn,
       certs
-    );
+    ).catch(downloadLocalConfig);
 
     addonPromise.then(
       res => {
-        if (!res || !res.gmpAddons) {
-          this._deferred.resolve({ gmpAddons: [] });
+        if (!res || !res.addons) {
+          this._deferred.resolve({ addons: [] });
         } else {
-          res.gmpAddons = res.gmpAddons.map(a => new GMPAddon(a));
+          res.addons = res.addons.map(a => new GMPAddon(a));
           this._deferred.resolve(res);
         }
         delete this._deferred;
       },
       ex => {
         this._deferred.reject(ex);
         delete this._deferred;
       }
@@ -218,20 +313,20 @@ GMPInstallManager.prototype = {
       );
       if (secondsBetweenChecks > secondsSinceLast) {
         log.info("Will not check for updates.");
         return { status: "too-frequent-no-check" };
       }
     }
 
     try {
-      let { usedFallback, gmpAddons } = await this.checkForAddons();
+      let { usedFallback, addons } = await this.checkForAddons();
       this._updateLastCheck();
-      log.info("Found " + gmpAddons.length + " addons advertised.");
-      let addonsToInstall = gmpAddons.filter(function(gmpAddon) {
+      log.info("Found " + addons.length + " addons advertised.");
+      let addonsToInstall = addons.filter(function(gmpAddon) {
         log.info("Found addon: " + gmpAddon.toString());
 
         if (!gmpAddon.isValid) {
           log.info("Addon |" + gmpAddon.id + "| is invalid.");
           return false;
         }
 
         if (GMPUtils.isPluginHidden(gmpAddon)) {
--- a/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js
+++ b/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js
@@ -165,28 +165,28 @@ add_test(function test_checkForAddons_no
 
 /**
  * Tests that no addons element returned resolves with no addons
  */
 add_task(async function test_checkForAddons_noAddonsElement() {
   overrideXHR(200, "<updates></updates>");
   let installManager = new GMPInstallManager();
   let res = await installManager.checkForAddons();
-  Assert.equal(res.gmpAddons.length, 0);
+  Assert.equal(res.addons.length, 0);
   installManager.uninit();
 });
 
 /**
  * Tests that empty addons element returned resolves with no addons
  */
 add_task(async function test_checkForAddons_emptyAddonsElement() {
   overrideXHR(200, "<updates><addons/></updates>");
   let installManager = new GMPInstallManager();
   let res = await installManager.checkForAddons();
-  Assert.equal(res.gmpAddons.length, 0);
+  Assert.equal(res.addons.length, 0);
   installManager.uninit();
 });
 
 /**
  * Tests that a response with the wrong root element rejects
  */
 add_test(function test_checkForAddons_wrongResponseXML() {
   overrideXHR(200, "<digits_of_pi>3.141592653589793....</digits_of_pi>");
@@ -318,18 +318,18 @@ add_task(async function test_checkForAdd
     '               hashFunction="sha256"' +
     '               hashValue="1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"' +
     '               version="1.1"/>' +
     "  </addons>" +
     "</updates>";
   overrideXHR(200, responseXML);
   let installManager = new GMPInstallManager();
   let res = await installManager.checkForAddons();
-  Assert.equal(res.gmpAddons.length, 1);
-  let gmpAddon = res.gmpAddons[0];
+  Assert.equal(res.addons.length, 1);
+  let gmpAddon = res.addons[0];
   Assert.equal(gmpAddon.id, "gmp-gmpopenh264");
   Assert.equal(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
   Assert.equal(gmpAddon.hashFunction, "sha256");
   Assert.equal(
     gmpAddon.hashValue,
     "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"
   );
   Assert.equal(gmpAddon.version, "1.1");
@@ -353,18 +353,18 @@ add_task(async function test_checkForAdd
     '               size="42"' +
     '               hashValue="1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"' +
     '               version="1.1"/>' +
     "  </addons>" +
     "</updates>";
   overrideXHR(200, responseXML);
   let installManager = new GMPInstallManager();
   let res = await installManager.checkForAddons();
-  Assert.equal(res.gmpAddons.length, 1);
-  let gmpAddon = res.gmpAddons[0];
+  Assert.equal(res.addons.length, 1);
+  let gmpAddon = res.addons[0];
   Assert.equal(gmpAddon.id, "openh264-plugin-no-at-symbol");
   Assert.equal(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
   Assert.equal(gmpAddon.hashFunction, "sha256");
   Assert.equal(
     gmpAddon.hashValue,
     "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"
   );
   Assert.equal(gmpAddon.size, 42);
@@ -426,47 +426,47 @@ add_task(
       '               hashFunction="sha512"' +
       '               hashValue="141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"' +
       '               notversion="9.1"/>' +
       "  </addons>" +
       "</updates>";
     overrideXHR(200, responseXML);
     let installManager = new GMPInstallManager();
     let res = await installManager.checkForAddons();
-    Assert.equal(res.gmpAddons.length, 7);
-    let gmpAddon = res.gmpAddons[0];
+    Assert.equal(res.addons.length, 7);
+    let gmpAddon = res.addons[0];
     Assert.equal(gmpAddon.id, "gmp-gmpopenh264");
     Assert.equal(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
     Assert.equal(gmpAddon.hashFunction, "sha256");
     Assert.equal(
       gmpAddon.hashValue,
       "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"
     );
     Assert.equal(gmpAddon.version, "1.1");
     Assert.ok(gmpAddon.isValid);
     Assert.ok(!gmpAddon.isInstalled);
 
-    gmpAddon = res.gmpAddons[1];
+    gmpAddon = res.addons[1];
     Assert.equal(gmpAddon.id, "NOT-gmp-gmpopenh264");
     Assert.equal(
       gmpAddon.URL,
       "http://127.0.0.1:8011/NOT-gmp-gmpopenh264-1.1.zip"
     );
     Assert.equal(gmpAddon.hashFunction, "sha512");
     Assert.equal(
       gmpAddon.hashValue,
       "141592656f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"
     );
     Assert.equal(gmpAddon.version, "9.1");
     Assert.ok(gmpAddon.isValid);
     Assert.ok(!gmpAddon.isInstalled);
 
-    for (let i = 2; i < res.gmpAddons.length; i++) {
-      Assert.ok(!res.gmpAddons[i].isValid);
-      Assert.ok(!res.gmpAddons[i].isInstalled);
+    for (let i = 2; i < res.addons.length; i++) {
+      Assert.ok(!res.addons[i].isValid);
+      Assert.ok(!res.addons[i].isInstalled);
     }
     installManager.uninit();
   }
 );
 
 /**
  * Tests that checking for addons when there are also updates available
  * works as expected.
@@ -484,18 +484,18 @@ add_task(async function test_checkForAdd
     '               hashFunction="sha256"' +
     '               hashValue="1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"' +
     '               version="1.1"/>' +
     "  </addons>" +
     "</updates>";
   overrideXHR(200, responseXML);
   let installManager = new GMPInstallManager();
   let res = await installManager.checkForAddons();
-  Assert.equal(res.gmpAddons.length, 1);
-  let gmpAddon = res.gmpAddons[0];
+  Assert.equal(res.addons.length, 1);
+  let gmpAddon = res.addons[0];
   Assert.equal(gmpAddon.id, "gmp-gmpopenh264");
   Assert.equal(gmpAddon.URL, "http://127.0.0.1:8011/gmp-gmpopenh264-1.1.zip");
   Assert.equal(gmpAddon.hashFunction, "sha256");
   Assert.equal(
     gmpAddon.hashValue,
     "1118b90d6f645eefc2b99af17bae396636ace1e33d079c88de715177584e2aee"
   );
   Assert.equal(gmpAddon.version, "1.1");
@@ -561,18 +561,18 @@ async function test_checkForAddons_insta
     (includeSize ? ' size="' + fileSize + '"' : "") +
     '               version="1.1"/>' +
     "  </addons>" +
     "</updates>";
 
   overrideXHR(200, responseXML);
   let installManager = new GMPInstallManager();
   let res = await installManager.checkForAddons();
-  Assert.equal(res.gmpAddons.length, 1);
-  let gmpAddon = res.gmpAddons[0];
+  Assert.equal(res.addons.length, 1);
+  let gmpAddon = res.addons[0];
   Assert.ok(!gmpAddon.isInstalled);
 
   try {
     let extractedPaths = await installManager.installAddon(gmpAddon);
     if (wantInstallReject) {
       Assert.ok(false); // installAddon() should have thrown.
     }
     Assert.equal(extractedPaths.length, 1);
@@ -711,18 +711,18 @@ add_test(function test_installAddon_noSe
     "  </addons>" +
     "</updates>";
 
   overrideXHR(200, responseXML);
   let installManager = new GMPInstallManager();
   let checkPromise = installManager.checkForAddons();
   checkPromise.then(
     res => {
-      Assert.equal(res.gmpAddons.length, 1);
-      let gmpAddon = res.gmpAddons[0];
+      Assert.equal(res.addons.length, 1);
+      let gmpAddon = res.addons[0];
 
       GMPInstallManager.overrideLeaveDownloadedZip = true;
       let installPromise = installManager.installAddon(gmpAddon);
       installPromise.then(
         extractedPaths => {
           do_throw("No server for install should reject");
         },
         err => {
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -405,17 +405,17 @@ GMPWrapper.prototype = {
       return this._updateTask;
     }
 
     this._updateTask = (async () => {
       this._log.trace("findUpdates() - updateTask");
       try {
         let installManager = new GMPInstallManager();
         let res = await installManager.checkForAddons();
-        let update = res.gmpAddons.find(addon => addon.id === this._plugin.id);
+        let update = res.addons.find(addon => addon.id === this._plugin.id);
         if (update && update.isValid && !update.isInstalled) {
           this._log.trace(
             "findUpdates() - found update for " +
               this._plugin.id +
               ", installing"
           );
           await installManager.installAddon(update);
         } else {
--- a/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
@@ -1,59 +1,29 @@
 /* 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/. */
 
 "use strict";
 
 /* exported ProductAddonChecker */
 
-const LOCAL_GMP_SOURCES = [
-  {
-    id: "gmp-gmpopenh264",
-    src: "chrome://global/content/gmp-sources/openh264.json",
-  },
-  {
-    id: "gmp-widevinecdm",
-    src: "chrome://global/content/gmp-sources/widevinecdm.json",
-  },
-];
-
 var EXPORTED_SYMBOLS = ["ProductAddonChecker"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { Log } = ChromeUtils.import("resource://gre/modules/Log.jsm");
 const { CertUtils } = ChromeUtils.import(
   "resource://gre/modules/CertUtils.jsm"
 );
 const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
 
 XPCOMUtils.defineLazyGlobalGetters(this, ["XMLHttpRequest"]);
 
-ChromeUtils.defineModuleGetter(
-  this,
-  "GMPPrefs",
-  "resource://gre/modules/GMPUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "UpdateUtils",
-  "resource://gre/modules/UpdateUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "ServiceRequest",
-  "resource://gre/modules/ServiceRequest.jsm"
-);
-
 // This exists so that tests can override the XHR behaviour for downloading
 // the addon update XML file.
 var CreateXHR = function() {
   return new XMLHttpRequest();
 };
 
 var logger = Log.repository.getLogger("addons.productaddons");
 
@@ -171,35 +141,16 @@ function downloadXML(url, allowNonBuiltI
     request.addEventListener("timeout", fail);
     request.addEventListener("load", success);
 
     logger.info("sending request to: " + url);
     request.send(null);
   });
 }
 
-function downloadJSON(uri) {
-  logger.info("fetching config from: " + uri);
-  return new Promise((resolve, reject) => {
-    let xmlHttp = new ServiceRequest({ mozAnon: true });
-
-    xmlHttp.onload = function(aResponse) {
-      resolve(JSON.parse(this.responseText));
-    };
-
-    xmlHttp.onerror = function(e) {
-      reject("Fetching " + uri + " results in error code: " + e.target.status);
-    };
-
-    xmlHttp.open("GET", uri);
-    xmlHttp.overrideMimeType("application/json");
-    xmlHttp.send();
-  });
-}
-
 /**
  * Parses a list of add-ons from a DOM document.
  *
  * @param  document
  *         The DOM document to parse.
  * @return null if there is no <addons> element otherwise an object containing
  *         an array of the addons listed and a field notifying whether the
  *         fallback was used.
@@ -239,77 +190,21 @@ function parseXML(document) {
     }
     addon.size = Number(addon.size) || undefined;
 
     results.push(addon);
   }
 
   return {
     usedFallback: false,
-    gmpAddons: results,
+    addons: results,
   };
 }
 
 /**
- * If downloading from the network fails (AUS server is down),
- * load the sources from local build configuration.
- */
-function downloadLocalConfig() {
-  if (!GMPPrefs.getBool(GMPPrefs.KEY_UPDATE_ENABLED, true)) {
-    logger.info("Updates are disabled via media.gmp-manager.updateEnabled");
-    return Promise.resolve({ usedFallback: true, gmpAddons: [] });
-  }
-
-  return Promise.all(
-    LOCAL_GMP_SOURCES.map(conf => {
-      return downloadJSON(conf.src).then(addons => {
-        let platforms = addons.vendors[conf.id].platforms;
-        let target = Services.appinfo.OS + "_" + UpdateUtils.ABI;
-        let details = null;
-
-        while (!details) {
-          if (!(target in platforms)) {
-            // There was no matching platform so return false, this addon
-            // will be filtered from the results below
-            logger.info("no details found for: " + target);
-            return false;
-          }
-          // Field either has the details of the binary or is an alias
-          // to another build target key that does
-          if (platforms[target].alias) {
-            target = platforms[target].alias;
-          } else {
-            details = platforms[target];
-          }
-        }
-
-        logger.info("found plugin: " + conf.id);
-        return {
-          id: conf.id,
-          URL: details.fileUrl,
-          hashFunction: addons.hashFunction,
-          hashValue: details.hashValue,
-          version: addons.vendors[conf.id].version,
-          size: details.filesize,
-        };
-      });
-    })
-  ).then(addons => {
-    // Some filters may not match this platform so
-    // filter those out
-    addons = addons.filter(x => x !== false);
-
-    return {
-      usedFallback: true,
-      gmpAddons: addons,
-    };
-  });
-}
-
-/**
  * Downloads file from a URL using XHR.
  *
  * @param  url
  *         The url to download from.
  * @param  options (optional)
  * @param  options.httpsOnlyNoUpgrade
  *         Prevents upgrade to https:// when HTTPS-Only Mode is enabled.
  * @return a promise that resolves to the path of a temporary file or rejects
@@ -469,24 +364,17 @@ const ProductAddonChecker = {
    * @param  allowedCerts
    *         The list of certificate attributes to match the SSL certificate
    *         against or null to skip checks.
    * @return a promise that resolves to an object containing the list of add-ons
    *         and whether the local fallback was used, or rejects with a JS
    *         exception in case of error.
    */
   getProductAddonList(url, allowNonBuiltIn = false, allowedCerts = null) {
-    if (!GMPPrefs.getBool(GMPPrefs.KEY_UPDATE_ENABLED, true)) {
-      logger.info("Updates are disabled via media.gmp-manager.updateEnabled");
-      return Promise.resolve({ usedFallback: true, gmpAddons: [] });
-    }
-
-    return downloadXML(url, allowNonBuiltIn, allowedCerts)
-      .then(parseXML)
-      .catch(downloadLocalConfig);
+    return downloadXML(url, allowNonBuiltIn, allowedCerts).then(parseXML);
   },
 
   /**
    * Downloads an add-on to a local file and checks that it matches the expected
    * file. The caller is responsible for deleting the temporary file returned.
    *
    * @param  addon
    *         The addon to download.
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -3889,27 +3889,30 @@ var XPIInstall = {
     if (!url) {
       await installer.cleanDirectories();
       return;
     }
 
     url = await UpdateUtils.formatUpdateURL(url);
 
     logger.info(`Starting system add-on update check from ${url}.`);
-    let res = await ProductAddonChecker.getProductAddonList(url);
+    let res = await ProductAddonChecker.getProductAddonList(
+      url,
+      true
+    ).catch(e => logger.error(`System addon update list error ${e}`));
 
     // If there was no list then do nothing.
-    if (!res || !res.gmpAddons) {
+    if (!res || !res.addons) {
       logger.info("No system add-ons list was returned.");
       await installer.cleanDirectories();
       return;
     }
 
     let addonList = new Map(
-      res.gmpAddons.map(spec => [spec.id, { spec, path: null, addon: null }])
+      res.addons.map(spec => [spec.id, { spec, path: null, addon: null }])
     );
 
     let setMatches = (wanted, existing) => {
       if (wanted.size != existing.size) {
         return false;
       }
 
       for (let [id, addon] of existing) {
--- a/toolkit/mozapps/extensions/test/browser/browser_gmpProvider.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_gmpProvider.js
@@ -35,17 +35,17 @@ var gPrefs = Services.prefs;
 var getKey = GMPScope.GMPPrefs.getPrefKey;
 
 function MockGMPInstallManager() {}
 
 MockGMPInstallManager.prototype = {
   checkForAddons: () =>
     Promise.resolve({
       usedFallback: true,
-      gmpAddons: gMockAddons,
+      addons: gMockAddons,
     }),
 
   installAddon: addon => {
     gInstalledAddonId = addon.id;
     gInstallDeferred.resolve();
     return Promise.resolve();
   },
 };
--- a/toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker.js
@@ -75,88 +75,96 @@ function getBinaryFileData(file) {
  * @param file1 The first file to compare
  * @param file2 The second file to compare
  */
 function compareFiles(file1, file2) {
   return compareBinaryData(getBinaryFileData(file1), getBinaryFileData(file2));
 }
 
 add_task(async function test_404() {
-  let res = await ProductAddonChecker.getProductAddonList(root + "404.xml");
-  Assert.ok(res.usedFallback);
+  await Assert.rejects(
+    ProductAddonChecker.getProductAddonList(root + "404.xml"),
+    /got node name: html/
+  );
 });
 
 add_task(async function test_not_xml() {
-  let res = await ProductAddonChecker.getProductAddonList(root + "bad.txt");
-  Assert.ok(res.usedFallback);
+  await Assert.rejects(
+    ProductAddonChecker.getProductAddonList(root + "bad.txt"),
+    /got node name: parsererror/
+  );
 });
 
 add_task(async function test_invalid_xml() {
-  let res = await ProductAddonChecker.getProductAddonList(root + "bad.xml");
-  Assert.ok(res.usedFallback);
+  await Assert.rejects(
+    ProductAddonChecker.getProductAddonList(root + "bad.xml"),
+    /got node name: parsererror/
+  );
 });
 
 add_task(async function test_wrong_xml() {
-  let res = await ProductAddonChecker.getProductAddonList(root + "bad2.xml");
-  Assert.ok(res.usedFallback);
+  await Assert.rejects(
+    ProductAddonChecker.getProductAddonList(root + "bad2.xml"),
+    /got node name: test/
+  );
 });
 
 add_task(async function test_missing() {
   let addons = await ProductAddonChecker.getProductAddonList(
     root + "missing.xml"
   );
   Assert.equal(addons, null);
 });
 
 add_task(async function test_empty() {
   let res = await ProductAddonChecker.getProductAddonList(root + "empty.xml");
-  Assert.ok(Array.isArray(res.gmpAddons));
-  Assert.equal(res.gmpAddons.length, 0);
+  Assert.ok(Array.isArray(res.addons));
+  Assert.equal(res.addons.length, 0);
 });
 
 add_task(async function test_good_xml() {
   let res = await ProductAddonChecker.getProductAddonList(root + "good.xml");
-  Assert.ok(Array.isArray(res.gmpAddons));
+  Assert.ok(Array.isArray(res.addons));
 
   // There are three valid entries in the XML
-  Assert.equal(res.gmpAddons.length, 5);
+  Assert.equal(res.addons.length, 5);
 
-  let addon = res.gmpAddons[0];
+  let addon = res.addons[0];
   Assert.equal(addon.id, "test1");
   Assert.equal(addon.URL, "http://example.com/test1.xpi");
   Assert.equal(addon.hashFunction, undefined);
   Assert.equal(addon.hashValue, undefined);
   Assert.equal(addon.version, undefined);
   Assert.equal(addon.size, undefined);
 
-  addon = res.gmpAddons[1];
+  addon = res.addons[1];
   Assert.equal(addon.id, "test2");
   Assert.equal(addon.URL, "http://example.com/test2.xpi");
   Assert.equal(addon.hashFunction, "md5");
   Assert.equal(addon.hashValue, "djhfgsjdhf");
   Assert.equal(addon.version, undefined);
   Assert.equal(addon.size, undefined);
 
-  addon = res.gmpAddons[2];
+  addon = res.addons[2];
   Assert.equal(addon.id, "test3");
   Assert.equal(addon.URL, "http://example.com/test3.xpi");
   Assert.equal(addon.hashFunction, undefined);
   Assert.equal(addon.hashValue, undefined);
   Assert.equal(addon.version, "1.0");
   Assert.equal(addon.size, 45);
 
-  addon = res.gmpAddons[3];
+  addon = res.addons[3];
   Assert.equal(addon.id, "test4");
   Assert.equal(addon.URL, undefined);
   Assert.equal(addon.hashFunction, undefined);
   Assert.equal(addon.hashValue, undefined);
   Assert.equal(addon.version, undefined);
   Assert.equal(addon.size, undefined);
 
-  addon = res.gmpAddons[4];
+  addon = res.addons[4];
   Assert.equal(addon.id, undefined);
   Assert.equal(addon.URL, "http://example.com/test5.xpi");
   Assert.equal(addon.hashFunction, undefined);
   Assert.equal(addon.hashValue, undefined);
   Assert.equal(addon.version, undefined);
   Assert.equal(addon.size, undefined);
 });
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_gmpProvider.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_gmpProvider.js
@@ -42,17 +42,17 @@ var gPrefs = Services.prefs;
 var gGetKey = GMPScope.GMPPrefs.getPrefKey;
 
 function MockGMPInstallManager() {}
 
 MockGMPInstallManager.prototype = {
   checkForAddons: () =>
     Promise.resolve({
       usedFallback: true,
-      gmpAddons: [...gMockAddons.values()],
+      addons: [...gMockAddons.values()],
     }),
 
   installAddon: addon => {
     gInstalledAddonId = addon.id;
     return Promise.resolve();
   },
 };