Bug 1041080 - Fix OpenH264Provider path registration, default enabled state and logging r=Unfocused
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Sat, 19 Jul 2014 20:01:01 +0200
changeset 217111 bf628f6b830cc4fe0fbe859c67b683fb9e95aa52
parent 217110 9520f63174d0c98a7a65d658068a289c07799231
child 217112 94b2e3eda6f079e17fbf260c02d45a1020574dda
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs1041080
milestone33.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 1041080 - Fix OpenH264Provider path registration, default enabled state and logging r=Unfocused
browser/app/profile/firefox.js
toolkit/modules/GMPInstallManager.jsm
toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
toolkit/mozapps/extensions/test/browser/browser_openH264.js
toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js
toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1648,9 +1648,9 @@ pref("experiments.enabled", true);
 pref("experiments.manifest.fetchIntervalSeconds", 86400);
 pref("experiments.manifest.uri", "https://telemetry-experiment.cdn.mozilla.net/manifest/v1/firefox/%VERSION%/%CHANNEL%");
 pref("experiments.manifest.certs.1.commonName", "*.cdn.mozilla.net");
 pref("experiments.manifest.certs.1.issuerName", "CN=Cybertrust Public SureServer SV CA,O=Cybertrust Inc");
 // Whether experiments are supported by the current application profile.
 pref("experiments.supported", true);
 
 // Enable the OpenH264 plugin support in the addon manager.
