Bug 1045209 - Remove media.gmp-gmpopenh264.path pref and set install path for OpenH264 plugin to <profile-dir>/<gmp-plugin-id>/<version>. r=unfocused,jesup
authorQeole <qeole@outlook.com>
Mon, 25 Aug 2014 17:23:34 +0200
changeset 222995 8058658b0a28cfbdbe1317ef9f4661591c3cfc2a
parent 222994 ba1d285f2ddebb2b61ee4ce3a1cc6d4ecd5712e2
child 222996 7c725f22a307c60be324ca578afdf202b3f4e3ca
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersunfocused, jesup
bugs1045209
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1045209 - Remove media.gmp-gmpopenh264.path pref and set install path for OpenH264 plugin to <profile-dir>/<gmp-plugin-id>/<version>. r=unfocused,jesup Certain usage scenarios, like enterprise roaming profile setups, lead to the installed OpenH264 plugin not being found anymore. We install the plugin into the profile directory, so the fix here is to just store the install path relative the profile and not an absolute path. We also now store the plugin in a version-specific subdirectory, which avoids further issues like e.g. Windows preventing updates due to locking loaded DLLs.
content/media/gmp/GMPChild.cpp
content/media/gmp/GMPParent.cpp
toolkit/modules/GMPInstallManager.jsm
toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
--- a/content/media/gmp/GMPChild.cpp
+++ b/content/media/gmp/GMPChild.cpp
@@ -64,21 +64,29 @@ GetPluginFile(const std::string& aPlugin
   }
 
 #if defined(XP_MACOSX)
   if (NS_FAILED(aLibFile->Clone(getter_AddRefs(aLibDirectory)))) {
     return false;
   }
 #endif
 
-  nsAutoString leafName;
-  if (NS_FAILED(aLibFile->GetLeafName(leafName))) {
+  nsCOMPtr<nsIFile> parent;
+  rv = aLibFile->GetParent(getter_AddRefs(parent));
+  if (NS_FAILED(rv)) {
     return false;
   }
-  nsAutoString baseName(Substring(leafName, 4, leafName.Length() - 1));
+
+  nsAutoString parentLeafName;
+  rv = parent->GetLeafName(parentLeafName);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  nsAutoString baseName(Substring(parentLeafName, 4, parentLeafName.Length() - 1));
 
 #if defined(XP_MACOSX)
   nsAutoString binaryName = NS_LITERAL_STRING("lib") + baseName + NS_LITERAL_STRING(".dylib");
 #elif defined(OS_POSIX)
   nsAutoString binaryName = NS_LITERAL_STRING("lib") + baseName + NS_LITERAL_STRING(".so");
 #elif defined(XP_WIN)
   nsAutoString binaryName =                            baseName + NS_LITERAL_STRING(".dll");
 #else
--- a/content/media/gmp/GMPParent.cpp
+++ b/content/media/gmp/GMPParent.cpp
@@ -85,26 +85,33 @@ GMPParent::Init(GeckoMediaPluginService 
 {
   MOZ_ASSERT(aPluginDir);
   MOZ_ASSERT(aService);
   MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
 
   mService = aService;
   mDirectory = aPluginDir;
 
-  nsAutoString leafname;
-  nsresult rv = aPluginDir->GetLeafName(leafname);
+  // aPluginDir is <profile-dir>/<gmp-plugin-id>/<version>
+  // where <gmp-plugin-id> should be gmp-gmpopenh264
+  nsCOMPtr<nsIFile> parent;
+  nsresult rv = aPluginDir->GetParent(getter_AddRefs(parent));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  nsAutoString parentLeafName;
+  rv = parent->GetLeafName(parentLeafName);
   if (NS_FAILED(rv)) {
     return rv;
   }
   LOGD(("%s::%s: %p for %s", __CLASS__, __FUNCTION__, this,
-       NS_LossyConvertUTF16toASCII(leafname).get()));
+       NS_LossyConvertUTF16toASCII(parentLeafName).get()));
 
-  MOZ_ASSERT(leafname.Length() > 4);
-  mName = Substring(leafname, 4);
+  MOZ_ASSERT(parentLeafName.Length() > 4);
+  mName = Substring(parentLeafName, 4);
 
   return ReadGMPMetaData();
 }
 
 void
 GMPParent::Crash()
 {
   if (mState != GMPStateNotLoaded) {
--- a/toolkit/modules/GMPInstallManager.jsm
+++ b/toolkit/modules/GMPInstallManager.jsm
@@ -102,17 +102,16 @@ let GMPPrefs = {
     return  key.replace("{0}", addon || "");
   },
 
   /**
    * List of keys which can be used in get and set
    */
   KEY_LOG_ENABLED: "media.gmp-manager.log",
   KEY_ADDON_LAST_UPDATE: "media.{0}.lastUpdate",
-  KEY_ADDON_PATH: "media.{0}.path",
   KEY_ADDON_VERSION: "media.{0}.version",
   KEY_ADDON_AUTOUPDATE: "media.{0}.autoupdate",
   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_UPDATE_SECONDS_BETWEEN_CHECKS: "media.gmp-manager.secondsBetweenChecks",
@@ -884,31 +883,31 @@ GMPDownloader.prototype = {
     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);
+      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_ADDON_LAST_UPDATE, now, gmpAddon.id);
-        // Setting the path pref signals installation completion to consumers,
-        // so set the version and potential other information they use first.
+        // 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_ADDON_VERSION, gmpAddon.version,
                      gmpAddon.id);
