Bug 727398 - Restartless extensions that uninstall themselves on startup break the UI. r=dtownsend

This commit is contained in:
Blair McBride 2012-03-15 16:21:06 +13:00
parent 6d99500c2c
commit 84e166a9e2
6 changed files with 159 additions and 96 deletions

View File

@ -6707,6 +6707,18 @@ AddonInstall.prototype = {
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
self.addon.type, file, "install",
reason);
}
AddonManagerPrivate.callAddonListeners("onInstalled",
createWrapper(self.addon));
LOG("Install of " + self.sourceURI.spec + " completed.");
self.state = AddonManager.STATE_INSTALLED;
AddonManagerPrivate.callInstallListeners("onInstallEnded",
self.listeners, self.wrapper,
createWrapper(self.addon));
if (self.addon.bootstrap) {
if (self.addon.active) {
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
self.addon.type, file, "startup",
@ -6716,14 +6728,6 @@ AddonInstall.prototype = {
XPIProvider.unloadBootstrapScope(self.addon.id);
}
}
AddonManagerPrivate.callAddonListeners("onInstalled",
createWrapper(self.addon));
LOG("Install of " + self.sourceURI.spec + " completed.");
self.state = AddonManager.STATE_INSTALLED;
AddonManagerPrivate.callInstallListeners("onInstallEnded",
self.listeners, self.wrapper,
createWrapper(self.addon));
});
}
}
@ -7779,7 +7783,15 @@ function AddonWrapper(aAddon) {
this.hasResource = function(aPath) {
let bundle = aAddon._sourceBundle.clone();
if (bundle.isDirectory()) {
// Bundle may not exist any more if the addon has just been uninstalled,
// but explicitly first checking .exists() results in unneeded file I/O.
try {
var isDir = bundle.isDirectory();
} catch (e) {
return false;
}
if (isDir) {
if (aPath) {
aPath.split("/").forEach(function(aPart) {
bundle.append(aPart);
@ -7790,10 +7802,16 @@ function AddonWrapper(aAddon) {
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
createInstance(Ci.nsIZipReader);
zipReader.open(bundle);
let result = zipReader.hasEntry(aPath);
zipReader.close();
return result;
try {
zipReader.open(bundle);
return zipReader.hasEntry(aPath);
}
catch (e) {
return false;
}
finally {
zipReader.close();
}
},
/**

View File

@ -8,6 +8,7 @@ function install(data, reason) {
}
function startup(data, reason) {
Components.utils.reportError("bootstrap startup");
Components.utils.import(data.resourceURI.spec + "version.jsm");
Services.prefs.setIntPref("bootstraptest.active_version", VERSION);
Services.prefs.setIntPref("bootstraptest.startup_reason", reason);

View File

@ -10,7 +10,7 @@
<!-- Front End MetaData -->
<em:name>Test 1</em:name>
<em:description>Test Description</em:description>
<em:bootstrap>true</em:bootstrap>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>

View File

@ -41,6 +41,14 @@ function resetPrefs() {
Services.prefs.setIntPref("bootstraptest.uninstall_reason", -1);
}
function waitForPref(aPref, aCallback) {
function prefChanged() {
Services.prefs.removeObserver(aPref, prefChanged);
aCallback();
}
Services.prefs.addObserver(aPref, prefChanged, false);
}
function getActiveVersion() {
return Services.prefs.getIntPref("bootstraptest.active_version");
}
@ -168,7 +176,13 @@ function run_test_1() {
"onInstallEnded",
], function() {
do_check_true(addon.hasResource("install.rdf"));
check_test_1(addon.syncGUID);
// startup should not have been called yet.
do_check_eq(getActiveVersion(), -1);
waitForPref("bootstraptest.active_version", function() {
check_test_1(addon.syncGUID);
});
});
install.install();
});
@ -364,7 +378,9 @@ function run_test_6() {
}, [
"onInstallStarted",
"onInstallEnded",
], check_test_6);
], function() {
waitForPref("bootstraptest.active_version", check_test_6);
});
install.install();
});
}
@ -494,7 +510,9 @@ function run_test_10() {
}, [
"onInstallStarted",
"onInstallEnded",
], check_test_10_pt1);
], function() {
waitForPref("bootstraptest.active_version", check_test_10_pt1);
});
install.install();
});
}
@ -535,7 +553,9 @@ function check_test_10_pt1() {
}, [
"onInstallStarted",
"onInstallEnded",
], check_test_10_pt2);
], function() {
waitForPref("bootstraptest.active_version", check_test_10_pt2);
});
install.install();
});
});
@ -1122,40 +1142,42 @@ function run_test_24() {
resetPrefs();
installAllFiles([do_get_addon("test_bootstrap1_1"), do_get_addon("test_bootstrap2_1")],
function() {
do_check_eq(getInstalledVersion(), 1);
do_check_eq(getActiveVersion(), 1);
do_check_eq(getInstalledVersion2(), 1);
do_check_eq(getActiveVersion2(), 1);
waitForPref("bootstraptest2.active_version", function() {
do_check_eq(getInstalledVersion(), 1);
do_check_eq(getActiveVersion(), 1);
do_check_eq(getInstalledVersion2(), 1);
do_check_eq(getActiveVersion2(), 1);
resetPrefs();
resetPrefs();
restartManager();
restartManager();
do_check_eq(getInstalledVersion(), -1);
do_check_eq(getActiveVersion(), 1);
do_check_eq(getInstalledVersion2(), -1);
do_check_eq(getActiveVersion2(), 1);
do_check_eq(getInstalledVersion(), -1);
do_check_eq(getActiveVersion(), 1);
do_check_eq(getInstalledVersion2(), -1);
do_check_eq(getActiveVersion2(), 1);
shutdownManager();
shutdownManager();
do_check_eq(getInstalledVersion(), -1);
do_check_eq(getActiveVersion(), 0);
do_check_eq(getInstalledVersion2(), -1);
do_check_eq(getActiveVersion2(), 0);
do_check_eq(getInstalledVersion(), -1);
do_check_eq(getActiveVersion(), 0);
do_check_eq(getInstalledVersion2(), -1);
do_check_eq(getActiveVersion2(), 0);
// Break the preferece
let bootstrappedAddons = JSON.parse(Services.prefs.getCharPref("extensions.bootstrappedAddons"));
bootstrappedAddons["bootstrap1@tests.mozilla.org"].descriptor += "foo";
Services.prefs.setCharPref("extensions.bootstrappedAddons", JSON.stringify(bootstrappedAddons));
// Break the preferece
let bootstrappedAddons = JSON.parse(Services.prefs.getCharPref("extensions.bootstrappedAddons"));
bootstrappedAddons["bootstrap1@tests.mozilla.org"].descriptor += "foo";
Services.prefs.setCharPref("extensions.bootstrappedAddons", JSON.stringify(bootstrappedAddons));
startupManager(false);
startupManager(false);
do_check_eq(getInstalledVersion(), -1);
do_check_eq(getActiveVersion(), 1);
do_check_eq(getInstalledVersion2(), -1);
do_check_eq(getActiveVersion2(), 1);
do_check_eq(getInstalledVersion(), -1);
do_check_eq(getActiveVersion(), 1);
do_check_eq(getInstalledVersion2(), -1);
do_check_eq(getActiveVersion2(), 1);
run_test_25();
run_test_25();
});
});
}
@ -1163,33 +1185,35 @@ function run_test_24() {
// the uninstall method
function run_test_25() {
installAllFiles([do_get_addon("test_bootstrap1_1")], function() {
do_check_eq(getInstalledVersion(), 1);
do_check_eq(getActiveVersion(), 1);
installAllFiles([do_get_addon("test_bootstrap1_4")], function() {
// Needs a restart to complete this so the old version stays running
waitForPref("bootstraptest.active_version", function() {
do_check_eq(getInstalledVersion(), 1);
do_check_eq(getActiveVersion(), 1);
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "1.0");
do_check_true(b1.isActive);
do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE));
restartManager();
do_check_eq(getInstalledVersion(), 0);
do_check_eq(getUninstallReason(), ADDON_UPGRADE);
do_check_eq(getActiveVersion(), 0);
installAllFiles([do_get_addon("test_bootstrap1_4")], function() {
// Needs a restart to complete this so the old version stays running
do_check_eq(getInstalledVersion(), 1);
do_check_eq(getActiveVersion(), 1);
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "4.0");
do_check_eq(b1.version, "1.0");
do_check_true(b1.isActive);
do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE);
do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE));
run_test_26();
restartManager();
do_check_eq(getInstalledVersion(), 0);
do_check_eq(getUninstallReason(), ADDON_UPGRADE);
do_check_eq(getActiveVersion(), 0);
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "4.0");
do_check_true(b1.isActive);
do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE);
run_test_26();
});
});
});
});

View File

@ -28,6 +28,7 @@ var testserver;
*/
var HunspellEngine = {
dictionaryDirs: [],
listener: null,
QueryInterface: function hunspell_qi(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
@ -47,10 +48,14 @@ var HunspellEngine = {
addDirectory: function hunspell_addDirectory(dir) {
this.dictionaryDirs.push(dir);
if (this.listener)
this.listener("addDirectory");
},
removeDirectory: function hunspell_addDirectory(dir) {
this.dictionaryDirs.splice(this.dictionaryDirs.indexOf(dir), 1);
if (this.listener)
this.listener("removeDirectory");
},
getInterface: function hunspell_gi(iid) {
@ -136,7 +141,11 @@ function run_test_1() {
"onInstallEnded",
], function() {
do_check_true(addon.hasResource("install.rdf"));
check_test_1();
HunspellEngine.listener = function(aEvent) {
HunspellEngine.listener = null;
do_check_eq(aEvent, "addDirectory");
check_test_1();
};
});
install.install();
});
@ -566,32 +575,36 @@ function check_test_23() {
// the uninstall method
function run_test_25() {
installAllFiles([do_get_addon("test_dictionary")], function() {
do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
installAllFiles([do_get_addon("test_dictionary_2")], function() {
// Needs a restart to complete this so the old version stays running
HunspellEngine.listener = function(aEvent) {
HunspellEngine.listener = null;
do_check_eq(aEvent, "addDirectory");
do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "1.0");
do_check_true(b1.isActive);
do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE));
restartManager();
do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
installAllFiles([do_get_addon("test_dictionary_2")], function() {
// Needs a restart to complete this so the old version stays running
do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "2.0");
do_check_eq(b1.version, "1.0");
do_check_true(b1.isActive);
do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE);
do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE));
run_test_26();
restartManager();
do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "2.0");
do_check_true(b1.isActive);
do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE);
run_test_26();
});
});
});
});
};
});
}

View File

@ -3,7 +3,7 @@
*/
// install.rdf size, icon.png size, subfile.txt size
const ADDON_SIZE = 635 + 15 + 26;
const ADDON_SIZE = 672 + 15 + 26;
// This verifies the functionality of getResourceURI
// There are two cases - with a filename it returns an nsIFileURL to the filename
@ -68,6 +68,13 @@ function run_test() {
a1.uninstall();
try {
// hasResource should never throw an exception.
do_check_false(a1.hasResource("icon.png"));
} catch (e) {
do_check_true(false);
}
restartManager();
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(newa1) {