Bug 1283116 - Implement chrome.management.getSelf, r?kmag draft
authorBob Silverberg <bsilverberg@mozilla.com>
Wed, 17 Aug 2016 17:03:39 -0400
changeset 401994 2ac36f49b369f13ac25de264cb70f3c9971b8743
parent 401500 fe895421dfbe1f1f8f1fc6a39bb20774423a6d74
child 528618 dad2c88a0c5e686dc1f250c1de9c9fa3b3072d56
push id26598
push userbmo:bob.silverberg@gmail.com
push dateWed, 17 Aug 2016 21:09:25 +0000
reviewerskmag
bugs1283116
milestone51.0a1
Bug 1283116 - Implement chrome.management.getSelf, r?kmag MozReview-Commit-ID: Bj9ZyF1meED
toolkit/components/extensions/ext-management.js
toolkit/components/extensions/schemas/management.json
toolkit/mozapps/extensions/test/xpcshell/test_ext_management.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
--- a/toolkit/components/extensions/ext-management.js
+++ b/toolkit/components/extensions/ext-management.js
@@ -1,9 +1,61 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
+XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
+                                  "resource://gre/modules/AddonManager.jsm");
+
+function installType(addon) {
+  if (addon.temporarilyInstalled) {
+    return "development";
+  } else if (addon.foreignInstall) {
+    return "sideload";
+  } else if (addon.isSystem) {
+    return "other";
+  }
+  return "normal";
+}
+
 extensions.registerSchemaAPI("management", (extension, context) => {
   return {
-    management: {},
+    management: {
+      getSelf: function() {
+        return new Promise((resolve, reject) => AddonManager.getAddonByID(extension.id, addon => {
+          try {
+            let m = extension.manifest;
+            let extInfo = {
+              id: extension.id,
+              name: addon.name,
+              shortName: m.short_name || "",
+              description: addon.description || "",
+              version: addon.version,
+              mayDisable: !!(addon.permissions & AddonManager.PERM_CAN_DISABLE),
+              enabled: addon.isActive,
+              optionsUrl: addon.optionsURL || "",
+              permissions: Array.from(extension.permissions).filter(perm => {
+                return !extension.whiteListedHosts.pat.includes(perm);
+              }),
+              hostPermissions: extension.whiteListedHosts.pat,
+              installType: installType(addon),
+            };
+            if (addon.homepageURL) {
+              extInfo.homepageUrl = addon.homepageURL;
+            }
+            if (addon.updateURL) {
+              extInfo.updateUrl = addon.updateURL;
+            }
+            if (m.icons) {
+              extInfo.icons = Object.keys(m.icons).map(key => {
+                return {size: Number(key), url: m.icons[key]};
+              });
+            }
+
+            resolve(extInfo);
+          } catch (e) {
+            reject(e);
+          }
+        }));
+      },
+    },
   };
 });
