summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2022-04-21 19:47:49 -0500
committerMatt A. Tobin <email@mattatobin.com>2022-04-21 19:47:49 -0500
commit465f4eb3a68ef3fdd894dafc4a6b9ce7fd7ccf8c (patch)
treef897ef4b086d31539c914a1d9b35d7cfe82a8cd2 /components
parent13d6ff7e3399952875e7ff7673b2506e7e5f4026 (diff)
downloadaura-central-465f4eb3a68ef3fdd894dafc4a6b9ce7fd7ccf8c.tar.gz
Issue #25 - Part 18: Remove GMP (or nearly all of it)
I had planned to ifdef GMP but the infection is so deep that I couldn't do discrete parts and have it stay building.
Diffstat (limited to 'components')
-rw-r--r--components/addons/content/extensions.js21
-rw-r--r--components/addons/content/extensions.xml6
-rw-r--r--components/addons/content/gmpPrefs.xul8
-rw-r--r--components/addons/extensions.manifest1
-rw-r--r--components/addons/jar.mn1
-rw-r--r--components/addons/locale/extensions.properties4
-rw-r--r--components/addons/moz.build8
-rw-r--r--components/addons/src/GMPInstallManager.jsm917
-rw-r--r--components/addons/src/GMPProvider.jsm605
-rw-r--r--components/addons/src/GMPUtils.jsm187
-rw-r--r--components/addons/src/ProductAddonChecker.jsm464
-rw-r--r--components/global/content/process-content.js7
12 files changed, 3 insertions, 2226 deletions
diff --git a/components/addons/content/extensions.js b/components/addons/content/extensions.js
index fe84bc460..f65fb4573 100644
--- a/components/addons/content/extensions.js
+++ b/components/addons/content/extensions.js
@@ -1013,9 +1013,7 @@ var gViewController = {
cmd_showItemPreferences: {
isEnabled: function cmd_showItemPreferences_isEnabled(aAddon) {
- if (!aAddon ||
- (!aAddon.isActive && !aAddon.isGMPlugin) ||
- !aAddon.optionsURL) {
+ if (!aAddon || (!aAddon.isActive) || !aAddon.optionsURL) {
return false;
}
if (gViewController.currentViewObj == gDetailView &&
@@ -2753,15 +2751,7 @@ var gDetailView = {
var fullDesc = document.getElementById("detail-fulldesc");
if (aAddon.fullDescription) {
- // The following is part of an awful hack to include the licenses for GMP
- // plugins without having bug 624602 fixed yet, and intentionally ignores
- // localisation.
- if (aAddon.isGMPlugin) {
- fullDesc.innerHTML = aAddon.fullDescription;
- } else {
- fullDesc.textContent = aAddon.fullDescription;
- }
-
+ fullDesc.textContent = aAddon.fullDescription;
fullDesc.hidden = false;
} else {
fullDesc.hidden = true;
@@ -3036,13 +3026,6 @@ var gDetailView = {
errorLink.value = gStrings.ext.GetStringFromName("details.notification.vulnerableNoUpdate.link");
errorLink.href = this._addon.blocklistURL;
errorLink.hidden = false;
- } else if (this._addon.isGMPlugin && !this._addon.isInstalled &&
- this._addon.isActive) {
- this.node.setAttribute("notification", "warning");
- let warning = document.getElementById("detail-warning");
- warning.textContent =
- gStrings.ext.formatStringFromName("details.notification.gmpPending",
- [this._addon.name], 1);
} else {
this.node.removeAttribute("notification");
}
diff --git a/components/addons/content/extensions.xml b/components/addons/content/extensions.xml
index f862b0f7e..9ea6a50df 100644
--- a/components/addons/content/extensions.xml
+++ b/components/addons/content/extensions.xml
@@ -1328,12 +1328,6 @@
this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableNoUpdate.link");
this._errorLink.href = this.mAddon.blocklistURL;
this._errorLink.hidden = false;
- } else if (this.mAddon.isGMPlugin && !this.mAddon.isInstalled &&
- this.mAddon.isActive) {
- this.setAttribute("notification", "warning");
- this._warning.textContent =
- gStrings.ext.formatStringFromName("notification.gmpPending",
- [this.mAddon.name], 1);
} else {
this.removeAttribute("notification");
}
diff --git a/components/addons/content/gmpPrefs.xul b/components/addons/content/gmpPrefs.xul
deleted file mode 100644
index ea7ee92fa..000000000
--- a/components/addons/content/gmpPrefs.xul
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- 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/. -->
-
-<!-- This is intentionally empty and a dummy to let the GMPProvider
- have a preferences button in the list view. -->
diff --git a/components/addons/extensions.manifest b/components/addons/extensions.manifest
index b56152e10..35d605575 100644
--- a/components/addons/extensions.manifest
+++ b/components/addons/extensions.manifest
@@ -13,4 +13,3 @@ contract @mozilla.org/addons/installtrigger;1 {9df8ef2b-94da-45c9-ab9f-132eb55fd
category JavaScript-global-property InstallTrigger @mozilla.org/addons/installtrigger;1
category addon-provider-module PluginProvider resource://gre/modules/addons/PluginProvider.jsm
-category addon-provider-module GMPProvider resource://gre/modules/addons/GMPProvider.jsm
diff --git a/components/addons/jar.mn b/components/addons/jar.mn
index 878be4df1..c674f8f83 100644
--- a/components/addons/jar.mn
+++ b/components/addons/jar.mn
@@ -29,7 +29,6 @@ toolkit.jar:
content/mozapps/extensions/newaddon.js (content/newaddon.js)
content/mozapps/extensions/setting.xml (content/setting.xml)
content/mozapps/extensions/pluginPrefs.xul (content/pluginPrefs.xul)
- content/mozapps/extensions/gmpPrefs.xul (content/gmpPrefs.xul)
content/mozapps/extensions/OpenH264-license.txt (content/OpenH264-license.txt)
content/mozapps/xpinstall/xpinstallConfirm.xul (content/xpinstallConfirm.xul)
content/mozapps/xpinstall/xpinstallConfirm.js (content/xpinstallConfirm.js)
diff --git a/components/addons/locale/extensions.properties b/components/addons/locale/extensions.properties
index c5de4f0c0..43ab02a47 100644
--- a/components/addons/locale/extensions.properties
+++ b/components/addons/locale/extensions.properties
@@ -57,8 +57,6 @@ notification.downloadError.retry.tooltip=Try downloading this add-on again
notification.installError=There was an error installing %1$S.
notification.installError.retry=Try again
notification.installError.retry.tooltip=Try downloading and installing this add-on again
-#LOCALIZATION NOTE (notification.gmpPending) %1$S is the add-on name.
-notification.gmpPending=%1$S will be installed shortly.
#LOCALIZATION NOTE (contributionAmount2) %S is the currency amount recommended for contributions
contributionAmount2=Suggested Contribution: %S
@@ -100,8 +98,6 @@ details.notification.install=%1$S will be installed after you restart %2$S.
details.notification.uninstall=%1$S will be uninstalled after you restart %2$S.
#LOCALIZATION NOTE (details.notification.upgrade) %1$S is the add-on name, %2$S is brand name
details.notification.upgrade=%1$S will be updated after you restart %2$S.
-#LOCALIZATION NOTE (details.notification.gmpPending) %1$S is the add-on name
-details.notification.gmpPending=%1$S will be installed shortly.
installFromFile.dialogTitle=Select add-on to install
installFromFile.filterName=Add-ons
diff --git a/components/addons/moz.build b/components/addons/moz.build
index 6b1e2fe93..f3e953c46 100644
--- a/components/addons/moz.build
+++ b/components/addons/moz.build
@@ -37,21 +37,15 @@ EXTRA_JS_MODULES += [
'src/LightweightThemeManager.jsm',
]
-EXTRA_PP_JS_MODULES += [
- 'src/AddonManager.jsm',
- 'src/GMPInstallManager.jsm',
- 'src/GMPUtils.jsm',
-]
+EXTRA_PP_JS_MODULES += ['src/AddonManager.jsm']
EXTRA_JS_MODULES.addons += [
'src/AddonLogging.jsm',
'src/AddonRepository.jsm',
'src/AddonRepository_SQLiteMigrator.jsm',
'src/Content.js',
- 'src/GMPProvider.jsm',
'src/LightweightThemeImageOptimizer.jsm',
'src/PluginProvider.jsm',
- 'src/ProductAddonChecker.jsm',
'src/SpellCheckDictionaryBootstrap.js',
]
diff --git a/components/addons/src/GMPInstallManager.jsm b/components/addons/src/GMPInstallManager.jsm
deleted file mode 100644
index fe4e2de10..000000000
--- a/components/addons/src/GMPInstallManager.jsm
+++ /dev/null
@@ -1,917 +0,0 @@
-/* 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";
-
-this.EXPORTED_SYMBOLS = [];
-
-const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} =
- Components;
-// Chunk size for the incremental downloader
-const DOWNLOAD_CHUNK_BYTES_SIZE = 300000;
-// Incremental downloader interval
-const DOWNLOAD_INTERVAL = 0;
-// 1 day default
-const DEFAULT_SECONDS_BETWEEN_CHECKS = 60 * 60 * 24;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/osfile.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/ctypes.jsm");
-Cu.import("resource://gre/modules/GMPUtils.jsm");
-
-this.EXPORTED_SYMBOLS = ["GMPInstallManager", "GMPExtractor", "GMPDownloader",
- "GMPAddon"];
-
-var gLocale = null;
-
-// Shared code for suppressing bad cert dialogs
-XPCOMUtils.defineLazyGetter(this, "gCertUtils", function() {
- let temp = { };
- Cu.import("resource://gre/modules/CertUtils.jsm", temp);
- return temp;
-});
-
-XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
- "resource://gre/modules/UpdateUtils.jsm");
-
-/**
- * Number of milliseconds after which we need to cancel `checkForAddons`.
- *
- * Bug 1087674 suggests that the XHR we use in `checkForAddons` may
- * never terminate in presence of network nuisances (e.g. strange
- * antivirus behavior). This timeout is a defensive measure to ensure
- * that we fail cleanly in such case.
- */
-const CHECK_FOR_ADDONS_TIMEOUT_DELAY_MS = 20000;
-
-function getScopedLogger(prefix) {
- // `PARENT_LOGGER_ID.` being passed here effectively links this logger
- // to the parentLogger.
- return Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP", prefix + " ");
-}
-
-// This is copied directly from nsUpdateService.js
-// It is used for calculating the URL string w/ var replacement.
-// TODO: refactor this out somewhere else
-XPCOMUtils.defineLazyGetter(this, "gOSVersion", function aus_gOSVersion() {
- let osVersion;
- let sysInfo = Cc["@mozilla.org/system-info;1"].
- getService(Ci.nsIPropertyBag2);
- try {
- osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
- }
- catch (e) {
- LOG("gOSVersion - OS Version unknown: updates are not possible.");
- }
-
- if (osVersion) {
-#ifdef XP_WIN
- const BYTE = ctypes.uint8_t;
- const WORD = ctypes.uint16_t;
- const DWORD = ctypes.uint32_t;
- const WCHAR = ctypes.char16_t;
- const BOOL = ctypes.int;
-
- // This structure is described at:
- // http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
- const SZCSDVERSIONLENGTH = 128;
- const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
- [
- {dwOSVersionInfoSize: DWORD},
- {dwMajorVersion: DWORD},
- {dwMinorVersion: DWORD},
- {dwBuildNumber: DWORD},
- {dwPlatformId: DWORD},
- {szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
- {wServicePackMajor: WORD},
- {wServicePackMinor: WORD},
- {wSuiteMask: WORD},
- {wProductType: BYTE},
- {wReserved: BYTE}
- ]);
-
- // This structure is described at:
- // http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
- const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
- [
- {wProcessorArchitecture: WORD},
- {wReserved: WORD},
- {dwPageSize: DWORD},
- {lpMinimumApplicationAddress: ctypes.voidptr_t},
- {lpMaximumApplicationAddress: ctypes.voidptr_t},
- {dwActiveProcessorMask: DWORD.ptr},
- {dwNumberOfProcessors: DWORD},
- {dwProcessorType: DWORD},
- {dwAllocationGranularity: DWORD},
- {wProcessorLevel: WORD},
- {wProcessorRevision: WORD}
- ]);
-
- let kernel32 = false;
- try {
- kernel32 = ctypes.open("Kernel32");
- } catch (e) {
- LOG("gOSVersion - Unable to open kernel32! " + e);
- osVersion += ".unknown (unknown)";
- }
-
- if(kernel32) {
- try {
- // Get Service pack info
- try {
- let GetVersionEx = kernel32.declare("GetVersionExW",
- ctypes.default_abi,
- BOOL,
- OSVERSIONINFOEXW.ptr);
- let winVer = OSVERSIONINFOEXW();
- winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
-
- if(0 !== GetVersionEx(winVer.address())) {
- osVersion += "." + winVer.wServicePackMajor
- + "." + winVer.wServicePackMinor;
- } else {
- LOG("gOSVersion - Unknown failure in GetVersionEX (returned 0)");
- osVersion += ".unknown";
- }
- } catch (e) {
- LOG("gOSVersion - error getting service pack information. Exception: " + e);
- osVersion += ".unknown";
- }
-
- // Get processor architecture
- let arch = "unknown";
- try {
- let GetNativeSystemInfo = kernel32.declare("GetNativeSystemInfo",
- ctypes.default_abi,
- ctypes.void_t,
- SYSTEM_INFO.ptr);
- let sysInfo = SYSTEM_INFO();
- // Default to unknown
- sysInfo.wProcessorArchitecture = 0xffff;
-
- GetNativeSystemInfo(sysInfo.address());
- switch(sysInfo.wProcessorArchitecture) {
- case 9:
- arch = "x64";
- break;
- case 6:
- arch = "IA64";
- break;
- case 0:
- arch = "x86";
- break;
- }
- } catch (e) {
- LOG("gOSVersion - error getting processor architecture. Exception: " + e);
- } finally {
- osVersion += " (" + arch + ")";
- }
- } finally {
- kernel32.close();
- }
- }
-#endif
-
- try {
- osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
- }
- catch (e) {
- // Not all platforms have a secondary widget library, so an error is nothing to worry about.
- }
- osVersion = encodeURIComponent(osVersion);
- }
- return osVersion;
-});
-
-/**
- * Provides an easy API for downloading and installing GMP Addons
- */
-function GMPInstallManager() {
-}
-/**
- * Temp file name used for downloading
- */
-GMPInstallManager.prototype = {
- /**
- * Obtains a URL with replacement of vars
- */
- _getURL: function() {
- let log = getScopedLogger("GMPInstallManager._getURL");
- // Use the override URL if it is specified. The override URL is just like
- // the normal URL but it does not check the cert.
- let url = GMPPrefs.get(GMPPrefs.KEY_URL_OVERRIDE);
- if (url) {
- log.info("Using override url: " + url);
- } else {
- url = GMPPrefs.get(GMPPrefs.KEY_URL);
- log.info("Using url: " + url);
- }
-
- url = UpdateUtils.formatUpdateURL(url);
- 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 array of GMPAddons
- * 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
- */
- checkForAddons: function() {
- let log = getScopedLogger("GMPInstallManager.checkForAddons");
- if (this._deferred) {
- log.error("checkForAddons already called");
- return Promise.reject({type: "alreadycalled"});
- }
- this._deferred = Promise.defer();
- let url = this._getURL();
-
- this._request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsISupports);
- // This is here to let unit test code override XHR
- if (this._request.wrappedJSObject) {
- this._request = this._request.wrappedJSObject;
- }
- this._request.open("GET", url, true);
- let allowNonBuiltIn = !GMPPrefs.get(GMPPrefs.KEY_CERT_CHECKATTRS, true);
- this._request.channel.notificationCallbacks =
- new gCertUtils.BadCertHandler(allowNonBuiltIn);
- // Prevent the request from reading from the cache.
- this._request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
- // Prevent the request from writing to the cache.
- this._request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
-
- this._request.overrideMimeType("text/xml");
- // The Cache-Control header is only interpreted by proxies and the
- // final destination. It does not help if a resource is already
- // cached locally.
- this._request.setRequestHeader("Cache-Control", "no-cache");
- // HTTP/1.0 servers might not implement Cache-Control and
- // might only implement Pragma: no-cache
- this._request.setRequestHeader("Pragma", "no-cache");
-
- this._request.timeout = CHECK_FOR_ADDONS_TIMEOUT_DELAY_MS;
- this._request.addEventListener("error", event => this.onFailXML("onErrorXML", event), false);
- this._request.addEventListener("abort", event => this.onFailXML("onAbortXML", event), false);
- this._request.addEventListener("timeout", event => this.onFailXML("onTimeoutXML", event), false);
- this._request.addEventListener("load", event => this.onLoadXML(event), false);
-
- log.info("sending request to: " + url);
- this._request.send(null);
-
- return this._deferred.promise;
- },
- /**
- * Installs the specified addon and calls a callback when done.
- * @param gmpAddon The GMPAddon object to install
- * @return a promise which will be resolved or rejected
- * The promise will resolve with an array of paths that were extracted
- * The promise will reject with an error object:
- * target: The XHR request object
- * status: The HTTP status code
- * type: A string to represent the type of error
- * downloaderr, verifyerr or previouserrorencountered
- */
- installAddon: function(gmpAddon) {
- if (this._deferred) {
- log.error("previous error encountered");
- return Promise.reject({type: "previouserrorencountered"});
- }
- this.gmpDownloader = new GMPDownloader(gmpAddon);
- return this.gmpDownloader.start();
- },
- _getTimeSinceLastCheck: function() {
- let now = Math.round(Date.now() / 1000);
- // Default to 0 here because `now - 0` will be returned later if that case
- // is hit. We want a large value so a check will occur.
- let lastCheck = GMPPrefs.get(GMPPrefs.KEY_UPDATE_LAST_CHECK, 0);
- // Handle clock jumps, return now since we want it to represent
- // a lot of time has passed since the last check.
- if (now < lastCheck) {
- return now;
- }
- return now - lastCheck;
- },
- get _isEMEEnabled() {
- return GMPPrefs.get(GMPPrefs.KEY_EME_ENABLED, true);
- },
- _isAddonUpdateEnabled: function(aAddon) {
- return GMPPrefs.get(GMPPrefs.KEY_PLUGIN_ENABLED, true, aAddon) &&
- GMPPrefs.get(GMPPrefs.KEY_PLUGIN_AUTOUPDATE, true, aAddon);
- },
- _updateLastCheck: function() {
- let now = Math.round(Date.now() / 1000);
- GMPPrefs.set(GMPPrefs.KEY_UPDATE_LAST_CHECK, now);
- },
- _versionchangeOccurred: function() {
- let savedBuildID = GMPPrefs.get(GMPPrefs.KEY_BUILDID, null);
- let buildID = Services.appinfo.platformBuildID;
- if (savedBuildID == buildID) {
- return false;
- }
- GMPPrefs.set(GMPPrefs.KEY_BUILDID, buildID);
- return true;
- },
- /**
- * Wrapper for checkForAddons and installAddon.
- * Will only install if not already installed and will log the results.
- * This will only install/update the OpenH264 and EME plugins
- * @return a promise which will be resolved if all addons could be installed
- * successfully, rejected otherwise.
- */
- simpleCheckAndInstall: Task.async(function*() {
- let log = getScopedLogger("GMPInstallManager.simpleCheckAndInstall");
-
- if (this._versionchangeOccurred()) {
- log.info("A version change occurred. Ignoring " +
- "media.gmp-manager.lastCheck to check immediately for " +
- "new or updated GMPs.");
- } else {
- let secondsBetweenChecks =
- GMPPrefs.get(GMPPrefs.KEY_SECONDS_BETWEEN_CHECKS,
- DEFAULT_SECONDS_BETWEEN_CHECKS)
- let secondsSinceLast = this._getTimeSinceLastCheck();
- log.info("Last check was: " + secondsSinceLast +
- " seconds ago, minimum seconds: " + secondsBetweenChecks);
- if (secondsBetweenChecks > secondsSinceLast) {
- log.info("Will not check for updates.");
- return {status: "too-frequent-no-check"};
- }
- }
-
- try {
- let gmpAddons = yield this.checkForAddons();
- this._updateLastCheck();
- log.info("Found " + gmpAddons.length + " addons advertised.");
- let addonsToInstall = gmpAddons.filter(function(gmpAddon) {
- log.info("Found addon: " + gmpAddon.toString());
-
- if (!gmpAddon.isValid || GMPUtils.isPluginHidden(gmpAddon) ||
- gmpAddon.isInstalled) {
- log.info("Addon invalid, hidden or already installed.");
- return false;
- }
-
- let addonUpdateEnabled = false;
- if (GMP_PLUGIN_IDS.indexOf(gmpAddon.id) >= 0) {
- addonUpdateEnabled = this._isAddonUpdateEnabled(gmpAddon.id);
- if (!addonUpdateEnabled) {
- log.info("Auto-update is off for " + gmpAddon.id +
- ", skipping check.");
- }
- } else {
- // Currently, we only support installs of OpenH264 and EME plugins.
- log.info("Auto-update is off for unknown plugin '" + gmpAddon.id +
- "', skipping check.");
- }
-
- return addonUpdateEnabled;
- }, this);
-
- if (!addonsToInstall.length) {
- log.info("No new addons to install, returning");
- return {status: "nothing-new-to-install"};
- }
-
- let installResults = [];
- let failureEncountered = false;
- for (let addon of addonsToInstall) {
- try {
- yield this.installAddon(addon);
- installResults.push({
- id: addon.id,
- result: "succeeded",
- });
- } catch (e) {
- failureEncountered = true;
- installResults.push({
- id: addon.id,
- result: "failed",
- });
- }
- }
- if (failureEncountered) {
- throw {status: "failed",
- results: installResults};
- }
- return {status: "succeeded",
- results: installResults};
- } catch(e) {
- log.error("Could not check for addons", e);
- throw e;
- }
- }),
-
- /**
- * Makes sure everything is cleaned up
- */
- uninit: function() {
- let log = getScopedLogger("GMPInstallManager.uninit");
- if (this._request) {
- log.info("Aborting request");
- this._request.abort();
- }
- if (this._deferred) {
- log.info("Rejecting deferred");
- this._deferred.reject({type: "uninitialized"});
- }
- log.info("Done cleanup");
- },
-
- /**
- * If set to true, specifies to leave the temporary downloaded zip file.
- * This is useful for tests.
- */
- overrideLeaveDownloadedZip: false,
-
- /**
- * The XMLHttpRequest succeeded and the document was loaded.
- * @param event The nsIDOMEvent for the load
- */
- onLoadXML: function(event) {
- let log = getScopedLogger("GMPInstallManager.onLoadXML");
- try {
- log.info("request completed downloading document");
- let certs = null;
- if (!Services.prefs.prefHasUserValue(GMPPrefs.KEY_URL_OVERRIDE) &&
- GMPPrefs.get(GMPPrefs.KEY_CERT_CHECKATTRS, true)) {
- certs = gCertUtils.readCertPrefs(GMPPrefs.KEY_CERTS_BRANCH);
- }
-
- let allowNonBuiltIn = !GMPPrefs.get(GMPPrefs.KEY_CERT_REQUIREBUILTIN,
- true);
- log.info("allowNonBuiltIn: " + allowNonBuiltIn);
-
- gCertUtils.checkCert(this._request.channel, allowNonBuiltIn, certs);
-
- this.parseResponseXML();
- } catch (ex) {
- log.error("could not load xml: " + ex);
- this._deferred.reject({
- target: event.target,
- status: this._getChannelStatus(event.target),
- message: "" + ex,
- });
- delete this._deferred;
- }
- },
-
- /**
- * Returns the status code for the XMLHttpRequest
- */
- _getChannelStatus: function(request) {
- let log = getScopedLogger("GMPInstallManager._getChannelStatus");
- let status = null;
- try {
- status = request.status;
- log.info("request.status is: " + request.status);
- }
- catch (e) {
- }
-
- if (status == null) {
- status = request.channel.QueryInterface(Ci.nsIRequest).status;
- }
- return status;
- },
-
- /**
- * There was an error of some kind during the XMLHttpRequest. This
- * error may have been caused by external factors (e.g. network
- * issues) or internally (by a timeout).
- *
- * @param event The nsIDOMEvent for the error
- */
- onFailXML: function(failure, event) {
- let log = getScopedLogger("GMPInstallManager.onFailXML " + failure);
- let request = event.target;
- let status = this._getChannelStatus(request);
- let message = "request.status: " + status + " (" + event.type + ")";
- log.warn(message);
- this._deferred.reject({
- target: request,
- status: status,
- message: message
- });
- delete this._deferred;
- },
-
- /**
- * Returns an array of GMPAddon objects discovered by the update check.
- * Or returns an empty array if there were any problems with parsing.
- * If there's an error, it will be logged if logging is enabled.
- */
- parseResponseXML: function() {
- try {
- let log = getScopedLogger("GMPInstallManager.parseResponseXML");
- let updatesElement = this._request.responseXML.documentElement;
- if (!updatesElement) {
- let message = "empty updates document";
- log.warn(message);
- this._deferred.reject({
- target: this._request,
- message: message
- });
- delete this._deferred;
- return;
- }
-
- if (updatesElement.nodeName != "updates") {
- let message = "got node name: " + updatesElement.nodeName +
- ", expected: updates";
- log.warn(message);
- this._deferred.reject({
- target: this._request,
- message: message
- });
- delete this._deferred;
- return;
- }
-
- const ELEMENT_NODE = Ci.nsIDOMNode.ELEMENT_NODE;
- let gmpResults = [];
- for (let i = 0; i < updatesElement.childNodes.length; ++i) {
- let updatesChildElement = updatesElement.childNodes.item(i);
- if (updatesChildElement.nodeType != ELEMENT_NODE) {
- continue;
- }
- if (updatesChildElement.localName == "addons") {
- gmpResults = GMPAddon.parseGMPAddonsNode(updatesChildElement);
- }
- }
- this._deferred.resolve(gmpResults);
- delete this._deferred;
- } catch (e) {
- this._deferred.reject({
- target: this._request,
- message: e
- });
- delete this._deferred;
- }
- },
-};
-
-/**
- * Used to construct a single GMP addon
- * GMPAddon objects are returns from GMPInstallManager.checkForAddons
- * GMPAddon objects can also be used in calls to GMPInstallManager.installAddon
- *
- * @param gmpAddon The AUS response XML's DOM element `addon`
- */
-function GMPAddon(gmpAddon) {
- let log = getScopedLogger("GMPAddon.constructor");
- gmpAddon.QueryInterface(Ci.nsIDOMElement);
- ["id", "URL", "hashFunction",
- "hashValue", "version", "size"].forEach(name => {
- if (gmpAddon.hasAttribute(name)) {
- this[name] = gmpAddon.getAttribute(name);
- }
- });
- this.size = Number(this.size) || undefined;
- log.info ("Created new addon: " + this.toString());
-}
-/**
- * Parses an XML GMP addons node from AUS into an array
- * @param addonsElement An nsIDOMElement compatible node with XML from AUS
- * @return An array of GMPAddon results
- */
-GMPAddon.parseGMPAddonsNode = function(addonsElement) {
- let log = getScopedLogger("GMPAddon.parseGMPAddonsNode");
- let gmpResults = [];
- if (addonsElement.localName !== "addons") {
- return;
- }
-
- addonsElement.QueryInterface(Ci.nsIDOMElement);
- let addonCount = addonsElement.childNodes.length;
- for (let i = 0; i < addonCount; ++i) {
- let addonElement = addonsElement.childNodes.item(i);
- if (addonElement.localName !== "addon") {
- continue;
- }
- addonElement.QueryInterface(Ci.nsIDOMElement);
- try {
- gmpResults.push(new GMPAddon(addonElement));
- } catch (e) {
- log.warn("invalid addon: " + e);
- continue;
- }
- }
- return gmpResults;
-};
-GMPAddon.prototype = {
- /**
- * Returns a string representation of the addon
- */
- toString: function() {
- return this.id + " (" +
- "isValid: " + this.isValid +
- ", isInstalled: " + this.isInstalled +
- ", hashFunction: " + this.hashFunction+
- ", hashValue: " + this.hashValue +
- (this.size !== undefined ? ", size: " + this.size : "" ) +
- ")";
- },
- /**
- * If all the fields aren't specified don't consider this addon valid
- * @return true if the addon is parsed and valid
- */
- get isValid() {
- return this.id && this.URL && this.version &&
- this.hashFunction && !!this.hashValue;
- },
- get isInstalled() {
- return this.version &&
- GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VERSION, "", this.id) === this.version;
- },
- get isEME() {
- return this.id == "gmp-widevinecdm" || this.id.indexOf("gmp-eme-") == 0;
- },
-};
-/**
- * Constructs a GMPExtractor object which is used to extract a GMP zip
- * into the specified location. (Which typically leties per platform)
- * @param zipPath The path on disk of the zip file to extract
- */
-function GMPExtractor(zipPath, installToDirPath) {
- this.zipPath = zipPath;
- this.installToDirPath = installToDirPath;
-}
-GMPExtractor.prototype = {
- /**
- * Obtains a list of all the entries in a zipfile in the format of *.*.
- * This also includes files inside directories.
- *
- * @param zipReader the nsIZipReader to check
- * @return An array of string name entries which can be used
- * in nsIZipReader.extract
- */
- _getZipEntries: function(zipReader) {
- let entries = [];
- let enumerator = zipReader.findEntries("*.*");
- while (enumerator.hasMore()) {
- entries.push(enumerator.getNext());
- }
- return entries;
- },
- /**
- * Installs the this.zipPath contents into the directory used to store GMP
- * addons for the current platform.
- *
- * @return a promise which will be resolved or rejected
- * See GMPInstallManager.installAddon for resolve/rejected info
- */
- install: function() {
- try {
- let log = getScopedLogger("GMPExtractor.install");
- this._deferred = Promise.defer();
- log.info("Installing " + this.zipPath + "...");
- // Get the input zip file
- let zipFile = Cc["@mozilla.org/file/local;1"].
- createInstance(Ci.nsIFile);
- zipFile.initWithPath(this.zipPath);
-
- // Initialize a zipReader and obtain the entries
- var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
- createInstance(Ci.nsIZipReader);
- zipReader.open(zipFile)
- let entries = this._getZipEntries(zipReader);
- let extractedPaths = [];
-
- // Extract each of the entries
- entries.forEach(entry => {
- // We don't need these types of files
- if (entry.includes("__MACOSX")) {
- return;
- }
- let outFile = Cc["@mozilla.org/file/local;1"].
- createInstance(Ci.nsILocalFile);
- outFile.initWithPath(this.installToDirPath);
- outFile.appendRelativePath(entry);
-
- // Make sure the directory hierarchy exists
- if(!outFile.parent.exists()) {
- outFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
- }
- zipReader.extract(entry, outFile);
- extractedPaths.push(outFile.path);
- log.info(entry + " was successfully extracted to: " +
- outFile.path);
- });
- zipReader.close();
- if (!GMPInstallManager.overrideLeaveDownloadedZip) {
- zipFile.remove(false);
- }
-
- log.info(this.zipPath + " was installed successfully");
- this._deferred.resolve(extractedPaths);
- } catch (e) {
- if (zipReader) {
- zipReader.close();
- }
- this._deferred.reject({
- target: this,
- status: e,
- type: "exception"
- });
- }
- return this._deferred.promise;
- }
-};
-
-
-/**
- * Constructs an object which downloads and initiates an install of
- * the specified GMPAddon object.
- * @param gmpAddon The addon to install.
- */
-function GMPDownloader(gmpAddon)
-{
- this._gmpAddon = gmpAddon;
-}
-/**
- * Computes the file hash of fileToHash with the specified hash function
- * @param hashFunctionName A hash function name such as sha512
- * @param fileToHash An nsIFile to hash
- * @return a promise which resolve to a digest in binary hex format
- */
-GMPDownloader.computeHash = function(hashFunctionName, fileToHash) {
- let log = getScopedLogger("GMPDownloader.computeHash");
- let digest;
- let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].
- createInstance(Ci.nsIFileInputStream);
- fileStream.init(fileToHash, FileUtils.MODE_RDONLY,
- FileUtils.PERMS_FILE, 0);
- try {
- let hash = Cc["@mozilla.org/security/hash;1"].
- createInstance(Ci.nsICryptoHash);
- let hashFunction =
- Ci.nsICryptoHash[hashFunctionName.toUpperCase()];
- if (!hashFunction) {
- log.error("could not get hash function");
- return Promise.reject();
- }
- hash.init(hashFunction);
- hash.updateFromStream(fileStream, -1);
- digest = binaryToHex(hash.finish(false));
- } catch (e) {
- log.warn("failed to compute hash: " + e);
- digest = "";
- }
- fileStream.close();
- return Promise.resolve(digest);
-},
-GMPDownloader.prototype = {
- /**
- * Starts the download process for an addon.
- * @return a promise which will be resolved or rejected
- * See GMPInstallManager.installAddon for resolve/rejected info
- */
- start: function() {
- let log = getScopedLogger("GMPDownloader.start");
- this._deferred = Promise.defer();
- if (!this._gmpAddon.isValid) {
- log.info("gmpAddon is not valid, will not continue");
- return Promise.reject({
- target: this,
- status: status,
- type: "downloaderr"
- });
- }
-
- let uri = Services.io.newURI(this._gmpAddon.URL, null, null);
- this._request = Cc["@mozilla.org/network/incremental-download;1"].
- createInstance(Ci.nsIIncrementalDownload);
- let gmpFile = FileUtils.getFile("TmpD", [this._gmpAddon.id + ".zip"]);
- if (gmpFile.exists()) {
- gmpFile.remove(false);
- }
-
- log.info("downloading from " + uri.spec + " to " + gmpFile.path);
- this._request.init(uri, gmpFile, DOWNLOAD_CHUNK_BYTES_SIZE,
- DOWNLOAD_INTERVAL);
- this._request.start(this, null);
- return this._deferred.promise;
- },
- // For nsIRequestObserver
- onStartRequest: function(request, context) {
- },
- // For nsIRequestObserver
- // Called when the GMP addon zip file is downloaded
- onStopRequest: function(request, context, status) {
- let log = getScopedLogger("GMPDownloader.onStopRequest");
- log.info("onStopRequest called");
- if (!Components.isSuccessCode(status)) {
- log.info("status failed: " + status);
- this._deferred.reject({
- target: this,
- status: status,
- type: "downloaderr"
- });
- return;
- }
-
- let promise = this._verifyDownload();
- promise.then(() => {
- log.info("GMP file is ready to unzip");
- let destination = this._request.destination;
-
- let zipPath = destination.path;
- let gmpAddon = this._gmpAddon;
- let installToDirPath = Cc["@mozilla.org/file/local;1"].
- createInstance(Ci.nsIFile);
- let path = OS.Path.join(OS.Constants.Path.profileDir,
- gmpAddon.id,
- gmpAddon.version);
- installToDirPath.initWithPath(path);
- log.info("install to directory path: " + installToDirPath.path);
- let gmpInstaller = new GMPExtractor(zipPath, installToDirPath.path);
- let installPromise = gmpInstaller.install();
- installPromise.then(extractedPaths => {
- // Success, set the prefs
- let now = Math.round(Date.now() / 1000);
- GMPPrefs.set(GMPPrefs.KEY_PLUGIN_LAST_UPDATE, now, gmpAddon.id);
- // Setting the version pref signals installation completion to consumers,
- // if you need to set other prefs etc. do it before this.
- GMPPrefs.set(GMPPrefs.KEY_PLUGIN_VERSION, gmpAddon.version,
- gmpAddon.id);
- this._deferred.resolve(extractedPaths);
- }, err => {
- this._deferred.reject(err);
- });
- }, err => {
- log.warn("verifyDownload check failed");
- this._deferred.reject({
- target: this,
- status: 200,
- type: "verifyerr"
- });
- });
- },
- /**
- * Verifies that the downloaded zip file's hash matches the GMPAddon hash.
- * @return a promise which resolves if the download verifies
- */
- _verifyDownload: function() {
- let verifyDownloadDeferred = Promise.defer();
- let log = getScopedLogger("GMPDownloader._verifyDownload");
- log.info("_verifyDownload called");
- if (!this._request) {
- return Promise.reject();
- }
-
- let destination = this._request.destination;
- log.info("for path: " + destination.path);
-
- // Ensure that the file size matches the expected file size.
- if (this._gmpAddon.size !== undefined &&
- destination.fileSize != this._gmpAddon.size) {
- log.warn("Downloader:_verifyDownload downloaded size " +
- destination.fileSize + " != expected size " +
- this._gmpAddon.size + ".");
- return Promise.reject();
- }
-
- let promise = GMPDownloader.computeHash(this._gmpAddon.hashFunction, destination);
- promise.then(digest => {
- let expectedDigest = this._gmpAddon.hashValue.toLowerCase();
- if (digest !== expectedDigest) {
- log.warn("hashes do not match! Got: `" +
- digest + "`, expected: `" + expectedDigest + "`");
- this._deferred.reject();
- return;
- }
-
- log.info("hashes match!");
- verifyDownloadDeferred.resolve();
- }, err => {
- verifyDownloadDeferred.reject();
- });
- return verifyDownloadDeferred.promise;
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver])
-};
-
-/**
- * Convert a string containing binary values to hex.
- */
-function binaryToHex(input) {
- let result = "";
- for (let i = 0; i < input.length; ++i) {
- let hex = input.charCodeAt(i).toString(16);
- if (hex.length == 1)
- hex = "0" + hex;
- result += hex;
- }
- return result;
-}
diff --git a/components/addons/src/GMPProvider.jsm b/components/addons/src/GMPProvider.jsm
deleted file mode 100644
index c89427101..000000000
--- a/components/addons/src/GMPProvider.jsm
+++ /dev/null
@@ -1,605 +0,0 @@
-/* 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";
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-this.EXPORTED_SYMBOLS = [];
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/AddonManager.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/osfile.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/GMPUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(
- this, "GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm");
-XPCOMUtils.defineLazyModuleGetter(
- this, "setTimeout", "resource://gre/modules/Timer.jsm");
-
-const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
-const STRING_TYPE_NAME = "type.%ID%.name";
-
-const SEC_IN_A_DAY = 24 * 60 * 60;
-// How long to wait after a user enabled EME before attempting to download CDMs.
-const GMP_CHECK_DELAY = 10 * 1000; // milliseconds
-
-const NS_GRE_DIR = "GreD";
-const CLEARKEY_PLUGIN_ID = "gmp-clearkey";
-const CLEARKEY_VERSION = "0.1";
-
-const GMP_LICENSE_INFO = "gmp_license_info";
-
-const GMP_PLUGINS = [
- {
- id: OPEN_H264_ID,
- name: "openH264_name",
- description: "openH264_description2",
- // The following licenseURL is part of an awful hack to include the OpenH264
- // license without having bug 624602 fixed yet, and intentionally ignores
- // localisation.
- licenseURL: "chrome://mozapps/content/extensions/OpenH264-license.txt",
- homepageURL: "http://www.openh264.org/",
- optionsURL: "chrome://mozapps/content/extensions/gmpPrefs.xul"
- },
- {
- id: WIDEVINE_ID,
- name: "widevine_name",
- // Describe the purpose of both CDMs in the same way.
- description: "widevine_description2",
- licenseURL: "https://www.google.com/policies/privacy/",
- homepageURL: "https://www.widevine.com/",
- optionsURL: "chrome://mozapps/content/extensions/gmpPrefs.xul",
- isEME: true
- }];
-XPCOMUtils.defineConstant(this, "GMP_PLUGINS", GMP_PLUGINS);
-
-XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
- () => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
-XPCOMUtils.defineLazyGetter(this, "gmpService",
- () => Cc["@mozilla.org/gecko-media-plugin-service;1"].getService(Ci.mozIGeckoMediaPluginChromeService));
-
-var messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
- .getService(Ci.nsIMessageListenerManager);
-
-var gLogger;
-var gLogAppenderDump = null;
-
-function configureLogging() {
- if (!gLogger) {
- gLogger = Log.repository.getLogger("Toolkit.GMP");
- gLogger.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()));
- }
- gLogger.level = GMPPrefs.get(GMPPrefs.KEY_LOGGING_LEVEL, Log.Level.Warn);
-
- let logDumping = GMPPrefs.get(GMPPrefs.KEY_LOGGING_DUMP, false);
- if (logDumping != !!gLogAppenderDump) {
- if (logDumping) {
- gLogAppenderDump = new Log.DumpAppender(new Log.BasicFormatter());
- gLogger.addAppender(gLogAppenderDump);
- } else {
- gLogger.removeAppender(gLogAppenderDump);
- gLogAppenderDump = null;
- }
- }
-}
-
-
-
-/**
- * The GMPWrapper provides the info for the various GMP plugins to public
- * callers through the API.
- */
-function GMPWrapper(aPluginInfo) {
- this._plugin = aPluginInfo;
- this._log =
- Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP",
- "GMPWrapper(" +
- this._plugin.id + ") ");
- Preferences.observe(GMPPrefs.getPrefKey(GMPPrefs.KEY_PLUGIN_ENABLED,
- this._plugin.id),
- this.onPrefEnabledChanged, this);
- Preferences.observe(GMPPrefs.getPrefKey(GMPPrefs.KEY_PLUGIN_VERSION,
- this._plugin.id),
- this.onPrefVersionChanged, this);
- if (this._plugin.isEME) {
- Preferences.observe(GMPPrefs.KEY_EME_ENABLED,
- this.onPrefEMEGlobalEnabledChanged, this);
- messageManager.addMessageListener("EMEVideo:ContentMediaKeysRequest", this);
- }
-}
-
-GMPWrapper.prototype = {
- // An active task that checks for plugin updates and installs them.
- _updateTask: null,
- _gmpPath: null,
- _isUpdateCheckPending: false,
-
- optionsType: AddonManager.OPTIONS_TYPE_INLINE,
- get optionsURL() { return this._plugin.optionsURL; },
-
- set gmpPath(aPath) { this._gmpPath = aPath; },
- get gmpPath() {
- if (!this._gmpPath && this.isInstalled) {
- this._gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
- this._plugin.id,
- GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VERSION,
- null, this._plugin.id));
- }
- return this._gmpPath;
- },
-
- get id() { return this._plugin.id; },
- get type() { return "plugin"; },
- get isGMPlugin() { return true; },
- get name() { return this._plugin.name; },
- get creator() { return null; },
- get homepageURL() { return this._plugin.homepageURL; },
-
- get description() { return this._plugin.description; },
- get fullDescription() { return this._plugin.fullDescription; },
-
- get version() { return GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VERSION, null,
- this._plugin.id); },
-
- get isActive() { return !this.appDisabled && !this.userDisabled; },
- get appDisabled() {
- if (this._plugin.isEME && !GMPPrefs.get(GMPPrefs.KEY_EME_ENABLED, true)) {
- // If "media.eme.enabled" is false, all EME plugins are disabled.
- return true;
- }
- return false;
- },
-
- get userDisabled() {
- return !GMPPrefs.get(GMPPrefs.KEY_PLUGIN_ENABLED, true, this._plugin.id);
- },
- set userDisabled(aVal) { GMPPrefs.set(GMPPrefs.KEY_PLUGIN_ENABLED,
- aVal === false,
- this._plugin.id); },
-
- get blocklistState() { return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; },
- get size() { return 0; },
- get scope() { return AddonManager.SCOPE_APPLICATION; },
- get pendingOperations() { return AddonManager.PENDING_NONE; },
-
- get operationsRequiringRestart() { return AddonManager.OP_NEEDS_RESTART_NONE },
-
- get permissions() {
- let permissions = 0;
- if (!this.appDisabled) {
- permissions |= AddonManager.PERM_CAN_UPGRADE;
- permissions |= this.userDisabled ? AddonManager.PERM_CAN_ENABLE :
- AddonManager.PERM_CAN_DISABLE;
- }
- return permissions;
- },
-
- get updateDate() {
- let time = Number(GMPPrefs.get(GMPPrefs.KEY_PLUGIN_LAST_UPDATE, null,
- this._plugin.id));
- if (time !== NaN && this.isInstalled) {
- return new Date(time * 1000)
- }
- return null;
- },
-
- get isCompatible() {
- return true;
- },
-
- get isPlatformCompatible() {
- return true;
- },
-
- get providesUpdatesSecurely() {
- return true;
- },
-
- get foreignInstall() {
- return false;
- },
-
- isCompatibleWith: function(aAppVersion, aPlatformVersion) {
- return true;
- },
-
- get applyBackgroundUpdates() {
- if (!GMPPrefs.isSet(GMPPrefs.KEY_PLUGIN_AUTOUPDATE, this._plugin.id)) {
- return AddonManager.AUTOUPDATE_DEFAULT;
- }
-
- return GMPPrefs.get(GMPPrefs.KEY_PLUGIN_AUTOUPDATE, true, this._plugin.id) ?
- AddonManager.AUTOUPDATE_ENABLE : AddonManager.AUTOUPDATE_DISABLE;
- },
-
- set applyBackgroundUpdates(aVal) {
- if (aVal == AddonManager.AUTOUPDATE_DEFAULT) {
- GMPPrefs.reset(GMPPrefs.KEY_PLUGIN_AUTOUPDATE, this._plugin.id);
- } else if (aVal == AddonManager.AUTOUPDATE_ENABLE) {
- GMPPrefs.set(GMPPrefs.KEY_PLUGIN_AUTOUPDATE, true, this._plugin.id);
- } else if (aVal == AddonManager.AUTOUPDATE_DISABLE) {
- GMPPrefs.set(GMPPrefs.KEY_PLUGIN_AUTOUPDATE, false, this._plugin.id);
- }
- },
-
- findUpdates: function(aListener, aReason, aAppVersion, aPlatformVersion) {
- this._log.trace("findUpdates() - " + this._plugin.id + " - reason=" +
- aReason);
-
- AddonManagerPrivate.callNoUpdateListeners(this, aListener);
-
- if (aReason === AddonManager.UPDATE_WHEN_PERIODIC_UPDATE) {
- if (!AddonManager.shouldAutoUpdate(this)) {
- this._log.trace("findUpdates() - " + this._plugin.id +
- " - no autoupdate");
- return Promise.resolve(false);
- }
-
- let secSinceLastCheck =
- Date.now() / 1000 - Preferences.get(GMPPrefs.KEY_UPDATE_LAST_CHECK, 0);
- if (secSinceLastCheck <= SEC_IN_A_DAY) {
- this._log.trace("findUpdates() - " + this._plugin.id +
- " - last check was less then a day ago");
- return Promise.resolve(false);
- }
- } else if (aReason !== AddonManager.UPDATE_WHEN_USER_REQUESTED) {
- this._log.trace("findUpdates() - " + this._plugin.id +
- " - the given reason to update is not supported");
- return Promise.resolve(false);
- }
-
- if (this._updateTask !== null) {
- this._log.trace("findUpdates() - " + this._plugin.id +
- " - update task already running");
- return this._updateTask;
- }
-
- this._updateTask = Task.spawn(function* GMPProvider_updateTask() {
- this._log.trace("findUpdates() - updateTask");
- try {
- let installManager = new GMPInstallManager();
- let gmpAddons = yield installManager.checkForAddons();
- let update = gmpAddons.find(function(aAddon) {
- return aAddon.id === this._plugin.id;
- }, this);
- if (update && update.isValid && !update.isInstalled) {
- this._log.trace("findUpdates() - found update for " +
- this._plugin.id + ", installing");
- yield installManager.installAddon(update);
- } else {
- this._log.trace("findUpdates() - no updates for " + this._plugin.id);
- }
- this._log.info("findUpdates() - updateTask succeeded for " +
- this._plugin.id);
- } catch (e) {
- this._log.error("findUpdates() - updateTask for " + this._plugin.id +
- " threw", e);
- throw e;
- } finally {
- this._updateTask = null;
- return true;
- }
- }.bind(this));
-
- return this._updateTask;
- },
-
- get pluginMimeTypes() { return []; },
- get pluginLibraries() {
- if (this.isInstalled) {
- let path = this.version;
- return [path];
- }
- return [];
- },
- get pluginFullpath() {
- if (this.isInstalled) {
- let path = OS.Path.join(OS.Constants.Path.profileDir,
- this._plugin.id,
- this.version);
- return [path];
- }
- return [];
- },
-
- get isInstalled() {
- return this.version && this.version.length > 0;
- },
-
- _handleEnabledChanged: function() {
- AddonManagerPrivate.callAddonListeners(this.isActive ?
- "onEnabling" : "onDisabling",
- this, false);
- if (this._gmpPath) {
- if (this.isActive) {
- this._log.info("onPrefEnabledChanged() - adding gmp directory " +
- this._gmpPath);
- gmpService.addPluginDirectory(this._gmpPath);
- } else {
- this._log.info("onPrefEnabledChanged() - removing gmp directory " +
- this._gmpPath);
- gmpService.removePluginDirectory(this._gmpPath);
- }
- }
- AddonManagerPrivate.callAddonListeners(this.isActive ?
- "onEnabled" : "onDisabled",
- this);
- },
-
- onPrefEMEGlobalEnabledChanged: function() {
- AddonManagerPrivate.callAddonListeners("onPropertyChanged", this,
- ["appDisabled"]);
- if (this.appDisabled) {
- this.uninstallPlugin();
- } else {
- AddonManagerPrivate.callInstallListeners("onExternalInstall", null, this,
- null, false);
- AddonManagerPrivate.callAddonListeners("onInstalling", this, false);
- AddonManagerPrivate.callAddonListeners("onInstalled", this);
- this.checkForUpdates(GMP_CHECK_DELAY);
- }
- if (!this.userDisabled) {
- this._handleEnabledChanged();
- }
- },
-
- checkForUpdates: function(delay) {
- if (this._isUpdateCheckPending) {
- return;
- }
- this._isUpdateCheckPending = true;
- GMPPrefs.reset(GMPPrefs.KEY_UPDATE_LAST_CHECK, null);
- // Delay this in case the user changes his mind and doesn't want to
- // enable EME after all.
- setTimeout(() => {
- if (!this.appDisabled) {
- let gmpInstallManager = new GMPInstallManager();
- // We don't really care about the results, if someone is interested
- // they can check the log.
- gmpInstallManager.simpleCheckAndInstall().then(null, () => {});
- }
- this._isUpdateCheckPending = false;
- }, delay);
- },
-
- receiveMessage: function({target: browser, data: data}) {
- this._log.trace("receiveMessage() data=" + data);
- let parsedData;
- try {
- parsedData = JSON.parse(data);
- } catch(ex) {
- this._log.error("Malformed EME video message with data: " + data);
- return;
- }
- let {status: status, keySystem: keySystem} = parsedData;
- if (status == "cdm-not-installed" || status == "cdm-insufficient-version") {
- this.checkForUpdates(0);
- }
- },
-
- onPrefEnabledChanged: function() {
- if (!this._plugin.isEME || !this.appDisabled) {
- this._handleEnabledChanged();
- }
- },
-
- onPrefVersionChanged: function() {
- AddonManagerPrivate.callAddonListeners("onUninstalling", this, false);
- if (this._gmpPath) {
- this._log.info("onPrefVersionChanged() - unregistering gmp directory " +
- this._gmpPath);
- gmpService.removeAndDeletePluginDirectory(this._gmpPath, true /* can defer */);
- }
- AddonManagerPrivate.callAddonListeners("onUninstalled", this);
-
- AddonManagerPrivate.callInstallListeners("onExternalInstall", null, this,
- null, false);
- AddonManagerPrivate.callAddonListeners("onInstalling", this, false);
- this._gmpPath = null;
- if (this.isInstalled) {
- this._gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
- this._plugin.id,
- GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VERSION,
- null, this._plugin.id));
- }
- if (this._gmpPath && this.isActive) {
- this._log.info("onPrefVersionChanged() - registering gmp directory " +
- this._gmpPath);
- gmpService.addPluginDirectory(this._gmpPath);
- }
- AddonManagerPrivate.callAddonListeners("onInstalled", this);
- },
-
- uninstallPlugin: function() {
- AddonManagerPrivate.callAddonListeners("onUninstalling", this, false);
- if (this.gmpPath) {
- this._log.info("uninstallPlugin() - unregistering gmp directory " +
- this.gmpPath);
- gmpService.removeAndDeletePluginDirectory(this.gmpPath);
- }
- GMPPrefs.reset(GMPPrefs.KEY_PLUGIN_VERSION, this.id);
- AddonManagerPrivate.callAddonListeners("onUninstalled", this);
- },
-
- shutdown: function() {
- Preferences.ignore(GMPPrefs.getPrefKey(GMPPrefs.KEY_PLUGIN_ENABLED,
- this._plugin.id),
- this.onPrefEnabledChanged, this);
- Preferences.ignore(GMPPrefs.getPrefKey(GMPPrefs.KEY_PLUGIN_VERSION,
- this._plugin.id),
- this.onPrefVersionChanged, this);
- if (this._plugin.isEME) {
- Preferences.ignore(GMPPrefs.KEY_EME_ENABLED,
- this.onPrefEMEGlobalEnabledChanged, this);
- messageManager.removeMessageListener("EMEVideo:ContentMediaKeysRequest", this);
- }
- return this._updateTask;
- },
-};
-
-var GMPProvider = {
- get name() { return "GMPProvider"; },
-
- _plugins: null,
-
- startup: function() {
- configureLogging();
- this._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP",
- "GMPProvider.");
- this.buildPluginList();
- this.ensureProperCDMInstallState();
-
- Preferences.observe(GMPPrefs.KEY_LOG_BASE, configureLogging);
-
- for (let [id, plugin] of this._plugins) {
- let wrapper = plugin.wrapper;
- let gmpPath = wrapper.gmpPath;
- let isEnabled = wrapper.isActive;
- this._log.trace("startup - enabled=" + isEnabled + ", gmpPath=" +
- gmpPath);
-
- if (gmpPath && isEnabled) {
- this._log.info("startup - adding gmp directory " + gmpPath);
- try {
- gmpService.addPluginDirectory(gmpPath);
- } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
- this._log.warn("startup - adding gmp directory failed with " +
- e.name + " - sandboxing not available?", e);
- }
- }
- }
-
- if (Preferences.get(GMPPrefs.KEY_EME_ENABLED, false)) {
- try {
- let greDir = Services.dirsvc.get(NS_GRE_DIR,
- Ci.nsILocalFile);
- let clearkeyPath = OS.Path.join(greDir.path,
- CLEARKEY_PLUGIN_ID,
- CLEARKEY_VERSION);
- this._log.info("startup - adding clearkey CDM directory " +
- clearkeyPath);
- gmpService.addPluginDirectory(clearkeyPath);
- } catch (e) {
- this._log.warn("startup - adding clearkey CDM failed", e);
- }
- }
- },
-
- shutdown: function() {
- this._log.trace("shutdown");
- Preferences.ignore(GMPPrefs.KEY_LOG_BASE, configureLogging);
-
- let shutdownTask = Task.spawn(function* GMPProvider_shutdownTask() {
- this._log.trace("shutdown - shutdownTask");
- let shutdownSucceeded = true;
-
- for (let plugin of this._plugins.values()) {
- try {
- yield plugin.wrapper.shutdown();
- } catch (e) {
- shutdownSucceeded = false;
- }
- }
-
- this._plugins = null;
-
- if (!shutdownSucceeded) {
- throw new Error("Shutdown failed");
- }
- }.bind(this));
-
- return shutdownTask;
- },
-
- getAddonByID: function(aId, aCallback) {
- if (!this.isEnabled) {
- aCallback(null);
- return;
- }
-
- let plugin = this._plugins.get(aId);
- if (plugin && !GMPUtils.isPluginHidden(plugin)) {
- aCallback(plugin.wrapper);
- } else {
- aCallback(null);
- }
- },
-
- getAddonsByTypes: function(aTypes, aCallback) {
- if (!this.isEnabled ||
- (aTypes && aTypes.indexOf("plugin") < 0)) {
- aCallback([]);
- return;
- }
-
- // Tycho:
- // let results = [p.wrapper for ([id, p] of this._plugins)
- // if (!GMPUtils.isPluginHidden(p))];
- let results = [];
- for (let [id, p] of this._plugins) {
- if (!GMPUtils.isPluginHidden(p)) {
- results.push(p.wrapper);
- }
- }
-
- aCallback(results);
- },
-
- get isEnabled() {
- return GMPPrefs.get(GMPPrefs.KEY_PROVIDER_ENABLED, false);
- },
-
- generateFullDescription: function(aLicenseURL, aLicenseInfo) {
- return "<xhtml:a href=\"" + aLicenseURL + "\" target=\"_blank\">" +
- aLicenseInfo + "</xhtml:a>."
- },
-
- buildPluginList: function() {
- let licenseInfo = pluginsBundle.GetStringFromName(GMP_LICENSE_INFO);
-
- this._plugins = new Map();
- for (let aPlugin of GMP_PLUGINS) {
- let plugin = {
- id: aPlugin.id,
- name: pluginsBundle.GetStringFromName(aPlugin.name),
- description: pluginsBundle.GetStringFromName(aPlugin.description),
- homepageURL: aPlugin.homepageURL,
- optionsURL: aPlugin.optionsURL,
- wrapper: null,
- isEME: aPlugin.isEME,
- };
- if (aPlugin.licenseURL) {
- plugin.fullDescription =
- this.generateFullDescription(aPlugin.licenseURL, licenseInfo);
- }
- plugin.wrapper = new GMPWrapper(plugin);
- this._plugins.set(plugin.id, plugin);
- }
- },
-
- ensureProperCDMInstallState: function() {
- if (!GMPPrefs.get(GMPPrefs.KEY_EME_ENABLED, true)) {
- for (let [id, plugin] of this._plugins) {
- if (plugin.isEME && plugin.wrapper.isInstalled) {
- gmpService.addPluginDirectory(plugin.wrapper.gmpPath);
- plugin.wrapper.uninstallPlugin();
- }
- }
- }
- },
-};
-
-AddonManagerPrivate.registerProvider(GMPProvider, [
- new AddonManagerPrivate.AddonType("plugin", URI_EXTENSION_STRINGS,
- STRING_TYPE_NAME,
- AddonManager.VIEW_TYPE_LIST, 6000,
- AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE)
-]);
diff --git a/components/addons/src/GMPUtils.jsm b/components/addons/src/GMPUtils.jsm
deleted file mode 100644
index 593fc3c8d..000000000
--- a/components/addons/src/GMPUtils.jsm
+++ /dev/null
@@ -1,187 +0,0 @@
-/* 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";
-
-const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} =
- Components;
-
-this.EXPORTED_SYMBOLS = [ "GMP_PLUGIN_IDS",
- "GMPPrefs",
- "GMPUtils",
- "OPEN_H264_ID",
- "WIDEVINE_ID" ];
-
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-// GMP IDs
-const OPEN_H264_ID = "gmp-gmpopenh264";
-const WIDEVINE_ID = "gmp-widevinecdm";
-const GMP_PLUGIN_IDS = [ OPEN_H264_ID, WIDEVINE_ID ];
-
-var GMPPluginUnsupportedReason = {
- NOT_WINDOWS: 1,
- WINDOWS_VERSION: 2,
-};
-
-var GMPPluginHiddenReason = {
- UNSUPPORTED: 1,
- EME_DISABLED: 2,
-};
-
-this.GMPUtils = {
- /**
- * Checks whether or not a given plugin is hidden. Hidden plugins are neither
- * downloaded nor displayed in the addons manager.
- * @param aPlugin
- * The plugin to check.
- */
- isPluginHidden: function(aPlugin) {
- if (!aPlugin.isEME) {
- return false;
- }
-
- if (!this._isPluginSupported(aPlugin) ||
- !this._isPluginVisible(aPlugin)) {
- return true;
- }
-
- if (!GMPPrefs.get(GMPPrefs.KEY_EME_ENABLED, true)) {
- return true;
- }
-
- return false;
- },
-
- /**
- * Checks whether or not a given plugin is supported by the current OS.
- * @param aPlugin
- * The plugin to check.
- */
- _isPluginSupported: function(aPlugin) {
- if (this._isPluginForceSupported(aPlugin)) {
- return true;
- }
- if (aPlugin.id == WIDEVINE_ID) {
-
-#if defined(XP_WIN) || defined(XP_LINUX)
- // The Widevine plugin is available for Windows versions Vista and later,
- // Mac OSX, and Linux.
- return true;
-#else
- return false;
-#endif
- }
-
- return true;
- },
-
- /**
- * Checks whether or not a given plugin is visible in the addons manager
- * UI and the "enable DRM" notification box. This can be used to test
- * plugins that aren't yet turned on in the mozconfig.
- * @param aPlugin
- * The plugin to check.
- */
- _isPluginVisible: function(aPlugin) {
- return GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VISIBLE, false, aPlugin.id);
- },
-
- /**
- * Checks whether or not a given plugin is forced-supported. This is used
- * in automated tests to override the checks that prevent GMPs running on an
- * unsupported platform.
- * @param aPlugin
- * The plugin to check.
- */
- _isPluginForceSupported: function(aPlugin) {
- return GMPPrefs.get(GMPPrefs.KEY_PLUGIN_FORCE_SUPPORTED, false, aPlugin.id);
- },
-};
-
-/**
- * Manages preferences for GMP addons
- */
-this.GMPPrefs = {
- KEY_EME_ENABLED: "media.eme.enabled",
- KEY_PLUGIN_ENABLED: "media.{0}.enabled",
- KEY_PLUGIN_LAST_UPDATE: "media.{0}.lastUpdate",
- KEY_PLUGIN_VERSION: "media.{0}.version",
- KEY_PLUGIN_AUTOUPDATE: "media.{0}.autoupdate",
- KEY_PLUGIN_VISIBLE: "media.{0}.visible",
- KEY_PLUGIN_ABI: "media.{0}.abi",
- KEY_PLUGIN_FORCE_SUPPORTED: "media.{0}.forceSupported",
- KEY_URL: "media.gmp-manager.url",
- KEY_URL_OVERRIDE: "media.gmp-manager.url.override",
- KEY_CERT_CHECKATTRS: "media.gmp-manager.cert.checkAttributes",
- KEY_CERT_REQUIREBUILTIN: "media.gmp-manager.cert.requireBuiltIn",
- KEY_UPDATE_LAST_CHECK: "media.gmp-manager.lastCheck",
- KEY_SECONDS_BETWEEN_CHECKS: "media.gmp-manager.secondsBetweenChecks",
- KEY_UPDATE_ENABLED: "media.gmp-manager.updateEnabled",
- KEY_APP_DISTRIBUTION: "distribution.id",
- KEY_APP_DISTRIBUTION_VERSION: "distribution.version",
- KEY_BUILDID: "media.gmp-manager.buildID",
- KEY_CERTS_BRANCH: "media.gmp-manager.certs.",
- KEY_PROVIDER_ENABLED: "media.gmp-provider.enabled",
- KEY_LOG_BASE: "media.gmp.log.",
- KEY_LOGGING_LEVEL: "media.gmp.log.level",
- KEY_LOGGING_DUMP: "media.gmp.log.dump",
-
- /**
- * Obtains the specified preference in relation to the specified plugin.
- * @param aKey The preference key value to use.
- * @param aDefaultValue The default value if no preference exists.
- * @param aPlugin The plugin to scope the preference to.
- * @return The obtained preference value, or the defaultValue if none exists.
- */
- get: function(aKey, aDefaultValue, aPlugin) {
- if (aKey === this.KEY_APP_DISTRIBUTION ||
- aKey === this.KEY_APP_DISTRIBUTION_VERSION) {
- return Services.prefs.getDefaultBranch(null).getCharPref(aKey, "default");
- }
- return Preferences.get(this.getPrefKey(aKey, aPlugin), aDefaultValue);
- },
-
- /**
- * Sets the specified preference in relation to the specified plugin.
- * @param aKey The preference key value to use.
- * @param aVal The value to set.
- * @param aPlugin The plugin to scope the preference to.
- */
- set: function(aKey, aVal, aPlugin) {
- Preferences.set(this.getPrefKey(aKey, aPlugin), aVal);
- },
-
- /**
- * Checks whether or not the specified preference is set in relation to the
- * specified plugin.
- * @param aKey The preference key value to use.
- * @param aPlugin The plugin to scope the preference to.
- * @return true if the preference is set, false otherwise.
- */
- isSet: function(aKey, aPlugin) {
- return Preferences.isSet(this.getPrefKey(aKey, aPlugin));
- },
-
- /**
- * Resets the specified preference in relation to the specified plugin to its
- * default.
- * @param aKey The preference key value to use.
- * @param aPlugin The plugin to scope the preference to.
- */
- reset: function(aKey, aPlugin) {
- Preferences.reset(this.getPrefKey(aKey, aPlugin));
- },
-
- /**
- * Scopes the specified preference key to the specified plugin.
- * @param aKey The preference key value to use.
- * @param aPlugin The plugin to scope the preference to.
- * @return A preference key scoped to the specified plugin.
- */
- getPrefKey: function(aKey, aPlugin) {
- return aKey.replace("{0}", aPlugin || "");
- },
-};
diff --git a/components/addons/src/ProductAddonChecker.jsm b/components/addons/src/ProductAddonChecker.jsm
deleted file mode 100644
index c6324da0a..000000000
--- a/components/addons/src/ProductAddonChecker.jsm
+++ /dev/null
@@ -1,464 +0,0 @@
-/* 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";
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-const LOCAL_EME_SOURCES = [{
- "id": "gmp-gmpopenh264",
- "src": "chrome://global/content/gmp-sources/openh264.json"
-}, {
- "id": "gmp-widevinecdm",
- "src": "chrome://global/content/gmp-sources/widevinecdm.json"
-}];
-
-this.EXPORTED_SYMBOLS = [ "ProductAddonChecker" ];
-
-Cu.importGlobalProperties(["XMLHttpRequest"]);
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/CertUtils.jsm");
-/* globals checkCert, BadCertHandler*/
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/osfile.jsm");
-
-/* globals GMPPrefs */
-XPCOMUtils.defineLazyModuleGetter(this, "GMPPrefs",
- "resource://gre/modules/GMPUtils.jsm");
-
-/* globals OS */
-
-XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
- "resource://gre/modules/UpdateUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(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 Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsISupports);
-}
-
-var logger = Log.repository.getLogger("addons.productaddons");
-
-/**
- * Number of milliseconds after which we need to cancel `downloadXML`.
- *
- * Bug 1087674 suggests that the XHR we use in `downloadXML` may
- * never terminate in presence of network nuisances (e.g. strange
- * antivirus behavior). This timeout is a defensive measure to ensure
- * that we fail cleanly in such case.
- */
-const TIMEOUT_DELAY_MS = 20000;
-// Chunk size for the incremental downloader
-const DOWNLOAD_CHUNK_BYTES_SIZE = 300000;
-// Incremental downloader interval
-const DOWNLOAD_INTERVAL = 0;
-// How much of a file to read into memory at a time for hashing
-const HASH_CHUNK_SIZE = 8192;
-
-/**
- * Gets the status of an XMLHttpRequest either directly or from its underlying
- * channel.
- *
- * @param request
- * The XMLHttpRequest.
- * @return an integer status value.
- */
-function getRequestStatus(request) {
- let status = null;
- try {
- status = request.status;
- }
- catch (e) {
- }
-
- if (status != null) {
- return status;
- }
-
- return request.channel.QueryInterface(Ci.nsIRequest).status;
-}
-
-/**
- * Downloads an XML document from a URL optionally testing the SSL certificate
- * for certain attributes.
- *
- * @param url
- * The url to download from.
- * @param allowNonBuiltIn
- * Whether to trust SSL certificates without a built-in CA issuer.
- * @param allowedCerts
- * The list of certificate attributes to match the SSL certificate
- * against or null to skip checks.
- * @return a promise that resolves to the DOM document downloaded or rejects
- * with a JS exception in case of error.
- */
-function downloadXML(url, allowNonBuiltIn = false, allowedCerts = null) {
- return new Promise((resolve, reject) => {
- let request = CreateXHR();
- // This is here to let unit test code override XHR
- if (request.wrappedJSObject) {
- request = request.wrappedJSObject;
- }
- request.open("GET", url, true);
- request.channel.notificationCallbacks = new BadCertHandler(allowNonBuiltIn);
- // Prevent the request from reading from the cache.
- request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
- // Prevent the request from writing to the cache.
- request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
- // Use conservative TLS settings. See bug 1325501.
- // TODO move to ServiceRequest.
- if (request.channel instanceof Ci.nsIHttpChannelInternal) {
- request.channel.QueryInterface(Ci.nsIHttpChannelInternal).beConservative = true;
- }
- request.timeout = TIMEOUT_DELAY_MS;
-
- request.overrideMimeType("text/xml");
- // The Cache-Control header is only interpreted by proxies and the
- // final destination. It does not help if a resource is already
- // cached locally.
- request.setRequestHeader("Cache-Control", "no-cache");
- // HTTP/1.0 servers might not implement Cache-Control and
- // might only implement Pragma: no-cache
- request.setRequestHeader("Pragma", "no-cache");
-
- let fail = (event) => {
- let request = event.target;
- let status = getRequestStatus(request);
- let message = "Failed downloading XML, status: " + status + ", reason: " + event.type;
- logger.warn(message);
- let ex = new Error(message);
- ex.status = status;
- reject(ex);
- };
-
- let success = (event) => {
- logger.info("Completed downloading document");
- let request = event.target;
-
- try {
- checkCert(request.channel, allowNonBuiltIn, allowedCerts);
- } catch (ex) {
- logger.error("Request failed certificate checks: " + ex);
- ex.status = getRequestStatus(request);
- reject(ex);
- return;
- }
-
- resolve(request.responseXML);
- };
-
- request.addEventListener("error", fail, false);
- request.addEventListener("abort", fail, false);
- request.addEventListener("timeout", fail, false);
- request.addEventListener("load", success, false);
-
- 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.
- */
-function parseXML(document) {
- // Check that the root element is correct
- if (document.documentElement.localName != "updates") {
- throw new Error("got node name: " + document.documentElement.localName +
- ", expected: updates");
- }
-
- // Check if there are any addons elements in the updates element
- let addons = document.querySelector("updates:root > addons");
- if (!addons) {
- return null;
- }
-
- let results = [];
- let addonList = document.querySelectorAll("updates:root > addons > addon");
- for (let addonElement of addonList) {
- let addon = {};
-
- for (let name of ["id", "URL", "hashFunction", "hashValue", "version", "size"]) {
- if (addonElement.hasAttribute(name)) {
- addon[name] = addonElement.getAttribute(name);
- }
- }
- addon.size = Number(addon.size) || undefined;
-
- results.push(addon);
- }
-
- return {
- usedFallback: false,
- gmpAddons: results
- };
-}
-
-/**
- * If downloading from the network fails (AUS server is down),
- * load the sources from local build configuration.
- */
-function downloadLocalConfig() {
-
- if (!GMPPrefs.get(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_EME_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.
- * @return a promise that resolves to the path of a temporary file or rejects
- * with a JS exception in case of error.
- */
-function downloadFile(url) {
- return new Promise((resolve, reject) => {
- let xhr = new XMLHttpRequest();
- xhr.onload = function(response) {
- logger.info("downloadXHR File download. status=" + xhr.status);
- if (xhr.status != 200 && xhr.status != 206) {
- reject(Components.Exception("File download failed", xhr.status));
- return;
- }
- Task.spawn(function* () {
- let f = yield OS.File.openUnique(OS.Path.join(OS.Constants.Path.tmpDir, "tmpaddon"));
- let path = f.path;
- logger.info(`Downloaded file will be saved to ${path}`);
- yield f.file.close();
- yield OS.File.writeAtomic(path, new Uint8Array(xhr.response));
- return path;
- }).then(resolve, reject);
- };
-
- let fail = (event) => {
- let request = event.target;
- let status = getRequestStatus(request);
- let message = "Failed downloading via XHR, status: " + status + ", reason: " + event.type;
- logger.warn(message);
- let ex = new Error(message);
- ex.status = status;
- reject(ex);
- };
- xhr.addEventListener("error", fail);
- xhr.addEventListener("abort", fail);
-
- xhr.responseType = "arraybuffer";
- try {
- xhr.open("GET", url);
- // Use conservative TLS settings. See bug 1325501.
- // TODO move to ServiceRequest.
- if (xhr.channel instanceof Ci.nsIHttpChannelInternal) {
- xhr.channel.QueryInterface(Ci.nsIHttpChannelInternal).beConservative = true;
- }
- xhr.send(null);
- } catch (ex) {
- reject(ex);
- }
- });
-}
-
-/**
- * Convert a string containing binary values to hex.
- */
-function binaryToHex(input) {
- let result = "";
- for (let i = 0; i < input.length; ++i) {
- let hex = input.charCodeAt(i).toString(16);
- if (hex.length == 1) {
- hex = "0" + hex;
- }
- result += hex;
- }
- return result;
-}
-
-/**
- * Calculates the hash of a file.
- *
- * @param hashFunction
- * The type of hash function to use, must be supported by nsICryptoHash.
- * @param path
- * The path of the file to hash.
- * @return a promise that resolves to hash of the file or rejects with a JS
- * exception in case of error.
- */
-var computeHash = Task.async(function*(hashFunction, path) {
- let file = yield OS.File.open(path, { existing: true, read: true });
- try {
- let hasher = Cc["@mozilla.org/security/hash;1"].
- createInstance(Ci.nsICryptoHash);
- hasher.initWithString(hashFunction);
-
- let bytes;
- do {
- bytes = yield file.read(HASH_CHUNK_SIZE);
- hasher.update(bytes, bytes.length);
- } while (bytes.length == HASH_CHUNK_SIZE);
-
- return binaryToHex(hasher.finish(false));
- }
- finally {
- yield file.close();
- }
-});
-
-/**
- * Verifies that a downloaded file matches what was expected.
- *
- * @param properties
- * The properties to check, `size` and `hashFunction` with `hashValue`
- * are supported. Any properties missing won't be checked.
- * @param path
- * The path of the file to check.
- * @return a promise that resolves if the file matched or rejects with a JS
- * exception in case of error.
- */
-var verifyFile = Task.async(function*(properties, path) {
- if (properties.size !== undefined) {
- let stat = yield OS.File.stat(path);
- if (stat.size != properties.size) {
- throw new Error("Downloaded file was " + stat.size + " bytes but expected " + properties.size + " bytes.");
- }
- }
-
- if (properties.hashFunction !== undefined) {
- let expectedDigest = properties.hashValue.toLowerCase();
- let digest = yield computeHash(properties.hashFunction, path);
- if (digest != expectedDigest) {
- throw new Error("Hash was `" + digest + "` but expected `" + expectedDigest + "`.");
- }
- }
-});
-
-const ProductAddonChecker = {
- /**
- * Downloads a list of add-ons from a URL optionally testing the SSL
- * certificate for certain attributes.
- *
- * @param url
- * The url to download from.
- * @param allowNonBuiltIn
- * Whether to trust SSL certificates without a built-in CA issuer.
- * @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: function(url, allowNonBuiltIn = false, allowedCerts = null) {
- if (!GMPPrefs.get(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);
- },
-
- /**
- * 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.
- * @return a promise that resolves to the temporary file downloaded or rejects
- * with a JS exception in case of error.
- */
- downloadAddon: Task.async(function*(addon) {
- let path = yield downloadFile(addon.URL);
- try {
- yield verifyFile(addon, path);
- return path;
- }
- catch (e) {
- yield OS.File.remove(path);
- throw e;
- }
- })
-}
diff --git a/components/global/content/process-content.js b/components/global/content/process-content.js
index 2ff8f908a..9d7e37100 100644
--- a/components/global/content/process-content.js
+++ b/components/global/content/process-content.js
@@ -14,13 +14,6 @@ Cu.import("resource://gre/modules/Services.jsm");
const gInContentProcess = Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
-Services.cpmm.addMessageListener("gmp-plugin-crash", msg => {
- let gmpservice = Cc["@mozilla.org/gecko-media-plugin-service;1"]
- .getService(Ci.mozIGeckoMediaPluginService);
-
- gmpservice.RunPluginCrashCallbacks(msg.data.pluginID, msg.data.pluginName);
-});
-
if (gInContentProcess) {
let ProcessObserver = {
TOPICS: [