зеркало из https://github.com/mozilla/pjs.git
Bug 555349: Finalize the restartless add-on format. r=robstrong
This commit is contained in:
Родитель
7746c1c7e5
Коммит
ab93423703
|
@ -107,12 +107,22 @@ const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
|
||||||
const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
|
const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
|
||||||
const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
|
const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
|
||||||
|
|
||||||
|
const BOOTSTRAP_REASONS = {
|
||||||
|
APP_STARTUP : 1,
|
||||||
|
APP_SHUTDOWN : 2,
|
||||||
|
ADDON_ENABLE : 3,
|
||||||
|
ADDON_DISABLE : 4,
|
||||||
|
ADDON_INSTALL : 5,
|
||||||
|
ADDON_UNINSTALL : 6,
|
||||||
|
ADDON_UPGRADE : 7,
|
||||||
|
ADDON_DOWNGRADE : 8
|
||||||
|
};
|
||||||
|
|
||||||
// Map new string type identifiers to old style nsIUpdateItem types
|
// Map new string type identifiers to old style nsIUpdateItem types
|
||||||
const TYPES = {
|
const TYPES = {
|
||||||
extension: 2,
|
extension: 2,
|
||||||
theme: 4,
|
theme: 4,
|
||||||
locale: 8,
|
locale: 8
|
||||||
bootstrapped: 64
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -393,6 +403,10 @@ function loadManifestFromRDF(aUri, aStream) {
|
||||||
addon.aboutURL = null;
|
addon.aboutURL = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only read the bootstrapped property for extensions
|
||||||
|
if (addon.type == "extension")
|
||||||
|
addon.bootstrap = getRDFProperty(ds, root, "bootstrap") == "true";
|
||||||
|
|
||||||
addon.defaultLocale = readLocale(ds, root, true);
|
addon.defaultLocale = readLocale(ds, root, true);
|
||||||
|
|
||||||
addon.locales = [];
|
addon.locales = [];
|
||||||
|
@ -1191,7 +1205,7 @@ var XPIProvider = {
|
||||||
WARN("Could not uninstall invalid item from locked install location");
|
WARN("Could not uninstall invalid item from locked install location");
|
||||||
// If this was an active add-on then we must force a restart
|
// If this was an active add-on then we must force a restart
|
||||||
if (aOldAddon.active) {
|
if (aOldAddon.active) {
|
||||||
if (aOldAddon.type == "bootstrapped")
|
if (aOldAddon.bootstrap)
|
||||||
delete XPIProvider.bootstrappedAddons[aOldAddon.id];
|
delete XPIProvider.bootstrappedAddons[aOldAddon.id];
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
|
@ -1212,8 +1226,8 @@ var XPIProvider = {
|
||||||
// If the old version was active and wasn't bootstrapped or the new
|
// If the old version was active and wasn't bootstrapped or the new
|
||||||
// version will be active and isn't bootstrapped then we must force a
|
// version will be active and isn't bootstrapped then we must force a
|
||||||
// restart
|
// restart
|
||||||
if ((aOldAddon.active && aOldAddon.type != "bootstrapped") ||
|
if ((aOldAddon.active && !aOldAddon.bootstrap) ||
|
||||||
(newAddon.active && newAddon.type != "bootstrapped")) {
|
(newAddon.active && !newAddon.bootstrap)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,7 +1264,7 @@ var XPIProvider = {
|
||||||
|
|
||||||
// If the add-on is bootstrappable and it should be active then
|
// If the add-on is bootstrappable and it should be active then
|
||||||
// mark it as active and add it to the list to be activated.
|
// mark it as active and add it to the list to be activated.
|
||||||
if (aOldAddon.type == "bootstrapped" && !aOldAddon.appDisabled &&
|
if (aOldAddon.bootstrap && !aOldAddon.appDisabled &&
|
||||||
!aOldAddon.userDisabled) {
|
!aOldAddon.userDisabled) {
|
||||||
aOldAddon.active = true;
|
aOldAddon.active = true;
|
||||||
XPIDatabase.updateAddonActive(aOldAddon);
|
XPIDatabase.updateAddonActive(aOldAddon);
|
||||||
|
@ -1281,7 +1295,7 @@ var XPIProvider = {
|
||||||
// If this is a visible add-on and it isn't userDisabled then we
|
// If this is a visible add-on and it isn't userDisabled then we
|
||||||
// may need a restart or to update the bootstrap list.
|
// may need a restart or to update the bootstrap list.
|
||||||
if (aOldAddon.visible && !aOldAddon.userDisabled) {
|
if (aOldAddon.visible && !aOldAddon.userDisabled) {
|
||||||
if (aOldAddon.type == "bootstrapped") {
|
if (aOldAddon.bootstrap) {
|
||||||
// When visible and not userDisabled, active is the opposite of
|
// When visible and not userDisabled, active is the opposite of
|
||||||
// appDisabled.
|
// appDisabled.
|
||||||
aOldAddon.active = !aOldAddon.appDisabled;
|
aOldAddon.active = !aOldAddon.appDisabled;
|
||||||
|
@ -1330,10 +1344,10 @@ var XPIProvider = {
|
||||||
|
|
||||||
// If this was an active add-on and bootstrapped we must remove it from
|
// If this was an active add-on and bootstrapped we must remove it from
|
||||||
// the bootstrapped list, otherwise we need to force a restart.
|
// the bootstrapped list, otherwise we need to force a restart.
|
||||||
if (aOldAddon.type != "bootstrapped")
|
if (!aOldAddon.bootstrap)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
delete XPIProvider.bootstrappedAddons[aOldAddon.id];
|
XPIProvider.unloadBootstrapScope(aOldAddon.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1398,16 +1412,17 @@ var XPIProvider = {
|
||||||
// Update the database.
|
// Update the database.
|
||||||
XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
||||||
|
|
||||||
// Visible bootstrapped add-ons need to be added to the bootstrap list.
|
// Visible bootstrapped add-ons need to have their install method called
|
||||||
if (newAddon.visible) {
|
if (newAddon.visible) {
|
||||||
visibleAddons[newAddon.id] = newAddon;
|
visibleAddons[newAddon.id] = newAddon;
|
||||||
if (newAddon.type != "bootstrapped")
|
if (!newAddon.bootstrap)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
XPIProvider.bootstrappedAddons[newAddon.id] = {
|
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
version: newAddon.version,
|
dir.persistentDescriptor = aAddonState.descriptor;
|
||||||
descriptor: aAddonState.descriptor
|
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, dir,
|
||||||
};
|
"install",
|
||||||
|
BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1566,12 +1581,11 @@ var XPIProvider = {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bootstrappedAddons = this.bootstrappedAddons;
|
for (let id in this.bootstrappedAddons) {
|
||||||
this.bootstrappedAddons = {};
|
|
||||||
for (let id in bootstrappedAddons) {
|
|
||||||
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
dir.persistentDescriptor = bootstrappedAddons[id].descriptor;
|
dir.persistentDescriptor = this.bootstrappedAddons[id].descriptor;
|
||||||
this.activateAddon(id, bootstrappedAddons[id].version, dir, true, false);
|
this.callBootstrapMethod(id, this.bootstrappedAddons[id].version, dir,
|
||||||
|
"startup", BOOTSTRAP_REASONS.APP_STARTUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let these shutdown a little earlier when they still have access to most
|
// Let these shutdown a little earlier when they still have access to most
|
||||||
|
@ -1580,8 +1594,13 @@ var XPIProvider = {
|
||||||
observe: function(aSubject, aTopic, aData) {
|
observe: function(aSubject, aTopic, aData) {
|
||||||
Services.prefs.setCharPref(PREF_BOOTSTRAP_ADDONS,
|
Services.prefs.setCharPref(PREF_BOOTSTRAP_ADDONS,
|
||||||
JSON.stringify(XPIProvider.bootstrappedAddons));
|
JSON.stringify(XPIProvider.bootstrappedAddons));
|
||||||
for (let id in XPIProvider.bootstrappedAddons)
|
for (let id in XPIProvider.bootstrappedAddons) {
|
||||||
XPIProvider.deactivateAddon(id, true, false);
|
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
|
dir.persistentDescriptor = XPIProvider.bootstrappedAddons[id].descriptor;
|
||||||
|
XPIProvider.callBootstrapMethod(id, XPIProvider.bootstrappedAddons[id].version,
|
||||||
|
dir, "shutdown",
|
||||||
|
BOOTSTRAP_REASONS.APP_SHUTDOWN);
|
||||||
|
}
|
||||||
Services.obs.removeObserver(this, "quit-application-granted");
|
Services.obs.removeObserver(this, "quit-application-granted");
|
||||||
}
|
}
|
||||||
}, "quit-application-granted", false);
|
}, "quit-application-granted", false);
|
||||||
|
@ -1872,7 +1891,7 @@ var XPIProvider = {
|
||||||
return aAddon.internalName !=
|
return aAddon.internalName !=
|
||||||
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
||||||
|
|
||||||
return aAddon.type != "bootstrapped";
|
return !aAddon.bootstrap;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1891,7 +1910,7 @@ var XPIProvider = {
|
||||||
return this.selectedSkin !=
|
return this.selectedSkin !=
|
||||||
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
||||||
|
|
||||||
return aAddon.type != "bootstrapped";
|
return !aAddon.bootstrap;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1907,7 +1926,7 @@ var XPIProvider = {
|
||||||
return aAddon.internalName ==
|
return aAddon.internalName ==
|
||||||
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
||||||
|
|
||||||
return aAddon.type != "bootstrapped";
|
return !aAddon.bootstrap;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1923,85 +1942,53 @@ var XPIProvider = {
|
||||||
return aAddon.internalName ==
|
return aAddon.internalName ==
|
||||||
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
|
||||||
|
|
||||||
return aAddon.type != "bootstrapped";
|
return !aAddon.bootstrap;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls a method in a bootstrap.js loaded scope logging any exceptions thrown.
|
* Loads a bootstrapped add-on's bootstrap.js into a sandbox and the reason
|
||||||
|
* values as constants in the scope. This will also add information about the
|
||||||
|
* add-on to the bootstrappedAddons dictionary and notify the crash reporter
|
||||||
|
* that new add-ons have been loaded.
|
||||||
*
|
*
|
||||||
* @param aId
|
* @param aId
|
||||||
* The ID of the add-on being bootstrapped
|
* The add-on's ID
|
||||||
* @param aScope
|
|
||||||
* The loaded JS scope to call into
|
|
||||||
* @param aMethods
|
|
||||||
* An array of methods. The first method in the array that exists in
|
|
||||||
* the scope will be called
|
|
||||||
*/
|
|
||||||
callBootstrapMethod: function XPI_callBootstrapMethod(aId, aScope, aMethods) {
|
|
||||||
for (let i = 0; i < aMethods.length; i++) {
|
|
||||||
if (aMethods[i] in aScope) {
|
|
||||||
LOG("Calling bootstrap method " + aMethods[i] + " on " + aId);
|
|
||||||
|
|
||||||
try {
|
|
||||||
aScope[aMethods[i]](aId);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
WARN("Exception running bootstrap method " + aMethods[i] + " on " +
|
|
||||||
aId + ": " + e);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activates a bootstrapped add-on by loading its JS scope and calling the
|
|
||||||
* appropriate method on it. Adds the add-on and its scope to the
|
|
||||||
* bootstrapScopes and bootstrappedAddons dictionaries.
|
|
||||||
*
|
|
||||||
* @param aId
|
|
||||||
* The ID of the add-on being activated
|
|
||||||
* @param aVersion
|
|
||||||
* The version of the add-on being activated
|
|
||||||
* @param aDir
|
* @param aDir
|
||||||
* The directory containing the add-on
|
* The nsILocalFile for the directory containing the add-on
|
||||||
* @param aStartup
|
* @param aVersion
|
||||||
* true if the add-on is being activated during startup
|
* The add-on's version
|
||||||
* @param aInstall
|
* @return a JavaScript scope
|
||||||
* true if the add-on is being activated during installation
|
|
||||||
*/
|
*/
|
||||||
activateAddon: function XPI_activateAddon(aId, aVersion, aDir, aStartup, aInstall) {
|
loadBootstrapScope: function XPI_loadBootstrapScope(aId, aDir, aVersion) {
|
||||||
let methods = ["enable"];
|
LOG("Loading bootstrap scope from " + aDir.path);
|
||||||
if (aStartup)
|
// Mark the add-on as active for the crash reporter before loading
|
||||||
methods.unshift("startup");
|
this.bootstrappedAddons[aId] = {
|
||||||
if (aInstall)
|
version: aVersion,
|
||||||
methods.unshift("install");
|
descriptor: aDir.persistentDescriptor
|
||||||
|
};
|
||||||
|
this.addAddonsToCrashReporter();
|
||||||
|
|
||||||
|
let principal = Cc["@mozilla.org/systemprincipal;1"].
|
||||||
|
createInstance(Ci.nsIPrincipal);
|
||||||
|
this.bootstrapScopes[aId] = new Components.utils.Sandbox(principal);
|
||||||
|
|
||||||
let bootstrap = aDir.clone();
|
let bootstrap = aDir.clone();
|
||||||
bootstrap.append("bootstrap.js");
|
bootstrap.append("bootstrap.js");
|
||||||
if (bootstrap.exists()) {
|
if (bootstrap.exists()) {
|
||||||
let uri = Services.io.newFileURI(bootstrap);
|
let uri = Services.io.newFileURI(bootstrap);
|
||||||
let principal = Cc["@mozilla.org/systemprincipal;1"].
|
|
||||||
createInstance(Ci.nsIPrincipal);
|
|
||||||
let scope = new Components.utils.Sandbox(principal);
|
|
||||||
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||||
createInstance(Ci.mozIJSSubScriptLoader);
|
createInstance(Ci.mozIJSSubScriptLoader);
|
||||||
|
|
||||||
// Mark the add-on as active for the crash reporter before loading
|
|
||||||
this.bootstrappedAddons[aId] = {
|
|
||||||
version: aVersion,
|
|
||||||
descriptor: aDir.persistentDescriptor
|
|
||||||
};
|
|
||||||
this.bootstrapScopes[aId] = scope;
|
|
||||||
this.addAddonsToCrashReporter();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loader.loadSubScript(uri.spec, scope);
|
loader.loadSubScript(uri.spec, this.bootstrapScopes[aId]);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
WARN("Error loading bootstrap.js for " + aId + ": " + e);
|
WARN("Error loading bootstrap.js for " + aId + ": " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.callBootstrapMethod(aId, scope, methods);
|
// Copy the reason values from the global object into the bootstrap scope.
|
||||||
|
for (let name in BOOTSTRAP_REASONS)
|
||||||
|
this.bootstrapScopes[aId][name] = BOOTSTRAP_REASONS[name];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WARN("Bootstrap missing for " + aId);
|
WARN("Bootstrap missing for " + aId);
|
||||||
|
@ -2009,34 +1996,58 @@ var XPIProvider = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dectivates a bootstrapped add-on by by calling the appropriate method on
|
* Unloads a bootstrap scope by dropping all references to it and then
|
||||||
* the cached JS scope. Removes the add-on and its scope from the
|
* updating the list of active add-ons with the crash reporter.
|
||||||
* bootstrapScopes and bootstrappedAddons dictionaries.
|
|
||||||
*
|
*
|
||||||
* @param aId
|
* @param aId
|
||||||
* The ID of the add-on being deactivated
|
* The add-on's ID
|
||||||
* @param aShutdown
|
|
||||||
* true if the add-on is being deactivated during shutdown
|
|
||||||
* @param aUninstall
|
|
||||||
* true if the add-on is being deactivated during uninstallation
|
|
||||||
*/
|
*/
|
||||||
deactivateAddon: function XPI_deactivateAddon(aId, aShutdown, aUninstall) {
|
unloadBootstrapScope: function XPI_unloadBootstrapScope(aId) {
|
||||||
if (!(aId in this.bootstrappedAddons)) {
|
delete this.bootstrapScopes[aId];
|
||||||
ERROR("Attempted to deactivate an add-on that was never activated");
|
delete this.bootstrappedAddons[aId];
|
||||||
|
this.addAddonsToCrashReporter();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a bootstrap method for an add-on.
|
||||||
|
*
|
||||||
|
* @param aId
|
||||||
|
* The ID of the add-on
|
||||||
|
* @param aVersion
|
||||||
|
* The version of the add-on
|
||||||
|
* @param aDir
|
||||||
|
* The nsILocalFile for the directory containing the add-on
|
||||||
|
* @param aMethod
|
||||||
|
* The name of the bootstrap method to call
|
||||||
|
* @param aReason
|
||||||
|
* The reason flag to pass to the bootstrap's startup method
|
||||||
|
*/
|
||||||
|
callBootstrapMethod: function XPI_callBootstrapMethod(aId, aVersion, aDir,
|
||||||
|
aMethod, aReason) {
|
||||||
|
// Load the scope if it hasn't already been loaded
|
||||||
|
if (!(aId in this.bootstrapScopes))
|
||||||
|
this.loadBootstrapScope(aId, aDir, aVersion);
|
||||||
|
|
||||||
|
if (!(aMethod in this.bootstrapScopes[aId])) {
|
||||||
|
WARN("Add-on " + aId + " is missing bootstrap method " + aMethod);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let scope = this.bootstrapScopes[aId];
|
|
||||||
delete this.bootstrappedAddons[aId];
|
|
||||||
delete this.bootstrapScopes[aId];
|
|
||||||
|
|
||||||
let methods = ["disable"];
|
let params = {
|
||||||
if (aShutdown)
|
id: aId,
|
||||||
methods.unshift("shutdown");
|
version: aVersion,
|
||||||
if (aUninstall)
|
installPath: aDir.clone()
|
||||||
methods.unshift("uninstall");
|
};
|
||||||
this.callBootstrapMethod(aId, scope, methods);
|
|
||||||
|
|
||||||
this.addAddonsToCrashReporter();
|
LOG("Calling bootstrap method " + aMethod + " on " + aId + " version " +
|
||||||
|
aVersion);
|
||||||
|
try {
|
||||||
|
this.bootstrapScopes[aId][aMethod](params, aReason);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
WARN("Exception running bootstrap method " + aMethods + " on " +
|
||||||
|
aId + ": " + e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2113,14 +2124,19 @@ var XPIProvider = {
|
||||||
aAddon.active = !isDisabled;
|
aAddon.active = !isDisabled;
|
||||||
XPIDatabase.updateAddonActive(aAddon);
|
XPIDatabase.updateAddonActive(aAddon);
|
||||||
if (isDisabled) {
|
if (isDisabled) {
|
||||||
if (aAddon.type == "bootstrapped")
|
if (aAddon.bootstrap) {
|
||||||
this.deactivateAddon(aAddon.id, false, false);
|
let dir = aAddon._installLocation.getLocationForID(aAddon.id);
|
||||||
|
this.callBootstrapMethod(aAddon.id, aAddon.version, dir, "shutdown",
|
||||||
|
BOOTSTRAP_REASONS.ADDON_DISABLE);
|
||||||
|
this.unloadBootstrapScope(aAddon.id);
|
||||||
|
}
|
||||||
AddonManagerPrivate.callAddonListeners("onDisabled", wrapper);
|
AddonManagerPrivate.callAddonListeners("onDisabled", wrapper);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (aAddon.type == "bootstrapped") {
|
if (aAddon.bootstrap) {
|
||||||
let dir = aAddon._installLocation.getLocationForID(aAddon.id);
|
let dir = aAddon._installLocation.getLocationForID(aAddon.id);
|
||||||
this.activateAddon(aAddon.id, aAddon.version, dir, false, false);
|
this.callBootstrapMethod(aAddon.id, aAddon.version, dir, "startup",
|
||||||
|
BOOTSTRAP_REASONS.ADDON_ENABLE);
|
||||||
}
|
}
|
||||||
AddonManagerPrivate.callAddonListeners("onEnabled", wrapper);
|
AddonManagerPrivate.callAddonListeners("onEnabled", wrapper);
|
||||||
}
|
}
|
||||||
|
@ -2174,8 +2190,16 @@ var XPIProvider = {
|
||||||
requiresRestart);
|
requiresRestart);
|
||||||
|
|
||||||
if (!requiresRestart) {
|
if (!requiresRestart) {
|
||||||
if (aAddon.type == "bootstrapped")
|
if (aAddon.bootstrap) {
|
||||||
this.deactivateAddon(aAddon.id, false, true);
|
let dir = aAddon._installLocation.getLocationForID(aAddon.id);
|
||||||
|
if (aAddon.active) {
|
||||||
|
this.callBootstrapMethod(aAddon.id, aAddon.version, dir, "shutdown",
|
||||||
|
BOOTSTRAP_REASONS.ADDON_UNINSTALL);
|
||||||
|
}
|
||||||
|
this.callBootstrapMethod(aAddon.id, aAddon.version, dir, "uninstall",
|
||||||
|
BOOTSTRAP_REASONS.ADDON_UNINSTALL);
|
||||||
|
this.unloadBootstrapScope(aAddon.id);
|
||||||
|
}
|
||||||
aAddon._installLocation.uninstallAddon(aAddon.id);
|
aAddon._installLocation.uninstallAddon(aAddon.id);
|
||||||
XPIDatabase.removeAddonMetadata(aAddon);
|
XPIDatabase.removeAddonMetadata(aAddon);
|
||||||
AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
|
AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
|
||||||
|
@ -2225,7 +2249,7 @@ const FIELDS_ADDON = "internal_id, id, location, version, type, internalName, "
|
||||||
"updateURL, updateKey, optionsURL, aboutURL, iconURL, " +
|
"updateURL, updateKey, optionsURL, aboutURL, iconURL, " +
|
||||||
"defaultLocale, visible, active, userDisabled, appDisabled, " +
|
"defaultLocale, visible, active, userDisabled, appDisabled, " +
|
||||||
"pendingUninstall, descriptor, installDate, updateDate, " +
|
"pendingUninstall, descriptor, installDate, updateDate, " +
|
||||||
"applyBackgroundUpdates";
|
"applyBackgroundUpdates, bootstrap";
|
||||||
|
|
||||||
// A helper function to simply log any errors that occur during async statements.
|
// A helper function to simply log any errors that occur during async statements.
|
||||||
function asyncErrorLogger(aError) {
|
function asyncErrorLogger(aError) {
|
||||||
|
@ -2261,7 +2285,7 @@ var XPIDatabase = {
|
||||||
":updateKey, :optionsURL, :aboutURL, :iconURL, " +
|
":updateKey, :optionsURL, :aboutURL, :iconURL, " +
|
||||||
":locale, :visible, :active, :userDisabled," +
|
":locale, :visible, :active, :userDisabled," +
|
||||||
" :appDisabled, 0, :descriptor, :installDate, " +
|
" :appDisabled, 0, :descriptor, :installDate, " +
|
||||||
":updateDate, :applyBackgroundUpdates)",
|
":updateDate, :applyBackgroundUpdates, :bootstrap)",
|
||||||
addAddonMetadata_addon_locale: "INSERT INTO addon_locale VALUES " +
|
addAddonMetadata_addon_locale: "INSERT INTO addon_locale VALUES " +
|
||||||
"(:internal_id, :name, :locale)",
|
"(:internal_id, :name, :locale)",
|
||||||
addAddonMetadata_locale: "INSERT INTO locale (name, description, creator, " +
|
addAddonMetadata_locale: "INSERT INTO locale (name, description, creator, " +
|
||||||
|
@ -2278,7 +2302,7 @@ var XPIDatabase = {
|
||||||
"internal_id=:internal_id",
|
"internal_id=:internal_id",
|
||||||
|
|
||||||
getActiveAddons: "SELECT " + FIELDS_ADDON + " FROM addon WHERE active=1 AND " +
|
getActiveAddons: "SELECT " + FIELDS_ADDON + " FROM addon WHERE active=1 AND " +
|
||||||
"type<>'theme' AND type<>'bootstrapped'",
|
"type<>'theme' AND bootstrap=0",
|
||||||
getActiveTheme: "SELECT " + FIELDS_ADDON + " FROM addon WHERE " +
|
getActiveTheme: "SELECT " + FIELDS_ADDON + " FROM addon WHERE " +
|
||||||
"internalName=:internalName AND type='theme'",
|
"internalName=:internalName AND type='theme'",
|
||||||
|
|
||||||
|
@ -2299,7 +2323,8 @@ var XPIDatabase = {
|
||||||
|
|
||||||
makeAddonVisible: "UPDATE addon SET visible=1 WHERE internal_id=:internal_id",
|
makeAddonVisible: "UPDATE addon SET visible=1 WHERE internal_id=:internal_id",
|
||||||
removeAddonMetadata: "DELETE FROM addon WHERE internal_id=:internal_id",
|
removeAddonMetadata: "DELETE FROM addon WHERE internal_id=:internal_id",
|
||||||
// Equates to active = visible && !userDisabled && !appDisabled && !pendingUninstall
|
// Equates to active = visible && !userDisabled && !appDisabled &&
|
||||||
|
// !pendingUninstall
|
||||||
setActiveAddons: "UPDATE addon SET active=MIN(visible, 1 - userDisabled, " +
|
setActiveAddons: "UPDATE addon SET active=MIN(visible, 1 - userDisabled, " +
|
||||||
"1 - appDisabled, 1 - pendingUninstall)",
|
"1 - appDisabled, 1 - pendingUninstall)",
|
||||||
setAddonProperties: "UPDATE addon SET userDisabled=:userDisabled, " +
|
setAddonProperties: "UPDATE addon SET userDisabled=:userDisabled, " +
|
||||||
|
@ -2369,9 +2394,11 @@ var XPIDatabase = {
|
||||||
if (disabled == "true" || disabled == "needs-disable")
|
if (disabled == "true" || disabled == "needs-disable")
|
||||||
migrateData[location][id].userDisabled = true;
|
migrateData[location][id].userDisabled = true;
|
||||||
|
|
||||||
let targetApps = ds.GetTargets(source, EM_R("targetApplication"), true);
|
let targetApps = ds.GetTargets(source, EM_R("targetApplication"),
|
||||||
|
true);
|
||||||
while (targetApps.hasMoreElements()) {
|
while (targetApps.hasMoreElements()) {
|
||||||
let targetApp = targetApps.getNext().QueryInterface(Ci.nsIRDFResource);
|
let targetApp = targetApps.getNext()
|
||||||
|
.QueryInterface(Ci.nsIRDFResource);
|
||||||
let appInfo = {
|
let appInfo = {
|
||||||
id: getRDFProperty(ds, targetApp, "id"),
|
id: getRDFProperty(ds, targetApp, "id"),
|
||||||
minVersion: getRDFProperty(ds, targetApp, "minVersion"),
|
minVersion: getRDFProperty(ds, targetApp, "minVersion"),
|
||||||
|
@ -2482,7 +2509,7 @@ var XPIDatabase = {
|
||||||
"pendingUninstall INTEGER, descriptor TEXT, " +
|
"pendingUninstall INTEGER, descriptor TEXT, " +
|
||||||
"installDate INTEGER, updateDate INTEGER, " +
|
"installDate INTEGER, updateDate INTEGER, " +
|
||||||
"applyBackgroundUpdates INTEGER, " +
|
"applyBackgroundUpdates INTEGER, " +
|
||||||
"UNIQUE (id, location)");
|
"bootstrap INTEGER, UNIQUE (id, location)");
|
||||||
this.connection.createTable("targetApplication",
|
this.connection.createTable("targetApplication",
|
||||||
"addon_internal_id INTEGER, " +
|
"addon_internal_id INTEGER, " +
|
||||||
"id TEXT, minVersion TEXT, maxVersion TEXT, " +
|
"id TEXT, minVersion TEXT, maxVersion TEXT, " +
|
||||||
|
@ -2618,7 +2645,8 @@ var XPIDatabase = {
|
||||||
addon.installDate = aRow.installDate;
|
addon.installDate = aRow.installDate;
|
||||||
addon.updateDate = aRow.updateDate;
|
addon.updateDate = aRow.updateDate;
|
||||||
["visible", "active", "userDisabled", "appDisabled",
|
["visible", "active", "userDisabled", "appDisabled",
|
||||||
"pendingUninstall", "applyBackgroundUpdates"].forEach(function(aProp) {
|
"pendingUninstall", "applyBackgroundUpdates",
|
||||||
|
"bootstrap"].forEach(function(aProp) {
|
||||||
addon[aProp] = aRow[aProp] != 0;
|
addon[aProp] = aRow[aProp] != 0;
|
||||||
});
|
});
|
||||||
this.addonCache[aRow.internal_id] = Components.utils.getWeakReference(addon);
|
this.addonCache[aRow.internal_id] = Components.utils.getWeakReference(addon);
|
||||||
|
@ -2768,7 +2796,8 @@ var XPIDatabase = {
|
||||||
addon.installDate = aRow.getResultByName("installDate");
|
addon.installDate = aRow.getResultByName("installDate");
|
||||||
addon.updateDate = aRow.getResultByName("updateDate");
|
addon.updateDate = aRow.getResultByName("updateDate");
|
||||||
["visible", "active", "userDisabled", "appDisabled",
|
["visible", "active", "userDisabled", "appDisabled",
|
||||||
"pendingUninstall", "applyBackgroundUpdates"].forEach(function(aProp) {
|
"pendingUninstall", "applyBackgroundUpdates",
|
||||||
|
"bootstrap"].forEach(function(aProp) {
|
||||||
addon[aProp] = aRow.getResultByName(aProp) != 0;
|
addon[aProp] = aRow.getResultByName(aProp) != 0;
|
||||||
});
|
});
|
||||||
this.addonCache[internal_id] = Components.utils.getWeakReference(addon);
|
this.addonCache[internal_id] = Components.utils.getWeakReference(addon);
|
||||||
|
@ -3042,8 +3071,8 @@ var XPIDatabase = {
|
||||||
stmt.params.installDate = aAddon.installDate;
|
stmt.params.installDate = aAddon.installDate;
|
||||||
stmt.params.updateDate = aAddon.updateDate;
|
stmt.params.updateDate = aAddon.updateDate;
|
||||||
copyProperties(aAddon, PROP_METADATA, stmt.params);
|
copyProperties(aAddon, PROP_METADATA, stmt.params);
|
||||||
["visible", "userDisabled", "appDisabled",
|
["visible", "userDisabled", "appDisabled", "applyBackgroundUpdates",
|
||||||
"applyBackgroundUpdates"].forEach(function(aProp) {
|
"bootstrap"].forEach(function(aProp) {
|
||||||
stmt.params[aProp] = aAddon[aProp] ? 1 : 0;
|
stmt.params[aProp] = aAddon[aProp] ? 1 : 0;
|
||||||
});
|
});
|
||||||
stmt.params.active = (aAddon.visible && !aAddon.userDisabled &&
|
stmt.params.active = (aAddon.visible && !aAddon.userDisabled &&
|
||||||
|
@ -3842,19 +3871,34 @@ AddonInstall.prototype = {
|
||||||
// See bug 553015.
|
// See bug 553015.
|
||||||
|
|
||||||
// Deactivate and remove the old add-on as necessary
|
// Deactivate and remove the old add-on as necessary
|
||||||
|
let reason = BOOTSTRAP_REASONS.ADDON_INSTALL;
|
||||||
if (this.existingAddon) {
|
if (this.existingAddon) {
|
||||||
if (this.existingAddon.active) {
|
if (Services.vc.compare(this.existingAddon.version, this.addon.version) < 0)
|
||||||
if (this.existingAddon.type == "bootstrapped")
|
reason = BOOTSTRAP_REASONS.ADDON_UPGRADE;
|
||||||
XPIProvider.deactivateAddon(this.existingAddon.id, false,
|
else
|
||||||
isUpgrade);
|
reason = BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||||
// If this is an upgrade its metadata will be removed below
|
|
||||||
if (!isUpgrade) {
|
if (this.existingAddon.bootstrap) {
|
||||||
this.existingAddon.active = false;
|
let dir = this.existingAddon._installLocation
|
||||||
XPIDatabase.updateAddonActive(this.existingAddon);
|
.getLocationForID(this.existingAddon.id);
|
||||||
|
if (this.existingAddon.active) {
|
||||||
|
XPIProvider.callBootstrapMethod(this.existingAddon.id,
|
||||||
|
this.existingAddon.version,
|
||||||
|
dir, "shutdown", reason);
|
||||||
}
|
}
|
||||||
|
XPIProvider.callBootstrapMethod(this.existingAddon.id,
|
||||||
|
this.existingAddon.version,
|
||||||
|
dir, "uninstall", reason);
|
||||||
|
XPIProvider.unloadBootstrapScope(this.existingAddon.id);
|
||||||
}
|
}
|
||||||
if (isUpgrade)
|
|
||||||
|
if (isUpgrade) {
|
||||||
this.installLocation.uninstallAddon(this.existingAddon.id);
|
this.installLocation.uninstallAddon(this.existingAddon.id);
|
||||||
|
}
|
||||||
|
else if (this.existingAddon.active) {
|
||||||
|
this.existingAddon.active = false;
|
||||||
|
XPIDatabase.updateAddonActive(this.existingAddon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install the new add-on into its final directory
|
// Install the new add-on into its final directory
|
||||||
|
@ -3878,8 +3922,17 @@ AddonInstall.prototype = {
|
||||||
XPIDatabase.getAddonInLocation(this.addon.id, this.installLocation.name,
|
XPIDatabase.getAddonInLocation(this.addon.id, this.installLocation.name,
|
||||||
function(a) {
|
function(a) {
|
||||||
self.addon = a;
|
self.addon = a;
|
||||||
if (self.addon.active && self.addon.type == "bootstrapped")
|
if (self.addon.bootstrap) {
|
||||||
XPIProvider.activateAddon(self.addon.id, self.addon.version, dir, false, true);
|
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
|
||||||
|
dir, "install", reason);
|
||||||
|
if (self.addon.active) {
|
||||||
|
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
|
||||||
|
dir, "startup", reason);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.unloadBootstrapScope(self.addon.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
AddonManagerPrivate.callAddonListeners("onInstalled",
|
AddonManagerPrivate.callAddonListeners("onInstalled",
|
||||||
createWrapper(self.addon));
|
createWrapper(self.addon));
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
function enable() {
|
function install(data, reason) {
|
||||||
Services.prefs.setIntPref("bootstraptest.version", 1);
|
Services.prefs.setIntPref("bootstraptest.installed_version", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable() {
|
function startup(data, reason) {
|
||||||
Services.prefs.setIntPref("bootstraptest.version", 0);
|
Services.prefs.setIntPref("bootstraptest.active_version", 1);
|
||||||
|
Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shutdown(data, reason) {
|
||||||
|
Services.prefs.setIntPref("bootstraptest.active_version", 0);
|
||||||
|
Services.prefs.setIntPref("bootstraptest.shutdown_reason", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstall(data, reason) {
|
||||||
|
Services.prefs.setIntPref("bootstraptest.installed_version", 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<Description about="urn:mozilla:install-manifest">
|
<Description about="urn:mozilla:install-manifest">
|
||||||
<em:id>bootstrap1@tests.mozilla.org</em:id>
|
<em:id>bootstrap1@tests.mozilla.org</em:id>
|
||||||
<em:version>1.0</em:version>
|
<em:version>1.0</em:version>
|
||||||
<em:type>64</em:type>
|
<em:bootstrap>true</em:bootstrap>
|
||||||
|
|
||||||
<!-- Front End MetaData -->
|
<!-- Front End MetaData -->
|
||||||
<em:name>Test Bootstrap 1</em:name>
|
<em:name>Test Bootstrap 1</em:name>
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
function enable() {
|
function install(data, reason) {
|
||||||
Services.prefs.setIntPref("bootstraptest.version", 2);
|
Services.prefs.setIntPref("bootstraptest.installed_version", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable() {
|
function startup(data, reason) {
|
||||||
Services.prefs.setIntPref("bootstraptest.version", 0);
|
Services.prefs.setIntPref("bootstraptest.active_version", 2);
|
||||||
|
Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shutdown(data, reason) {
|
||||||
|
Services.prefs.setIntPref("bootstraptest.active_version", 0);
|
||||||
|
Services.prefs.setIntPref("bootstraptest.shutdown_reason", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstall(data, reason) {
|
||||||
|
Services.prefs.setIntPref("bootstraptest.installed_version", 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<Description about="urn:mozilla:install-manifest">
|
<Description about="urn:mozilla:install-manifest">
|
||||||
<em:id>bootstrap1@tests.mozilla.org</em:id>
|
<em:id>bootstrap1@tests.mozilla.org</em:id>
|
||||||
<em:version>2.0</em:version>
|
<em:version>2.0</em:version>
|
||||||
<em:type>64</em:type>
|
<em:bootstrap>true</em:bootstrap>
|
||||||
|
|
||||||
<!-- Front End MetaData -->
|
<!-- Front End MetaData -->
|
||||||
<em:name>Test Bootstrap 1</em:name>
|
<em:name>Test Bootstrap 1</em:name>
|
||||||
|
|
|
@ -2,6 +2,15 @@
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const APP_STARTUP = 1;
|
||||||
|
const APP_SHUTDOWN = 2;
|
||||||
|
const ADDON_ENABLE = 3;
|
||||||
|
const ADDON_DISABLE = 4;
|
||||||
|
const ADDON_INSTALL = 5;
|
||||||
|
const ADDON_UNINSTALL = 6;
|
||||||
|
const ADDON_UPGRADE = 7;
|
||||||
|
const ADDON_DOWNGRADE = 8;
|
||||||
|
|
||||||
// This verifies that bootstrappable add-ons can be used with restarts.
|
// This verifies that bootstrappable add-ons can be used with restarts.
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
@ -10,8 +19,20 @@ Services.prefs.setIntPref("bootstraptest.version", 0);
|
||||||
const profileDir = gProfD.clone();
|
const profileDir = gProfD.clone();
|
||||||
profileDir.append("extensions");
|
profileDir.append("extensions");
|
||||||
|
|
||||||
function getActivatedVersion() {
|
function getActiveVersion() {
|
||||||
return Services.prefs.getIntPref("bootstraptest.version");
|
return Services.prefs.getIntPref("bootstraptest.active_version");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInstalledVersion() {
|
||||||
|
return Services.prefs.getIntPref("bootstraptest.installed_version");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStartupReason() {
|
||||||
|
return Services.prefs.getIntPref("bootstraptest.startup_reason");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getShutdownReason() {
|
||||||
|
return Services.prefs.getIntPref("bootstraptest.shutdown_reason");
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
|
@ -33,7 +54,7 @@ function run_test_1() {
|
||||||
ensure_test_completed();
|
ensure_test_completed();
|
||||||
|
|
||||||
do_check_neq(install, null);
|
do_check_neq(install, null);
|
||||||
do_check_eq(install.type, "bootstrapped");
|
do_check_eq(install.type, "extension");
|
||||||
do_check_eq(install.version, "1.0");
|
do_check_eq(install.version, "1.0");
|
||||||
do_check_eq(install.name, "Test Bootstrap 1");
|
do_check_eq(install.name, "Test Bootstrap 1");
|
||||||
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
|
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
|
||||||
|
@ -62,7 +83,9 @@ function check_test_1() {
|
||||||
do_check_false(b1.appDisabled);
|
do_check_false(b1.appDisabled);
|
||||||
do_check_false(b1.userDisabled);
|
do_check_false(b1.userDisabled);
|
||||||
do_check_true(b1.isActive);
|
do_check_true(b1.isActive);
|
||||||
do_check_eq(getActivatedVersion(), 1);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 1);
|
||||||
|
do_check_eq(getStartupReason(), ADDON_INSTALL);
|
||||||
do_check_true(b1.hasResource("install.rdf"));
|
do_check_true(b1.hasResource("install.rdf"));
|
||||||
do_check_true(b1.hasResource("bootstrap.js"));
|
do_check_true(b1.hasResource("bootstrap.js"));
|
||||||
do_check_false(b1.hasResource("foo.bar"));
|
do_check_false(b1.hasResource("foo.bar"));
|
||||||
|
@ -100,7 +123,9 @@ function run_test_2() {
|
||||||
do_check_false(b1.appDisabled);
|
do_check_false(b1.appDisabled);
|
||||||
do_check_true(b1.userDisabled);
|
do_check_true(b1.userDisabled);
|
||||||
do_check_false(b1.isActive);
|
do_check_false(b1.isActive);
|
||||||
do_check_eq(getActivatedVersion(), 0);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_DISABLE);
|
||||||
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(newb1) {
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(newb1) {
|
||||||
|
@ -118,9 +143,13 @@ function run_test_2() {
|
||||||
// Test that restarting doesn't accidentally re-enable
|
// Test that restarting doesn't accidentally re-enable
|
||||||
function run_test_3() {
|
function run_test_3() {
|
||||||
shutdownManager();
|
shutdownManager();
|
||||||
do_check_eq(getActivatedVersion(), 0);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_DISABLE);
|
||||||
startupManager(0, false);
|
startupManager(0, false);
|
||||||
do_check_eq(getActivatedVersion(), 0);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_DISABLE);
|
||||||
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||||
|
@ -152,7 +181,9 @@ function run_test_4() {
|
||||||
do_check_false(b1.appDisabled);
|
do_check_false(b1.appDisabled);
|
||||||
do_check_false(b1.userDisabled);
|
do_check_false(b1.userDisabled);
|
||||||
do_check_true(b1.isActive);
|
do_check_true(b1.isActive);
|
||||||
do_check_eq(getActivatedVersion(), 1);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 1);
|
||||||
|
do_check_eq(getStartupReason(), ADDON_ENABLE);
|
||||||
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(newb1) {
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(newb1) {
|
||||||
|
@ -170,10 +201,14 @@ function run_test_4() {
|
||||||
// Tests that a restart shuts down and restarts the add-on
|
// Tests that a restart shuts down and restarts the add-on
|
||||||
function run_test_5() {
|
function run_test_5() {
|
||||||
shutdownManager();
|
shutdownManager();
|
||||||
do_check_eq(getActivatedVersion(), 0);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_eq(getShutdownReason(), APP_SHUTDOWN);
|
||||||
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
startupManager(0, false);
|
startupManager(0, false);
|
||||||
do_check_eq(getActivatedVersion(), 1);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 1);
|
||||||
|
do_check_eq(getStartupReason(), APP_STARTUP);
|
||||||
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||||
|
@ -198,7 +233,7 @@ function run_test_6() {
|
||||||
ensure_test_completed();
|
ensure_test_completed();
|
||||||
|
|
||||||
do_check_neq(install, null);
|
do_check_neq(install, null);
|
||||||
do_check_eq(install.type, "bootstrapped");
|
do_check_eq(install.type, "extension");
|
||||||
do_check_eq(install.version, "2.0");
|
do_check_eq(install.version, "2.0");
|
||||||
do_check_eq(install.name, "Test Bootstrap 1");
|
do_check_eq(install.name, "Test Bootstrap 1");
|
||||||
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
|
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
|
||||||
|
@ -223,7 +258,10 @@ function check_test_6() {
|
||||||
do_check_false(b1.appDisabled);
|
do_check_false(b1.appDisabled);
|
||||||
do_check_false(b1.userDisabled);
|
do_check_false(b1.userDisabled);
|
||||||
do_check_true(b1.isActive);
|
do_check_true(b1.isActive);
|
||||||
do_check_eq(getActivatedVersion(), 2);
|
do_check_eq(getInstalledVersion(), 2);
|
||||||
|
do_check_eq(getActiveVersion(), 2);
|
||||||
|
do_check_eq(getStartupReason(), ADDON_UPGRADE);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_UPGRADE);
|
||||||
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
||||||
|
|
||||||
|
@ -249,7 +287,9 @@ function run_test_7() {
|
||||||
|
|
||||||
function check_test_7() {
|
function check_test_7() {
|
||||||
ensure_test_completed();
|
ensure_test_completed();
|
||||||
do_check_eq(getActivatedVersion(), 0);
|
do_check_eq(getInstalledVersion(), 0);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_UNINSTALL);
|
||||||
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
||||||
|
|
||||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||||
|
@ -291,7 +331,9 @@ function run_test_8() {
|
||||||
do_check_false(b1.appDisabled);
|
do_check_false(b1.appDisabled);
|
||||||
do_check_false(b1.userDisabled);
|
do_check_false(b1.userDisabled);
|
||||||
do_check_true(b1.isActive);
|
do_check_true(b1.isActive);
|
||||||
do_check_eq(getActivatedVersion(), 1);
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 1);
|
||||||
|
do_check_eq(getStartupReason(), APP_STARTUP);
|
||||||
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
run_test_9();
|
run_test_9();
|
||||||
|
@ -311,6 +353,133 @@ function run_test_9() {
|
||||||
do_check_eq(b1, null);
|
do_check_eq(b1, null);
|
||||||
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
do_test_finished();
|
run_test_10();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tests that installing a downgrade sends the right reason
|
||||||
|
function run_test_10() {
|
||||||
|
prepare_test({ }, [
|
||||||
|
"onNewInstall"
|
||||||
|
]);
|
||||||
|
|
||||||
|
AddonManager.getInstallForFile(do_get_addon("test_bootstrap1_2"), function(install) {
|
||||||
|
ensure_test_completed();
|
||||||
|
|
||||||
|
do_check_neq(install, null);
|
||||||
|
do_check_eq(install.type, "extension");
|
||||||
|
do_check_eq(install.version, "2.0");
|
||||||
|
do_check_eq(install.name, "Test Bootstrap 1");
|
||||||
|
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
|
||||||
|
do_check_true(install.addon.hasResource("install.rdf"));
|
||||||
|
do_check_true(install.addon.hasResource("bootstrap.js"));
|
||||||
|
do_check_false(install.addon.hasResource("foo.bar"));
|
||||||
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
||||||
|
|
||||||
|
prepare_test({
|
||||||
|
"bootstrap1@tests.mozilla.org": [
|
||||||
|
["onInstalling", false],
|
||||||
|
"onInstalled"
|
||||||
|
]
|
||||||
|
}, [
|
||||||
|
"onInstallStarted",
|
||||||
|
"onInstallEnded",
|
||||||
|
], check_test_10_pt1);
|
||||||
|
install.install();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_test_10_pt1() {
|
||||||
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||||
|
do_check_neq(b1, null);
|
||||||
|
do_check_eq(b1.version, "2.0");
|
||||||
|
do_check_false(b1.appDisabled);
|
||||||
|
do_check_false(b1.userDisabled);
|
||||||
|
do_check_true(b1.isActive);
|
||||||
|
do_check_eq(getInstalledVersion(), 2);
|
||||||
|
do_check_eq(getActiveVersion(), 2);
|
||||||
|
do_check_eq(getStartupReason(), ADDON_INSTALL);
|
||||||
|
do_check_true(b1.hasResource("install.rdf"));
|
||||||
|
do_check_true(b1.hasResource("bootstrap.js"));
|
||||||
|
do_check_false(b1.hasResource("foo.bar"));
|
||||||
|
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
||||||
|
|
||||||
|
prepare_test({ }, [
|
||||||
|
"onNewInstall"
|
||||||
|
]);
|
||||||
|
|
||||||
|
AddonManager.getInstallForFile(do_get_addon("test_bootstrap1_1"), function(install) {
|
||||||
|
ensure_test_completed();
|
||||||
|
|
||||||
|
do_check_neq(install, null);
|
||||||
|
do_check_eq(install.type, "extension");
|
||||||
|
do_check_eq(install.version, "1.0");
|
||||||
|
do_check_eq(install.name, "Test Bootstrap 1");
|
||||||
|
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
|
||||||
|
|
||||||
|
prepare_test({
|
||||||
|
"bootstrap1@tests.mozilla.org": [
|
||||||
|
["onInstalling", false],
|
||||||
|
"onInstalled"
|
||||||
|
]
|
||||||
|
}, [
|
||||||
|
"onInstallStarted",
|
||||||
|
"onInstallEnded",
|
||||||
|
], check_test_10_pt2);
|
||||||
|
install.install();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_test_10_pt2() {
|
||||||
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||||
|
do_check_neq(b1, null);
|
||||||
|
do_check_eq(b1.version, "1.0");
|
||||||
|
do_check_false(b1.appDisabled);
|
||||||
|
do_check_false(b1.userDisabled);
|
||||||
|
do_check_true(b1.isActive);
|
||||||
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 1);
|
||||||
|
do_check_eq(getStartupReason(), ADDON_DOWNGRADE);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_DOWNGRADE);
|
||||||
|
do_check_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "2.0");
|
||||||
|
|
||||||
|
run_test_11();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that uninstalling a disabled add-on still calls the uninstall method
|
||||||
|
function run_test_11() {
|
||||||
|
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||||
|
prepare_test({
|
||||||
|
"bootstrap1@tests.mozilla.org": [
|
||||||
|
["onDisabling", false],
|
||||||
|
"onDisabled",
|
||||||
|
["onUninstalling", false],
|
||||||
|
"onUninstalled"
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
b1.userDisabled = true;
|
||||||
|
|
||||||
|
do_check_eq(getInstalledVersion(), 1);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_eq(getShutdownReason(), ADDON_DISABLE);
|
||||||
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
|
b1.uninstall();
|
||||||
|
|
||||||
|
check_test_11();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_test_11() {
|
||||||
|
ensure_test_completed();
|
||||||
|
do_check_eq(getInstalledVersion(), 0);
|
||||||
|
do_check_eq(getActiveVersion(), 0);
|
||||||
|
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
|
||||||
|
|
||||||
|
do_test_finished();
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче