Bug 1042161 - Handle OpenH264 updates for long-running sessions. r=unfocused, a=sledru
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Fri, 01 Aug 2014 14:28:39 +0200
changeset 217578 c0e95adfb454e1253601dd18e29c30b51ddad4a4
parent 217577 4d0bbb50982d98cfc39f184ecacc6c9a8f8310b7
child 217579 8c851314912eee9bf79cb809aedee0117d90605f
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, sledru
bugs1042161
milestone33.0a2
Bug 1042161 - Handle OpenH264 updates for long-running sessions. r=unfocused, a=sledru
testing/profiles/prefs_general.js
toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
toolkit/mozapps/extensions/test/browser/browser_openH264.js
toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -36,17 +36,17 @@ user_pref("test.mousescroll", true);
 user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
 user_pref("network.http.prompt-temp-redirect", false);
 user_pref("media.cache_size", 100);
 user_pref("media.volume_scale", "0.01");
 user_pref("security.warn_viewing_mixed", false);
 user_pref("app.update.enabled", false);
 user_pref("app.update.staging.enabled", false);
 // Make sure GMPInstallManager won't hit the network.
-user_pref("media.gmp-manager.url", "https://%(server)s/dummy.xml");
+user_pref("media.gmp-manager.url.override", "http://%(server)s/dummy.xml");
 user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
 user_pref("dom.w3c_touch_events.enabled", 1);
 user_pref("dom.undo_manager.enabled", true);
 user_pref("dom.webcomponents.enabled", true);
 user_pref("dom.animations-api.core.enabled", true);
 // Set a future policy version to avoid the telemetry prompt.
 user_pref("toolkit.telemetry.prompted", 999);
 user_pref("toolkit.telemetry.notifiedOptOut", 999);
--- a/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
+++ b/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
@@ -13,37 +13,40 @@ 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 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/";
 const OPENH264_OPTIONS_URL     = "chrome://mozapps/content/extensions/openH264Prefs.xul";
 
+const GMP_PREF_LASTCHECK       = "media.gmp-manager.lastCheck";
+
 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;
@@ -167,38 +170,60 @@ let OpenH264Wrapper = {
     }
   },
 
   findUpdates: function(aListener, aReason, aAppVersion, aPlatformVersion) {
     this._log.trace("findUpdates() - reason=" + aReason);
 
     AddonManagerPrivate.callNoUpdateListeners(this, aListener);
 
-    if (aReason !== AddonManager.UPDATE_WHEN_USER_REQUESTED ||
-        this._updateTask !== null) {
-      return;
+    if (aReason === AddonManager.UPDATE_WHEN_PERIODIC_UPDATE) {
+      if (!AddonManager.shouldAutoUpdate(this)) {
+        this._log.trace("findUpdates() - no autoupdate");
+        return Promise.resolve(false);
+      }
+
+      let secSinceLastCheck = Date.now() / 1000 - Preferences.get(GMP_PREF_LASTCHECK, 0);
+      if (secSinceLastCheck <= SEC_IN_A_DAY) {
+        this._log.trace("findUpdates() - last check was less then a day ago");
+        return Promise.resolve(false);
+      }
+    } else if (aReason !== AddonManager.UPDATE_WHEN_USER_REQUESTED) {
+      this._log.trace("findUpdates() - unsupported reason");
+      return Promise.resolve(false);
+    }
+
+    if (this._updateTask !== null) {
+      this._log.trace("findUpdates() - update task already running");
+      return this._updateTask;
     }
 
     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) {
+          this._log.trace("findUpdates() - found update, installing");
           yield installManager.installAddon(openH264);
+        } else {
+          this._log.trace("findUpdates() - no updates");
         }
         this._log.info("findUpdates() - updateTask succeeded");
       } catch (e) {
         this._log.error("findUpdates() - updateTask threw: " + e);
         throw e;
       } finally {
         this._updateTask = null;
+        return true;
       }
     }.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)] : [];
   },
   get pluginFullpath() {
--- a/toolkit/mozapps/extensions/test/browser/browser_openH264.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_openH264.js
@@ -13,16 +13,18 @@ const OPENH264_PREF_BRANCH     = "media.
 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 GMP_PREF_LASTCHECK       = "media.gmp-manager.lastCheck";
+const GMP_PREF_LOG             = "media.gmp-manager.log";
 
 const TEST_DATE = new Date(2013, 0, 1, 12);
 
 let gManagerWindow;
 let gCategoryUtilities;
 let gIsEnUsLocale;
 
 let MockGMPAddon = Object.freeze({
@@ -83,30 +85,33 @@ function openDetailsView(aId) {
   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);
+  Services.prefs.setBoolPref(GMP_PREF_LOG, true);
 
   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);
+    Services.prefs.clearUserPref(GMP_PREF_LOG);
+    Services.prefs.clearUserPref(GMP_PREF_LASTCHECK);
   });
 
   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.