--- a/toolkit/components/extensions/schemas/management.json
+++ b/toolkit/components/extensions/schemas/management.json
@@ -193,17 +193,16 @@
               }
             ]
           }
         ]
       },
       {
         "name": "getSelf",
         "type": "function",
-        "unsupported": true,
         "description": "Returns information about the calling extension. Note: This function can be used without requesting the 'management' permission in the manifest.",
         "async": "callback",
         "parameters": [
           {
             "type": "function",
             "name": "callback",
             "optional": true,
             "parameters": [
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_ext_management.js
@@ -0,0 +1,137 @@
+"use strict";
+
+add_task(function* setup() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "48", "48");
+  startupManager();
+});
+
+/* eslint-disable no-undef */
+// Shared background function for getSelf tests
+function backgroundGetSelf() {
+  browser.management.getSelf().then(extInfo => {
+    browser.test.sendMessage("management-getSelf", extInfo);
+  }, error => {
+    browser.test.notifyFail(`getSelf rejected with error: ${error}`);
+  });
+}
+/* eslint-enable no-undef */
+
+add_task(function* test_management_get_self_complete() {
+  const id = "get_self_test_complete@tests.mozilla.com";
+  const permissions = ["management", "cookies"];
+  const hostPermissions = ["*://example.org/", "https://foo.example.org/"];
+
+  let manifest = {
+    applications: {
+      gecko: {
+        id,
+        update_url: "https://updates.mozilla.com/",
+      },
+    },
+    name: "test extension name",
+    short_name: "test extension short name",
+    description: "test extension description",
+    version: "1.0",
+    homepage_url: "http://www.example.com/",
+    options_ui: {
+      "page": "get_self_options.html",
+    },
+    icons: {
+      "16": "icons/icon-16.png",
+      "48": "icons/icon-48.png",
+    },
+    permissions: [...permissions, ...hostPermissions],
+  };
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest,
+    background: backgroundGetSelf,
+    useAddonManager: "temporary",
+  });
+  yield extension.startup();
+  let extInfo = yield extension.awaitMessage("management-getSelf");
+
+  equal(extInfo.id, id, "getSelf returned the expected id");
+  equal(extInfo.installType, "development", "getSelf returned the expected installType");
+  for (let prop of ["name", "description", "version"]) {
+    equal(extInfo[prop], manifest[prop], `getSelf returned the expected ${prop}`);
+  }
+  equal(extInfo.shortName, manifest.short_name, "getSelf returned the expected shortName");
+  equal(extInfo.mayDisable, true, "getSelf returned the expected value for mayDisable");
+  equal(extInfo.enabled, true, "getSelf returned the expected value for enabled");
+  equal(extInfo.homepageUrl, manifest.homepage_url, "getSelf returned the expected homepageUrl");
+  equal(extInfo.updateUrl, manifest.applications.gecko.update_url, "getSelf returned the expected updateUrl");
+  ok(extInfo.optionsUrl.endsWith(manifest.options_ui.page), "getSelf returned the expected optionsUrl");
+  for (let [index, size] of Object.keys(manifest.icons).sort().entries()) {
+    equal(extInfo.icons[index].size, +size, "getSelf returned the expected icon size");
+    equal(extInfo.icons[index].url, manifest.icons[size], "getSelf returned the expected icon url");
+  }
+  deepEqual(extInfo.permissions.sort(), permissions.sort(), "getSelf returned the expected permissions");
+  deepEqual(extInfo.hostPermissions.sort(), hostPermissions.sort(), "getSelf returned the expected hostPermissions");
+  equal(extInfo.installType, "development", "getSelf returned the expected installType");
+  yield extension.unload();
+});
+
+add_task(function* test_management_get_self_minimal() {
+  const id = "get_self_test_minimal@tests.mozilla.com";
+
+  let manifest = {
+    applications: {
+      gecko: {
+        id,
+      },
+    },
+    name: "test extension name",
+    version: "1.0",
+  };
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest,
+    background: backgroundGetSelf,
+    useAddonManager: "temporary",
+  });
+  yield extension.startup();
+  let extInfo = yield extension.awaitMessage("management-getSelf");
+
+  equal(extInfo.id, id, "getSelf returned the expected id");
+  equal(extInfo.installType, "development", "getSelf returned the expected installType");
+  for (let prop of ["name", "version"]) {
+    equal(extInfo[prop], manifest[prop], `getSelf returned the expected ${prop}`);
+  }
+  for (let prop of ["shortName", "description", "optionsUrl"]) {
+    equal(extInfo[prop], "", `getSelf returned the expected ${prop}`);
+  }
+  for (let prop of ["homepageUrl", " updateUrl", "icons"]) {
+    equal(Reflect.getOwnPropertyDescriptor(extInfo, prop), undefined, `getSelf did not return a ${prop} property`);
+  }
+  for (let prop of ["permissions", "hostPermissions"]) {
+    deepEqual(extInfo[prop], [], `getSelf returned the expected ${prop}`);
+  }
+  yield extension.unload();
+});
+
+add_task(function* test_management_get_self_permanent() {
+  const id = "get_self_test_permanent@tests.mozilla.com";
+
+  let manifest = {
+    applications: {
+      gecko: {
+        id,
+      },
+    },
+    name: "test extension name",
+    version: "1.0",
+  };
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest,
+    background: backgroundGetSelf,
+    useAddonManager: "permanent",
+  });
+  yield extension.startup();
+  let extInfo = yield extension.awaitMessage("management-getSelf");
+
+  equal(extInfo.id, id, "getSelf returned the expected id");
+  equal(extInfo.installType, "normal", "getSelf returned the expected installType");
+  yield extension.unload();
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
@@ -312,8 +312,9 @@ skip-if = appname == "thunderbird"
 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]
+[test_ext_management.js]