-        GMPPrefs.set(GMPPrefs.KEY_ADDON_PATH,
-                     installToDirPath.path, gmpAddon.id);
         this._deferred.resolve(extractedPaths);
       }, err => {
         this._deferred.reject(err);
       });
     }, err => {
       log.warn("verifyDownload check failed");
       this._deferred.reject({
         target: this,
--- a/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
+++ b/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
@@ -24,17 +24,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 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;
 
 const OPENH264_PLUGIN_ID       = "gmp-gmpopenh264";
 const OPENH264_PREF_BRANCH     = "media." + OPENH264_PLUGIN_ID + ".";
 const OPENH264_PREF_ENABLED    = "enabled";
-const OPENH264_PREF_PATH       = "path";
 const OPENH264_PREF_VERSION    = "version";
 const OPENH264_PREF_LASTUPDATE = "lastUpdate";
 const OPENH264_PREF_AUTOUPDATE = "autoupdate";
 const OPENH264_PREF_PROVIDERENABLED = "provider.enabled";
 const OPENH264_PREF_LOGGING    = "provider.logging";
 const OPENH264_PREF_LOGGING_LEVEL = OPENH264_PREF_LOGGING + ".level"; // media.gmp-gmpopenh264.provider.logging.level
 const OPENH264_PREF_LOGGING_DUMP = OPENH264_PREF_LOGGING + ".dump"; // media.gmp-gmpopenh264.provider.logging.dump
 const OPENH264_HOMEPAGE_URL    = "http://www.openh264.org/";
@@ -89,22 +88,17 @@ let OpenH264Wrapper = {
   get id() { return OPENH264_PLUGIN_ID; },
   get type() { return "plugin"; },
   get name() { return pluginsBundle.GetStringFromName("openH264_name"); },
   get creator() { return null; },
   get homepageURL() { return OPENH264_HOMEPAGE_URL; },
 
   get description() { return pluginsBundle.GetStringFromName("openH264_description"); },
 
-  get version() {
-    if (this.isInstalled) {
-      return prefs.get(OPENH264_PREF_VERSION, "");
-    }
-    return "";
-  },
+  get version() { return prefs.get(OPENH264_PREF_VERSION, ""); },
 
   get isActive() { return !this.userDisabled; },
   get appDisabled() { return false; },
 
   get userDisabled() { return !prefs.get(OPENH264_PREF_ENABLED, true); },
   set userDisabled(aVal) { prefs.set(OPENH264_PREF_ENABLED, aVal === false); },
 
   get blocklistState() { return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; },
@@ -218,58 +212,70 @@ let OpenH264Wrapper = {
       }
     }.bind(this));
 
     return this._updateTask;
   },
 
   get pluginMimeTypes() { return []; },
   get pluginLibraries() {
-    let path = prefs.get(OPENH264_PREF_PATH, null);
-    return path && path.length ? [OS.Path.basename(path)] : [];
+    if (this.isInstalled) {
+      let path = this.version;
+      return [path];
+    }
+    return [];
   },
   get pluginFullpath() {
-    let path = prefs.get(OPENH264_PREF_PATH, null);
-    return path && path.length ? [path] : [];
+    if (this.isInstalled) {
+      let path = OS.Path.join(OS.Constants.Path.profileDir,
+                              OPENH264_PLUGIN_ID,
+                              this.version);
+      return [path];
+    }
+    return [];
   },
 
   get isInstalled() {
-    let path = prefs.get(OPENH264_PREF_PATH, "");
-    return path.length > 0;
+    return this.version.length > 0;
   },
 };
 
 let OpenH264Provider = {
   startup: function() {
     configureLogging();
     this._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.OpenH264Provider",
                                                           "OpenH264Provider" + "::");
     OpenH264Wrapper._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.OpenH264Provider",
                                                                      "OpenH264Wrapper" + "::");