@@ -225,32 +230,40 @@ add_task(function* testPreferencesButton
     wait_for_view_load(gManagerWindow, deferred.resolve);
     yield deferred.promise;
 
     is(gOptionsObserver.lastDisplayed, OPENH264_PLUGIN_ID);
   }
 });
 
 add_task(function* testUpdateButton() {
+  Services.prefs.clearUserPref(GMP_PREF_LASTCHECK);
+
   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.getAnonymousElementByAttribute(item, "anonid", "preferences-btn");
+  EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
+  let deferred = Promise.defer();
+  wait_for_view_load(gManagerWindow, deferred.resolve);
+  yield deferred.promise;
+
   let button = doc.getElementById("detail-findUpdates-btn");
   Assert.ok(button != null, "Got detail-findUpdates-btn");
-  button.click();
+  EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
   yield gInstallDeferred.promise;
 
   Assert.equal(gInstalledAddonId, OPENH264_PLUGIN_ID);
   delete OpenH264Scope.GMPInstallManager;
 });
 
 add_task(function* test_cleanup() {
   yield close_manager(gManagerWindow);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_openh264.js
@@ -10,33 +10,58 @@ const OPENH264_PREF_BRANCH     = "media.
 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 GMP_PREF_LASTCHECK       = "media.gmp-manager.lastCheck";
+const GMP_PREF_LOG             = "media.gmp-manager.log";
+const SEC_IN_A_DAY             = 24 * 60 * 60;
 
 XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
   () => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
 
-let gProfileDir = null;
+let MockGMPAddon = Object.freeze({
+  id: OPENH264_PLUGIN_ID,
+  isOpenH264: true,
+  isInstalled: false,
+});
+
+let gInstalledAddonId = "";
+
+function MockGMPInstallManager() {
+}
+
+MockGMPInstallManager.prototype = {
+  checkForAddons: () => Promise.resolve([MockGMPAddon]),
+
+  installAddon: addon => {
+    gInstalledAddonId = addon.id;
+    return Promise.resolve();
+  },
+};
+
 
 function run_test() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
   startupManager();
+
+  Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true);
+  Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0);
+  Services.prefs.setBoolPref(GMP_PREF_LOG, true);
+
   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, "");
@@ -213,8 +238,40 @@ add_task(function* test_pluginRegistrati
   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);
 });
+
+add_task(function* test_periodicUpdate() {
+  let OpenH264Scope = Cu.import("resource://gre/modules/addons/OpenH264Provider.jsm");
+  Object.defineProperty(OpenH264Scope, "GMPInstallManager", {
+    value: MockGMPInstallManager,
+    writable: true,
+    enumerable: true,
+    configurable: true
+  });
+
+  Services.prefs.clearUserPref(OPENH264_PREF_AUTOUPDATE);
+  let addons = yield promiseAddonsByIDs([OPENH264_PLUGIN_ID]);
+  let prefs = Services.prefs;
+  Assert.equal(addons.length, 1);
+  let addon = addons[0];
+
+  addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
+  Services.prefs.setIntPref(GMP_PREF_LASTCHECK, 0);
+  let result = yield addon.findUpdates({}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
+  Assert.strictEqual(result, false);
+
+  addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_ENABLE;
+  Services.prefs.setIntPref(GMP_PREF_LASTCHECK, Date.now() / 1000 - 60);
+  result = yield addon.findUpdates({}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
+  Assert.strictEqual(result, false);
+
+  Services.prefs.setIntPref(GMP_PREF_LASTCHECK, Date.now() / 1000 - 2 * SEC_IN_A_DAY);
+  gInstalledAddonId = "";
+  result = yield addon.findUpdates({}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
+  Assert.strictEqual(result, true);
+  Assert.equal(gInstalledAddonId, OPENH264_PLUGIN_ID);
+});