-pref("media.gmp-gmpopenh264.providerEnabled", true);
+pref("media.gmp-gmpopenh264.provider.enabled", true);
--- a/toolkit/modules/GMPInstallManager.jsm
+++ b/toolkit/modules/GMPInstallManager.jsm
@@ -870,20 +870,22 @@ GMPDownloader.prototype = {
       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.
+        GMPPrefs.set(GMPPrefs.KEY_ADDON_VERSION, gmpAddon.version,
+                     gmpAddon.id);
         GMPPrefs.set(GMPPrefs.KEY_ADDON_PATH,
                      installToDirPath.path, gmpAddon.id);
-        GMPPrefs.set(GMPPrefs.KEY_ADDON_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,
--- a/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
+++ b/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
@@ -10,38 +10,66 @@ const 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");
 
 const URI_EXTENSION_STRINGS    = "chrome://mozapps/locale/extensions/extensions.properties";
 const STRING_TYPE_NAME         = "type.%ID%.name";
 
 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 = "providerEnabled";
+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/";
 const OPENH264_OPTIONS_URL     = "chrome://mozapps/content/extensions/openH264Prefs.xul";
 
 XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
   () => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
 XPCOMUtils.defineLazyGetter(this, "prefs",
   () => new Preferences(OPENH264_PREF_BRANCH));
 XPCOMUtils.defineLazyGetter(this, "gmpService",
   () => Cc["@mozilla.org/gecko-media-plugin-service;1"].getService(Ci.mozIGeckoMediaPluginService));
 
+let gLogger;
+let gLogDumping = false;
+let gLogAppenderDump = null;
+
+function configureLogging() {
+  if (!gLogger) {
+    gLogger = Log.repository.getLogger("Toolkit.OpenH264Provider");
+    gLogger.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()));
+  }
+  gLogger.level = prefs.get(OPENH264_PREF_LOGGING_LEVEL, Log.Level.Warn);
+
+  let logDumping = prefs.get(OPENH264_PREF_LOGGING_DUMP, false);
+  if (logDumping != gLogDumping) {
+    if (logDumping) {
+      gLogAppenderDump = new Log.DumpAppender(new Log.BasicFormatter());
+      gLogger.addAppender(gLogAppenderDump);
+    } else {
+      gLogger.removeAppender(gLogAppenderDump);
+      gLogAppenderDump = null;
+    }
+    gLogDumping = logDumping;
+  }
+}
+
 /**
  * The OpenH264Wrapper provides the info for the OpenH264 GMP plugin to public callers through the API.
  */
 
 let OpenH264Wrapper = Object.freeze({
   optionsType: AddonManager.OPTIONS_TYPE_INLINE,
   optionsURL: OPENH264_OPTIONS_URL,
 
@@ -58,17 +86,17 @@ let OpenH264Wrapper = Object.freeze({
       return prefs.get(OPENH264_PREF_VERSION, "");
     }
     return "";
   },
 
   get isActive() { return !this.userDisabled; },
   get appDisabled() { return false; },
 
-  get userDisabled() { return !prefs.get(OPENH264_PREF_ENABLED, 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; },
   get size() { return 0; },
   get scope() { return AddonManager.SCOPE_APPLICATION; },
   get pendingOperations() { return AddonManager.PENDING_NONE; },
 
   get operationsRequiringRestart() { return AddonManager.OP_NEEDS_RESTART_NONE },
@@ -80,17 +108,17 @@ let OpenH264Wrapper = Object.freeze({
                                          AddonManager.PERM_CAN_DISABLE;
     }
     return permissions;
   },
 
   get updateDate() {
     let time = Number(prefs.get(OPENH264_PREF_LASTUPDATE, null));
     if (time !== NaN && this.isInstalled) {
-      return new Date(time)
+      return new Date(time * 1000)
     }
     return null;
   },
 
   get isCompatible() {
     return true;
   },
 
@@ -153,55 +181,76 @@ let OpenH264Wrapper = Object.freeze({
   get isInstalled() {
     let path = prefs.get(OPENH264_PREF_PATH, "");
     return path.length > 0;
   },
 });
 
 let OpenH264Provider = {
   startup: function() {
+    configureLogging();
+    this._log = Log.repository.getLogger("Toolkit.OpenH264Provider");
+    this.gmpPath = prefs.get(OPENH264_PREF_PATH, 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_LOGGING, configureLogging);
 
-    this.gmpPath = prefs.get(OPENH264_PREF_PATH, null);
-    if (this.gmpPath) {
+    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_LOGGING, configureLogging);
   },
 
   onPrefEnabledChanged: function() {
     let wrapper = OpenH264Wrapper;
 
     AddonManagerPrivate.callAddonListeners(wrapper.isActive ?
                                            "onEnabling" : "onDisabling",
                                            wrapper, false);
+    if (this.gmpPath) {
+      if (wrapper.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(wrapper.isActive ?
                                            "onEnabled" : "onDisabled",
                                            wrapper);
   },
 
   onPrefPathChanged: function() {
     let wrapper = OpenH264Wrapper;
 
     AddonManagerPrivate.callAddonListeners("onUninstalling", wrapper, false);
     if (this.gmpPath) {
+      this._log.info("onPrefPathChanged() - removing 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);
-    if (this.gmpPath) {
+    if (this.gmpPath && wrapper.isActive) {
+      this._log.info("onPrefPathChanged() - adding 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,
--- a/toolkit/mozapps/extensions/test/browser/browser_openH264.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_openH264.js
@@ -6,16 +6,19 @@ let {AddonTestUtils} = Components.utils.
 
 const OPENH264_PLUGIN_ID       = "gmp-gmpopenh264";
 const OPENH264_PREF_BRANCH     = "media." + OPENH264_PLUGIN_ID + ".";
 const OPENH264_PREF_ENABLED    = OPENH264_PREF_BRANCH + "enabled";
 const OPENH264_PREF_PATH       = OPENH264_PREF_BRANCH + "path";
 const OPENH264_PREF_VERSION    = OPENH264_PREF_BRANCH + "version";
 const OPENH264_PREF_LASTUPDATE = OPENH264_PREF_BRANCH + "lastUpdate";
 const OPENH264_PREF_AUTOUPDATE = OPENH264_PREF_BRANCH + "autoupdate";
+const PREF_LOGGING             = OPENH264_PREF_BRANCH + "provider.logging";
+const PREF_LOGGING_LEVEL       = PREF_LOGGING + ".level";
+const PREF_LOGGING_DUMP        = PREF_LOGGING + ".dump";
 
 const TEST_DATE = new Date(2013, 0, 1, 12);
 
 let gManagerWindow;
 let gCategoryUtilities;
 let gIsEnUsLocale;
 
 let gOptionsObserver = {
@@ -51,27 +54,32 @@ function openDetailsView(aId) {
   EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow);
 
   let deferred = Promise.defer();
   wait_for_view_load(gManagerWindow, deferred.resolve);
   return deferred.promise;
 }
 
 add_task(function* initializeState() {
+  Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true);
+  Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0);
+
   gManagerWindow = yield open_manager();
   gCategoryUtilities = new CategoryUtilities(gManagerWindow);
 
   registerCleanupFunction(() => {
     Services.obs.removeObserver(gOptionsObserver, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED);
 
     Services.prefs.clearUserPref(OPENH264_PREF_ENABLED);
     Services.prefs.clearUserPref(OPENH264_PREF_PATH);
     Services.prefs.clearUserPref(OPENH264_PREF_VERSION);
     Services.prefs.clearUserPref(OPENH264_PREF_LASTUPDATE);
     Services.prefs.clearUserPref(OPENH264_PREF_AUTOUPDATE);
+    Services.prefs.clearUserPref(PREF_LOGGING_DUMP);
+    Services.prefs.clearUserPref(PREF_LOGGING_LEVEL);
   });
 
   let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
   gIsEnUsLocale = chrome.getSelectedLocale("global") == "en-US";
 
   Services.obs.addObserver(gOptionsObserver, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED, false);
 
   // Start out with OpenH264 not being installed, disabled and automatic updates disabled.
--- a/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js
@@ -97,17 +97,17 @@ registrar.registerFactory(Components.ID(
                           "Fake Plugin Host",
                           "@mozilla.org/plugin/host;1", PluginHostFactory);
 
 var gPluginIDs = [null, null, null, null, null];
 
 function run_test() {
   do_test_pending();
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
-  Services.prefs.setBoolPref("media.gmp-gmpopenh264.providerEnabled", false);
+  Services.prefs.setBoolPref("media.gmp-gmpopenh264.provider.enabled", false);
 
   startupManager();
 
   run_test_1();
 }
 
 function found_plugin(aNum, aId) {
   if (gPluginIDs[aNum])
--- a/toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
@@ -7,31 +7,36 @@ const {classes: Cc, interfaces: Ci, util
 
 const OPENH264_PLUGIN_ID       = "gmp-gmpopenh264";
 const OPENH264_PREF_BRANCH     = "media." + OPENH264_PLUGIN_ID + ".";
 const OPENH264_PREF_ENABLED    = OPENH264_PREF_BRANCH + "enabled";
 const OPENH264_PREF_PATH       = OPENH264_PREF_BRANCH + "path";
 const OPENH264_PREF_VERSION    = OPENH264_PREF_BRANCH + "version";
 const OPENH264_PREF_LASTUPDATE = OPENH264_PREF_BRANCH + "lastUpdate";
 const OPENH264_PREF_AUTOUPDATE = OPENH264_PREF_BRANCH + "autoupdate";
+const PREF_LOGGING             = OPENH264_PREF_BRANCH + "provider.logging";
+const PREF_LOGGING_LEVEL       = PREF_LOGGING + ".level";
+const PREF_LOGGING_DUMP        = PREF_LOGGING + ".dump";
 
 XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
   () => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
 
 let gProfileDir = null;
 
 function run_test() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
   startupManager();
   run_next_test();
 }
 
 add_task(function* test_notInstalled() {
   Services.prefs.setCharPref(OPENH264_PREF_PATH, "");
   Services.prefs.setBoolPref(OPENH264_PREF_ENABLED, false);
+  Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true);
+  Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0);
 
   let addons = yield promiseAddonsByIDs([OPENH264_PLUGIN_ID]);
   Assert.equal(addons.length, 1);
   let addon = addons[0];
 
   Assert.ok(!addon.isInstalled);
   Assert.equal(addon.type, "plugin");
   Assert.equal(addon.version, "");
@@ -68,23 +73,24 @@ add_task(function* test_notInstalled() {
   Assert.ok(libraries);
   Assert.equal(libraries.length, 0);
   Assert.equal(addon.pluginFullpath, "");
 });
 
 add_task(function* test_installed() {
   const TEST_DATE = new Date(2013, 0, 1, 12);
   const TEST_VERSION = "1.2.3.4";
+  const TEST_TIME_SEC = Math.round(TEST_DATE.getTime() / 1000);
 
   let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
   file.append("openh264");
   file.append("testDir");
 
   Services.prefs.setBoolPref(OPENH264_PREF_ENABLED, false);
-  Services.prefs.setCharPref(OPENH264_PREF_LASTUPDATE, "" + TEST_DATE.getTime());
+  Services.prefs.setCharPref(OPENH264_PREF_LASTUPDATE, "" + TEST_TIME_SEC);
   Services.prefs.setCharPref(OPENH264_PREF_VERSION, TEST_VERSION);
   Services.prefs.setCharPref(OPENH264_PREF_PATH, file.path);
 
   let addons = yield promiseAddonsByIDs([OPENH264_PLUGIN_ID]);
   Assert.equal(addons.length, 1);
   let addon = addons[0];
 
   Assert.ok(addon.isInstalled);
@@ -95,17 +101,17 @@ add_task(function* test_installed() {
 
   Assert.ok(!addon.isActive);
   Assert.ok(!addon.appDisabled);
   Assert.ok(addon.userDisabled);
 
   Assert.equal(addon.permissions, AddonManager.PERM_CAN_UPGRADE |
                                   AddonManager.PERM_CAN_ENABLE);
 
-  Assert.equal(addon.updateDate.getTime(), TEST_DATE.getTime());
+  Assert.equal(addon.updateDate.getTime(), TEST_TIME_SEC * 1000);
 
   let mimetypes = addon.pluginMimeTypes;
   Assert.ok(mimetypes);
   Assert.equal(mimetypes.length, 0);
   let libraries = addon.pluginLibraries;
   Assert.ok(libraries);
   Assert.equal(libraries.length, 1);
   Assert.equal(libraries[0], "testDir");
@@ -158,16 +164,17 @@ add_task(function* test_pluginRegistrati
 
   let MockGMPService = {
     addPluginDirectory: path => addedPath = path,
     removePluginDirectory: path => removedPath = path,
   };
 
   let OpenH264Scope = Cu.import("resource://gre/modules/addons/OpenH264Provider.jsm");
   OpenH264Scope.gmpService = MockGMPService;
+  Services.prefs.setBoolPref(OPENH264_PREF_ENABLED, true);
 
   // Check that the OpenH264 plugin gets registered after startup.
   Services.prefs.setCharPref(OPENH264_PREF_PATH, file.path);
   clearPaths();
   yield promiseRestartManager();
   Assert.equal(addedPath, file.path);
   Assert.equal(removedPath, null);
 
@@ -186,9 +193,28 @@ add_task(function* test_pluginRegistrati
   // Changing the pref mid-session should cause unregistration and registration.
   Services.prefs.setCharPref(OPENH264_PREF_PATH, file.path);
   clearPaths();
   let file2 = file.clone();
   file2.append("foo");
   Services.prefs.setCharPref(OPENH264_PREF_PATH, file2.path);
   Assert.equal(addedPath, file2.path);
   Assert.equal(removedPath, file.path);
+
+  // Disabling OpenH264 should cause unregistration.
+  Services.prefs.setCharPref(OPENH264_PREF_PATH, file.path);
+  clearPaths();
+  Services.prefs.setBoolPref(OPENH264_PREF_ENABLED, false);
+  Assert.equal(addedPath, null);
+  Assert.equal(removedPath, file.path);
+
+  // Restarting with OpenH264 disabled should not cause registration.
+  clearPaths();
+  yield promiseRestartManager();
+  Assert.equal(addedPath, null);
+  Assert.equal(removedPath, null);
+
+  // Re-enabling OpenH264 should cause registration.
+  clearPaths();
+  Services.prefs.setBoolPref(OPENH264_PREF_ENABLED, true);
+  Assert.equal(addedPath, file.path);
+  Assert.equal(removedPath, null);
 });
--- a/toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
@@ -62,17 +62,17 @@ registrar.registerFactory(Components.ID(
                           "@mozilla.org/plugin/host;1", PluginHostFactory);
 
 // This verifies that when the list of plugins changes the add-ons manager
 // correctly updates
 function run_test() {
   do_test_pending();
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
-  Services.prefs.setBoolPref("media.gmp-gmpopenh264.providerEnabled", false);
+  Services.prefs.setBoolPref("media.gmp-gmpopenh264.provider.enabled", false);
 
   startupManager();
   AddonManager.addAddonListener(AddonListener);
   AddonManager.addInstallListener(InstallListener);
 
   run_test_1();
 }