зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
1e54660e25
Коммит
5132bb180d
|
@ -534,13 +534,8 @@ class AddonInternal {
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateBlocklistState(options = {}) {
|
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 oldState = this.blocklistState;
|
||||||
|
|
||||||
let entry = await this.findBlocklistEntry();
|
let entry = await this.findBlocklistEntry();
|
||||||
|
@ -685,6 +680,14 @@ class AddonInternal {
|
||||||
|
|
||||||
return permissions;
|
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);
|
addon.appDisabled = !XPIDatabase.isUsableAddon(addon);
|
||||||
|
|
||||||
defineSyncGUID(addon);
|
defineSyncGUID(addon);
|
||||||
|
@ -1705,7 +1706,7 @@ class AddonInstall {
|
||||||
/**
|
/**
|
||||||
* Installs the add-on into the install location.
|
* Installs the add-on into the install location.
|
||||||
*/
|
*/
|
||||||
startInstall() {
|
async startInstall() {
|
||||||
this.state = AddonManager.STATE_INSTALLING;
|
this.state = AddonManager.STATE_INSTALLING;
|
||||||
if (!this._callInstallListeners("onInstallStarted")) {
|
if (!this._callInstallListeners("onInstallStarted")) {
|
||||||
this.state = AddonManager.STATE_DOWNLOADED;
|
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 &&
|
let isUpgrade = this.existingAddon &&
|
||||||
this.existingAddon.location == this.location;
|
this.existingAddon.location == this.location;
|
||||||
|
|
||||||
|
@ -1736,7 +1750,7 @@ class AddonInstall {
|
||||||
|
|
||||||
let stagedAddon = this.location.installer.getStagingDir();
|
let stagedAddon = this.location.installer.getStagingDir();
|
||||||
|
|
||||||
(async () => {
|
try {
|
||||||
await this.location.installer.requestStagingDir();
|
await this.location.installer.requestStagingDir();
|
||||||
|
|
||||||
// remove any previously staged files
|
// remove any previously staged files
|
||||||
|
@ -1767,8 +1781,7 @@ class AddonInstall {
|
||||||
this.addon.visible = true;
|
this.addon.visible = true;
|
||||||
|
|
||||||
if (isUpgrade) {
|
if (isUpgrade) {
|
||||||
this.addon = XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon,
|
this.addon = XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon, file.path);
|
||||||
file.path);
|
|
||||||
let state = this.location.get(this.addon.id);
|
let state = this.location.get(this.addon.id);
|
||||||
if (state) {
|
if (state) {
|
||||||
state.syncWithDB(this.addon, true);
|
state.syncWithDB(this.addon, true);
|
||||||
|
@ -1813,7 +1826,7 @@ class AddonInstall {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
await this._startupPromise;
|
await this._startupPromise;
|
||||||
})().catch((e) => {
|
} catch (e) {
|
||||||
logger.warn(`Failed to install ${this.file.path} from ${this.sourceURI.spec} to ${stagedAddon.path}`, e);
|
logger.warn(`Failed to install ${this.file.path} from ${this.sourceURI.spec} to ${stagedAddon.path}`, e);
|
||||||
|
|
||||||
if (stagedAddon.exists())
|
if (stagedAddon.exists())
|
||||||
|
@ -1824,10 +1837,10 @@ class AddonInstall {
|
||||||
AddonManagerPrivate.callAddonListeners("onOperationCancelled",
|
AddonManagerPrivate.callAddonListeners("onOperationCancelled",
|
||||||
this.addon.wrapper);
|
this.addon.wrapper);
|
||||||
this._callInstallListeners("onInstallFailed");
|
this._callInstallListeners("onInstallFailed");
|
||||||
}).then(() => {
|
} finally {
|
||||||
this.removeTemporaryFile();
|
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);
|
let addon = await XPIDatabase.getVisibleAddonForID(this.addon.id);
|
||||||
|
|
||||||
this.existingAddon = addon;
|
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.updateDate = Date.now();
|
||||||
this.addon.installDate = addon ? addon.installDate : this.addon.updateDate;
|
this.addon.installDate = addon ? addon.installDate : this.addon.updateDate;
|
||||||
|
|
||||||
|
@ -2398,7 +2412,8 @@ var DownloadAddonInstall = class extends AddonInstall {
|
||||||
} else {
|
} else {
|
||||||
this.addon.installDate = this.addon.updateDate;
|
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 (this._callInstallListeners("onDownloadEnded")) {
|
||||||
// If a listener changed our state then do not proceed with the install
|
// 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_registerchrome.js]
|
||||||
[test_registry.js]
|
[test_registry.js]
|
||||||
skip-if = os != 'win'
|
skip-if = os != 'win'
|
||||||
|
[test_reinstall_disabled_addon.js]
|
||||||
[test_reload.js]
|
[test_reload.js]
|
||||||
# Bug 676992: test consistently hangs on Android
|
# Bug 676992: test consistently hangs on Android
|
||||||
# There's a problem removing a temp file without manually clearing the cache on Windows
|
# There's a problem removing a temp file without manually clearing the cache on Windows
|
||||||
|
|
Загрузка…
Ссылка в новой задаче