Bug 1039226 - Trigger explicit OpenH264 updates from OpenH264Provider. r=unfocused a=sylvestre
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Wed, 23 Jul 2014 16:00:55 +0200
changeset 217317 9dde3907962cba3d233f352f726402c502299220
parent 217316 e5466a63b5b9c1a68ad31fe47cef55d8a6765dc5
child 217318 683f69c347f1e284a9bac160b9104bdccb1371ec
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, sylvestre
bugs1039226
milestone33.0a2
Bug 1039226 - Trigger explicit OpenH264 updates from OpenH264Provider. r=unfocused a=sylvestre
toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
toolkit/mozapps/extensions/test/browser/browser_openH264.js
--- a/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
+++ b/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
@@ -11,16 +11,21 @@ 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");
+Cu.import("resource://gre/modules/Task.jsm");
+
+//Cu.import("resource://gre/modules/GMPInstallManager.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager",
+                                  "resource://gre/modules/GMPInstallManager.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";
@@ -64,17 +69,22 @@ function configureLogging() {
     gLogDumping = logDumping;
   }
 }
 
 /**
  * The OpenH264Wrapper provides the info for the OpenH264 GMP plugin to public callers through the API.
  */
 
-let OpenH264Wrapper = Object.freeze({
+let OpenH264Wrapper = {
+  // An active task that checks for OpenH264 updates and installs them.
+  _updateTask: null,
+
+  _log: null,
+
   optionsType: AddonManager.OPTIONS_TYPE_INLINE,
   optionsURL: OPENH264_OPTIONS_URL,
 
   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; },
@@ -153,46 +163,67 @@ let OpenH264Wrapper = Object.freeze({
     } else if (aVal == AddonManager.AUTOUPDATE_ENABLE) {
       prefs.set(OPENH264_PREF_AUTOUPDATE, true);
     } else if (aVal == AddonManager.AUTOUPDATE_DISABLE) {
       prefs.set(OPENH264_PREF_AUTOUPDATE, false);
     }
   },
 
   findUpdates: function(aListener, aReason, aAppVersion, aPlatformVersion) {
-    // TODO: Hook up to openh264 update for AddonManager.UPDATE_WHEN_USER_REQUESTED (pending bug 1035225)
+    this._log.trace("findUpdates() - reason=" + aReason);
+
+    AddonManagerPrivate.callNoUpdateListeners(this, aListener);
+
+    if (aReason !== AddonManager.UPDATE_WHEN_USER_REQUESTED ||
+        this._updateTask !== null) {
+      return;
+    }
 
-    if ("onNoCompatibilityUpdateAvailable" in aListener)
-      aListener.onNoCompatibilityUpdateAvailable(this);
-    if ("onNoUpdateAvailable" in aListener)
-      aListener.onNoUpdateAvailable(this);
-    if ("onUpdateFinished" in aListener)
-      aListener.onUpdateFinished(this);
+    this._updateTask = Task.spawn(function* OpenH264Provider_updateTask() {
+      this._log.trace("findUpdates() - updateTask");
+      try {
+        let installManager = new GMPInstallManager();
+        let addons = yield installManager.checkForAddons();
+        let openH264 = addons.find(addon => addon.isOpenH264);
+        if (openH264 && !openH264.isInstalled) {
+          yield installManager.installAddon(openH264);
+        }
+        this._log.info("findUpdates() - updateTask succeeded");
+      } catch (e) {
+        this._log.error("findUpdates() - updateTask threw: " + e);
+        throw e;
+      } finally {
+        this._updateTask = null;
+      }
+    }.bind(this));
   },
 
   get pluginMimeTypes() { return []; },
   get pluginLibraries() {
     let path = prefs.get(OPENH264_PREF_PATH, null);
     return path && path.length ? [OS.Path.basename(path)] : [];
   },
   get pluginFullpath() {
     let path = prefs.get(OPENH264_PREF_PATH, null);
     return path && path.length ? [path] : [];
   },
 
   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._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.OpenH264Provider",
+                                                          "OpenH264Provider" + "::");
+    OpenH264Wrapper._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.OpenH264Provider",
+                                                                     "OpenH264Wrapper" + "::");
     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);
@@ -205,16 +236,18 @@ let OpenH264Provider = {
   },
 
   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);
+
+    return OpenH264Wrapper._updateTask;
   },
 
   onPrefEnabledChanged: function() {
     let wrapper = OpenH264Wrapper;
 
     AddonManagerPrivate.callAddonListeners(wrapper.isActive ?
                                            "onEnabling" : "onDisabling",
                                            wrapper, false);
--- a/toolkit/mozapps/extensions/test/browser/browser_openH264.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_openH264.js
@@ -1,13 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-let {AddonTestUtils} = Components.utils.import("resource://testing-common/AddonManagerTesting.jsm", {});
+"use strict";
+
+Cu.import("resource://gre/modules/Promise.jsm");
+let {AddonTestUtils} = Cu.import("resource://testing-common/AddonManagerTesting.jsm", {});
+let OpenH264Scope = Cu.import("resource://gre/modules/addons/OpenH264Provider.jsm");
 
 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";
@@ -16,16 +20,39 @@ const PREF_LOGGING_LEVEL       = PREF_LO
 const PREF_LOGGING_DUMP        = PREF_LOGGING + ".dump";
 
 const TEST_DATE = new Date(2013, 0, 1, 12);
 
 let gManagerWindow;
 let gCategoryUtilities;
 let gIsEnUsLocale;
 
+let MockGMPAddon = Object.freeze({
+  id: OPENH264_PLUGIN_ID,
+  isOpenH264: true,
+  isInstalled: false,
+});
+
+let gInstalledAddonId = "";
+let gInstallDeferred = null;
+
+function MockGMPInstallManager() {
+}
+
+MockGMPInstallManager.prototype = {
+  checkForAddons: () => Promise.resolve([MockGMPAddon]),
+
+  installAddon: addon => {
+    gInstalledAddonId = addon.id;
+    gInstallDeferred.resolve();
+    return Promise.resolve();
+  },
+};
+
+
 let gOptionsObserver = {
   lastDisplayed: null,
   observe: function(aSubject, aTopic, aData) {
     if (aTopic == AddonManager.OPTIONS_NOTIFICATION_DISPLAYED) {
       this.lastDisplayed = aData;
     }
   }
 };
@@ -197,11 +224,33 @@ add_task(function* testPreferencesButton
     let deferred = Promise.defer();
     wait_for_view_load(gManagerWindow, deferred.resolve);
     yield deferred.promise;
 
     is(gOptionsObserver.lastDisplayed, OPENH264_PLUGIN_ID);
   }
 });
 
+add_task(function* testUpdateButton() {
+  yield gCategoryUtilities.openType("plugin");
+  let doc = gManagerWindow.document;
+  let item = get_addon_element(gManagerWindow, OPENH264_PLUGIN_ID);
+
+  Object.defineProperty(OpenH264Scope, "GMPInstallManager", {
+    value: MockGMPInstallManager,
+    writable: true,
+    enumerable: true,
+    configurable: true
+  });
+  gInstalledAddonId = "";
+  gInstallDeferred = Promise.defer();
+
+  let button = doc.getElementById("detail-findUpdates-btn");
+  Assert.ok(button != null, "Got detail-findUpdates-btn");
+  button.click();
+  yield gInstallDeferred.promise;
+
+  Assert.equal(gInstalledAddonId, OPENH264_PLUGIN_ID);
+});
+
 add_task(function* test_cleanup() {
   yield close_manager(gManagerWindow);
 });