1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
8 ChromeUtils.defineESModuleGetters(lazy, {
9 UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",
13 export const OPEN_H264_ID = "gmp-gmpopenh264";
14 export const WIDEVINE_L1_ID = "gmp-widevinecdm-l1";
15 export const WIDEVINE_L3_ID = "gmp-widevinecdm";
17 export const GMP_PLUGIN_IDS = [OPEN_H264_ID, WIDEVINE_L1_ID, WIDEVINE_L3_ID];
19 export var GMPUtils = {
21 * Checks whether or not a given plugin is hidden. Hidden plugins are neither
22 * downloaded nor displayed in the addons manager.
24 * The plugin to check.
26 isPluginHidden(aPlugin) {
27 if (!this._isPluginSupported(aPlugin) || !this._isPluginVisible(aPlugin)) {
35 if (!GMPPrefs.getBool(GMPPrefs.KEY_EME_ENABLED, true)) {
43 * Checks whether or not a given plugin is supported by the current OS.
45 * The plugin to check.
47 _isPluginSupported(aPlugin) {
48 if (this._isPluginForceSupported(aPlugin)) {
51 if (aPlugin.id == WIDEVINE_L1_ID) {
52 // The Widevine L1 plugin is currently only available for Windows x64.
54 AppConstants.MOZ_WMF_CDM &&
55 AppConstants.platform == "win" &&
56 lazy.UpdateUtils.ABI.match(/x64/)
59 if (aPlugin.id == WIDEVINE_L1_ID || aPlugin.id == WIDEVINE_L3_ID) {
60 // The Widevine plugin is available for Windows versions Vista and later,
61 // Mac OSX, and Linux.
63 AppConstants.platform == "win" ||
64 AppConstants.platform == "macosx" ||
65 AppConstants.platform == "linux"
73 * Checks whether or not a given plugin is visible in the addons manager
74 * UI and the "enable DRM" notification box. This can be used to test
75 * plugins that aren't yet turned on in the mozconfig.
77 * The plugin to check.
79 _isPluginVisible(aPlugin) {
80 return GMPPrefs.getBool(GMPPrefs.KEY_PLUGIN_VISIBLE, false, aPlugin.id);
84 * Checks whether or not a given plugin is forced-supported. This is used
85 * in automated tests to override the checks that prevent GMPs running on an
86 * unsupported platform.
88 * The plugin to check.
90 _isPluginForceSupported(aPlugin) {
91 return GMPPrefs.getBool(
92 GMPPrefs.KEY_PLUGIN_FORCE_SUPPORTED,
100 AppConstants.platform == "win" && lazy.UpdateUtils.ABI.match(/aarch64/)
104 _getChromiumUpdateParameters(aPlugin) {
106 if (AppConstants.platform === "win") {
108 } else if (AppConstants.platform === "macosx") {
110 } else if (AppConstants.platform === "linux") {
111 params += "&os=Linux";
113 throw new Error("Unknown platform " + AppConstants.platform);
116 const abi = Services.appinfo.XPCOMABI;
117 if (abi.match(/aarch64/)) {
118 params += "&arch=arm64&os_arch=arm64";
119 } else if (abi.match(/x86_64/)) {
120 params += "&arch=x64&os_arch=x64";
121 } else if (abi.match(/x86/)) {
122 params += "&arch=x86&os_arch=x86";
124 throw new Error("Unknown ABI " + abi);
129 GMPPrefs.KEY_PLUGIN_FORCE_CHROMIUM_BETA,
134 params += "&testrequest=1";
140 _expectedABI(aPlugin) {
141 let defaultABI = lazy.UpdateUtils.ABI;
142 let expectedABIs = [defaultABI];
143 if (aPlugin.id == WIDEVINE_L3_ID && this._isWindowsOnARM64()) {
144 // On Windows on aarch64, we may use either the x86 or the ARM64 plugin
145 // as we are still shipping the former to release.
146 expectedABIs.push(defaultABI.replace(/aarch64/g, "x86"));
148 return expectedABIs.join(",");
153 * Manages preferences for GMP addons
155 export var GMPPrefs = {
156 KEY_EME_ENABLED: "media.eme.enabled",
157 KEY_PLUGIN_ENABLED: "media.{0}.enabled",
158 KEY_PLUGIN_LAST_DOWNLOAD: "media.{0}.lastDownload",
159 KEY_PLUGIN_LAST_DOWNLOAD_FAILED: "media.{0}.lastDownloadFailed",
160 KEY_PLUGIN_LAST_DOWNLOAD_FAIL_REASON: "media.{0}.lastDownloadFailReason",
161 KEY_PLUGIN_LAST_INSTALL_FAILED: "media.{0}.lastInstallFailed",
162 KEY_PLUGIN_LAST_INSTALL_FAIL_REASON: "media.{0}.lastInstallFailReason",
163 KEY_PLUGIN_LAST_INSTALL_START: "media.{0}.lastInstallStart",
164 KEY_PLUGIN_LAST_UPDATE: "media.{0}.lastUpdate",
165 KEY_PLUGIN_HASHVALUE: "media.{0}.hashValue",
166 KEY_PLUGIN_VERSION: "media.{0}.version",
167 KEY_PLUGIN_AUTOUPDATE: "media.{0}.autoupdate",
168 KEY_PLUGIN_VISIBLE: "media.{0}.visible",
169 KEY_PLUGIN_ABI: "media.{0}.abi",
170 KEY_PLUGIN_FORCE_SUPPORTED: "media.{0}.forceSupported",
171 KEY_PLUGIN_FORCE_INSTALL: "media.{0}.forceInstall",
172 KEY_PLUGIN_ALLOW_X64_ON_ARM64: "media.{0}.allow-x64-plugin-on-arm64",
173 KEY_PLUGIN_CHROMIUM_GUID: "media.{0}.chromium-guid",
174 KEY_PLUGIN_FORCE_CHROMIUM_UPDATE: "media.{0}.force-chromium-update",
175 KEY_PLUGIN_FORCE_CHROMIUM_BETA: "media.{0}.force-chromium-beta",
176 KEY_ALLOW_LOCAL_SOURCES: "media.gmp-manager.allowLocalSources",
177 KEY_URL: "media.gmp-manager.url",
178 KEY_URL_OVERRIDE: "media.gmp-manager.url.override",
179 KEY_CHROMIUM_UPDATE_URL: "media.gmp-manager.chromium-update-url",
180 KEY_CERT_CHECKATTRS: "media.gmp-manager.cert.checkAttributes",
181 KEY_CERT_REQUIREBUILTIN: "media.gmp-manager.cert.requireBuiltIn",
182 KEY_CHECK_CONTENT_SIGNATURE: "media.gmp-manager.checkContentSignature",
183 KEY_UPDATE_LAST_CHECK: "media.gmp-manager.lastCheck",
184 KEY_UPDATE_LAST_EMPTY_CHECK: "media.gmp-manager.lastEmptyCheck",
185 KEY_SECONDS_BETWEEN_CHECKS: "media.gmp-manager.secondsBetweenChecks",
186 KEY_UPDATE_ENABLED: "media.gmp-manager.updateEnabled",
187 KEY_APP_DISTRIBUTION: "distribution.id",
188 KEY_APP_DISTRIBUTION_VERSION: "distribution.version",
189 KEY_BUILDID: "media.gmp-manager.buildID",
190 KEY_CERTS_BRANCH: "media.gmp-manager.certs.",
191 KEY_PROVIDER_ENABLED: "media.gmp-provider.enabled",
192 KEY_LOG_BASE: "media.gmp.log.",
193 KEY_LOGGING_LEVEL: "media.gmp.log.level",
194 KEY_LOGGING_DUMP: "media.gmp.log.dump",
197 * Obtains the specified string preference in relation to the specified plugin.
198 * @param aKey The preference key value to use.
199 * @param aDefaultValue The default value if no preference exists.
200 * @param aPlugin The plugin to scope the preference to.
201 * @return The obtained preference value, or the defaultValue if none exists.
203 getString(aKey, aDefaultValue, aPlugin) {
205 aKey === this.KEY_APP_DISTRIBUTION ||
206 aKey === this.KEY_APP_DISTRIBUTION_VERSION
208 return Services.prefs.getDefaultBranch(null).getCharPref(aKey, "default");
210 return Services.prefs.getStringPref(
211 this.getPrefKey(aKey, aPlugin),
217 * Obtains the specified int preference in relation to the specified plugin.
218 * @param aKey The preference key value to use.
219 * @param aDefaultValue The default value if no preference exists.
220 * @param aPlugin The plugin to scope the preference to.
221 * @return The obtained preference value, or the defaultValue if none exists.
223 getInt(aKey, aDefaultValue, aPlugin) {
224 return Services.prefs.getIntPref(
225 this.getPrefKey(aKey, aPlugin),
231 * Obtains the specified bool preference in relation to the specified plugin.
232 * @param aKey The preference key value to use.
233 * @param aDefaultValue The default value if no preference exists.
234 * @param aPlugin The plugin to scope the preference to.
235 * @return The obtained preference value, or the defaultValue if none exists.
237 getBool(aKey, aDefaultValue, aPlugin) {
238 return Services.prefs.getBoolPref(
239 this.getPrefKey(aKey, aPlugin),
245 * Sets the specified string preference in relation to the specified plugin.
246 * @param aKey The preference key value to use.
247 * @param aVal The value to set.
248 * @param aPlugin The plugin to scope the preference to.
250 setString(aKey, aVal, aPlugin) {
251 Services.prefs.setStringPref(this.getPrefKey(aKey, aPlugin), aVal);
255 * Sets the specified bool preference in relation to the specified plugin.
256 * @param aKey The preference key value to use.
257 * @param aVal The value to set.
258 * @param aPlugin The plugin to scope the preference to.
260 setBool(aKey, aVal, aPlugin) {
261 Services.prefs.setBoolPref(this.getPrefKey(aKey, aPlugin), aVal);
265 * Sets the specified int preference in relation to the specified plugin.
266 * @param aKey The preference key value to use.
267 * @param aVal The value to set.
268 * @param aPlugin The plugin to scope the preference to.
270 setInt(aKey, aVal, aPlugin) {
271 Services.prefs.setIntPref(this.getPrefKey(aKey, aPlugin), aVal);
275 * Checks whether or not the specified preference is set in relation to the
277 * @param aKey The preference key value to use.
278 * @param aPlugin The plugin to scope the preference to.
279 * @return true if the preference is set, false otherwise.
281 isSet(aKey, aPlugin) {
282 return Services.prefs.prefHasUserValue(this.getPrefKey(aKey, aPlugin));
286 * Resets the specified preference in relation to the specified plugin to its
288 * @param aKey The preference key value to use.
289 * @param aPlugin The plugin to scope the preference to.
291 reset(aKey, aPlugin) {
292 Services.prefs.clearUserPref(this.getPrefKey(aKey, aPlugin));
296 * Scopes the specified preference key to the specified plugin.
297 * @param aKey The preference key value to use.
298 * @param aPlugin The plugin to scope the preference to.
299 * @return A preference key scoped to the specified plugin.
301 getPrefKey(aKey, aPlugin) {
302 return aKey.replace("{0}", aPlugin || "");