-    this.gmpPath = prefs.get(OPENH264_PREF_PATH, null);
+    this.gmpPath = null;
+    if (OpenH264Wrapper.isInstalled) {
+      this.gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
+                                  OPENH264_PLUGIN_ID,
+                                  prefs.get(OPENH264_PREF_VERSION, null));
+    }
     let enabled = prefs.get(OPENH264_PREF_ENABLED, true);
     this._log.trace("startup() - enabled=" + enabled + ", gmpPath="+this.gmpPath);
 
 
     Services.obs.addObserver(this, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED, false);
     prefs.observe(OPENH264_PREF_ENABLED, this.onPrefEnabledChanged, this);
-    prefs.observe(OPENH264_PREF_PATH, this.onPrefPathChanged, this);
+    prefs.observe(OPENH264_PREF_VERSION, this.onPrefVersionChanged, this);
     prefs.observe(OPENH264_PREF_LOGGING, configureLogging);
 
     if (this.gmpPath && enabled) {
       this._log.info("startup() - adding gmp directory " + this.gmpPath);
       gmpService.addPluginDirectory(this.gmpPath);
     }
   },
 
   shutdown: function() {
     this._log.trace("shutdown()");
     Services.obs.removeObserver(this, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED);
     prefs.ignore(OPENH264_PREF_ENABLED, this.onPrefEnabledChanged, this);
-    prefs.ignore(OPENH264_PREF_PATH, this.onPrefPathChanged, this);
+    prefs.ignore(OPENH264_PREF_VERSION, this.onPrefVersionChanged, this);
     prefs.ignore(OPENH264_PREF_LOGGING, configureLogging);
 
     return OpenH264Wrapper._updateTask;
   },
 
   onPrefEnabledChanged: function() {
     let wrapper = OpenH264Wrapper;
 
@@ -285,30 +291,35 @@ let OpenH264Provider = {
         gmpService.removePluginDirectory(this.gmpPath);
       }
     }
     AddonManagerPrivate.callAddonListeners(wrapper.isActive ?
                                            "onEnabled" : "onDisabled",
                                            wrapper);
   },
 
-  onPrefPathChanged: function() {
+  onPrefVersionChanged: function() {
     let wrapper = OpenH264Wrapper;
 
     AddonManagerPrivate.callAddonListeners("onUninstalling", wrapper, false);
     if (this.gmpPath) {
-      this._log.info("onPrefPathChanged() - removing gmp directory " + this.gmpPath);
+      this._log.info("onPrefVersionChanged() - unregistering gmp directory " + this.gmpPath);
       gmpService.removePluginDirectory(this.gmpPath);
     }
     AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
 
     AddonManagerPrivate.callInstallListeners("onExternalInstall", null, wrapper, null, false);
-    this.gmpPath = prefs.get(OPENH264_PREF_PATH, null);
+    this.gmpPath = null;
+    if (OpenH264Wrapper.isInstalled) {
+      this.gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
+                                  OPENH264_PLUGIN_ID,
+                                  prefs.get(OPENH264_PREF_VERSION, null));
+    }
     if (this.gmpPath && wrapper.isActive) {
-      this._log.info("onPrefPathChanged() - adding gmp directory " + this.gmpPath);
+      this._log.info("onPrefVersionChanged() - registering gmp directory " + this.gmpPath);
       gmpService.addPluginDirectory(this.gmpPath);
     }
     AddonManagerPrivate.callAddonListeners("onInstalled", wrapper);
   },
 
   buildWrapper: function() {
     let description = pluginsBundle.GetStringFromName("openH264_description");
     return new OpenH264Wrapper(OPENH264_PLUGIN_ID,