From e853b6f3b48170e7c4098c36fc70b92b8a705606 Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Tue, 20 Apr 2010 15:14:15 -0700 Subject: [PATCH] Bug 552731: Update FUEL to use the new EM APIs. r=mfinkle --- browser/fuel/src/fuelApplication.js | 1 - browser/fuel/test/Makefile.in | 1 - browser/fuel/test/browser_Extensions.js | 126 ------------ .../components/exthelper/extApplication.js | 112 ++++------- .../components/exthelper/extIApplication.idl | 14 +- toolkit/content/aboutSupport.js | 30 +-- .../extensions/test/xpcshell/test_fuel.js | 188 ++++++++++++++++++ 7 files changed, 258 insertions(+), 214 deletions(-) delete mode 100644 browser/fuel/test/browser_Extensions.js create mode 100644 toolkit/mozapps/extensions/test/xpcshell/test_fuel.js diff --git a/browser/fuel/src/fuelApplication.js b/browser/fuel/src/fuelApplication.js index 4fa627cc0077..7ff09eff87c3 100644 --- a/browser/fuel/src/fuelApplication.js +++ b/browser/fuel/src/fuelApplication.js @@ -657,7 +657,6 @@ var ApplicationFactory = { }; - //================================================= // Application constructor function Application() { diff --git a/browser/fuel/test/Makefile.in b/browser/fuel/test/Makefile.in index 3ef2f3a4974e..87bf8d34d95b 100644 --- a/browser/fuel/test/Makefile.in +++ b/browser/fuel/test/Makefile.in @@ -50,7 +50,6 @@ _BROWSER_FILES =browser_Application.js \ browser_ApplicationQuitting.js \ browser_Bookmarks.js \ browser_Browser.js \ - browser_Extensions.js \ ContentA.html \ ContentB.html \ ContentWithFrames.html \ diff --git a/browser/fuel/test/browser_Extensions.js b/browser/fuel/test/browser_Extensions.js deleted file mode 100644 index f039432047aa..000000000000 --- a/browser/fuel/test/browser_Extensions.js +++ /dev/null @@ -1,126 +0,0 @@ -// The various pieces that we'll be testing -var testdata = { - dummyid: "fuel-dummy-extension@mozilla.org", - dummyname: "Dummy Extension", - inspectorid: "inspector@mozilla.org", - inspectorname: "DOM Inspector", - missing: "fuel.fuel-test-missing", - dummy: "fuel.fuel-test" -}; -var gLastEvent = ""; - -function test() { - // test to see if the extensions object is available - ok(Application.extensions, "Check for the 'Extensions' object"); - - // test to see if a non-existant extension exists - ok(!Application.extensions.has(testdata.dummyid), "Check non-existant extension for existence"); - - // BUG 420028: Must find a way to add a dummy extension for test suite - return; - - // test to see if an extension exists - ok(Application.extensions.has(testdata.inspectorid), "Check extension for existence"); - - var inspector = Application.extensions.get(testdata.inspectorid); - is(inspector.id, testdata.inspectorid, "Check 'Extension.id' for known extension"); - is(inspector.name, testdata.inspectorname, "Check 'Extension.name' for known extension"); - // The known version number changes too frequently to hardcode in - ok(inspector.version, "Check 'Extension.version' for known extension"); - ok(inspector.firstRun, "Check 'Extension.firstRun' for known extension"); - ok(inspector.enabled, "Check 'Extension.enabled' for known extension"); - - // test to see if extension find works - is(Application.extensions.all.length, 1, "Check a find for all extensions"); - // STORAGE TESTING - // Make sure the we are given the same extension (cached) so things like .storage work right - inspector.storage.set("test", "simple check"); - ok(inspector.storage.has("test"), "Checking that extension storage worked"); - - var inspector2 = Application.extensions.get(testdata.inspectorid); - is(inspector2.id, testdata.inspectorid, "Check 'Extension.id' for known extension - from cache"); - ok(inspector.storage.has("test"), "Checking that extension storage worked - from cache"); - is(inspector2.storage.get("test", "cache"), inspector.storage.get("test", "original"), "Checking that the storage of same extension is correct - from cache"); - - inspector.events.addListener("disable", onGenericEvent); - inspector.events.addListener("enable", onGenericEvent); - inspector.events.addListener("uninstall", onGenericEvent); - inspector.events.addListener("cancel", onGenericEvent); - - var extmgr = Components.classes["@mozilla.org/extensions/manager;1"] - .getService(Components.interfaces.nsIExtensionManager); - - extmgr.disableItem(testdata.inspectorid); - is(gLastEvent, "disable", "Checking that disable event is fired"); - - // enabling after a disable will only fire a 'cancel' event - // see - http://mxr.mozilla.org/seamonkey/source/toolkit/mozapps/extensions/src/nsExtensionManager.js.in#5216 - extmgr.enableItem(testdata.inspectorid); - is(gLastEvent, "cancel", "Checking that enable (cancel) event is fired"); - - extmgr.uninstallItem(testdata.inspectorid); - is(gLastEvent, "uninstall", "Checking that uninstall event is fired"); - - extmgr.cancelUninstallItem(testdata.inspectorid); - is(gLastEvent, "cancel", "Checking that cancel event is fired"); - - // PREF TESTING - // Reset the install event preference, so that we can test it again later - inspector.prefs.get("install-event-fired").reset(); - - // test the value of the preference root - is(Application.extensions.all[0].prefs.root, "extensions.inspector@mozilla.org.", "Check an extension preference root"); - - // test getting non-existing values - var itemValue = inspector.prefs.getValue(testdata.missing, "default"); - is(itemValue, "default", "Check 'Extension.prefs.getValue' for non-existing item"); - - is(inspector.prefs.get(testdata.missing), null, "Check 'Extension.prefs.get' for non-existing item"); - - // test setting and getting a value - inspector.prefs.setValue(testdata.dummy, "dummy"); - itemValue = inspector.prefs.getValue(testdata.dummy, "default"); - is(itemValue, "dummy", "Check 'Extension.prefs.getValue' for existing item"); - - // test for overwriting an existing value - inspector.prefs.setValue(testdata.dummy, "smarty"); - itemValue = inspector.prefs.getValue(testdata.dummy, "default"); - is(itemValue, "smarty", "Check 'Extension.prefs.getValue' for overwritten item"); - - // test setting and getting a value - inspector.prefs.get(testdata.dummy).value = "dummy2"; - itemValue = inspector.prefs.get(testdata.dummy).value; - is(itemValue, "dummy2", "Check 'Extension.prefs.get().value' for existing item"); - - // test resetting a pref [since there is no default value, the pref should disappear] - inspector.prefs.get(testdata.dummy).reset(); - var itemValue = inspector.prefs.getValue(testdata.dummy, "default"); - is(itemValue, "default", "Check 'Extension.prefs.getValue' for reset pref"); - - // test to see if a non-existant property exists - ok(!inspector.prefs.has(testdata.dummy), "Check non-existant property for existence"); - - waitForExplicitFinish(); - inspector.prefs.events.addListener("change", onPrefChange); - inspector.prefs.setValue("fuel.fuel-test", "change event"); -} - -function onGenericEvent(event) { - gLastEvent = event.type; -} - -function onPrefChange(evt) { - var inspector3 = Application.extensions.get(testdata.inspectorid); - - is(evt.data, testdata.dummy, "Check 'Extension.prefs.set' fired a change event"); - inspector3.prefs.events.removeListener("change", onPrefChange); - - inspector3.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2); - inspector3.prefs.setValue("fuel.fuel-test", "change event2"); -} - -function onPrefChange2(evt) { - is(evt.data, testdata.dummy, "Check 'Extension.prefs.set' fired a change event for a single preference"); - - finish(); -} diff --git a/toolkit/components/exthelper/extApplication.js b/toolkit/components/exthelper/extApplication.js index e05f4d7a1330..68d013620ea1 100644 --- a/toolkit/components/exthelper/extApplication.js +++ b/toolkit/components/exthelper/extApplication.js @@ -36,6 +36,7 @@ * ***** END LICENSE BLOCK ***** */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/AddonManager.jsm"); //================================================= // Shutdown - used to store cleanup functions which will @@ -395,7 +396,7 @@ SessionStorage.prototype = { function Extension(aItem) { this._item = aItem; this._firstRun = false; - this._prefs = new PreferenceBranch("extensions." + this._item.id + "."); + this._prefs = new PreferenceBranch("extensions." + this.id + "."); this._storage = new SessionStorage(); this._events = new Events(); @@ -405,22 +406,8 @@ function Extension(aItem) { this._firstRun = true; } - this._enabled = false; - const PREFIX_ITEM_URI = "urn:mozilla:item:"; - const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; - var rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService); - var itemResource = rdf.GetResource(PREFIX_ITEM_URI + this._item.id); - if (itemResource) { - var extmgr = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager); - var ds = extmgr.datasource; - var target = ds.GetTarget(itemResource, rdf.GetResource(PREFIX_NS_EM + "isDisabled"), true); - if (target && target instanceof Ci.nsIRDFLiteral) - this._enabled = (target.Value != "true"); - } - - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - os.addObserver(this, "em-action-requested", false); + AddonManager.addAddonListener(this); + AddonManager.addInstallListener(this); var self = this; gShutdown.push(function(){ self._shutdown(); }); @@ -431,31 +418,38 @@ function Extension(aItem) { Extension.prototype = { // cleanup observer so we don't leak _shutdown: function ext_shutdown() { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - os.removeObserver(this, "em-action-requested"); + AddonManager.removeAddonListener(this); + AddonManager.removeInstallListener(this); this._prefs = null; this._storage = null; this._events = null; }, - // for nsIObserver - observe: function ext_observe(aSubject, aTopic, aData) - { - if ((aSubject instanceof Ci.nsIUpdateItem) && (aSubject.id == this._item.id)) - { - if (aData == "item-uninstalled") - this._events.dispatch("uninstall", this._item.id); - else if (aData == "item-disabled") - this._events.dispatch("disable", this._item.id); - else if (aData == "item-enabled") - this._events.dispatch("enable", this._item.id); - else if (aData == "item-cancel-action") - this._events.dispatch("cancel", this._item.id); - else if (aData == "item-upgraded") - this._events.dispatch("upgrade", this._item.id); - } + // for AddonListener + onDisabling: function(addon, needsRestart) { + if (addon.id == this.id) + this._events.dispatch("disable", this.id); + }, + + onEnabling: function(addon, needsRestart) { + if (addon.id == this.id) + this._events.dispatch("enable", this.id); + }, + + onUninstalling: function(addon, needsRestart) { + if (addon.id == this.id) + this._events.dispatch("uninstall", this.id); + }, + + onOperationCancelled: function(addon) { + if (addon.id == this.id) + this._events.dispatch("cancel", this.id); + }, + + onInstallEnded: function(install, addon) { + if (addon.id == this.id) + this._events.dispatch("upgrade", this.id); }, get id() { @@ -467,7 +461,7 @@ Extension.prototype = { }, get enabled() { - return this._enabled; + return this._item.isActive; }, get version() { @@ -496,13 +490,13 @@ Extension.prototype = { //================================================= // Extensions constructor -function Extensions() { - XPCOMUtils.defineLazyServiceGetter(this, "_extmgr", - "@mozilla.org/extensions/manager;1", - "nsIExtensionManager"); - +function Extensions(addons) { this._cache = {}; + addons.forEach(function(addon) { + this._cache[addon.id] = new Extension(addon); + }, this); + var self = this; gShutdown.push(function() { self._shutdown(); }); } @@ -511,22 +505,9 @@ function Extensions() { // Extensions implementation Extensions.prototype = { _shutdown : function exts_shutdown() { - this._extmgr = null; this._cache = null; }, - /* - * Helper method to check cache before creating a new extension - */ - _get : function exts_get(aId) { - if (this._cache.hasOwnProperty(aId)) - return this._cache[aId]; - - var newExt = new Extension(this._extmgr.getItemForID(aId)); - this._cache[aId] = newExt; - return newExt; - }, - get all() { return this.find({}); }, @@ -538,22 +519,15 @@ Extensions.prototype = { // minVersion: "1.0" // maxVersion: "2.0" find : function exts_find(aOptions) { - var retVal = []; - var items = this._extmgr.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION); - - for (var i = 0; i < items.length; i++) { - retVal.push(this._get(items[i].id)); - } - - return retVal; + return [e for each (e in this._cache)]; }, has : function exts_has(aId) { - return this._extmgr.getItemForID(aId) != null; + return aId in this._cache; }, get : function exts_get(aId) { - return this.has(aId) ? this._get(aId) : null; + return this.has(aId) ? this._cache[aId] : null; }, QueryInterface : XPCOMUtils.generateQI([Ci.extIExtensions]) @@ -663,10 +637,10 @@ extApplication.prototype = { return this.prefs; }, - get extensions() { - let extensions = new Extensions(); - this.__defineGetter__("extensions", function() extensions); - return this.extensions; + getExtensions: function(callback) { + AddonManager.getAddonsByTypes(["extension"], function(addons) { + callback.callback(new Extensions(addons)); + }); }, get events() { diff --git a/toolkit/components/exthelper/extIApplication.idl b/toolkit/components/exthelper/extIApplication.idl index 9d6e7c2c4bbb..7710cc5bb682 100644 --- a/toolkit/components/exthelper/extIApplication.idl +++ b/toolkit/components/exthelper/extIApplication.idl @@ -308,7 +308,6 @@ interface extIExtension : nsISupports readonly attribute extIEvents events; }; - /** * Interface representing a list of all installed extensions */ @@ -339,6 +338,15 @@ interface extIExtensions : nsISupports extIExtension get(in AString aId); }; +/** + * Interface representing a callback that receives an array of extIExtensions + */ +[scriptable, function, uuid(2571cbb5-550d-4400-8038-75df9b553f98)] +interface extIExtensionsCallback : nsISupports +{ + void callback(in nsIVariant extensions); +}; + /** * Interface representing a simple storage system */ @@ -382,7 +390,7 @@ interface extISessionStorage : nsISupports nsIVariant get(in AString aName, in nsIVariant aDefaultValue); }; -[scriptable, uuid(e53d6610-7468-11dd-ad8b-0800200c9a66)] +[scriptable, uuid(2be87909-0817-4292-acfa-fc39be53be3f)] interface extIApplication : nsISupports { /** @@ -409,7 +417,7 @@ interface extIApplication : nsISupports * The extensions object for the application. Contains a list * of all installed extensions. */ - readonly attribute extIExtensions extensions; + void getExtensions(in extIExtensionsCallback aCallback); /** * The preferences object for the application. Defaults to an empty diff --git a/toolkit/content/aboutSupport.js b/toolkit/content/aboutSupport.js index 6fa30cb4958b..27c40d9aca7e 100644 --- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -93,24 +93,26 @@ window.onload = function () { document.getElementById("supportLink").href = supportUrl; // Update the other sections. - populateExtensionsSection(); populatePreferencesSection(); + populateExtensionsSection(); } function populateExtensionsSection() { - let extensions = Application.extensions.all; - let trExtensions = []; - for (let i = 0; i < extensions.length; i++) { - let extension = extensions[i]; - let tr = createParentElement("tr", [ - createElement("td", extension.name), - createElement("td", extension.version), - createElement("td", extension.enabled), - createElement("td", extension.id), - ]); - trExtensions.push(tr); - } - appendChildren(document.getElementById("extensions-tbody"), trExtensions); + Application.getExtensions(function (extensions) { + let all = extensions.all; + let trExtensions = []; + for (let i = 0; i < all.length; i++) { + let extension = all[i]; + let tr = createParentElement("tr", [ + createElement("td", extension.name), + createElement("td", extension.version), + createElement("td", extension.enabled), + createElement("td", extension.id), + ]); + trExtensions.push(tr); + } + appendChildren(document.getElementById("extensions-tbody"), trExtensions); + }); } function populatePreferencesSection() { diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_fuel.js b/toolkit/mozapps/extensions/test/xpcshell/test_fuel.js new file mode 100644 index 000000000000..cbf29a2e77a6 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_fuel.js @@ -0,0 +1,188 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dave Townsend + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** + */ + +// This just verifies that FUEL integrates to the add-ons manager + +var testdata = { + dummyid: "fuel-dummy-extension@mozilla.org", + dummyname: "Dummy Extension", + inspectorid: "addon1@tests.mozilla.org", + inspectorname: "Test Addon", + missing: "fuel.fuel-test-missing", + dummy: "fuel.fuel-test" +}; + +var Application = AM_Cc["@mozilla.org/fuel/application;1"]. + getService(AM_Ci.nsISupports); + +function run_test() { + do_test_pending(); + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); + + const profileDir = gProfD.clone(); + profileDir.append("extensions"); + + var dest = profileDir.clone(); + dest.append("addon1@tests.mozilla.org"); + writeInstallRDFToDir({ + id: "addon1@tests.mozilla.org", + version: "1.0", + name: "Test Addon", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "1" + }], + }, dest); + + startupManager(1); + + Application.getExtensions(function(extensions) { + // test to see if the extensions object is available + do_check_neq(extensions, null); + + // test to see if a non-existant extension exists + do_check_true(!extensions.has(testdata.dummyid)); + + // test to see if an extension exists + do_check_true(extensions.has(testdata.inspectorid)); + + var inspector = extensions.get(testdata.inspectorid); + do_check_eq(inspector.id, testdata.inspectorid); + do_check_eq(inspector.name, testdata.inspectorname); + do_check_eq(inspector.version, "1.0"); + do_check_true(inspector.firstRun, true); + do_check_true(inspector.enabled); + + // test to see if extension find works + do_check_eq(extensions.all.length, 1); + // STORAGE TESTING + // Make sure the we are given the same extension (cached) so things like .storage work right + inspector.storage.set("test", "simple check"); + do_check_true(inspector.storage.has("test")); + + var inspector2 = extensions.get(testdata.inspectorid); + do_check_eq(inspector2.id, testdata.inspectorid); + do_check_true(inspector.storage.has("test")); + do_check_eq(inspector2.storage.get("test", "cache"), inspector.storage.get("test", "original")); + + inspector.events.addListener("disable", onGenericEvent); + inspector.events.addListener("enable", onGenericEvent); + inspector.events.addListener("uninstall", onGenericEvent); + inspector.events.addListener("cancel", onGenericEvent); + + AddonManager.getAddon(testdata.inspectorid, function(a) { + a.userDisabled = true; + + do_check_eq(gLastEvent, "disable"); + + // enabling after a disable will only fire a 'cancel' event + // see - http://mxr.mozilla.org/seamonkey/source/toolkit/mozapps/extensions/src/nsExtensionManager.js.in#5216 + a.userDisabled = false; + do_check_eq(gLastEvent, "cancel"); + + a.uninstall(); + do_check_eq(gLastEvent, "uninstall"); + + a.cancelUninstall(); + do_check_eq(gLastEvent, "cancel"); + + // PREF TESTING + // Reset the install event preference, so that we can test it again later + //inspector.prefs.get("install-event-fired").reset(); + + // test the value of the preference root + do_check_eq(extensions.all[0].prefs.root, "extensions.addon1@tests.mozilla.org."); + + // test getting non-existing values + var itemValue = inspector.prefs.getValue(testdata.missing, "default"); + do_check_eq(itemValue, "default"); + + do_check_eq(inspector.prefs.get(testdata.missing), null); + + // test setting and getting a value + inspector.prefs.setValue(testdata.dummy, "dummy"); + itemValue = inspector.prefs.getValue(testdata.dummy, "default"); + do_check_eq(itemValue, "dummy"); + + // test for overwriting an existing value + inspector.prefs.setValue(testdata.dummy, "smarty"); + itemValue = inspector.prefs.getValue(testdata.dummy, "default"); + do_check_eq(itemValue, "smarty"); + + // test setting and getting a value + inspector.prefs.get(testdata.dummy).value = "dummy2"; + itemValue = inspector.prefs.get(testdata.dummy).value; + do_check_eq(itemValue, "dummy2"); + + // test resetting a pref [since there is no default value, the pref should disappear] + inspector.prefs.get(testdata.dummy).reset(); + var itemValue = inspector.prefs.getValue(testdata.dummy, "default"); + do_check_eq(itemValue, "default"); + + // test to see if a non-existant property exists + do_check_true(!inspector.prefs.has(testdata.dummy)); + + inspector.prefs.events.addListener("change", onPrefChange); + inspector.prefs.setValue("fuel.fuel-test", "change event"); + }); + }); +} + +function onGenericEvent(event) { + gLastEvent = event.type; +} + +function onPrefChange(evt) { + Application.getExtensions(function(extensions) { + var inspector3 = extensions.get(testdata.inspectorid); + + do_check_eq(evt.data, testdata.dummy); + inspector3.prefs.events.removeListener("change", onPrefChange); + + inspector3.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2); + inspector3.prefs.setValue("fuel.fuel-test", "change event2"); + }); +} + +function onPrefChange2(evt) { + do_check_eq(evt.data, testdata.dummy); + + do_test_finished(); +}