DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (39c1aeb25240)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
/* 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 EXPORTED_SYMBOLS = [
  "GMP_PLUGIN_IDS",
  "GMPPrefs",
  "GMPUtils",
  "OPEN_H264_ID",
  "WIDEVINE_ID",
];

const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { AppConstants } = ChromeUtils.import(
  "resource://gre/modules/AppConstants.jsm"
);
const { UpdateUtils } = ChromeUtils.import(
  "resource://gre/modules/UpdateUtils.jsm"
);

// GMP IDs
const OPEN_H264_ID = "gmp-gmpopenh264";
const WIDEVINE_ID = "gmp-widevinecdm";
const GMP_PLUGIN_IDS = [OPEN_H264_ID, WIDEVINE_ID];

var 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(aPlugin) {
    if (this._is32bitModeMacOS()) {
      // GMPs are hidden on MacOS when running in 32 bit mode.
      // See bug 1291537.
      return true;
    }

    if (!this._isPluginSupported(aPlugin) || !this._isPluginVisible(aPlugin)) {
      return true;
    }

    if (!aPlugin.isEME) {
      return false;
    }

    if (!GMPPrefs.getBool(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(aPlugin) {
    if (this._isPluginForceSupported(aPlugin)) {
      return true;
    }
    if (aPlugin.id == WIDEVINE_ID) {
      // The Widevine plugin is available for Windows versions Vista and later,
      // Mac OSX, and Linux.
      return (
        AppConstants.platform == "win" ||
        AppConstants.platform == "macosx" ||
        AppConstants.platform == "linux"
      );
    }

    return true;
  },

  _is32bitModeMacOS() {
    if (AppConstants.platform != "macosx") {
      return false;
    }
    return Services.appinfo.XPCOMABI.split("-")[0] == "x86";
  },

  /**
   * 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(aPlugin) {
    return GMPPrefs.getBool(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(aPlugin) {
    return GMPPrefs.getBool(
      GMPPrefs.KEY_PLUGIN_FORCE_SUPPORTED,
      false,
      aPlugin.id
    );
  },

  _isWindowsOnARM64() {
    return AppConstants.platform == "win" && UpdateUtils.ABI.match(/aarch64/);
  },

  _expectedABI(aPlugin) {
    let defaultABI = UpdateUtils.ABI;
    if (aPlugin.id == WIDEVINE_ID && this._isWindowsOnARM64()) {
      // On Windows on aarch64, we need the x86 plugin,
      // as there's no native aarch64 plugins yet.
      defaultABI = defaultABI.replace(/aarch64/g, "x86");
    }
    return defaultABI;
  },
};

/**
 * Manages preferences for GMP addons
 */
var 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 string 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.
   */
  getString(aKey, aDefaultValue, aPlugin) {
    if (
      aKey === this.KEY_APP_DISTRIBUTION ||
      aKey === this.KEY_APP_DISTRIBUTION_VERSION
    ) {
      return Services.prefs.getDefaultBranch(null).getCharPref(aKey, "default");
    }
    return Services.prefs.getStringPref(
      this.getPrefKey(aKey, aPlugin),
      aDefaultValue
    );
  },

  /**
   * Obtains the specified int 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.
   */
  getInt(aKey, aDefaultValue, aPlugin) {
    return Services.prefs.getIntPref(
      this.getPrefKey(aKey, aPlugin),
      aDefaultValue
    );
  },

  /**
   * Obtains the specified bool 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.
   */
  getBool(aKey, aDefaultValue, aPlugin) {
    return Services.prefs.getBoolPref(
      this.getPrefKey(aKey, aPlugin),
      aDefaultValue
    );
  },

  /**
   * Sets the specified string 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.
   */
  setString(aKey, aVal, aPlugin) {
    Services.prefs.setStringPref(this.getPrefKey(aKey, aPlugin), aVal);
  },

  /**
   * Sets the specified bool 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.
   */
  setBool(aKey, aVal, aPlugin) {
    Services.prefs.setBoolPref(this.getPrefKey(aKey, aPlugin), aVal);
  },

  /**
   * Sets the specified int 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.
   */
  setInt(aKey, aVal, aPlugin) {
    Services.prefs.setIntPref(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(aKey, aPlugin) {
    return Services.prefs.prefHasUserValue(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(aKey, aPlugin) {
    Services.prefs.clearUserPref(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(aKey, aPlugin) {
    return aKey.replace("{0}", aPlugin || "");
  },
};