Bug 1313298. Reinstall disable extension of the same version. r=aswan

Enable a disabled addon when user re-installs the same version.

Before this change disabled addons couldn't be enabled back even if user intentionally reinstalls the same version of addon.
Now if user reinstalls the same version - addon will be enabled back.

Differential Revision: https://phabricator.services.mozilla.com/D4435

--HG--
extra : moz-landing-system : lando
This commit is contained in:
apranovich 2018-09-22 22:26:22 +00:00
Родитель 1e54660e25
Коммит 5132bb180d
4 изменённых файлов: 225 добавлений и 17 удалений

Просмотреть файл

@ -534,13 +534,8 @@ class AddonInternal {
}
async updateBlocklistState(options = {}) {
let {applySoftBlock = true, oldAddon = null, updateDatabase = true} = options;
let {applySoftBlock = true, updateDatabase = true} = options;
if (oldAddon) {
this.userDisabled = oldAddon.userDisabled;
this.softDisabled = oldAddon.softDisabled;
this.blocklistState = oldAddon.blocklistState;
}
let oldState = this.blocklistState;
let entry = await this.findBlocklistEntry();
@ -685,6 +680,14 @@ class AddonInternal {
return permissions;
}
propagateDisabledState(oldAddon) {
if (oldAddon) {
this.userDisabled = oldAddon.userDisabled;
this.softDisabled = oldAddon.softDisabled;
this.blocklistState = oldAddon.blocklistState;
}
}
}
/**

Просмотреть файл

@ -829,7 +829,8 @@ var loadManifest = async function(aPackage, aLocation, aOldAddon) {
}
}
await addon.updateBlocklistState({oldAddon: aOldAddon});
addon.propagateDisabledState(aOldAddon);
await addon.updateBlocklistState();
addon.appDisabled = !XPIDatabase.isUsableAddon(addon);
defineSyncGUID(addon);
@ -1705,7 +1706,7 @@ class AddonInstall {
/**
* Installs the add-on into the install location.
*/
startInstall() {
async startInstall() {
this.state = AddonManager.STATE_INSTALLING;
if (!this._callInstallListeners("onInstallStarted")) {
this.state = AddonManager.STATE_DOWNLOADED;
@ -1726,6 +1727,19 @@ class AddonInstall {
}
}
// Reinstall existing user-disabled addon (of the same installed version).
// If addon is marked to be uninstalled - don't reinstall it.
if (this.existingAddon &&
this.existingAddon.location === this.location &&
this.existingAddon.version === this.addon.version &&
this.existingAddon.userDisabled &&
!this.existingAddon.pendingUninstall) {
await XPIDatabase.updateAddonDisabledState(this.existingAddon, false);
this.state = AddonManager.STATE_INSTALLED;
this._callInstallListeners("onInstallEnded", this.existingAddon.wrapper);
return;
}
let isUpgrade = this.existingAddon &&
this.existingAddon.location == this.location;
@ -1736,7 +1750,7 @@ class AddonInstall {
let stagedAddon = this.location.installer.getStagingDir();
(async () => {
try {
await this.location.installer.requestStagingDir();
// remove any previously staged files
@ -1767,8 +1781,7 @@ class AddonInstall {
this.addon.visible = true;
if (isUpgrade) {
this.addon = XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon,
file.path);
this.addon = XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon, file.path);
let state = this.location.get(this.addon.id);
if (state) {
state.syncWithDB(this.addon, true);
@ -1813,7 +1826,7 @@ class AddonInstall {
})();
await this._startupPromise;
})().catch((e) => {
} catch (e) {
logger.warn(`Failed to install ${this.file.path} from ${this.sourceURI.spec} to ${stagedAddon.path}`, e);
if (stagedAddon.exists())
@ -1824,10 +1837,10 @@ class AddonInstall {
AddonManagerPrivate.callAddonListeners("onOperationCancelled",
this.addon.wrapper);
this._callInstallListeners("onInstallFailed");
}).then(() => {
} finally {
this.removeTemporaryFile();
return this.location.installer.releaseStagingDir();
});
this.location.installer.releaseStagingDir();
}
}
/**
@ -2003,7 +2016,8 @@ var LocalAddonInstall = class extends AddonInstall {
let addon = await XPIDatabase.getVisibleAddonForID(this.addon.id);
this.existingAddon = addon;
await this.addon.updateBlocklistState({oldAddon: this.existingAddon});
this.addon.propagateDisabledState(this.existingAddon);
await this.addon.updateBlocklistState();
this.addon.updateDate = Date.now();
this.addon.installDate = addon ? addon.installDate : this.addon.updateDate;
@ -2398,7 +2412,8 @@ var DownloadAddonInstall = class extends AddonInstall {
} else {
this.addon.installDate = this.addon.updateDate;
}
await this.addon.updateBlocklistState({oldAddon: this.existingAddon});
this.addon.propagateDisabledState(this.existingAddon);
await this.addon.updateBlocklistState();
if (this._callInstallListeners("onDownloadEnded")) {
// If a listener changed our state then do not proceed with the install

Просмотреть файл

@ -0,0 +1,189 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const ID = "test_addon@tests.mozilla.org";
const ADDONS = {
test_install1_1: {
name: "Test 1 Addon",
description: "Test 1 addon description",
manifest_version: 2,
version: "1.0",
applications: {
gecko: {
id: ID,
},
},
},
test_install1_2: {
name: "Test 1 Addon",
description: "Test 1 addon description",
manifest_version: 2,
version: "2.0",
applications: {
gecko: {
id: ID,
},
},
},
};
add_task(async function setup() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
await promiseStartupManager();
});
// User intentionally reinstalls existing disabled addon of the same version.
// No onInstalling nor onInstalled are fired.
add_task(async function reinstallExistingDisabledAddonSameVersion() {
prepare_test({
[ID]: [
["onInstalling", false],
"onInstalled",
],
}, [
"onNewInstall",
"onInstallStarted",
"onInstallEnded",
]);
const xpi = AddonTestUtils.createTempWebExtensionFile({manifest: ADDONS.test_install1_1});
let install = await AddonManager.getInstallForFile(xpi);
await install.install();
ensure_test_completed();
let addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.pendingOperations, AddonManager.PENDING_NONE);
ok(addon.isActive);
ok(!addon.userDisabled);
prepare_test({
[ID]: [
["onDisabling", false],
"onDisabled",
],
});
await addon.disable();
ensure_test_completed();
addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.pendingOperations, AddonManager.PENDING_NONE);
ok(!addon.isActive);
ok(addon.userDisabled);
prepare_test({
[ID]: [
["onEnabling", false],
"onEnabled",
],
}, [
"onNewInstall",
"onInstallStarted",
"onInstallEnded",
]);
const xpi2 = AddonTestUtils.createTempWebExtensionFile({manifest: ADDONS.test_install1_1});
install = await AddonManager.getInstallForFile(xpi2);
await install.install();
ensure_test_completed();
addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.pendingOperations, AddonManager.PENDING_NONE);
ok(addon.isActive);
ok(!addon.userDisabled);
prepare_test({
[ID]: [
["onUninstalling", false],
"onUninstalled",
],
});
await addon.uninstall();
ensure_test_completed();
addon = await promiseAddonByID(ID);
equal(addon, null);
await promiseRestartManager();
});
// User intentionally reinstalls existing disabled addon of different version,
// but addon *still should be disabled*.
add_task(async function reinstallExistingDisabledAddonDifferentVersion() {
prepare_test({
[ID]: [
["onInstalling", false],
"onInstalled",
],
}, [
"onNewInstall",
"onInstallStarted",
"onInstallEnded",
]);
const xpi = AddonTestUtils.createTempWebExtensionFile({manifest: ADDONS.test_install1_1});
let install = await AddonManager.getInstallForFile(xpi);
await install.install();
ensure_test_completed();
let addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.pendingOperations, AddonManager.PENDING_NONE);
ok(addon.isActive);
ok(!addon.userDisabled);
prepare_test({
[ID]: [
["onDisabling", false],
"onDisabled",
],
});
await addon.disable();
ensure_test_completed();
addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.pendingOperations, AddonManager.PENDING_NONE);
ok(!addon.isActive);
ok(addon.userDisabled);
prepare_test({
[ID]: [
["onInstalling", false],
"onInstalled",
],
}, [
"onNewInstall",
"onInstallStarted",
"onInstallEnded",
]);
let xpi2 = AddonTestUtils.createTempWebExtensionFile({manifest: ADDONS.test_install1_2});
install = await AddonManager.getInstallForFile(xpi2);
await install.install();
ensure_test_completed();
addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.pendingOperations, AddonManager.PENDING_NONE);
ok(!addon.isActive);
ok(addon.userDisabled);
equal(addon.version, "2.0");
prepare_test({
[ID]: [
["onUninstalling", false],
"onUninstalled",
],
});
await addon.uninstall();
ensure_test_completed();
addon = await promiseAddonByID(ID);
equal(addon, null);
});

Просмотреть файл

@ -184,6 +184,7 @@ skip-if = require_signing
[test_registerchrome.js]
[test_registry.js]
skip-if = os != 'win'
[test_reinstall_disabled_addon.js]
[test_reload.js]
# Bug 676992: test consistently hangs on Android
# There's a problem removing a temp file without manually clearing the cache on Windows