Bug 1041080 - Fix OpenH264Provider path registration, default enabled state and logging r=Unfocused a=kwierso
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Sat, 19 Jul 2014 20:01:01 +0200
changeset 195132 0894d2cdb16ddf542fc511fd45dc6226d8b10c98
parent 195131 1e7f2af8d929c663e3b2c47a77d0028b86791a9d
child 195168 56bec38169671937b4b0b77f09caf9da4dbb360b
push id46521
push userryanvm@gmail.com
push dateSun, 20 Jul 2014 19:14:27 +0000
treeherdermozilla-inbound@4ca15c5bab96 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused, kwierso
bugs1041080
milestone33.0a1
first release with
nightly linux32
0894d2cdb16d / 33.0a1 / 20140720030203 / files
nightly linux64
0894d2cdb16d / 33.0a1 / 20140720030203 / files
nightly mac
0894d2cdb16d / 33.0a1 / 20140720030203 / files
nightly win32
0894d2cdb16d / 33.0a1 / 20140720030203 / files
nightly win64
0894d2cdb16d / 33.0a1 / 20140720030203 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1041080 - Fix OpenH264Provider path registration, default enabled state and logging r=Unfocused a=kwierso
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();
 }