mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 06:45:42 +00:00
Bug 553017: Make revealing and hiding bootstrapped add-ons in non-profile install locations work correctly. r=robstrong, a=blocks-final
This commit is contained in:
parent
e8a5ffb557
commit
666a25ba40
@ -1853,13 +1853,22 @@ var XPIProvider = {
|
||||
XPIDatabase.updateAddonMetadata(aOldAddon, newAddon, aAddonState.descriptor);
|
||||
if (newAddon.visible) {
|
||||
visibleAddons[newAddon.id] = newAddon;
|
||||
// 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
|
||||
// restart
|
||||
if ((aOldAddon.active && !aOldAddon.bootstrap) ||
|
||||
(newAddon.active && !newAddon.bootstrap)) {
|
||||
return true;
|
||||
|
||||
// If the new add-on is bootstrapped and active then call its install method
|
||||
if (newAddon.active && newAddon.bootstrap) {
|
||||
let installReason = Services.vc.compare(aOldAddon.version, newAddon.version) < 0 ?
|
||||
BOOTSTRAP_REASONS.ADDON_UPGRADE :
|
||||
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.persistentDescriptor = aAddonState.descriptor;
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, file,
|
||||
"install", installReason);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise the caches will need to be invalidated
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1892,16 +1901,23 @@ var XPIProvider = {
|
||||
if (!aOldAddon.visible) {
|
||||
XPIDatabase.makeAddonVisible(aOldAddon);
|
||||
|
||||
// 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.
|
||||
if (aOldAddon.bootstrap && !aOldAddon.appDisabled &&
|
||||
!aOldAddon.userDisabled) {
|
||||
aOldAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aOldAddon);
|
||||
XPIProvider.bootstrappedAddons[aOldAddon.id] = {
|
||||
version: aOldAddon.version,
|
||||
descriptor: aAddonState.descriptor
|
||||
};
|
||||
if (aOldAddon.bootstrap) {
|
||||
// The add-on is bootstrappable so call its install script
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.persistentDescriptor = aAddonState.descriptor;
|
||||
XPIProvider.callBootstrapMethod(aOldAddon.id, aOldAddon.version, file,
|
||||
"install",
|
||||
BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||
|
||||
// If it should be active then mark it as active otherwise unload
|
||||
// its scope
|
||||
if (!aOldAddon.appDisabled && !aOldAddon.userDisabled) {
|
||||
aOldAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aOldAddon);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise a restart is necessary
|
||||
@ -1988,7 +2004,11 @@ var XPIProvider = {
|
||||
if (!aOldAddon.bootstrap)
|
||||
return true;
|
||||
|
||||
XPIProvider.unloadBootstrapScope(aOldAddon.id);
|
||||
// If this is the currently active bootstrapped add-on for this ID then
|
||||
// remove it from the list.
|
||||
if (aOldAddon.id in XPIProvider.bootstrappedAddons &&
|
||||
XPIProvider.bootstrappedAddons[aOldAddon.id].descriptor == aOldAddon._descriptor)
|
||||
XPIProvider.unloadBootstrapScope(aOldAddon.id);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -2083,6 +2103,26 @@ var XPIProvider = {
|
||||
XPIProvider.allAppGlobal = false;
|
||||
|
||||
visibleAddons[newAddon.id] = newAddon;
|
||||
|
||||
let installReason = BOOTSTRAP_REASONS.ADDON_INSTALL;
|
||||
|
||||
// If we're hiding a bootstrapped add-on then call its uninstall method
|
||||
if (newAddon.id in XPIProvider.bootstrappedAddons) {
|
||||
let oldBootstrap = XPIProvider.bootstrappedAddons[newAddon.id];
|
||||
|
||||
installReason = Services.vc.compare(oldBootstrap.version, newAddon.version) < 0 ?
|
||||
BOOTSTRAP_REASONS.ADDON_UPGRADE :
|
||||
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||
|
||||
let oldAddonFile = Cc["@mozilla.org/file/local;1"].
|
||||
createInstance(Ci.nsILocalFile);
|
||||
oldAddonFile.persistentDescriptor = oldBootstrap.descriptor;
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, oldBootstrap.version,
|
||||
oldAddonFile, "uninstall",
|
||||
installReason);
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
}
|
||||
|
||||
if (!newAddon.bootstrap)
|
||||
return true;
|
||||
|
||||
@ -2090,8 +2130,7 @@ var XPIProvider = {
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.persistentDescriptor = aAddonState.descriptor;
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, file,
|
||||
"install",
|
||||
BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||
"install", installReason);
|
||||
if (!newAddon.active)
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
}
|
||||
@ -3037,7 +3076,53 @@ var XPIProvider = {
|
||||
aAddon._installLocation.uninstallAddon(aAddon.id);
|
||||
XPIDatabase.removeAddonMetadata(aAddon);
|
||||
AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
|
||||
// TODO reveal hidden add-ons (bug 557710)
|
||||
|
||||
// Reveal the highest priority add-on with the same ID
|
||||
function revealAddon(aAddon) {
|
||||
XPIDatabase.makeAddonVisible(aAddon);
|
||||
|
||||
let wrappedAddon = createWrapper(aAddon);
|
||||
AddonManagerPrivate.callAddonListeners("onInstalling", wrappedAddon, false);
|
||||
|
||||
if (!aAddon.userDisabled && !aAddon.appDisabled &&
|
||||
!XPIProvider.enableRequiresRestart(aAddon)) {
|
||||
aAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aAddon);
|
||||
}
|
||||
|
||||
if (aAddon.bootstrap) {
|
||||
let file = aAddon._installLocation.getLocationForID(aAddon.id);
|
||||
XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file,
|
||||
"install", BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||
|
||||
if (aAddon.active) {
|
||||
XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file,
|
||||
"startup", BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(aAddon.id);
|
||||
}
|
||||
}
|
||||
|
||||
// We always send onInstalled even if a restart is required to enable
|
||||
// the revealed add-on
|
||||
AddonManagerPrivate.callAddonListeners("onInstalled", wrappedAddon);
|
||||
}
|
||||
|
||||
function checkInstallLocation(aPos) {
|
||||
if (aPos < 0)
|
||||
return;
|
||||
|
||||
let location = XPIProvider.installLocations[aPos];
|
||||
XPIDatabase.getAddonInLocation(aAddon.id, location.name, function(aNewAddon) {
|
||||
if (aNewAddon)
|
||||
revealAddon(aNewAddon);
|
||||
else
|
||||
checkInstallLocation(aPos - 1);
|
||||
})
|
||||
}
|
||||
|
||||
checkInstallLocation(this.installLocations.length - 1);
|
||||
}
|
||||
|
||||
// Notify any other providers that a new theme has been enabled
|
||||
|
@ -2,6 +2,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function install(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 1);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", reason);
|
||||
}
|
||||
|
||||
function startup(data, reason) {
|
||||
@ -16,4 +17,5 @@ function shutdown(data, reason) {
|
||||
|
||||
function uninstall(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 0);
|
||||
Services.prefs.setIntPref("bootstraptest.uninstall_reason", reason);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function install(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 2);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", reason);
|
||||
}
|
||||
|
||||
function startup(data, reason) {
|
||||
@ -16,4 +17,5 @@ function shutdown(data, reason) {
|
||||
|
||||
function uninstall(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 0);
|
||||
Services.prefs.setIntPref("bootstraptest.uninstall_reason", reason);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function install(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 3);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", reason);
|
||||
}
|
||||
|
||||
function startup(data, reason) {
|
||||
@ -16,4 +17,5 @@ function shutdown(data, reason) {
|
||||
|
||||
function uninstall(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 0);
|
||||
Services.prefs.setIntPref("bootstraptest.uninstall_reason", reason);
|
||||
}
|
||||
|
@ -14,10 +14,27 @@ const ADDON_DOWNGRADE = 8;
|
||||
// This verifies that bootstrappable add-ons can be used without restarts.
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
Services.prefs.setIntPref("bootstraptest.version", 0);
|
||||
// Enable loading extensions from the user scopes
|
||||
Services.prefs.setIntPref("extensions.enabledScopes",
|
||||
AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_USER);
|
||||
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
const userExtDir = gProfD.clone();
|
||||
userExtDir.append("extensions2");
|
||||
userExtDir.append(gAppInfo.ID);
|
||||
registerDirectory("XREUSysExt", userExtDir.parent);
|
||||
|
||||
function resetPrefs() {
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", -1);
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", -1);
|
||||
Services.prefs.setIntPref("bootstraptest.startup_reason", -1);
|
||||
Services.prefs.setIntPref("bootstraptest.shutdown_reason", -1);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", -1);
|
||||
Services.prefs.setIntPref("bootstraptest.uninstall_reason", -1);
|
||||
}
|
||||
|
||||
function getActiveVersion() {
|
||||
return Services.prefs.getIntPref("bootstraptest.active_version");
|
||||
@ -35,9 +52,18 @@ function getShutdownReason() {
|
||||
return Services.prefs.getIntPref("bootstraptest.shutdown_reason");
|
||||
}
|
||||
|
||||
function getInstallReason() {
|
||||
return Services.prefs.getIntPref("bootstraptest.install_reason");
|
||||
}
|
||||
|
||||
function getUninstallReason() {
|
||||
return Services.prefs.getIntPref("bootstraptest.uninstall_reason");
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
||||
resetPrefs();
|
||||
|
||||
startupManager();
|
||||
|
||||
@ -746,8 +772,252 @@ function run_test_16() {
|
||||
do_check_eq(getInstalledVersion(), 1);
|
||||
do_check_eq(getActiveVersion(), 1);
|
||||
|
||||
do_test_finished();
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
b1.uninstall();
|
||||
|
||||
run_test_17();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Check that a bootstrapped extension in a non-profile location is loaded
|
||||
function run_test_17() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = userExtDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_1"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
|
||||
resetPrefs();
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have installed and started
|
||||
do_check_eq(getInstalledVersion(), 1);
|
||||
do_check_eq(getActiveVersion(), 1);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "1.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
run_test_18();
|
||||
});
|
||||
}
|
||||
|
||||
// Check that installing a new bootstrapped extension in the profile replaces
|
||||
// the existing one
|
||||
function run_test_18() {
|
||||
resetPrefs();
|
||||
installAllFiles([do_get_addon("test_bootstrap1_2")], function() {
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have installed and started
|
||||
do_check_eq(getInstalledVersion(), 2);
|
||||
do_check_eq(getActiveVersion(), 2);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "2.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
do_check_eq(getShutdownReason(), ADDON_UPGRADE);
|
||||
do_check_eq(getUninstallReason(), ADDON_UPGRADE);
|
||||
do_check_eq(getInstallReason(), ADDON_UPGRADE);
|
||||
do_check_eq(getStartupReason(), ADDON_UPGRADE);
|
||||
|
||||
run_test_19();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Check that uninstalling the profile version reveals the non-profile one
|
||||
function run_test_19() {
|
||||
resetPrefs();
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// The revealed add-on gets activated asynchronously
|
||||
prepare_test({
|
||||
"bootstrap1@tests.mozilla.org": [
|
||||
["onUninstalling", false],
|
||||
"onUninstalled",
|
||||
["onInstalling", false],
|
||||
"onInstalled"
|
||||
]
|
||||
}, [], check_test_19);
|
||||
|
||||
b1.uninstall();
|
||||
});
|
||||
}
|
||||
|
||||
function check_test_19() {
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have reverted to the older version
|
||||
do_check_eq(getInstalledVersion(), 1);
|
||||
do_check_eq(getActiveVersion(), 1);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "1.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
// TODO these reasons really should be ADDON_DOWNGRADE (bug 607818)
|
||||
do_check_eq(getShutdownReason(), ADDON_UNINSTALL);
|
||||
do_check_eq(getUninstallReason(), ADDON_UNINSTALL);
|
||||
do_check_eq(getInstallReason(), ADDON_INSTALL);
|
||||
do_check_eq(getStartupReason(), ADDON_INSTALL);
|
||||
|
||||
run_test_20();
|
||||
});
|
||||
}
|
||||
|
||||
// Check that a new profile extension detected at startup replaces the non-profile
|
||||
// one
|
||||
function run_test_20() {
|
||||
resetPrefs();
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_2"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have installed and started
|
||||
do_check_eq(getInstalledVersion(), 2);
|
||||
do_check_eq(getActiveVersion(), 2);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "2.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
do_check_eq(getShutdownReason(), APP_SHUTDOWN);
|
||||
do_check_eq(getUninstallReason(), ADDON_UPGRADE);
|
||||
do_check_eq(getInstallReason(), ADDON_UPGRADE);
|
||||
do_check_eq(getStartupReason(), APP_STARTUP);
|
||||
|
||||
run_test_21();
|
||||
});
|
||||
}
|
||||
|
||||
// Check that a detected removal reveals the non-profile one
|
||||
function run_test_21() {
|
||||
resetPrefs();
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.remove(true);
|
||||
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have installed and started
|
||||
do_check_eq(getInstalledVersion(), 1);
|
||||
do_check_eq(getActiveVersion(), 1);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "1.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
do_check_eq(getShutdownReason(), APP_SHUTDOWN);
|
||||
|
||||
// This won't be set as the bootstrap script was gone so we couldn't
|
||||
// uninstall it properly
|
||||
do_check_eq(getUninstallReason(), -1);
|
||||
|
||||
// TODO this reason should probably be ADDON_DOWNGRADE (bug 607818)
|
||||
do_check_eq(getInstallReason(), ADDON_INSTALL);
|
||||
|
||||
do_check_eq(getStartupReason(), APP_STARTUP);
|
||||
|
||||
dir = userExtDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.remove(true);
|
||||
|
||||
restartManager();
|
||||
|
||||
run_test_22();
|
||||
});
|
||||
}
|
||||
|
||||
// Check that an upgrade from the filesystem is detected and applied correctly
|
||||
function run_test_22() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_1"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
|
||||
// Make it look old so changes are detected
|
||||
setExtensionModifiedTime(dir.parent, dir.parent.lastModifiedTime - 5000);
|
||||
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have installed and started
|
||||
do_check_eq(getInstalledVersion(), 1);
|
||||
do_check_eq(getActiveVersion(), 1);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "1.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
resetPrefs();
|
||||
shutdownManager();
|
||||
|
||||
dir = dir.parent;
|
||||
dir.remove(true);
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_2"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
// Should have installed and started
|
||||
do_check_eq(getInstalledVersion(), 2);
|
||||
do_check_eq(getActiveVersion(), 2);
|
||||
do_check_neq(b1, null);
|
||||
do_check_eq(b1.version, "2.0");
|
||||
do_check_true(b1.isActive);
|
||||
|
||||
do_check_eq(getShutdownReason(), APP_SHUTDOWN);
|
||||
|
||||
// This won't be set as the bootstrap script was gone so we couldn't
|
||||
// uninstall it properly
|
||||
do_check_eq(getUninstallReason(), -1);
|
||||
|
||||
do_check_eq(getInstallReason(), ADDON_UPGRADE);
|
||||
do_check_eq(getStartupReason(), APP_STARTUP);
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user