Bug 1294439: Mark add-ons as soft disabled even if they are app disabled. r=aswan draft
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 11 Aug 2016 10:57:39 -0700
changeset 399707 a18e4ab6999e25fd1948bffa32d67282d94e0884
parent 399641 9dae91a2c31d1d7ee1f426b4f61179a42e0dab64
child 528033 673470f6b958dc969ca95aa5cc515fea332c81f9
push id25953
push userdtownsend@mozilla.com
push dateThu, 11 Aug 2016 22:22:25 +0000
reviewersaswan
bugs1294439
milestone51.0a1
Bug 1294439: Mark add-ons as soft disabled even if they are app disabled. r=aswan MozReview-Commit-ID: FcPwk5YEtRT
toolkit/mozapps/extensions/nsBlocklistService.js
toolkit/mozapps/extensions/test/xpcshell/data/test_softblocked1.xml
toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js
toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -1378,18 +1378,25 @@ Blocklist.prototype = {
         if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED &&
             oldState == Ci.nsIBlocklistService.STATE_BLOCKED) {
           addon.softDisabled = true;
           continue;
         }
 
         // If the add-on is already disabled for some reason then don't warn
         // about it
-        if (!addon.isActive)
+        if (!addon.isActive) {
+          // But mark it as softblocked if necessary. Note that we avoid setting
+          // softDisabled at the same time as userDisabled to make it clear
+          // which was the original cause of the add-on becoming disabled in a
+          // way that the user can change.
+          if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED && !addon.userDisabled)
+            addon.softDisabled = true;
           continue;
+        }
 
         addonList.push({
           name: addon.name,
           version: addon.version,
           icon: addon.iconURL,
           disable: false,
           blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
           item: addon,
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_softblocked1.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+  <emItems>
+    <emItem id="softblock1@tests.mozilla.org">
+      <versionRange severity="1"/>
+    </emItem>
+  </emItems>
+</blocklist>
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js
@@ -337,24 +337,24 @@ function check_test_pt2() {
 
   AddonManager.getAddonsByIDs(ADDONS.map(a => a.id), callback_soon(function(addons) {
     // Should have disabled this add-on as requested
     do_check_eq(check_addon_state(addons[2]), "true,true,false");
     do_check_eq(check_plugin_state(PLUGINS[2]), "true,false");
 
     // The blocked add-on should have changed to soft disabled
     do_check_eq(check_addon_state(addons[5]), "true,true,false");
+    do_check_eq(check_addon_state(addons[6]), "true,true,true");
     do_check_eq(check_plugin_state(PLUGINS[5]), "true,false");
 
     // These should have been unchanged
     do_check_eq(check_addon_state(addons[0]), "true,false,false");
     do_check_eq(check_addon_state(addons[1]), "false,false,false");
     do_check_eq(check_addon_state(addons[3]), "true,true,false");
     do_check_eq(check_addon_state(addons[4]), "false,false,false");
-    do_check_eq(check_addon_state(addons[6]), "false,false,true");
     do_check_eq(check_plugin_state(PLUGINS[0]), "true,false");
     do_check_eq(check_plugin_state(PLUGINS[1]), "false,false");
     do_check_eq(check_plugin_state(PLUGINS[3]), "true,false");
     do_check_eq(check_plugin_state(PLUGINS[4]), "false,false");
 
     // Back to starting state
     addons[2].userDisabled = false;
     addons[5].userDisabled = false;
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_softblocked.js
@@ -0,0 +1,109 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const { utils: Cu, interfaces: Ci, classes: Cc, results: Cr } = Components;
+
+const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul";
+
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://testing-common/MockRegistrar.jsm");
+
+// Allow insecure updates
+Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false)
+
+const testserver = createHttpServer();
+gPort = testserver.identity.primaryPort;
+testserver.registerDirectory("/data/", do_get_file("data"));
+
+// Don't need the full interface, attempts to call other methods will just
+// throw which is just fine
+var WindowWatcher = {
+  openWindow: function(parent, url, name, features, openArgs) {
+    // Should be called to list the newly blocklisted items
+    do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG);
+
+    // Simulate auto-disabling any softblocks
+    var list = openArgs.wrappedJSObject.list;
+    list.forEach(function(aItem) {
+      if (!aItem.blocked)
+        aItem.disable = true;
+    });
+
+    //run the code after the blocklist is closed
+    Services.obs.notifyObservers(null, "addon-blocklist-closed", null);
+  },
+
+  QueryInterface: function(iid) {
+    if (iid.equals(Ci.nsIWindowWatcher)
+     || iid.equals(Ci.nsISupports))
+      return this;
+
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  }
+};
+
+MockRegistrar.register("@mozilla.org/embedcomp/window-watcher;1", WindowWatcher);
+
+const profileDir = gProfD.clone();
+profileDir.append("extensions");
+
+function load_blocklist(aFile) {
+  return new Promise((resolve, reject) => {
+    Services.obs.addObserver(function() {
+      Services.obs.removeObserver(arguments.callee, "blocklist-updated");
+
+      resolve();
+    }, "blocklist-updated", false);
+
+    Services.prefs.setCharPref("extensions.blocklist.url", `http://localhost:${gPort}/data/${aFile}`);
+    var blocklist = Cc["@mozilla.org/extensions/blocklist;1"].
+                    getService(Ci.nsITimerCallback);
+    blocklist.notify(null);
+  });
+}
+
+function run_test() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
+  run_next_test();
+}
+
+// Tests that an appDisabled add-on that becomes softBlocked remains disabled
+// when becoming appEnabled
+add_task(function* () {
+  writeInstallRDFForExtension({
+    id: "softblock1@tests.mozilla.org",
+    version: "1.0",
+    name: "Softblocked add-on",
+    targetApplications: [{
+      id: "xpcshell@tests.mozilla.org",
+      minVersion: "2",
+      maxVersion: "3"
+    }]
+  }, profileDir);
+
+  startupManager();
+
+  let s1 = yield promiseAddonByID("softblock1@tests.mozilla.org");
+
+  // Make sure to mark it as previously enabled.
+  s1.userDisabled = false;
+
+  do_check_false(s1.softDisabled);
+  do_check_true(s1.appDisabled);
+  do_check_false(s1.isActive);
+
+  yield load_blocklist("test_softblocked1.xml");
+
+  do_check_true(s1.softDisabled);
+  do_check_true(s1.appDisabled);
+  do_check_false(s1.isActive);
+
+  yield promiseRestartManager("2");
+
+  s1 = yield promiseAddonByID("softblock1@tests.mozilla.org");
+
+  do_check_true(s1.softDisabled);
+  do_check_false(s1.appDisabled);
+  do_check_false(s1.isActive);
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
@@ -311,8 +311,9 @@ skip-if = appname == "thunderbird"
 [test_bug1180901_2.js]
 skip-if = os != "win"
 [test_bug1180901.js]
 skip-if = os != "win"
 [test_e10s_restartless.js]
 [test_switch_os.js]
 # Bug 1246231
 skip-if = os == "mac" && debug
+[test_softblocked.js]
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -35,10 +35,9 @@ skip-if = appname != "firefox"
 [test_temporary.js]
 [test_proxies.js]
 [test_proxy.js]
 [test_pass_symbol.js]
 [test_delay_update.js]
 [test_nodisable_hidden.js]
 [test_dependencies.js]
 
-
 [include:xpcshell-shared.ini]