Bug 552731: Update FUEL to use the new EM APIs. r=mfinkle
authorDave Townsend <dtownsend@oxymoronical.com>
Tue, 20 Apr 2010 15:14:15 -0700
changeset 42036 03c840d33d051eee7859ed2a7aa9a787caac72b1
parent 42035 fa0c375977c00d471adf0570191d875b527740d5
child 42037 f9268514ed9d512fac67931048852453d954001b
push idunknown
push userunknown
push dateunknown
reviewersmfinkle
bugs552731
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 552731: Update FUEL to use the new EM APIs. r=mfinkle
browser/fuel/src/fuelApplication.js
browser/fuel/test/Makefile.in
browser/fuel/test/browser_Extensions.js
toolkit/components/exthelper/extApplication.js
toolkit/components/exthelper/extIApplication.idl
toolkit/content/aboutSupport.js
toolkit/mozapps/extensions/test/xpcshell/test_fuel.js
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -652,17 +652,16 @@ var ApplicationFactory = {
       gSingleton = new Application();
     }
 
     return gSingleton.QueryInterface(aIID);
   }
 };
 
 
-
 //=================================================
 // Application constructor
 function Application() {
   this.initToolkitHelpers();
   this._bookmarks = null;
 }
 
 //=================================================
--- a/browser/fuel/test/Makefile.in
+++ b/browser/fuel/test/Makefile.in
@@ -45,16 +45,15 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES =browser_Application.js \
 		browser_ApplicationPrefs.js \
 		browser_ApplicationStorage.js \
 		browser_ApplicationQuitting.js \
 		browser_Bookmarks.js \
 		browser_Browser.js \
-		browser_Extensions.js \
 		ContentA.html \
 		ContentB.html \
 		ContentWithFrames.html \
 		$(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
deleted file mode 100644
--- 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();
-}
--- a/toolkit/components/exthelper/extApplication.js
+++ b/toolkit/components/exthelper/extApplication.js
@@ -31,16 +31,17 @@
  * 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 ***** */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/AddonManager.jsm");
 
 //=================================================
 // Shutdown - used to store cleanup functions which will
 //            be called on Application shutdown
 var gShutdown = [];
 
 //=================================================
 // Console constructor
@@ -390,89 +391,82 @@ SessionStorage.prototype = {
 };
 
 
 //=================================================
 // Extension constructor
 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();
 
   var installPref = "install-event-fired";
   if (!this._prefs.has(installPref)) {
     this._prefs.setValue(installPref, true);
     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(); });
 }
 
 //=================================================
 // Extension implementation
 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() {
     return this._item.id;
   },
 
   get name() {
     return this._item.name;
   },
 
   get enabled() {
-    return this._enabled;
+    return this._item.isActive;
   },
 
   get version() {
     return this._item.version;
   },
 
   get firstRun() {
     return this._firstRun;
@@ -491,74 +485,54 @@ Extension.prototype = {
   },
 
   QueryInterface : XPCOMUtils.generateQI([Ci.extIExtension])
 };
 
 
 //=================================================
 // Extensions constructor
-function Extensions() {
-  XPCOMUtils.defineLazyServiceGetter(this, "_extmgr",
-                                     "@mozilla.org/extensions/manager;1",
-                                     "nsIExtensionManager");
+function Extensions(addons) {
+  this._cache = {};
 
-  this._cache = {};
+  addons.forEach(function(addon) {
+    this._cache[addon.id] = new Extension(addon);
+  }, this);
 
   var self = this;
   gShutdown.push(function() { self._shutdown(); });
 }
 
 //=================================================
 // 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({});
   },
 
   // XXX: Disabled until we can figure out the wrapped object issues
   // id: "some@id" or /id/
   // name: "name" or /name/
   // version: "1.0.1"
   // 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])
 };
 
 //=================================================
 // extApplication constructor
 function extApplication() {
@@ -658,20 +632,20 @@ extApplication.prototype = {
   },
 
   get prefs() {
     let prefs = new PreferenceBranch("");
     this.__defineGetter__("prefs", function() prefs);
     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() {
 
     // This ensures that FUEL only registers for notifications as needed
     // by callers. Note that the unload (xpcom-shutdown) event is listened
     // for by default, as it's needed for cleanup purposes.
     var self = this;
--- a/toolkit/components/exthelper/extIApplication.idl
+++ b/toolkit/components/exthelper/extIApplication.idl
@@ -303,17 +303,16 @@ interface extIExtension : nsISupports
 
   /**
    * The events object for the extension.
    * supports: "uninstall"
    */
   readonly attribute extIEvents events;
 }; 
 
-
 /**
  * Interface representing a list of all installed extensions
  */
 [scriptable, uuid(de281930-aa5a-11db-abbd-0800200c9a66)]
 interface extIExtensions : nsISupports
 {
   /**
    * Array of extIExtension listing all extensions in the application.
@@ -335,16 +334,25 @@ interface extIExtensions : nsISupports
    *          The id of an extension
    * @returns An extension object or null if no extension exists
    *          with the given id.
    */
   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
  */
 [scriptable, uuid(0787ac44-29b9-4889-b97f-13573aec6971)]
 interface extISessionStorage : nsISupports
 {
   /**
    * The events object for the storage
    * supports: "change"
@@ -377,17 +385,17 @@ interface extISessionStorage : nsISuppor
    * @param   aDefaultValue
    *          The value to return if no item exists with the given name
    * @returns value of the item or the given default value if no item
    *          exists with the given name.
    */
   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
 {
   /**
    * The id of the application.
    */
   readonly attribute AString id;
 
   /**
@@ -404,17 +412,17 @@ interface extIApplication : nsISupports
    * The console object for the application.
    */
   readonly attribute extIConsole console;
 
   /**
    * 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
    * root branch.
    */
   readonly attribute extIPreferenceBranch prefs;
 
   /**
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -88,34 +88,36 @@ window.onload = function () {
   let supportUrl = urlFormatter.formatURLPref("app.support.baseURL");
 
   // Update the application basics section.
   document.getElementById("application-box").textContent = Application.name;
   document.getElementById("version-box").textContent = Application.version;
   document.getElementById("supportLink").href = supportUrl;
 
   // Update the other sections.
+  populatePreferencesSection();
   populateExtensionsSection();
-  populatePreferencesSection();
 }
 
 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() {
   let modifiedPrefs = getModifiedPrefs();
 
   function comparePrefs(pref1, pref2) {
     if (pref1.name < pref2.name)
       return -1;
new file mode 100644
--- /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 <dtownsend@oxymoronical.com>
+ *
+ * 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();
+}