зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1353194) for leaving unreferenced files
Backed out changeset 246b6aae8157 (bug 1353194) Backed out changeset e3c293ceedf3 (bug 1353194) MozReview-Commit-ID: EshIZ3vmebw
This commit is contained in:
Родитель
c7ced59fed
Коммит
ce9216dc28
|
@ -2,16 +2,20 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# LOCALIZATION NOTE (addonUpdateHeader)
|
||||
# %S will be replace with the localized name of the application
|
||||
addonUpdateTitle=%S Update
|
||||
|
||||
# LOCALIZATION NOTE (addonUpdateMessage)
|
||||
# %S will be replace with the localized name of the application
|
||||
addonUpdateMessage=%S is updating your extensions…
|
||||
|
||||
addonUpdateCancelMessage=Still updating. Want to wait?
|
||||
|
||||
# LOCALIZATION NOTE (addonUpdateCancelButton)
|
||||
# %S will be replace with the localized name of the application
|
||||
addonUpdateCancelButton=Stop update and launch %S
|
||||
mismatchCheckNow=Check Now
|
||||
mismatchCheckNowAccesskey=C
|
||||
mismatchDontCheck=Don’t Check
|
||||
mismatchDontCheckAccesskey=D
|
||||
installButtonText=Install Now
|
||||
installButtonTextAccesskey=I
|
||||
nextButtonText=Next >
|
||||
nextButtonTextAccesskey=N
|
||||
cancelButtonText=Cancel
|
||||
cancelButtonTextAccesskey=C
|
||||
statusPrefix=Finished checking %S
|
||||
downloadingPrefix=Downloading: %S
|
||||
installingPrefix=Installing: %S
|
||||
closeButton=Close
|
||||
installErrors=%S was unable to install updates for the following add-ons:
|
||||
checkingErrors=%S was unable to check for updates for the following add-ons:
|
||||
installErrorItemFormat=%S (%S)
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
body {
|
||||
font: message-box;
|
||||
min-width: 480px;
|
||||
}
|
||||
|
||||
#message {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#message, #cancel-section {
|
||||
margin: 10px 5px;
|
||||
}
|
||||
|
||||
#progress {
|
||||
width: calc(100% - 10px);
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
#cancel-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#cancel-message {
|
||||
vertical-align: middle;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script src="update.js"></script>
|
||||
<link rel="stylesheet" href="chrome://mozapps/content/extensions/update.css">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div id="message"></div>
|
||||
|
||||
<progress id="progress" val="0" max="1"></progress>
|
||||
|
||||
<div id="cancel-section">
|
||||
<span id="cancel-message"></span>
|
||||
<button id="cancel-btn"></button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,24 +1,633 @@
|
|||
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This UI is only opened from the Extension Manager when the app is upgraded.
|
||||
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
/* exported gAdminDisabledPage, gFinishedPage, gFoundPage, gInstallErrorsPage,
|
||||
* gNoUpdatesPage, gOfflinePage, gUpdatePage */
|
||||
|
||||
let BRAND_PROPS = "chrome://branding/locale/brand.properties";
|
||||
let UPDATE_PROPS = "chrome://mozapps/locale/extensions/update.properties";
|
||||
const PREF_UPDATE_EXTENSIONS_ENABLED = "extensions.update.enabled";
|
||||
const PREF_XPINSTALL_ENABLED = "xpinstall.enabled";
|
||||
|
||||
let appName = Services.strings.createBundle(BRAND_PROPS)
|
||||
.GetStringFromName("brandShortName");
|
||||
let bundle = Services.strings.createBundle(UPDATE_PROPS);
|
||||
// timeout (in milliseconds) to wait for response to the metadata ping
|
||||
const METADATA_TIMEOUT = 30000;
|
||||
|
||||
let titleText = bundle.formatStringFromName("addonUpdateTitle", [appName], 1);
|
||||
let messageText = bundle.formatStringFromName("addonUpdateMessage", [appName], 1);
|
||||
let cancelText = bundle.GetStringFromName("addonUpdateCancelMessage");
|
||||
let cancelButtonText = bundle.formatStringFromName("addonUpdateCancelButton", [appName], 1);
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate", "resource://gre/modules/AddonManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository", "resource://gre/modules/addons/AddonRepository.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/Log.jsm");
|
||||
var logger = null;
|
||||
|
||||
document.title = titleText;
|
||||
var gUpdateWizard = {
|
||||
// When synchronizing app compatibility info this contains all installed
|
||||
// add-ons. When checking for compatible versions this contains only
|
||||
// incompatible add-ons.
|
||||
addons: [],
|
||||
// Contains a Set of IDs for add-on that were disabled by the application update.
|
||||
affectedAddonIDs: null,
|
||||
// The add-ons that we found updates available for
|
||||
addonsToUpdate: [],
|
||||
shouldSuggestAutoChecking: false,
|
||||
shouldAutoCheck: false,
|
||||
xpinstallEnabled: true,
|
||||
xpinstallLocked: false,
|
||||
// cached AddonInstall entries for add-ons we might want to update,
|
||||
// keyed by add-on ID
|
||||
addonInstalls: new Map(),
|
||||
shuttingDown: false,
|
||||
// Count the add-ons disabled by this update, enabled/disabled by
|
||||
// metadata checks, and upgraded.
|
||||
disabled: 0,
|
||||
metadataEnabled: 0,
|
||||
metadataDisabled: 0,
|
||||
upgraded: 0,
|
||||
upgradeFailed: 0,
|
||||
upgradeDeclined: 0,
|
||||
|
||||
window.addEventListener("load", e => {
|
||||
document.getElementById("message").textContent = messageText;
|
||||
document.getElementById("cancel-message").textContent = cancelText;
|
||||
document.getElementById("cancel-btn").textContent = cancelButtonText;
|
||||
window.sizeToContent();
|
||||
});
|
||||
init() {
|
||||
logger = Log.repository.getLogger("addons.update-dialog");
|
||||
// XXX could we pass the addons themselves rather than the IDs?
|
||||
this.affectedAddonIDs = new Set(window.arguments[0]);
|
||||
|
||||
try {
|
||||
this.shouldSuggestAutoChecking =
|
||||
!Services.prefs.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
try {
|
||||
this.xpinstallEnabled = Services.prefs.getBoolPref(PREF_XPINSTALL_ENABLED);
|
||||
this.xpinstallLocked = Services.prefs.prefIsLocked(PREF_XPINSTALL_ENABLED);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (Services.io.offline)
|
||||
document.documentElement.currentPage = document.getElementById("offline");
|
||||
else
|
||||
document.documentElement.currentPage = document.getElementById("versioninfo");
|
||||
},
|
||||
|
||||
onWizardFinish: function gUpdateWizard_onWizardFinish() {
|
||||
if (this.shouldSuggestAutoChecking)
|
||||
Services.prefs.setBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED, this.shouldAutoCheck);
|
||||
},
|
||||
|
||||
_setUpButton(aButtonID, aButtonKey, aDisabled) {
|
||||
var strings = document.getElementById("updateStrings");
|
||||
var button = document.documentElement.getButton(aButtonID);
|
||||
if (aButtonKey) {
|
||||
button.label = strings.getString(aButtonKey);
|
||||
try {
|
||||
button.setAttribute("accesskey", strings.getString(aButtonKey + "Accesskey"));
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
button.disabled = aDisabled;
|
||||
},
|
||||
|
||||
setButtonLabels(aBackButton, aBackButtonIsDisabled,
|
||||
aNextButton, aNextButtonIsDisabled,
|
||||
aCancelButton, aCancelButtonIsDisabled) {
|
||||
this._setUpButton("back", aBackButton, aBackButtonIsDisabled);
|
||||
this._setUpButton("next", aNextButton, aNextButtonIsDisabled);
|
||||
this._setUpButton("cancel", aCancelButton, aCancelButtonIsDisabled);
|
||||
},
|
||||
|
||||
// Update Errors
|
||||
errorItems: [],
|
||||
|
||||
checkForErrors(aElementIDToShow) {
|
||||
if (this.errorItems.length > 0)
|
||||
document.getElementById(aElementIDToShow).hidden = false;
|
||||
},
|
||||
|
||||
onWizardClose(aEvent) {
|
||||
return this.onWizardCancel();
|
||||
},
|
||||
|
||||
onWizardCancel() {
|
||||
gUpdateWizard.shuttingDown = true;
|
||||
// Allow add-ons to continue downloading and installing
|
||||
// in the background, though some may require a later restart
|
||||
// Pages that are waiting for user input go into the background
|
||||
// on cancel
|
||||
if (gMismatchPage.waiting) {
|
||||
logger.info("Dialog closed in mismatch page");
|
||||
if (gUpdateWizard.addonInstalls.size > 0) {
|
||||
gInstallingPage.startInstalls(
|
||||
Array.from(gUpdateWizard.addonInstalls.values()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pages that do asynchronous things will just keep running and check
|
||||
// gUpdateWizard.shuttingDown to trigger background behaviour
|
||||
if (!gInstallingPage.installing) {
|
||||
logger.info("Dialog closed while waiting for updated compatibility information");
|
||||
} else {
|
||||
logger.info("Dialog closed while downloading and installing updates");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var gOfflinePage = {
|
||||
onPageAdvanced() {
|
||||
Services.io.offline = false;
|
||||
return true;
|
||||
},
|
||||
|
||||
toggleOffline() {
|
||||
var nextbtn = document.documentElement.getButton("next");
|
||||
nextbtn.disabled = !nextbtn.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
// Addon listener to count addons enabled/disabled by metadata checks
|
||||
var listener = {
|
||||
onDisabled(aAddon) {
|
||||
gUpdateWizard.affectedAddonIDs.add(aAddon.id);
|
||||
gUpdateWizard.metadataDisabled++;
|
||||
},
|
||||
onEnabled(aAddon) {
|
||||
gUpdateWizard.affectedAddonIDs.delete(aAddon.id);
|
||||
gUpdateWizard.metadataEnabled++;
|
||||
}
|
||||
};
|
||||
|
||||
var gVersionInfoPage = {
|
||||
_completeCount: 0,
|
||||
_totalCount: 0,
|
||||
_versionInfoDone: false,
|
||||
async onPageShow() {
|
||||
gUpdateWizard.setButtonLabels(null, true,
|
||||
"nextButtonText", true,
|
||||
"cancelButtonText", false);
|
||||
|
||||
gUpdateWizard.disabled = gUpdateWizard.affectedAddonIDs.size;
|
||||
|
||||
// Ensure compatibility overrides are up to date before checking for
|
||||
// individual addon updates.
|
||||
AddonManager.addAddonListener(listener);
|
||||
if (AddonRepository.isMetadataStale()) {
|
||||
// Do the metadata ping, listening for any newly enabled/disabled add-ons.
|
||||
await AddonRepository.repopulateCache(METADATA_TIMEOUT);
|
||||
if (gUpdateWizard.shuttingDown) {
|
||||
logger.debug("repopulateCache completed after dialog closed");
|
||||
}
|
||||
}
|
||||
// Fetch the add-ons that are still affected by this update,
|
||||
// excluding the hotfix add-on.
|
||||
let idlist = Array.from(gUpdateWizard.affectedAddonIDs).filter(
|
||||
a => a.id != AddonManager.hotfixID);
|
||||
if (idlist.length < 1) {
|
||||
gVersionInfoPage.onAllUpdatesFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug("Fetching affected addons " + idlist.toSource());
|
||||
let fetchedAddons = await AddonManager.getAddonsByIDs(idlist);
|
||||
// We shouldn't get nulls here, but let's be paranoid...
|
||||
gUpdateWizard.addons = fetchedAddons.filter(a => a);
|
||||
if (gUpdateWizard.addons.length < 1) {
|
||||
gVersionInfoPage.onAllUpdatesFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
gVersionInfoPage._totalCount = gUpdateWizard.addons.length;
|
||||
|
||||
for (let addon of gUpdateWizard.addons) {
|
||||
logger.debug("VersionInfo Finding updates for ${id}", addon);
|
||||
addon.findUpdates(gVersionInfoPage, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
|
||||
}
|
||||
},
|
||||
|
||||
onAllUpdatesFinished() {
|
||||
AddonManager.removeAddonListener(listener);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_disabled",
|
||||
gUpdateWizard.disabled);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_enabled",
|
||||
gUpdateWizard.metadataEnabled);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_disabled",
|
||||
gUpdateWizard.metadataDisabled);
|
||||
// Record 0 for these here in case we exit early; values will be replaced
|
||||
// later if we actually upgrade any.
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded", 0);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed", 0);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined", 0);
|
||||
// Filter out any add-ons that are now enabled.
|
||||
let addonList = gUpdateWizard.addons.map(a => a.id + ":" + a.appDisabled);
|
||||
logger.debug("VersionInfo updates finished: found " + addonList.toSource());
|
||||
let filteredAddons = [];
|
||||
for (let a of gUpdateWizard.addons) {
|
||||
if (a.appDisabled) {
|
||||
logger.debug("Continuing with add-on " + a.id);
|
||||
filteredAddons.push(a);
|
||||
} else if (gUpdateWizard.addonInstalls.has(a.id)) {
|
||||
gUpdateWizard.addonInstalls.get(a.id).cancel();
|
||||
gUpdateWizard.addonInstalls.delete(a.id);
|
||||
}
|
||||
}
|
||||
gUpdateWizard.addons = filteredAddons;
|
||||
|
||||
if (gUpdateWizard.shuttingDown) {
|
||||
// jump directly to updating auto-update add-ons in the background
|
||||
if (gUpdateWizard.addonInstalls.size > 0) {
|
||||
let installs = Array.from(gUpdateWizard.addonInstalls.values());
|
||||
gInstallingPage.startInstalls(installs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (filteredAddons.length > 0) {
|
||||
if (!gUpdateWizard.xpinstallEnabled && gUpdateWizard.xpinstallLocked) {
|
||||
document.documentElement.currentPage = document.getElementById("adminDisabled");
|
||||
return;
|
||||
}
|
||||
document.documentElement.currentPage = document.getElementById("mismatch");
|
||||
} else {
|
||||
logger.info("VersionInfo: No updates require further action");
|
||||
// VersionInfo compatibility updates resolved all compatibility problems,
|
||||
// close this window and continue starting the application...
|
||||
// XXX Bug 314754 - We need to use setTimeout to close the window due to
|
||||
// the EM using xmlHttpRequest when checking for updates.
|
||||
setTimeout(close, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// UpdateListener
|
||||
onUpdateFinished(aAddon, status) {
|
||||
++this._completeCount;
|
||||
|
||||
if (status != AddonManager.UPDATE_STATUS_NO_ERROR) {
|
||||
logger.debug("VersionInfo update " + this._completeCount + " of " + this._totalCount +
|
||||
" failed for " + aAddon.id + ": " + status);
|
||||
gUpdateWizard.errorItems.push(aAddon);
|
||||
} else {
|
||||
logger.debug("VersionInfo update " + this._completeCount + " of " + this._totalCount +
|
||||
" finished for " + aAddon.id);
|
||||
}
|
||||
|
||||
// If we're not in the background, just make a list of add-ons that have
|
||||
// updates available
|
||||
if (!gUpdateWizard.shuttingDown) {
|
||||
// If we're still in the update check window and the add-on is now active
|
||||
// then it won't have been disabled by startup
|
||||
if (aAddon.active) {
|
||||
AddonManagerPrivate.removeStartupChange(AddonManager.STARTUP_CHANGE_DISABLED, aAddon.id);
|
||||
gUpdateWizard.metadataEnabled++;
|
||||
}
|
||||
|
||||
// Update the status text and progress bar
|
||||
var updateStrings = document.getElementById("updateStrings");
|
||||
var statusElt = document.getElementById("versioninfo.status");
|
||||
var statusString = updateStrings.getFormattedString("statusPrefix", [aAddon.name]);
|
||||
statusElt.setAttribute("value", statusString);
|
||||
|
||||
// Update the status text and progress bar
|
||||
var progress = document.getElementById("versioninfo.progress");
|
||||
progress.mode = "normal";
|
||||
progress.value = Math.ceil((this._completeCount / this._totalCount) * 100);
|
||||
}
|
||||
|
||||
if (this._completeCount == this._totalCount)
|
||||
this.onAllUpdatesFinished();
|
||||
},
|
||||
|
||||
onUpdateAvailable(aAddon, aInstall) {
|
||||
logger.debug("VersionInfo got an install for " + aAddon.id + ": " + aAddon.version);
|
||||
gUpdateWizard.addonInstalls.set(aAddon.id, aInstall);
|
||||
},
|
||||
};
|
||||
|
||||
var gMismatchPage = {
|
||||
waiting: false,
|
||||
|
||||
onPageShow() {
|
||||
gMismatchPage.waiting = true;
|
||||
gUpdateWizard.setButtonLabels(null, true,
|
||||
"mismatchCheckNow", false,
|
||||
"mismatchDontCheck", false);
|
||||
document.documentElement.getButton("next").focus();
|
||||
|
||||
var incompatible = document.getElementById("mismatch.incompatible");
|
||||
for (let addon of gUpdateWizard.addons) {
|
||||
var listitem = document.createElement("listitem");
|
||||
listitem.setAttribute("label", addon.name + " " + addon.version);
|
||||
incompatible.appendChild(listitem);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var gUpdatePage = {
|
||||
_totalCount: 0,
|
||||
_completeCount: 0,
|
||||
onPageShow() {
|
||||
gMismatchPage.waiting = false;
|
||||
gUpdateWizard.setButtonLabels(null, true,
|
||||
"nextButtonText", true,
|
||||
"cancelButtonText", false);
|
||||
document.documentElement.getButton("next").focus();
|
||||
|
||||
gUpdateWizard.errorItems = [];
|
||||
|
||||
this._totalCount = gUpdateWizard.addons.length;
|
||||
for (let addon of gUpdateWizard.addons) {
|
||||
logger.debug("UpdatePage requesting update for " + addon.id);
|
||||
// Redundant call to find updates again here when we already got them
|
||||
// in the VersionInfo page: https://bugzilla.mozilla.org/show_bug.cgi?id=960597
|
||||
addon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
|
||||
}
|
||||
},
|
||||
|
||||
onAllUpdatesFinished() {
|
||||
if (gUpdateWizard.shuttingDown)
|
||||
return;
|
||||
|
||||
var nextPage = document.getElementById("noupdates");
|
||||
if (gUpdateWizard.addonsToUpdate.length > 0)
|
||||
nextPage = document.getElementById("found");
|
||||
document.documentElement.currentPage = nextPage;
|
||||
},
|
||||
|
||||
// UpdateListener
|
||||
onUpdateAvailable(aAddon, aInstall) {
|
||||
logger.debug("UpdatePage got an update for " + aAddon.id + ": " + aAddon.version);
|
||||
gUpdateWizard.addonsToUpdate.push(aInstall);
|
||||
},
|
||||
|
||||
onUpdateFinished(aAddon, status) {
|
||||
if (status != AddonManager.UPDATE_STATUS_NO_ERROR)
|
||||
gUpdateWizard.errorItems.push(aAddon);
|
||||
|
||||
++this._completeCount;
|
||||
|
||||
if (!gUpdateWizard.shuttingDown) {
|
||||
// Update the status text and progress bar
|
||||
var updateStrings = document.getElementById("updateStrings");
|
||||
var statusElt = document.getElementById("checking.status");
|
||||
var statusString = updateStrings.getFormattedString("statusPrefix", [aAddon.name]);
|
||||
statusElt.setAttribute("value", statusString);
|
||||
|
||||
var progress = document.getElementById("checking.progress");
|
||||
progress.value = Math.ceil((this._completeCount / this._totalCount) * 100);
|
||||
}
|
||||
|
||||
if (this._completeCount == this._totalCount)
|
||||
this.onAllUpdatesFinished()
|
||||
},
|
||||
};
|
||||
|
||||
var gFoundPage = {
|
||||
onPageShow() {
|
||||
gUpdateWizard.setButtonLabels(null, true,
|
||||
"installButtonText", false,
|
||||
null, false);
|
||||
|
||||
var foundUpdates = document.getElementById("found.updates");
|
||||
for (let install of gUpdateWizard.addonsToUpdate) {
|
||||
let listItem = foundUpdates.appendItem(install.name + " " + install.version);
|
||||
listItem.setAttribute("type", "checkbox");
|
||||
listItem.setAttribute("checked", "true");
|
||||
listItem.install = install;
|
||||
}
|
||||
|
||||
if (!gUpdateWizard.xpinstallEnabled) {
|
||||
document.getElementById("xpinstallDisabledAlert").hidden = false;
|
||||
document.getElementById("enableXPInstall").focus();
|
||||
document.documentElement.getButton("next").disabled = true;
|
||||
} else {
|
||||
document.documentElement.getButton("next").focus();
|
||||
document.documentElement.getButton("next").disabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
toggleXPInstallEnable(aEvent) {
|
||||
var enabled = aEvent.target.checked;
|
||||
gUpdateWizard.xpinstallEnabled = enabled;
|
||||
var pref = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
pref.setBoolPref(PREF_XPINSTALL_ENABLED, enabled);
|
||||
this.updateNextButton();
|
||||
},
|
||||
|
||||
updateNextButton() {
|
||||
if (!gUpdateWizard.xpinstallEnabled) {
|
||||
document.documentElement.getButton("next").disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var oneChecked = false;
|
||||
var foundUpdates = document.getElementById("found.updates");
|
||||
var updates = foundUpdates.getElementsByTagName("listitem");
|
||||
for (let update of updates) {
|
||||
if (!update.checked)
|
||||
continue;
|
||||
oneChecked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gUpdateWizard.setButtonLabels(null, true,
|
||||
"installButtonText", true,
|
||||
null, false);
|
||||
document.getElementById("found").setAttribute("next", "installing");
|
||||
document.documentElement.getButton("next").disabled = !oneChecked;
|
||||
}
|
||||
};
|
||||
|
||||
var gInstallingPage = {
|
||||
_installs: [],
|
||||
_errors: [],
|
||||
_strings: null,
|
||||
_currentInstall: -1,
|
||||
_installing: false,
|
||||
|
||||
// Initialize fields we need for installing and tracking progress,
|
||||
// and start iterating through the installations
|
||||
startInstalls(aInstallList) {
|
||||
if (!gUpdateWizard.xpinstallEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let installs = Array.from(aInstallList).map(a => a.existingAddon.id);
|
||||
logger.debug("Start installs for " + installs.toSource());
|
||||
this._errors = [];
|
||||
this._installs = aInstallList;
|
||||
this._installing = true;
|
||||
this.startNextInstall();
|
||||
},
|
||||
|
||||
onPageShow() {
|
||||
gUpdateWizard.setButtonLabels(null, true,
|
||||
"nextButtonText", true,
|
||||
null, true);
|
||||
|
||||
var foundUpdates = document.getElementById("found.updates");
|
||||
var updates = foundUpdates.getElementsByTagName("listitem");
|
||||
let toInstall = [];
|
||||
for (let update of updates) {
|
||||
if (!update.checked) {
|
||||
logger.info("User chose to cancel update of " + update.label);
|
||||
gUpdateWizard.upgradeDeclined++;
|
||||
update.install.cancel();
|
||||
continue;
|
||||
}
|
||||
toInstall.push(update.install);
|
||||
}
|
||||
this._strings = document.getElementById("updateStrings");
|
||||
|
||||
this.startInstalls(toInstall);
|
||||
},
|
||||
|
||||
startNextInstall() {
|
||||
if (this._currentInstall >= 0) {
|
||||
this._installs[this._currentInstall].removeListener(this);
|
||||
}
|
||||
|
||||
this._currentInstall++;
|
||||
|
||||
if (this._installs.length == this._currentInstall) {
|
||||
Services.obs.notifyObservers(null, "TEST:all-updates-done");
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded",
|
||||
gUpdateWizard.upgraded);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed",
|
||||
gUpdateWizard.upgradeFailed);
|
||||
AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined",
|
||||
gUpdateWizard.upgradeDeclined);
|
||||
this._installing = false;
|
||||
if (gUpdateWizard.shuttingDown) {
|
||||
return;
|
||||
}
|
||||
var nextPage = this._errors.length > 0 ? "installerrors" : "finished";
|
||||
document.getElementById("installing").setAttribute("next", nextPage);
|
||||
document.documentElement.advance();
|
||||
return;
|
||||
}
|
||||
|
||||
let install = this._installs[this._currentInstall];
|
||||
|
||||
if (gUpdateWizard.shuttingDown && !AddonManager.shouldAutoUpdate(install.existingAddon)) {
|
||||
logger.debug("Don't update " + install.existingAddon.id + " in background");
|
||||
gUpdateWizard.upgradeDeclined++;
|
||||
install.cancel();
|
||||
this.startNextInstall();
|
||||
return;
|
||||
}
|
||||
install.addListener(this);
|
||||
install.install();
|
||||
},
|
||||
|
||||
// InstallListener
|
||||
onDownloadStarted(aInstall) {
|
||||
if (gUpdateWizard.shuttingDown) {
|
||||
return;
|
||||
}
|
||||
var strings = document.getElementById("updateStrings");
|
||||
var label = strings.getFormattedString("downloadingPrefix", [aInstall.name]);
|
||||
var actionItem = document.getElementById("actionItem");
|
||||
actionItem.value = label;
|
||||
},
|
||||
|
||||
onDownloadProgress(aInstall) {
|
||||
if (gUpdateWizard.shuttingDown) {
|
||||
return;
|
||||
}
|
||||
var downloadProgress = document.getElementById("downloadProgress");
|
||||
downloadProgress.value = Math.ceil(100 * aInstall.progress / aInstall.maxProgress);
|
||||
},
|
||||
|
||||
onDownloadEnded(aInstall) {
|
||||
},
|
||||
|
||||
onDownloadFailed(aInstall) {
|
||||
this._errors.push(aInstall);
|
||||
|
||||
gUpdateWizard.upgradeFailed++;
|
||||
this.startNextInstall();
|
||||
},
|
||||
|
||||
onInstallStarted(aInstall) {
|
||||
if (gUpdateWizard.shuttingDown) {
|
||||
return;
|
||||
}
|
||||
var strings = document.getElementById("updateStrings");
|
||||
var label = strings.getFormattedString("installingPrefix", [aInstall.name]);
|
||||
var actionItem = document.getElementById("actionItem");
|
||||
actionItem.value = label;
|
||||
},
|
||||
|
||||
onInstallEnded(aInstall, aAddon) {
|
||||
if (!gUpdateWizard.shuttingDown) {
|
||||
// Remember that this add-on was updated during startup
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
|
||||
aAddon.id);
|
||||
}
|
||||
|
||||
gUpdateWizard.upgraded++;
|
||||
this.startNextInstall();
|
||||
},
|
||||
|
||||
onInstallFailed(aInstall) {
|
||||
this._errors.push(aInstall);
|
||||
|
||||
gUpdateWizard.upgradeFailed++;
|
||||
this.startNextInstall();
|
||||
}
|
||||
};
|
||||
|
||||
var gInstallErrorsPage = {
|
||||
onPageShow() {
|
||||
gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
|
||||
document.documentElement.getButton("finish").focus();
|
||||
},
|
||||
};
|
||||
|
||||
// Displayed when there are incompatible add-ons and the xpinstall.enabled
|
||||
// pref is false and locked.
|
||||
var gAdminDisabledPage = {
|
||||
onPageShow() {
|
||||
gUpdateWizard.setButtonLabels(null, true, null, true,
|
||||
"cancelButtonText", true);
|
||||
document.documentElement.getButton("finish").focus();
|
||||
}
|
||||
};
|
||||
|
||||
// Displayed when selected add-on updates have been installed without error.
|
||||
// There can still be add-ons that are not compatible and don't have an update.
|
||||
var gFinishedPage = {
|
||||
onPageShow() {
|
||||
gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
|
||||
document.documentElement.getButton("finish").focus();
|
||||
|
||||
if (gUpdateWizard.shouldSuggestAutoChecking) {
|
||||
document.getElementById("finishedCheckDisabled").hidden = false;
|
||||
gUpdateWizard.shouldAutoCheck = true;
|
||||
} else
|
||||
document.getElementById("finishedCheckEnabled").hidden = false;
|
||||
|
||||
document.documentElement.getButton("finish").focus();
|
||||
}
|
||||
};
|
||||
|
||||
// Displayed when there are incompatible add-ons and there are no available
|
||||
// updates.
|
||||
var gNoUpdatesPage = {
|
||||
onPageShow(aEvent) {
|
||||
gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
|
||||
if (gUpdateWizard.shouldSuggestAutoChecking) {
|
||||
document.getElementById("noupdatesCheckDisabled").hidden = false;
|
||||
gUpdateWizard.shouldAutoCheck = true;
|
||||
} else
|
||||
document.getElementById("noupdatesCheckEnabled").hidden = false;
|
||||
|
||||
gUpdateWizard.checkForErrors("updateCheckErrorNotFound");
|
||||
document.documentElement.getButton("finish").focus();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/skin/extensions/update.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE wizard [
|
||||
<!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/extensions/update.dtd">
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%updateDTD;
|
||||
%brandDTD;
|
||||
]>
|
||||
|
||||
<wizard id="updateWizard"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&updateWizard.title;"
|
||||
windowtype="Addons:Compatibility"
|
||||
branded="true"
|
||||
onload="gUpdateWizard.init();"
|
||||
onwizardfinish="gUpdateWizard.onWizardFinish();"
|
||||
onwizardcancel="return gUpdateWizard.onWizardCancel();"
|
||||
onclose="return gUpdateWizard.onWizardClose(event);"
|
||||
buttons="accept,cancel">
|
||||
|
||||
<script type="application/javascript" src="chrome://mozapps/content/extensions/update.js"/>
|
||||
|
||||
<stringbundleset id="updateSet">
|
||||
<stringbundle id="brandStrings" src="chrome://branding/locale/brand.properties"/>
|
||||
<stringbundle id="updateStrings" src="chrome://mozapps/locale/extensions/update.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<wizardpage id="dummy" pageid="dummy"/>
|
||||
|
||||
<wizardpage id="offline" pageid="offline" next="versioninfo"
|
||||
label="&offline.title;"
|
||||
onpageadvanced="return gOfflinePage.onPageAdvanced();">
|
||||
<description>&offline.description;</description>
|
||||
<checkbox id="toggleOffline"
|
||||
checked="true"
|
||||
label="&offline.toggleOffline.label;"
|
||||
accesskey="&offline.toggleOffline.accesskey;"
|
||||
oncommand="gOfflinePage.toggleOffline();"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="versioninfo" pageid="versioninfo" next="mismatch"
|
||||
label="&versioninfo.wizard.title;"
|
||||
onpageshow="gVersionInfoPage.onPageShow();">
|
||||
<label>&versioninfo.top.label;</label>
|
||||
<separator class="thin"/>
|
||||
<progressmeter id="versioninfo.progress" mode="undetermined"/>
|
||||
<hbox align="center">
|
||||
<image id="versioninfo.throbber" class="throbber"/>
|
||||
<label flex="1" id="versioninfo.status" crop="right">&versioninfo.waiting;</label>
|
||||
</hbox>
|
||||
<separator/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="mismatch" pageid="mismatch" next="checking"
|
||||
label="&mismatch.win.title;"
|
||||
onpageshow="gMismatchPage.onPageShow();">
|
||||
<label>&mismatch.top.label;</label>
|
||||
<separator class="thin"/>
|
||||
<listbox id="mismatch.incompatible" flex="1"/>
|
||||
<separator class="thin"/>
|
||||
<label>&mismatch.bottom.label;</label>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="checking" pageid="checking" next="noupdates"
|
||||
label="&checking.wizard.title;"
|
||||
onpageshow="gUpdatePage.onPageShow();">
|
||||
<label>&checking.top.label;</label>
|
||||
<separator class="thin"/>
|
||||
<progressmeter id="checking.progress"/>
|
||||
<hbox align="center">
|
||||
<image id="checking.throbber" class="throbber"/>
|
||||
<label id="checking.status" flex="1" crop="right">&checking.status;</label>
|
||||
</hbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="noupdates" pageid="noupdates"
|
||||
label="&noupdates.wizard.title;"
|
||||
onpageshow="gNoUpdatesPage.onPageShow();">
|
||||
<description>&noupdates.intro.desc;</description>
|
||||
<separator class="thin"/>
|
||||
<hbox id="updateCheckErrorNotFound" class="alertBox" hidden="true" align="top">
|
||||
<description flex="1">&noupdates.error.desc;</description>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<description id="noupdatesCheckEnabled" hidden="true">
|
||||
&noupdates.checkEnabled.desc;
|
||||
</description>
|
||||
<vbox id="noupdatesCheckDisabled" hidden="true">
|
||||
<description>&finished.checkDisabled.desc;</description>
|
||||
<checkbox label="&enableChecking.label;" checked="true"
|
||||
oncommand="gUpdateWizard.shouldAutoCheck = this.checked;"/>
|
||||
</vbox>
|
||||
<separator flex="1"/>
|
||||
#ifndef XP_MACOSX
|
||||
<label>&clickFinish.label;</label>
|
||||
#else
|
||||
<label>&clickFinish.labelMac;</label>
|
||||
#endif
|
||||
<separator class="thin"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="found" pageid="found" next="installing"
|
||||
label="&found.wizard.title;"
|
||||
onpageshow="gFoundPage.onPageShow();">
|
||||
<label>&found.top.label;</label>
|
||||
<separator class="thin"/>
|
||||
<listbox id="found.updates" flex="1" seltype="multiple"
|
||||
onclick="gFoundPage.updateNextButton();"/>
|
||||
<separator class="thin"/>
|
||||
<vbox align="left" id="xpinstallDisabledAlert" hidden="true">
|
||||
<description>&found.disabledXPinstall.label;</description>
|
||||
<checkbox label="&found.enableXPInstall.label;"
|
||||
id="enableXPInstall"
|
||||
accesskey="&found.enableXPInstall.accesskey;"
|
||||
oncommand="gFoundPage.toggleXPInstallEnable(event);"/>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="installing" pageid="installing" next="finished"
|
||||
label="&installing.wizard.title;"
|
||||
onpageshow="gInstallingPage.onPageShow();">
|
||||
<label>&installing.top.label;</label>
|
||||
<progressmeter id="downloadProgress"/>
|
||||
<hbox align="center">
|
||||
<image id="installing.throbber" class="throbber"/>
|
||||
<label id="actionItem" flex="1" crop="right"/>
|
||||
</hbox>
|
||||
<separator/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="installerrors" pageid="installerrors"
|
||||
label="&installerrors.wizard.title;"
|
||||
onpageshow="gInstallErrorsPage.onPageShow();">
|
||||
<hbox align="top" class="alertBox">
|
||||
<description flex="1">&installerrors.intro.label;</description>
|
||||
</hbox>
|
||||
<separator flex="1"/>
|
||||
#ifndef XP_MACOSX
|
||||
<label>&clickFinish.label;</label>
|
||||
#else
|
||||
<label>&clickFinish.labelMac;</label>
|
||||
#endif
|
||||
<separator class="thin"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="adminDisabled" pageid="adminDisabled"
|
||||
label="&adminDisabled.wizard.title;"
|
||||
onpageshow="gAdminDisabledPage.onPageShow();">
|
||||
<separator/>
|
||||
<hbox class="alertBox" align="top">
|
||||
<description flex="1">&adminDisabled.warning.label;</description>
|
||||
</hbox>
|
||||
<separator flex="1"/>
|
||||
#ifndef XP_MACOSX
|
||||
<label>&clickFinish.label;</label>
|
||||
#else
|
||||
<label>&clickFinish.labelMac;</label>
|
||||
#endif
|
||||
<separator class="thin"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="finished" pageid="finished"
|
||||
label="&finished.wizard.title;"
|
||||
onpageshow="gFinishedPage.onPageShow();">
|
||||
|
||||
<label>&finished.top.label;</label>
|
||||
<separator/>
|
||||
<description id="finishedCheckEnabled" hidden="true">
|
||||
&finished.checkEnabled.desc;
|
||||
</description>
|
||||
<vbox id="finishedCheckDisabled" hidden="true">
|
||||
<description>&finished.checkDisabled.desc;</description>
|
||||
<checkbox label="&enableChecking.label;" checked="true"
|
||||
oncommand="gUpdateWizard.shouldAutoCheck = this.checked;"/>
|
||||
</vbox>
|
||||
<separator flex="1"/>
|
||||
#ifndef XP_MACOSX
|
||||
<label>&clickFinish.label;</label>
|
||||
#else
|
||||
<label>&clickFinish.labelMac;</label>
|
||||
#endif
|
||||
<separator class="thin"/>
|
||||
</wizardpage>
|
||||
|
||||
</wizard>
|
||||
|
|
@ -36,8 +36,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
isAddonPartOfE10SRollout: "resource://gre/modules/addons/E10SAddonsRollout.jsm",
|
||||
JSONFile: "resource://gre/modules/JSONFile.jsm",
|
||||
LegacyExtensionsUtils: "resource://gre/modules/LegacyExtensionsUtils.jsm",
|
||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
clearTimeout: "resource://gre/modules/Timer.jsm",
|
||||
|
||||
DownloadAddonInstall: "resource://gre/modules/addons/XPIInstall.jsm",
|
||||
LocalAddonInstall: "resource://gre/modules/addons/XPIInstall.jsm",
|
||||
|
@ -109,6 +107,7 @@ const OBSOLETE_PREFERENCES = [
|
|||
"extensions.installCache",
|
||||
];
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
|
||||
|
||||
const DIR_EXTENSIONS = "extensions";
|
||||
|
@ -773,20 +772,6 @@ function canRunInSafeMode(aAddon) {
|
|||
return aAddon._installLocation.isSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this addon should be disabled due to being legacy
|
||||
*
|
||||
* @param {Addon} addon The addon to check
|
||||
*
|
||||
* @returns {boolean} Whether the addon should be disabled for being legacy
|
||||
*/
|
||||
function isDisabledLegacy(addon) {
|
||||
return (!AddonSettings.ALLOW_LEGACY_EXTENSIONS &&
|
||||
LEGACY_TYPES.has(addon.type) &&
|
||||
!addon._installLocation.isSystem &&
|
||||
addon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates whether an add-on should be appDisabled or not.
|
||||
*
|
||||
|
@ -843,7 +828,9 @@ function isUsableAddon(aAddon) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (isDisabledLegacy(aAddon)) {
|
||||
if (!AddonSettings.ALLOW_LEGACY_EXTENSIONS && LEGACY_TYPES.has(aAddon.type) &&
|
||||
!aAddon._installLocation.isSystem &&
|
||||
aAddon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED) {
|
||||
logger.warn(`disabling legacy extension ${aAddon.id}`);
|
||||
return false;
|
||||
}
|
||||
|
@ -2173,11 +2160,10 @@ this.XPIProvider = {
|
|||
AddonManagerPrivate.markProviderSafe(this);
|
||||
|
||||
if (aAppChanged && !this.allAppGlobal &&
|
||||
Services.prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true) &&
|
||||
AddonManager.updateEnabled) {
|
||||
Services.prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true)) {
|
||||
let addonsToUpdate = this.shouldForceUpdateCheck(aAppChanged);
|
||||
if (addonsToUpdate) {
|
||||
this.noLegacyStartupCheck(addonsToUpdate);
|
||||
this.showUpgradeUI(addonsToUpdate);
|
||||
flushCaches = true;
|
||||
}
|
||||
}
|
||||
|
@ -2209,12 +2195,6 @@ this.XPIProvider = {
|
|||
AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_begin");
|
||||
|
||||
for (let addon of this.sortBootstrappedAddons()) {
|
||||
// The startup update check above may have already started some
|
||||
// extensions, make sure not to try to start them twice.
|
||||
let activeAddon = this.activeAddons.get(addon.id);
|
||||
if (activeAddon && activeAddon.started) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
let reason = BOOTSTRAP_REASONS.APP_STARTUP;
|
||||
// Eventually set INSTALLED reason when a bootstrap addon
|
||||
|
@ -2435,8 +2415,9 @@ this.XPIProvider = {
|
|||
* application directory then we may need to synchronize compatibility
|
||||
* information but only if the mismatch UI isn't disabled.
|
||||
*
|
||||
* @returns null if no update check is needed, otherwise an array of add-on
|
||||
* IDs to check for updates.
|
||||
* @returns False if no update check is needed, otherwise an array of add-on
|
||||
* IDs to check for updates. Array may be empty if no add-ons can be/need
|
||||
* to be updated, but the metadata check needs to be performed.
|
||||
*/
|
||||
shouldForceUpdateCheck(aAppChanged) {
|
||||
AddonManagerPrivate.recordSimpleMeasure("XPIDB_metadata_age", AddonRepository.metadataAge());
|
||||
|
@ -2451,132 +2432,49 @@ this.XPIProvider = {
|
|||
for (let addon of addons) {
|
||||
if ((startupChanges.indexOf(addon.id) != -1) &&
|
||||
(addon.permissions() & AddonManager.PERM_CAN_UPGRADE) &&
|
||||
(!addon.isCompatible || isDisabledLegacy(addon))) {
|
||||
!addon.isCompatible) {
|
||||
logger.debug("shouldForceUpdateCheck: can upgrade disabled add-on " + addon.id);
|
||||
forceUpdate.push(addon.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AddonRepository.isMetadataStale()) {
|
||||
logger.debug("shouldForceUpdateCheck: metadata is stale");
|
||||
return forceUpdate;
|
||||
}
|
||||
if (forceUpdate.length > 0) {
|
||||
return forceUpdate;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Perform startup check for updates of legacy extensions.
|
||||
* This runs during startup when an app update has made some add-ons
|
||||
* incompatible and legacy add-on support is diasabled.
|
||||
* In this case, we just do a quiet update check.
|
||||
* Shows the "Compatibility Updates" UI.
|
||||
*
|
||||
* @param {Array<string>} ids The ids of the addons to check for updates.
|
||||
*
|
||||
* @returns {Set<string>} The ids of any addons that were updated. These
|
||||
* addons will have been started by the update
|
||||
* process so they should not be started by the
|
||||
* regular bootstrap startup code.
|
||||
* @param aAddonIDs
|
||||
* Array opf addon IDs that were disabled by the application update, and
|
||||
* should therefore be checked for updates.
|
||||
*/
|
||||
noLegacyStartupCheck(ids) {
|
||||
let started = new Set();
|
||||
const DIALOG = "chrome://mozapps/content/extensions/update.html";
|
||||
const SHOW_DIALOG_DELAY = 1000;
|
||||
const SHOW_CANCEL_DELAY = 30000;
|
||||
showUpgradeUI(aAddonIDs) {
|
||||
logger.debug("XPI_showUpgradeUI: " + aAddonIDs.toSource());
|
||||
Services.telemetry.getHistogramById("ADDON_MANAGER_UPGRADE_UI_SHOWN").add(1);
|
||||
|
||||
// Keep track of a value between 0 and 1 indicating the progress
|
||||
// for each addon. Just combine these linearly into a single
|
||||
// value for the progress bar in the update dialog.
|
||||
let updateProgress = val => {};
|
||||
let progressByID = new Map();
|
||||
function setProgress(id, val) {
|
||||
progressByID.set(id, val);
|
||||
updateProgress(Array.from(progressByID.values()).reduce((a, b) => a + b) / progressByID.size);
|
||||
}
|
||||
// Flip a flag to indicate that we interrupted startup with an interactive prompt
|
||||
Services.startup.interrupted = true;
|
||||
|
||||
// Do an update check for one addon and try to apply the update if
|
||||
// there is one. Progress for the check is arbitrarily defined as
|
||||
// 10% done when the update check is done, between 10-90% during the
|
||||
// download, then 100% when the update has been installed.
|
||||
let checkOne = async (id) => {
|
||||
logger.debug(`Checking for updates to disabled addon ${id}\n`);
|
||||
var variant = Cc["@mozilla.org/variant;1"].
|
||||
createInstance(Ci.nsIWritableVariant);
|
||||
variant.setFromVariant(aAddonIDs);
|
||||
|
||||
setProgress(id, 0);
|
||||
// This *must* be modal as it has to block startup.
|
||||
var features = "chrome,centerscreen,dialog,titlebar,modal";
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
|
||||
|
||||
let addon = await AddonManager.getAddonByID(id);
|
||||
let install = await new Promise(resolve => addon.findUpdates({
|
||||
onUpdateFinished() { resolve(null); },
|
||||
onUpdateAvailable(addon, install) { resolve(install); },
|
||||
}, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED));
|
||||
|
||||
if (!install) {
|
||||
setProgress(id, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
setProgress(id, 0.1);
|
||||
|
||||
let installPromise = new Promise(resolve => {
|
||||
let finish = () => {
|
||||
setProgress(id, 1);
|
||||
resolve();
|
||||
};
|
||||
install.addListener({
|
||||
onDownloadProgress() {
|
||||
if (install.maxProgress != 0) {
|
||||
setProgress(id, 0.1 + 0.8 * install.progress / install.maxProgress);
|
||||
}
|
||||
},
|
||||
onDownloadEnded() {
|
||||
setProgress(id, 0.9);
|
||||
},
|
||||
onDownloadFailed: finish,
|
||||
onInstallFailed: finish,
|
||||
onInstallEnded() {
|
||||
started.add(id);
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED, id);
|
||||
finish();
|
||||
},
|
||||
});
|
||||
});
|
||||
install.install();
|
||||
await installPromise;
|
||||
};
|
||||
|
||||
let finished = false;
|
||||
Promise.all(ids.map(checkOne)).then(() => { finished = true; });
|
||||
|
||||
let window;
|
||||
let timer = setTimeout(() => {
|
||||
const FEATURES = "chrome,dialog,centerscreen,scrollbars=no";
|
||||
window = Services.ww.openWindow(null, DIALOG, "", FEATURES, null);
|
||||
|
||||
let cancelDiv;
|
||||
window.addEventListener("DOMContentLoaded", e => {
|
||||
let progress = window.document.getElementById("progress");
|
||||
updateProgress = val => { progress.value = val; };
|
||||
|
||||
cancelDiv = window.document.getElementById("cancel-section");
|
||||
cancelDiv.setAttribute("style", "display: none;");
|
||||
|
||||
let cancelBtn = window.document.getElementById("cancel-btn");
|
||||
cancelBtn.addEventListener("click", e => { finished = true; });
|
||||
});
|
||||
|
||||
timer = setTimeout(() => {
|
||||
cancelDiv.removeAttribute("style");
|
||||
window.sizeToContent();
|
||||
}, SHOW_CANCEL_DELAY - SHOW_DIALOG_DELAY);
|
||||
}, SHOW_DIALOG_DELAY);
|
||||
|
||||
Services.tm.spinEventLoopUntil(() => finished);
|
||||
|
||||
clearTimeout(timer);
|
||||
if (window) {
|
||||
window.close();
|
||||
}
|
||||
|
||||
return started;
|
||||
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
|
||||
},
|
||||
|
||||
async updateSystemAddons() {
|
||||
|
@ -4283,7 +4181,6 @@ this.XPIProvider = {
|
|||
bootstrapScope: null,
|
||||
// a Symbol passed to this add-on, which it can use to identify itself
|
||||
instanceID: Symbol(aId),
|
||||
started: false,
|
||||
});
|
||||
|
||||
// Mark the add-on as active for the crash reporter before loading
|
||||
|
@ -4440,18 +4337,12 @@ this.XPIProvider = {
|
|||
// That will be logged below.
|
||||
}
|
||||
|
||||
if (aMethod == "startup") {
|
||||
activeAddon.started = true;
|
||||
} else if (aMethod == "shutdown") {
|
||||
activeAddon.started = false;
|
||||
|
||||
// Extensions are automatically deinitialized in the correct order at shutdown.
|
||||
if (aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
|
||||
activeAddon.disable = true;
|
||||
for (let addon of this.getDependentAddons(aAddon)) {
|
||||
if (addon.active)
|
||||
this.updateAddonDisabledState(addon);
|
||||
}
|
||||
// Extensions are automatically deinitialized in the correct order at shutdown.
|
||||
if (aMethod == "shutdown" && aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
|
||||
activeAddon.disable = true;
|
||||
for (let addon of this.getDependentAddons(aAddon)) {
|
||||
if (addon.active)
|
||||
this.updateAddonDisabledState(addon);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,8 @@ toolkit.jar:
|
|||
content/mozapps/extensions/blocklist.js (content/blocklist.js)
|
||||
content/mozapps/extensions/blocklist.css (content/blocklist.css)
|
||||
content/mozapps/extensions/blocklist.xml (content/blocklist.xml)
|
||||
content/mozapps/extensions/update.html (content/update.html)
|
||||
* content/mozapps/extensions/update.xul (content/update.xul)
|
||||
content/mozapps/extensions/update.js (content/update.js)
|
||||
content/mozapps/extensions/update.css (content/update.css)
|
||||
content/mozapps/extensions/eula.xul (content/eula.xul)
|
||||
content/mozapps/extensions/eula.js (content/eula.js)
|
||||
content/mozapps/extensions/newaddon.xul (content/newaddon.xul)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>min1max1@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>1</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Test minVersion 1 maxVersion 1</em:name>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>min1max3@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Test minVersion 1 maxVersion 3</em:name>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>min1max3b@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Another Test minVersion 1 maxVersion 3</em:name>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>override1x2-1x3@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
<em:updateURL>http://localhost:4444/data/test_bug542391.rdf</em:updateURL>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>2</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Test override compat from 1..2 to 1..3</em:name>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>upgradeable1x2-3@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>2</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Test min 1 max 2 upgrade to 3</em:name>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>upgradeable1x2-3@tests.mozilla.org</em:id>
|
||||
<em:version>2.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>3</em:minVersion>
|
||||
<em:maxVersion>3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Test min 1 max 2 upgrade to 3</em:name>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-1@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon1</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-10@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon10</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-2@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon2</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-3@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon3</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-4@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>1.0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon4</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-5@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon5</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-6@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon6</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-7@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon7</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичные данные
toolkit/mozapps/extensions/test/browser/addons/browser_bug557956_8_1.xpi
Normal file
Двоичные данные
toolkit/mozapps/extensions/test/browser/addons/browser_bug557956_8_1.xpi
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-8@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon8</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Двоичные данные
toolkit/mozapps/extensions/test/browser/addons/browser_bug557956_9_1.xpi
Normal file
Двоичные данные
toolkit/mozapps/extensions/test/browser/addons/browser_bug557956_9_1.xpi
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>bug557956-9@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0.3</em:minVersion>
|
||||
<em:maxVersion>0.3</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Addon9</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
|
@ -37,6 +37,7 @@ skip-if = buildapp == 'mulet'
|
|||
[browser_dragdrop_incompat.js]
|
||||
[browser_experiments.js]
|
||||
[browser_list.js]
|
||||
[browser_metadataTimeout.js]
|
||||
[browser_sorting.js]
|
||||
[browser_sorting_plugins.js]
|
||||
[browser_plugin_enabled_state_locked.js]
|
||||
|
|
|
@ -4,6 +4,7 @@ support-files =
|
|||
addons/*
|
||||
addon_about.xul
|
||||
addon_prefs.xul
|
||||
cancelCompatCheck.sjs
|
||||
discovery.html
|
||||
discovery_frame.html
|
||||
discovery_install.html
|
||||
|
@ -15,6 +16,10 @@ support-files =
|
|||
releaseNotes.xhtml
|
||||
blockNoPlugins.xml
|
||||
blockPluginHard.xml
|
||||
browser_bug557956.rdf
|
||||
browser_bug557956_8_2.xpi
|
||||
browser_bug557956_9_2.xpi
|
||||
browser_bug557956.xml
|
||||
browser_bug591465.xml
|
||||
browser_bug593535.xml
|
||||
browser_searching.xml
|
||||
|
@ -41,7 +46,9 @@ support-files =
|
|||
!/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi
|
||||
|
||||
[browser_addonrepository_performance.js]
|
||||
[browser_bug557956.js]
|
||||
[browser_bug616841.js]
|
||||
[browser_cancelCompatCheck.js]
|
||||
[browser_checkAddonCompatibility.js]
|
||||
[browser_discovery_install.js]
|
||||
[browser_eula.js]
|
||||
|
|
|
@ -0,0 +1,518 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Test the compatibility dialog that displays during startup when the browser
|
||||
// version changes.
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_MIN_APP_COMPAT = "extensions.minCompatibleAppVersion";
|
||||
const PREF_MIN_PLATFORM_COMPAT = "extensions.minCompatiblePlatformVersion";
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
// avoid the 'leaked window property' check
|
||||
var scope = {};
|
||||
Components.utils.import("resource://gre/modules/TelemetrySession.jsm", scope);
|
||||
var TelemetrySession = scope.TelemetrySession;
|
||||
|
||||
/**
|
||||
* Test add-ons:
|
||||
*
|
||||
* Addon minVersion maxVersion Notes
|
||||
* addon1 0 *
|
||||
* addon2 0 0
|
||||
* addon3 0 0
|
||||
* addon4 1 *
|
||||
* addon5 0 0 Made compatible by update check
|
||||
* addon6 0 0 Made compatible by update check
|
||||
* addon7 0 0 Has a broken update available
|
||||
* addon8 0 0 Has an update available
|
||||
* addon9 0 0 Has an update available
|
||||
*/
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(2);
|
||||
waitForExplicitFinish();
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
// Test generates a lot of available installs so just cancel them all
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
for (let install of aInstalls)
|
||||
install.cancel();
|
||||
|
||||
Services.prefs.clearUserPref(PREF_MIN_APP_COMPAT);
|
||||
Services.prefs.clearUserPref(PREF_MIN_PLATFORM_COMPAT);
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function install_test_addons(aCallback) {
|
||||
// Use a blank update URL
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "missing.rdf");
|
||||
|
||||
let names = ["browser_bug557956_1",
|
||||
"browser_bug557956_2",
|
||||
"browser_bug557956_3",
|
||||
"browser_bug557956_4",
|
||||
"browser_bug557956_5",
|
||||
"browser_bug557956_6",
|
||||
"browser_bug557956_7",
|
||||
"browser_bug557956_8_1",
|
||||
"browser_bug557956_9_1",
|
||||
"browser_bug557956_10"];
|
||||
|
||||
let installPromises = Promise.all(
|
||||
names.map(name => AddonManager.getInstallForURL(`${TESTROOT}addons/${name}.xpi`,
|
||||
null, "application/x-xpinstall")));
|
||||
|
||||
installPromises.then(installs => {
|
||||
var listener = {
|
||||
installCount: 0,
|
||||
|
||||
onInstallEnded() {
|
||||
this.installCount++;
|
||||
if (this.installCount == installs.length) {
|
||||
// Switch to the test update URL
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "browser_bug557956.rdf");
|
||||
|
||||
executeSoon(aCallback);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (let install of installs) {
|
||||
install.addListener(listener);
|
||||
install.install();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function uninstall_test_addons(aCallback) {
|
||||
AddonManager.getAddonsByIDs(["bug557956-1@tests.mozilla.org",
|
||||
"bug557956-2@tests.mozilla.org",
|
||||
"bug557956-3@tests.mozilla.org",
|
||||
"bug557956-4@tests.mozilla.org",
|
||||
"bug557956-5@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org",
|
||||
"bug557956-7@tests.mozilla.org",
|
||||
"bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org",
|
||||
"bug557956-10@tests.mozilla.org"],
|
||||
function(aAddons) {
|
||||
for (let addon of aAddons) {
|
||||
if (addon)
|
||||
addon.uninstall();
|
||||
}
|
||||
aCallback();
|
||||
});
|
||||
}
|
||||
|
||||
// Open the compatibility dialog, with the list of addon IDs
|
||||
// that were disabled by this "update"
|
||||
function open_compatibility_window(aDisabledAddons, aCallback) {
|
||||
// This will reset the longer timeout multiplier to 2 which will give each
|
||||
// test that calls open_compatibility_window a minimum of 60 seconds to
|
||||
// complete.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
var variant = Cc["@mozilla.org/variant;1"].
|
||||
createInstance(Ci.nsIWritableVariant);
|
||||
variant.setFromVariant(aDisabledAddons);
|
||||
|
||||
// Cannot be modal as we want to interact with it, shouldn't cause problems
|
||||
// with testing though.
|
||||
var features = "chrome,centerscreen,dialog,titlebar";
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
var win = ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
|
||||
|
||||
win.addEventListener("load", function() {
|
||||
info("Compatibility dialog opened");
|
||||
|
||||
function page_shown(aEvent) {
|
||||
if (aEvent.target.pageid)
|
||||
info("Page " + aEvent.target.pageid + " shown");
|
||||
}
|
||||
|
||||
win.addEventListener("pageshow", page_shown);
|
||||
win.addEventListener("unload", function() {
|
||||
win.removeEventListener("pageshow", page_shown);
|
||||
info("Compatibility dialog closed");
|
||||
}, {once: true});
|
||||
|
||||
aCallback(win);
|
||||
}, {once: true});
|
||||
}
|
||||
|
||||
function wait_for_window_close(aWindow, aCallback) {
|
||||
aWindow.addEventListener("unload", function() {
|
||||
aCallback();
|
||||
}, {once: true});
|
||||
}
|
||||
|
||||
function wait_for_page(aWindow, aPageId, aCallback) {
|
||||
var page = aWindow.document.getElementById(aPageId);
|
||||
page.addEventListener("pageshow", function() {
|
||||
executeSoon(function() {
|
||||
aCallback(aWindow);
|
||||
});
|
||||
}, {once: true});
|
||||
}
|
||||
|
||||
function get_list_names(aList) {
|
||||
var items = [];
|
||||
for (let listItem of aList.childNodes)
|
||||
items.push(listItem.label);
|
||||
items.sort();
|
||||
return items;
|
||||
}
|
||||
|
||||
function check_telemetry({disabled, metaenabled, metadisabled, upgraded, failed, declined}) {
|
||||
let ping = TelemetrySession.getPayload();
|
||||
// info(JSON.stringify(ping));
|
||||
let am = ping.simpleMeasurements.addonManager;
|
||||
if (disabled !== undefined)
|
||||
is(am.appUpdate_disabled, disabled, disabled + " add-ons disabled by version change");
|
||||
if (metaenabled !== undefined)
|
||||
is(am.appUpdate_metadata_enabled, metaenabled, metaenabled + " add-ons enabled by metadata");
|
||||
if (metadisabled !== undefined)
|
||||
is(am.appUpdate_metadata_disabled, metadisabled, metadisabled + " add-ons disabled by metadata");
|
||||
if (upgraded !== undefined)
|
||||
is(am.appUpdate_upgraded, upgraded, upgraded + " add-ons upgraded");
|
||||
if (failed !== undefined)
|
||||
is(am.appUpdate_upgradeFailed, failed, failed + " upgrades failed");
|
||||
if (declined !== undefined)
|
||||
is(am.appUpdate_upgradeDeclined, declined, declined + " upgrades declined");
|
||||
}
|
||||
|
||||
add_test(function test_setup() {
|
||||
let oldCanRecord = Services.telemetry.canRecordExtended;
|
||||
Services.telemetry.canRecordExtended = true;
|
||||
registerCleanupFunction(function() {
|
||||
Services.telemetry.canRecordExtended = oldCanRecord;
|
||||
});
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
// Tests that the right add-ons show up in the mismatch dialog and updates can
|
||||
// be installed
|
||||
add_test(function basic_mismatch() {
|
||||
install_test_addons(function() {
|
||||
// These add-ons become disabled
|
||||
var disabledAddonIds = [
|
||||
"bug557956-3@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org",
|
||||
"bug557956-7@tests.mozilla.org",
|
||||
"bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org"
|
||||
];
|
||||
|
||||
AddonManager.getAddonsByIDs(["bug557956-5@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org"],
|
||||
function([a5, a6]) {
|
||||
// Check starting (pre-update) conditions
|
||||
ok(!a5.isCompatible, "bug557956-5 should not be compatible");
|
||||
ok(!a6.isCompatible, "bug557956-6 should not be compatible");
|
||||
|
||||
open_compatibility_window(disabledAddonIds, function(aWindow) {
|
||||
var doc = aWindow.document;
|
||||
wait_for_page(aWindow, "mismatch", function(aWindow) {
|
||||
var items = get_list_names(doc.getElementById("mismatch.incompatible"));
|
||||
// Check that compatibility updates from individual add-on update checks were applied.
|
||||
is(items.length, 4, "Should have seen 4 still incompatible items");
|
||||
is(items[0], "Addon3 1.0", "Should have seen addon3 still incompatible");
|
||||
is(items[1], "Addon7 1.0", "Should have seen addon7 still incompatible");
|
||||
is(items[2], "Addon8 1.0", "Should have seen addon8 still incompatible");
|
||||
is(items[3], "Addon9 1.0", "Should have seen addon9 still incompatible");
|
||||
|
||||
// If it wasn't disabled by this run, we don't try to enable it
|
||||
ok(!a5.isCompatible, "bug557956-5 should not be compatible");
|
||||
ok(a6.isCompatible, "bug557956-6 should be compatible");
|
||||
|
||||
var button = doc.documentElement.getButton("next");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_page(aWindow, "found", function(aWindow) {
|
||||
ok(doc.getElementById("xpinstallDisabledAlert").hidden,
|
||||
"Install should be allowed");
|
||||
|
||||
var list = doc.getElementById("found.updates");
|
||||
var items = get_list_names(list);
|
||||
is(items.length, 3, "Should have seen 3 updates available");
|
||||
is(items[0], "Addon7 2.0", "Should have seen update for addon7");
|
||||
is(items[1], "Addon8 2.0", "Should have seen update for addon8");
|
||||
is(items[2], "Addon9 2.0", "Should have seen update for addon9");
|
||||
|
||||
ok(!doc.documentElement.getButton("next").disabled,
|
||||
"Next button should be enabled");
|
||||
|
||||
// Uncheck all
|
||||
for (let listItem of list.childNodes)
|
||||
EventUtils.synthesizeMouse(listItem, 2, 2, { }, aWindow);
|
||||
|
||||
ok(doc.documentElement.getButton("next").disabled,
|
||||
"Next button should not be enabled");
|
||||
|
||||
// Check the ones we want to install
|
||||
for (let listItem of list.childNodes) {
|
||||
if (listItem.label != "Addon7 2.0")
|
||||
EventUtils.synthesizeMouse(listItem, 2, 2, { }, aWindow);
|
||||
}
|
||||
|
||||
var button = doc.documentElement.getButton("next");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_page(aWindow, "finished", function(aWindow) {
|
||||
var button = doc.documentElement.getButton("finish");
|
||||
ok(!button.hidden, "Finish button should not be hidden");
|
||||
ok(!button.disabled, "Finish button should not be disabled");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_window_close(aWindow, function() {
|
||||
AddonManager.getAddonsByIDs(["bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org"],
|
||||
function([a8, a9]) {
|
||||
is(a8.version, "2.0", "bug557956-8 should have updated");
|
||||
is(a9.version, "2.0", "bug557956-9 should have updated");
|
||||
|
||||
check_telemetry({disabled: 5, metaenabled: 1, metadisabled: 0,
|
||||
upgraded: 2, failed: 0, declined: 1});
|
||||
|
||||
uninstall_test_addons(run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that the install failures show the install failed page and disabling
|
||||
// xpinstall shows the right UI.
|
||||
add_test(function failure_page() {
|
||||
install_test_addons(function() {
|
||||
// These add-ons become disabled
|
||||
var disabledAddonIds = [
|
||||
"bug557956-3@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org",
|
||||
"bug557956-7@tests.mozilla.org",
|
||||
"bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org"
|
||||
];
|
||||
|
||||
Services.prefs.setBoolPref("xpinstall.enabled", false);
|
||||
|
||||
open_compatibility_window(disabledAddonIds, function(aWindow) {
|
||||
var doc = aWindow.document;
|
||||
wait_for_page(aWindow, "mismatch", function(aWindow) {
|
||||
var items = get_list_names(doc.getElementById("mismatch.incompatible"));
|
||||
is(items.length, 4, "Should have seen 4 still incompatible items");
|
||||
is(items[0], "Addon3 1.0", "Should have seen addon3 still incompatible");
|
||||
is(items[1], "Addon7 1.0", "Should have seen addon7 still incompatible");
|
||||
is(items[2], "Addon8 1.0", "Should have seen addon8 still incompatible");
|
||||
is(items[3], "Addon9 1.0", "Should have seen addon9 still incompatible");
|
||||
|
||||
// Check that compatibility updates were applied.
|
||||
AddonManager.getAddonsByIDs(["bug557956-5@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org"],
|
||||
function([a5, a6]) {
|
||||
ok(!a5.isCompatible, "bug557956-5 should not be compatible");
|
||||
ok(a6.isCompatible, "bug557956-6 should be compatible");
|
||||
|
||||
var button = doc.documentElement.getButton("next");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_page(aWindow, "found", function(aWindow) {
|
||||
ok(!doc.getElementById("xpinstallDisabledAlert").hidden,
|
||||
"Install should not be allowed");
|
||||
|
||||
ok(doc.documentElement.getButton("next").disabled,
|
||||
"Next button should be disabled");
|
||||
|
||||
var checkbox = doc.getElementById("enableXPInstall");
|
||||
EventUtils.synthesizeMouse(checkbox, 2, 2, { }, aWindow);
|
||||
|
||||
ok(!doc.documentElement.getButton("next").disabled,
|
||||
"Next button should be enabled");
|
||||
|
||||
var list = doc.getElementById("found.updates");
|
||||
var items = get_list_names(list);
|
||||
is(items.length, 3, "Should have seen 3 updates available");
|
||||
is(items[0], "Addon7 2.0", "Should have seen update for addon7");
|
||||
is(items[1], "Addon8 2.0", "Should have seen update for addon8");
|
||||
is(items[2], "Addon9 2.0", "Should have seen update for addon9");
|
||||
|
||||
// Unheck the ones we don't want to install
|
||||
for (let listItem of list.childNodes) {
|
||||
if (listItem.label != "Addon7 2.0")
|
||||
EventUtils.synthesizeMouse(listItem, 2, 2, { }, aWindow);
|
||||
}
|
||||
|
||||
var button = doc.documentElement.getButton("next");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_page(aWindow, "installerrors", function(aWindow) {
|
||||
var button = doc.documentElement.getButton("finish");
|
||||
ok(!button.hidden, "Finish button should not be hidden");
|
||||
ok(!button.disabled, "Finish button should not be disabled");
|
||||
|
||||
wait_for_window_close(aWindow, function() {
|
||||
uninstall_test_addons(run_next_test);
|
||||
});
|
||||
|
||||
check_telemetry({disabled: 5, metaenabled: 1, metadisabled: 0,
|
||||
upgraded: 0, failed: 1, declined: 2});
|
||||
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that no add-ons show up in the mismatch dialog when they are all disabled
|
||||
add_test(function all_disabled() {
|
||||
install_test_addons(function() {
|
||||
AddonManager.getAddonsByIDs(["bug557956-1@tests.mozilla.org",
|
||||
"bug557956-2@tests.mozilla.org",
|
||||
"bug557956-3@tests.mozilla.org",
|
||||
"bug557956-4@tests.mozilla.org",
|
||||
"bug557956-5@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org",
|
||||
"bug557956-7@tests.mozilla.org",
|
||||
"bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org",
|
||||
"bug557956-10@tests.mozilla.org"],
|
||||
function(aAddons) {
|
||||
for (let addon of aAddons)
|
||||
addon.userDisabled = true;
|
||||
|
||||
open_compatibility_window([], function(aWindow) {
|
||||
// Should close immediately on its own
|
||||
wait_for_window_close(aWindow, function() {
|
||||
uninstall_test_addons(run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that the right UI shows for when no updates are available
|
||||
add_test(function no_updates() {
|
||||
install_test_addons(function() {
|
||||
AddonManager.getAddonsByIDs(["bug557956-7@tests.mozilla.org",
|
||||
"bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org",
|
||||
"bug557956-10@tests.mozilla.org"],
|
||||
function(aAddons) {
|
||||
for (let addon of aAddons)
|
||||
addon.uninstall();
|
||||
|
||||
// These add-ons were disabled by the upgrade
|
||||
var inactiveAddonIds = [
|
||||
"bug557956-3@tests.mozilla.org",
|
||||
"bug557956-5@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org"
|
||||
];
|
||||
|
||||
open_compatibility_window(inactiveAddonIds, function(aWindow) {
|
||||
var doc = aWindow.document;
|
||||
wait_for_page(aWindow, "mismatch", function(aWindow) {
|
||||
var items = get_list_names(doc.getElementById("mismatch.incompatible"));
|
||||
is(items.length, 1, "Should have seen 1 still incompatible items");
|
||||
is(items[0], "Addon3 1.0", "Should have seen addon3 still incompatible");
|
||||
|
||||
var button = doc.documentElement.getButton("next");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_page(aWindow, "noupdates", function(aWindow) {
|
||||
var button = doc.documentElement.getButton("finish");
|
||||
ok(!button.hidden, "Finish button should not be hidden");
|
||||
ok(!button.disabled, "Finish button should not be disabled");
|
||||
|
||||
wait_for_window_close(aWindow, function() {
|
||||
uninstall_test_addons(run_next_test);
|
||||
});
|
||||
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that compatibility overrides are retrieved and affect addon
|
||||
// compatibility.
|
||||
add_test(function overrides_retrieved() {
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, false);
|
||||
Services.prefs.setCharPref(PREF_MIN_APP_COMPAT, "0");
|
||||
Services.prefs.setCharPref(PREF_MIN_PLATFORM_COMPAT, "0");
|
||||
is(AddonManager.strictCompatibility, false, "Strict compatibility should be disabled");
|
||||
|
||||
// Use a blank update URL
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "missing.rdf");
|
||||
|
||||
install_test_addons(function() {
|
||||
|
||||
AddonManager.getAddonsByIDs(["bug557956-1@tests.mozilla.org",
|
||||
"bug557956-2@tests.mozilla.org",
|
||||
"bug557956-3@tests.mozilla.org",
|
||||
"bug557956-4@tests.mozilla.org",
|
||||
"bug557956-5@tests.mozilla.org",
|
||||
"bug557956-6@tests.mozilla.org",
|
||||
"bug557956-7@tests.mozilla.org",
|
||||
"bug557956-8@tests.mozilla.org",
|
||||
"bug557956-9@tests.mozilla.org",
|
||||
"bug557956-10@tests.mozilla.org"],
|
||||
function(aAddons) {
|
||||
|
||||
for (let addon of aAddons) {
|
||||
if (addon.id == "bug557956-10@tests.mozilla.org")
|
||||
is(addon.isCompatible, true, "Addon10 should be compatible before compat overrides are refreshed");
|
||||
else
|
||||
addon.uninstall();
|
||||
}
|
||||
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, TESTROOT + "browser_bug557956.xml");
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
|
||||
open_compatibility_window([], function(aWindow) {
|
||||
var doc = aWindow.document;
|
||||
wait_for_page(aWindow, "mismatch", function(aWindow) {
|
||||
var items = get_list_names(doc.getElementById("mismatch.incompatible"));
|
||||
is(items.length, 1, "Should have seen 1 incompatible item");
|
||||
is(items[0], "Addon10 1.0", "Should have seen addon10 as incompatible");
|
||||
|
||||
var button = doc.documentElement.getButton("next");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
|
||||
wait_for_page(aWindow, "noupdates", function(aWindow) {
|
||||
var button = doc.documentElement.getButton("finish");
|
||||
ok(!button.hidden, "Finish button should not be hidden");
|
||||
ok(!button.disabled, "Finish button should not be disabled");
|
||||
|
||||
wait_for_window_close(aWindow, function() {
|
||||
uninstall_test_addons(run_next_test);
|
||||
});
|
||||
|
||||
check_telemetry({disabled: 0, metaenabled: 0, metadisabled: 1,
|
||||
upgraded: 0, failed: 0, declined: 0});
|
||||
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,310 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-1@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-2@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-3@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-4@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-5@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-6@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-7@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
<em:updateLink>http://example.com/browser/toolkit/mozapps/extensions/test/browser/browser_bug557956_7_2.xpi</em:updateLink>
|
||||
<em:updateHash>sha1:18674cf7ad76664e0ead6280a43cc0c681180505</em:updateHash>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
<em:updateLink>http://example.com/browser/toolkit/mozapps/extensions/test/browser/browser_bug557956_7_2.xpi</em:updateLink>
|
||||
<em:updateHash>sha1:18674cf7ad76664e0ead6280a43cc0c681180505</em:updateHash>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-8@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
<em:updateLink>http://example.com/browser/toolkit/mozapps/extensions/test/browser/browser_bug557956_8_2.xpi</em:updateLink>
|
||||
<em:updateHash>sha1:5691c398e55ddf93aa1076b9820619d21d40acbc</em:updateHash>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
<em:updateLink>http://example.com/browser/toolkit/mozapps/extensions/test/browser/browser_bug557956_8_2.xpi</em:updateLink>
|
||||
<em:updateHash>sha1:5691c398e55ddf93aa1076b9820619d21d40acbc</em:updateHash>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:bug557956-9@tests.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>0</em:maxVersion>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>2.0</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
<em:updateLink>http://example.com/browser/toolkit/mozapps/extensions/test/browser/browser_bug557956_9_2.xpi</em:updateLink>
|
||||
<em:updateHash>sha1:1ae63bfc6f67a4503a1ff1bd02402c98fef19ae3</em:updateHash>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
<em:updateLink>http://example.com/browser/toolkit/mozapps/extensions/test/browser/browser_bug557956_9_2.xpi</em:updateLink>
|
||||
<em:updateHash>sha1:1ae63bfc6f67a4503a1ff1bd02402c98fef19ae3</em:updateHash>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
|
||||
</RDF:RDF>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<searchresults total_results="1">
|
||||
<addon_compatibility hosted="false">
|
||||
<guid>bug557956-10@tests.mozilla.org</guid>
|
||||
<name>Addon10</name>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>1.0</min_version>
|
||||
<max_version>2.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>999.0</max_version>
|
||||
<appID>toolkit@mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
</searchresults>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,450 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
|
||||
// Test that we can cancel the add-on compatibility check while it is
|
||||
// in progress (bug 772484).
|
||||
// Test framework copied from browser_bug557956.js
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_MIN_PLATFORM_COMPAT = "extensions.minCompatiblePlatformVersion";
|
||||
const PREF_METADATA_LASTUPDATE = "extensions.getAddons.cache.lastUpdate";
|
||||
|
||||
var repo = {};
|
||||
Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm", repo);
|
||||
|
||||
/**
|
||||
* Test add-ons:
|
||||
*
|
||||
* Addon minVersion maxVersion Notes
|
||||
* addon1 0 *
|
||||
* addon2 0 0
|
||||
* addon3 0 0
|
||||
* addon4 1 *
|
||||
* addon5 0 0 Made compatible by update check
|
||||
* addon6 0 0 Made compatible by update check
|
||||
* addon7 0 0 Has a broken update available
|
||||
* addon8 0 0 Has an update available
|
||||
* addon9 0 0 Has an update available
|
||||
* addon10 0 0 Made incompatible by override check
|
||||
*/
|
||||
|
||||
// describe the addons
|
||||
var ao1 = { file: "browser_bug557956_1", id: "bug557956-1@tests.mozilla.org"};
|
||||
var ao2 = { file: "browser_bug557956_2", id: "bug557956-2@tests.mozilla.org"};
|
||||
var ao3 = { file: "browser_bug557956_3", id: "bug557956-3@tests.mozilla.org"};
|
||||
var ao4 = { file: "browser_bug557956_4", id: "bug557956-4@tests.mozilla.org"};
|
||||
var ao5 = { file: "browser_bug557956_5", id: "bug557956-5@tests.mozilla.org"};
|
||||
var ao6 = { file: "browser_bug557956_6", id: "bug557956-6@tests.mozilla.org"};
|
||||
var ao7 = { file: "browser_bug557956_7", id: "bug557956-7@tests.mozilla.org"};
|
||||
var ao8 = { file: "browser_bug557956_8_1", id: "bug557956-8@tests.mozilla.org"};
|
||||
var ao9 = { file: "browser_bug557956_9_1", id: "bug557956-9@tests.mozilla.org"};
|
||||
var ao10 = { file: "browser_bug557956_10", id: "bug557956-10@tests.mozilla.org"};
|
||||
|
||||
// Return a promise that resolves after the specified delay in MS
|
||||
function delayMS(aDelay) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, aDelay);
|
||||
});
|
||||
}
|
||||
|
||||
// Return a promise that resolves when the specified observer topic is notified
|
||||
function promise_observer(aTopic) {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observer(aSubject, aObsTopic, aData) {
|
||||
Services.obs.removeObserver(observer, aObsTopic);
|
||||
resolve([aSubject, aData]);
|
||||
}, aTopic);
|
||||
});
|
||||
}
|
||||
|
||||
// Install a set of addons using a bogus update URL so that we can force
|
||||
// the compatibility update to happen later
|
||||
// @param aUpdateURL The real update URL to use after the add-ons are installed
|
||||
function promise_install_test_addons(aAddonList, aUpdateURL) {
|
||||
info("Starting add-on installs");
|
||||
return new Promise(resolve => {
|
||||
|
||||
// Use a blank update URL
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "missing.rdf");
|
||||
|
||||
let installPromises = Promise.all(
|
||||
aAddonList.map(addon => AddonManager.getInstallForURL(`${TESTROOT}addons/${addon.file}.xpi`,
|
||||
null, "application/x-xpinstall")));
|
||||
|
||||
installPromises.then(installs => {
|
||||
var listener = {
|
||||
installCount: 0,
|
||||
|
||||
onInstallEnded() {
|
||||
this.installCount++;
|
||||
if (this.installCount == installs.length) {
|
||||
info("Done add-on installs");
|
||||
// Switch to the test update URL
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, aUpdateURL);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (let install of installs) {
|
||||
install.addListener(listener);
|
||||
install.install();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function promise_addons_by_ids(aAddonIDs) {
|
||||
info("promise_addons_by_ids " + aAddonIDs.toSource());
|
||||
return new Promise(resolve => {
|
||||
AddonManager.getAddonsByIDs(aAddonIDs, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
async function promise_uninstall_test_addons() {
|
||||
info("Starting add-on uninstalls");
|
||||
let addons = await promise_addons_by_ids([ao1.id, ao2.id, ao3.id, ao4.id, ao5.id,
|
||||
ao6.id, ao7.id, ao8.id, ao9.id, ao10.id]);
|
||||
await new Promise(resolve => {
|
||||
let uninstallCount = addons.length;
|
||||
let listener = {
|
||||
onUninstalled(aAddon) {
|
||||
if (aAddon) {
|
||||
info("Finished uninstalling " + aAddon.id);
|
||||
}
|
||||
if (--uninstallCount == 0) {
|
||||
info("Done add-on uninstalls");
|
||||
AddonManager.removeAddonListener(listener);
|
||||
resolve();
|
||||
}
|
||||
}};
|
||||
AddonManager.addAddonListener(listener);
|
||||
for (let addon of addons) {
|
||||
if (addon)
|
||||
addon.uninstall();
|
||||
else
|
||||
listener.onUninstalled(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Returns promise{window}, resolves with a handle to the compatibility
|
||||
// check window
|
||||
function promise_open_compatibility_window(aInactiveAddonIds) {
|
||||
return new Promise(resolve => {
|
||||
// This will reset the longer timeout multiplier to 2 which will give each
|
||||
// test that calls open_compatibility_window a minimum of 60 seconds to
|
||||
// complete.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
var variant = Cc["@mozilla.org/variant;1"].
|
||||
createInstance(Ci.nsIWritableVariant);
|
||||
variant.setFromVariant(aInactiveAddonIds);
|
||||
|
||||
// Cannot be modal as we want to interract with it, shouldn't cause problems
|
||||
// with testing though.
|
||||
var features = "chrome,centerscreen,dialog,titlebar";
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
var win = ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
|
||||
|
||||
win.addEventListener("load", function listener() {
|
||||
function page_shown(aEvent) {
|
||||
if (aEvent.target.pageid)
|
||||
info("Page " + aEvent.target.pageid + " shown");
|
||||
}
|
||||
|
||||
win.removeEventListener("load", listener);
|
||||
|
||||
info("Compatibility dialog opened");
|
||||
|
||||
win.addEventListener("pageshow", page_shown);
|
||||
win.addEventListener("unload", function() {
|
||||
win.removeEventListener("pageshow", page_shown);
|
||||
dump("Compatibility dialog closed\n");
|
||||
}, {once: true});
|
||||
|
||||
resolve(win);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function promise_window_close(aWindow) {
|
||||
return new Promise(resolve => {
|
||||
aWindow.addEventListener("unload", function() {
|
||||
resolve(aWindow);
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function promise_page(aWindow, aPageId) {
|
||||
return new Promise(resolve => {
|
||||
var page = aWindow.document.getElementById(aPageId);
|
||||
if (aWindow.document.getElementById("updateWizard").currentPage === page) {
|
||||
resolve(aWindow);
|
||||
} else {
|
||||
page.addEventListener("pageshow", function() {
|
||||
executeSoon(function() {
|
||||
resolve(aWindow);
|
||||
});
|
||||
}, {once: true});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// These add-ons became inactive during the upgrade
|
||||
var inactiveAddonIds = [
|
||||
ao5.id,
|
||||
ao6.id,
|
||||
ao7.id,
|
||||
ao8.id,
|
||||
ao9.id
|
||||
];
|
||||
|
||||
// Make sure the addons in the list are not installed
|
||||
async function check_addons_uninstalled(aAddonList) {
|
||||
let foundList = await promise_addons_by_ids(aAddonList.map(a => a.id));
|
||||
for (let i = 0; i < aAddonList.length; i++) {
|
||||
ok(!foundList[i], "Addon " + aAddonList[i].id + " is not installed");
|
||||
}
|
||||
info("Add-on uninstall check complete");
|
||||
await true;
|
||||
}
|
||||
|
||||
// Test what happens when the user cancels during AddonRepository.repopulateCache()
|
||||
// Add-ons that have updates available should not update if they were disabled before
|
||||
// For this test, addon8 became disabled during update and addon9 was previously disabled,
|
||||
// so addon8 should update and addon9 should not
|
||||
add_task(async function cancel_during_repopulate() {
|
||||
let a5, a8, a9, a10;
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
Services.prefs.setCharPref(PREF_MIN_PLATFORM_COMPAT, "0");
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "missing.rdf");
|
||||
|
||||
let installsDone = promise_observer("TEST:all-updates-done");
|
||||
|
||||
// Don't pull compatibility data during add-on install
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false);
|
||||
// Set up our test addons so that the server-side JS has a 500ms delay to make
|
||||
// sure we cancel the dialog before we get the data we want to refill our
|
||||
// AddonRepository cache
|
||||
let addonList = [ao5, ao8, ao9, ao10];
|
||||
await promise_install_test_addons(addonList,
|
||||
TESTROOT + "cancelCompatCheck.sjs?500");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, TESTROOT + "browser_bug557956.xml");
|
||||
|
||||
[a5, a8, a9] = await promise_addons_by_ids([ao5.id, ao8.id, ao9.id]);
|
||||
ok(!a5.isCompatible, "addon5 should not be compatible");
|
||||
ok(!a8.isCompatible, "addon8 should not be compatible");
|
||||
ok(!a9.isCompatible, "addon9 should not be compatible");
|
||||
|
||||
let compatWindow = await promise_open_compatibility_window([ao5.id, ao8.id]);
|
||||
var doc = compatWindow.document;
|
||||
await promise_page(compatWindow, "versioninfo");
|
||||
|
||||
// Brief delay to let the update window finish requesting all add-ons and start
|
||||
// reloading the addon repository
|
||||
await delayMS(50);
|
||||
|
||||
info("Cancel the compatibility check dialog");
|
||||
var button = doc.documentElement.getButton("cancel");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, compatWindow);
|
||||
|
||||
info("Waiting for installs to complete");
|
||||
await installsDone;
|
||||
ok(!repo.AddonRepository.isSearching, "Background installs are done");
|
||||
|
||||
// There should be no active updates
|
||||
let installs = await new Promise(resolve => {
|
||||
AddonManager.getAllInstalls(resolve);
|
||||
});
|
||||
is(installs.length, 0, "There should be no active installs after background installs are done");
|
||||
|
||||
// addon8 should have updated in the background,
|
||||
// addon9 was listed as previously disabled so it should not have updated
|
||||
[a5, a8, a9, a10] = await promise_addons_by_ids([ao5.id, ao8.id, ao9.id, ao10.id]);
|
||||
ok(a5.isCompatible, "addon5 should be compatible");
|
||||
ok(a8.isCompatible, "addon8 should have been upgraded");
|
||||
ok(!a9.isCompatible, "addon9 should not have been upgraded");
|
||||
ok(!a10.isCompatible, "addon10 should not be compatible");
|
||||
|
||||
info("Updates done");
|
||||
await promise_uninstall_test_addons();
|
||||
info("done uninstalling add-ons");
|
||||
});
|
||||
|
||||
// User cancels after repopulateCache, while we're waiting for the addon.findUpdates()
|
||||
// calls in gVersionInfoPage_onPageShow() to complete
|
||||
// For this test, both addon8 and addon9 were disabled by this update, but addon8
|
||||
// is set to not auto-update, so only addon9 should update in the background
|
||||
add_task(async function cancel_during_findUpdates() {
|
||||
let a5, a8, a9;
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
Services.prefs.setCharPref(PREF_MIN_PLATFORM_COMPAT, "0");
|
||||
|
||||
// Clear the AddonRepository-last-updated preference to ensure that it reloads
|
||||
Services.prefs.clearUserPref(PREF_METADATA_LASTUPDATE);
|
||||
let observeUpdateDone = promise_observer("TEST:addon-repository-data-updated");
|
||||
let installsDone = promise_observer("TEST:all-updates-done");
|
||||
|
||||
// Don't pull compatibility data during add-on install
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false);
|
||||
// No delay on the .sjs this time because we want the cache to repopulate
|
||||
let addonList = [ao3, ao5, ao6, ao7, ao8, ao9];
|
||||
await promise_install_test_addons(addonList,
|
||||
TESTROOT + "cancelCompatCheck.sjs");
|
||||
|
||||
[a8] = await promise_addons_by_ids([ao8.id]);
|
||||
a8.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
|
||||
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
let compatWindow = await promise_open_compatibility_window(inactiveAddonIds);
|
||||
var doc = compatWindow.document;
|
||||
await promise_page(compatWindow, "versioninfo");
|
||||
|
||||
info("Waiting for repository-data-updated");
|
||||
await observeUpdateDone;
|
||||
|
||||
// Quick wait to make sure the findUpdates calls get queued
|
||||
await delayMS(5);
|
||||
|
||||
info("Cancel the compatibility check dialog");
|
||||
var button = doc.documentElement.getButton("cancel");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, compatWindow);
|
||||
|
||||
info("Waiting for installs to complete 2");
|
||||
await installsDone;
|
||||
ok(!repo.AddonRepository.isSearching, "Background installs are done 2");
|
||||
|
||||
// addon8 should have updated in the background,
|
||||
// addon9 was listed as previously disabled so it should not have updated
|
||||
[a5, a8, a9] = await promise_addons_by_ids([ao5.id, ao8.id, ao9.id]);
|
||||
ok(a5.isCompatible, "addon5 should be compatible");
|
||||
ok(!a8.isCompatible, "addon8 should not have been upgraded");
|
||||
ok(a9.isCompatible, "addon9 should have been upgraded");
|
||||
|
||||
let installs = await new Promise(resolve => {
|
||||
AddonManager.getAllInstalls(resolve);
|
||||
});
|
||||
is(installs.length, 0, "There should be no active installs after the dialog is cancelled 2");
|
||||
|
||||
info("findUpdates done");
|
||||
await promise_uninstall_test_addons();
|
||||
});
|
||||
|
||||
// Cancelling during the 'mismatch' screen allows add-ons that can auto-update
|
||||
// to continue updating in the background and cancels any other updates
|
||||
// Same conditions as the previous test - addon8 and addon9 have updates available,
|
||||
// addon8 is set to not auto-update so only addon9 should become compatible
|
||||
add_task(async function cancel_mismatch() {
|
||||
let a3, a5, a7, a8, a9;
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
Services.prefs.setCharPref(PREF_MIN_PLATFORM_COMPAT, "0");
|
||||
|
||||
// Clear the AddonRepository-last-updated preference to ensure that it reloads
|
||||
Services.prefs.clearUserPref(PREF_METADATA_LASTUPDATE);
|
||||
let installsDone = promise_observer("TEST:all-updates-done");
|
||||
|
||||
// Don't pull compatibility data during add-on install
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false);
|
||||
// No delay on the .sjs this time because we want the cache to repopulate
|
||||
let addonList = [ao3, ao5, ao6, ao7, ao8, ao9];
|
||||
await promise_install_test_addons(addonList,
|
||||
TESTROOT + "cancelCompatCheck.sjs");
|
||||
|
||||
[a8] = await promise_addons_by_ids([ao8.id]);
|
||||
a8.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
|
||||
|
||||
// Check that the addons start out not compatible.
|
||||
[a3, a7, a8, a9] = await promise_addons_by_ids([ao3.id, ao7.id, ao8.id, ao9.id]);
|
||||
ok(!a3.isCompatible, "addon3 should not be compatible");
|
||||
ok(!a7.isCompatible, "addon7 should not be compatible");
|
||||
ok(!a8.isCompatible, "addon8 should not be compatible");
|
||||
ok(!a9.isCompatible, "addon9 should not be compatible");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
let compatWindow = await promise_open_compatibility_window(inactiveAddonIds);
|
||||
var doc = compatWindow.document;
|
||||
info("Wait for mismatch page");
|
||||
await promise_page(compatWindow, "mismatch");
|
||||
info("Click the Don't Check button");
|
||||
var button = doc.documentElement.getButton("cancel");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, compatWindow);
|
||||
|
||||
await promise_window_close(compatWindow);
|
||||
info("Waiting for installs to complete in cancel_mismatch");
|
||||
await installsDone;
|
||||
|
||||
// addon8 should not have updated in the background,
|
||||
// addon9 was listed as previously disabled so it should not have updated
|
||||
[a5, a8, a9] = await promise_addons_by_ids([ao5.id, ao8.id, ao9.id]);
|
||||
ok(a5.isCompatible, "addon5 should be compatible");
|
||||
ok(!a8.isCompatible, "addon8 should not have been upgraded");
|
||||
ok(a9.isCompatible, "addon9 should have been upgraded");
|
||||
|
||||
// Make sure there are no pending addon installs
|
||||
let installs = await new Promise(resolve => {
|
||||
AddonManager.getAllInstalls(resolve);
|
||||
});
|
||||
ok(installs.length == 0, "No remaining add-on installs (" + installs.toSource() + ")");
|
||||
|
||||
await promise_uninstall_test_addons();
|
||||
await check_addons_uninstalled(addonList);
|
||||
});
|
||||
|
||||
// Cancelling during the 'mismatch' screen with only add-ons that have
|
||||
// no updates available
|
||||
add_task(async function cancel_mismatch_no_updates() {
|
||||
let a3, a5, a6
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
Services.prefs.setCharPref(PREF_MIN_PLATFORM_COMPAT, "0");
|
||||
|
||||
// Don't pull compatibility data during add-on install
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false);
|
||||
// No delay on the .sjs this time because we want the cache to repopulate
|
||||
let addonList = [ao3, ao5, ao6];
|
||||
await promise_install_test_addons(addonList,
|
||||
TESTROOT + "cancelCompatCheck.sjs");
|
||||
|
||||
// Check that the addons start out not compatible.
|
||||
[a3, a5, a6] = await promise_addons_by_ids([ao3.id, ao5.id, ao6.id]);
|
||||
ok(!a3.isCompatible, "addon3 should not be compatible");
|
||||
ok(!a5.isCompatible, "addon5 should not be compatible");
|
||||
ok(!a6.isCompatible, "addon6 should not be compatible");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
let compatWindow = await promise_open_compatibility_window([ao3.id, ao5.id, ao6.id]);
|
||||
var doc = compatWindow.document;
|
||||
info("Wait for mismatch page");
|
||||
await promise_page(compatWindow, "mismatch");
|
||||
info("Click the Don't Check button");
|
||||
var button = doc.documentElement.getButton("cancel");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, { }, compatWindow);
|
||||
|
||||
await promise_window_close(compatWindow);
|
||||
|
||||
[a3, a5, a6] = await promise_addons_by_ids([ao3.id, ao5.id, ao6.id]);
|
||||
ok(!a3.isCompatible, "addon3 should not be compatible");
|
||||
ok(a5.isCompatible, "addon5 should have become compatible");
|
||||
ok(a6.isCompatible, "addon6 should have become compatible");
|
||||
|
||||
// Make sure there are no pending addon installs
|
||||
let installs = await new Promise(resolve => {
|
||||
AddonManager.getAllInstalls(resolve);
|
||||
});
|
||||
ok(installs.length == 0, "No remaining add-on installs (" + installs.toSource() + ")");
|
||||
|
||||
await promise_uninstall_test_addons();
|
||||
await check_addons_uninstalled(addonList);
|
||||
});
|
|
@ -25,6 +25,9 @@ function test() {
|
|||
ok(a.isCompatible, a.type + " " + a.name + " " + a.version + " should be compatible");
|
||||
allCompatible = allCompatible && a.isCompatible;
|
||||
}
|
||||
// Add a reminder.
|
||||
if (!allCompatible)
|
||||
ok(false, "As this test failed, test browser_bug557956.js should have failed, too.");
|
||||
|
||||
finish();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Test how update window behaves when metadata ping times out
|
||||
// bug 965788
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
|
||||
const PREF_METADATA_LASTUPDATE = "extensions.getAddons.cache.lastUpdate";
|
||||
|
||||
Components.utils.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
var repo = {};
|
||||
var ARContext = Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm", repo);
|
||||
|
||||
// Mock out the XMLHttpRequest factory for AddonRepository so
|
||||
// we can reply with a timeout
|
||||
var pXHRStarted = Promise.defer();
|
||||
var oldXHRConstructor = ARContext.ServiceRequest;
|
||||
ARContext.ServiceRequest = function() {
|
||||
this._handlers = new Map();
|
||||
this.mozBackgroundRequest = false;
|
||||
this.timeout = undefined;
|
||||
this.open = function(aMethod, aURI, aAsync) {
|
||||
this.method = aMethod;
|
||||
this.uri = aURI;
|
||||
this.async = aAsync;
|
||||
info("Opened XHR for " + aMethod + " " + aURI);
|
||||
};
|
||||
this.overrideMimeType = function(aMimeType) {
|
||||
this.mimeType = aMimeType;
|
||||
};
|
||||
this.addEventListener = function(aEvent, aHandler, aCapture) {
|
||||
this._handlers.set(aEvent, aHandler);
|
||||
};
|
||||
this.send = function(aBody) {
|
||||
info("Send XHR for " + this.method + " " + this.uri + " handlers: " + [this._handlers.keys()].join(", "));
|
||||
pXHRStarted.resolve(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Returns promise{window}, resolves with a handle to the compatibility
|
||||
// check window
|
||||
function promise_open_compatibility_window(aInactiveAddonIds) {
|
||||
return new Promise(resolve => {
|
||||
// This will reset the longer timeout multiplier to 2 which will give each
|
||||
// test that calls open_compatibility_window a minimum of 60 seconds to
|
||||
// complete.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
var variant = Cc["@mozilla.org/variant;1"].
|
||||
createInstance(Ci.nsIWritableVariant);
|
||||
variant.setFromVariant(aInactiveAddonIds);
|
||||
|
||||
// Cannot be modal as we want to interract with it, shouldn't cause problems
|
||||
// with testing though.
|
||||
var features = "chrome,centerscreen,dialog,titlebar";
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
var win = ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
|
||||
|
||||
win.addEventListener("load", function listener() {
|
||||
function page_shown(aEvent) {
|
||||
if (aEvent.target.pageid)
|
||||
info("Page " + aEvent.target.pageid + " shown");
|
||||
}
|
||||
|
||||
win.removeEventListener("load", listener);
|
||||
|
||||
info("Compatibility dialog opened");
|
||||
|
||||
win.addEventListener("pageshow", page_shown);
|
||||
win.addEventListener("unload", function() {
|
||||
win.removeEventListener("pageshow", page_shown);
|
||||
dump("Compatibility dialog closed\n");
|
||||
}, {once: true});
|
||||
|
||||
resolve(win);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function promise_window_close(aWindow) {
|
||||
return new Promise(resolve => {
|
||||
aWindow.addEventListener("unload", function() {
|
||||
resolve(aWindow);
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
// Start the compatibility update dialog, but use the mock XHR to respond with
|
||||
// a timeout
|
||||
add_task(async function amo_ping_timeout() {
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
Services.prefs.clearUserPref(PREF_METADATA_LASTUPDATE);
|
||||
let compatWindow = await promise_open_compatibility_window([]);
|
||||
|
||||
let xhr = await pXHRStarted.promise;
|
||||
is(xhr.timeout, 30000, "XHR request should have 30 second timeout");
|
||||
ok(xhr._handlers.has("timeout"), "Timeout handler set on XHR");
|
||||
// call back the timeout handler
|
||||
xhr._handlers.get("timeout")();
|
||||
|
||||
// Put the old XHR constructor back
|
||||
ARContext.ServiceRequest = oldXHRConstructor;
|
||||
// The window should close without further interaction
|
||||
await promise_window_close(compatWindow);
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Delay before responding to an HTTP call attempting to read
|
||||
// an addon update RDF file
|
||||
|
||||
function handleRequest(req, resp) {
|
||||
resp.processAsync();
|
||||
resp.setHeader("Cache-Control", "no-cache, no-store", false);
|
||||
resp.setHeader("Content-Type", "text/xml;charset=utf-8", false);
|
||||
|
||||
let file = null;
|
||||
getObjectState("SERVER_ROOT", function(serverRoot)
|
||||
{
|
||||
file = serverRoot.getFile("browser/toolkit/mozapps/extensions/test/browser/browser_bug557956.rdf");
|
||||
});
|
||||
dump("*** cancelCompatCheck.sjs: " + file.path + "\n");
|
||||
let fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
fstream.init(file, -1, 0, 0);
|
||||
let cstream = null;
|
||||
cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIConverterInputStream);
|
||||
cstream.init(fstream, "UTF-8", 0, 0);
|
||||
|
||||
// The delay can be passed on the query string
|
||||
let delay = req.queryString + 0;
|
||||
|
||||
timer = Components.classes["@mozilla.org/timer;1"].
|
||||
createInstance(Components.interfaces.nsITimer);
|
||||
timer.init(function sendFile() {
|
||||
dump("cancelCompatCheck: starting to send file\n");
|
||||
let str = {};
|
||||
let read = 0;
|
||||
do {
|
||||
// read as much as we can and put it in str.value
|
||||
read = cstream.readString(0xffffffff, str);
|
||||
resp.write(str.value);
|
||||
} while (read != 0);
|
||||
cstream.close();
|
||||
resp.finish();
|
||||
}, delay, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
|
@ -0,0 +1,462 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
const PREF_EM_SHOW_MISMATCH_UI = "extensions.showMismatchUI";
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
var Cr = Components.results;
|
||||
|
||||
Cu.import("resource://testing-common/MockRegistrar.jsm");
|
||||
var testserver;
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
var gInstallUpdate = false;
|
||||
var gCheckUpdates = false;
|
||||
|
||||
// This will be called to show the compatibility update dialog.
|
||||
var WindowWatcher = {
|
||||
expected: false,
|
||||
args: null,
|
||||
|
||||
openWindow(parent, url, name, features, args) {
|
||||
do_check_true(Services.startup.interrupted);
|
||||
do_check_eq(url, URI_EXTENSION_UPDATE_DIALOG);
|
||||
do_check_true(this.expected);
|
||||
this.expected = false;
|
||||
this.args = args.QueryInterface(AM_Ci.nsIVariant);
|
||||
|
||||
var updated = !gCheckUpdates;
|
||||
if (gCheckUpdates) {
|
||||
AddonManager.getAddonByID("override1x2-1x3@tests.mozilla.org", function(a6) {
|
||||
a6.findUpdates({
|
||||
onUpdateFinished() {
|
||||
AddonManagerPrivate.removeStartupChange("disabled", "override1x2-1x3@tests.mozilla.org");
|
||||
updated = true;
|
||||
}
|
||||
}, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
|
||||
});
|
||||
}
|
||||
|
||||
var installed = !gInstallUpdate;
|
||||
if (gInstallUpdate) {
|
||||
// Simulate installing an update while in the dialog
|
||||
installAllFiles([do_get_addon("upgradeable1x2-3_2")], function() {
|
||||
AddonManagerPrivate.removeStartupChange("disabled", "upgradeable1x2-3@tests.mozilla.org");
|
||||
AddonManagerPrivate.addStartupChange("updated", "upgradeable1x2-3@tests.mozilla.org");
|
||||
installed = true;
|
||||
});
|
||||
}
|
||||
|
||||
// The dialog is meant to be opened modally and the install operation can be
|
||||
// asynchronous, so we must spin an event loop (like the modal window does)
|
||||
// until the install is complete
|
||||
let tm = AM_Cc["@mozilla.org/thread-manager;1"].
|
||||
getService(AM_Ci.nsIThreadManager);
|
||||
|
||||
tm.spinEventLoopUntil(() => installed && updated);
|
||||
},
|
||||
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIWindowWatcher)
|
||||
|| iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
MockRegistrar.register("@mozilla.org/embedcomp/window-watcher;1", WindowWatcher);
|
||||
|
||||
function check_state_v1([a1, a2, a3, a4, a5, a6]) {
|
||||
do_check_neq(a1, null);
|
||||
do_check_false(a1.appDisabled);
|
||||
do_check_false(a1.userDisabled);
|
||||
do_check_true(a1.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a1.id));
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_false(a2.appDisabled);
|
||||
do_check_true(a2.userDisabled);
|
||||
do_check_false(a2.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_false(a3.appDisabled);
|
||||
do_check_false(a3.userDisabled);
|
||||
do_check_true(a3.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a3.id));
|
||||
do_check_eq(a3.version, "1.0");
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_false(a4.appDisabled);
|
||||
do_check_true(a4.userDisabled);
|
||||
do_check_false(a4.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.appDisabled);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_true(a5.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a5.id));
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_false(a6.appDisabled);
|
||||
do_check_false(a6.userDisabled);
|
||||
do_check_true(a6.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
}
|
||||
|
||||
function check_state_v1_2([a1, a2, a3, a4, a5, a6]) {
|
||||
do_check_neq(a1, null);
|
||||
do_check_false(a1.appDisabled);
|
||||
do_check_false(a1.userDisabled);
|
||||
do_check_true(a1.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a1.id));
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_false(a2.appDisabled);
|
||||
do_check_true(a2.userDisabled);
|
||||
do_check_false(a2.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_true(a3.appDisabled);
|
||||
do_check_false(a3.userDisabled);
|
||||
do_check_false(a3.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a3.id));
|
||||
do_check_eq(a3.version, "2.0");
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_false(a4.appDisabled);
|
||||
do_check_true(a4.userDisabled);
|
||||
do_check_false(a4.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.appDisabled);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_true(a5.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a5.id));
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_false(a6.appDisabled);
|
||||
do_check_false(a6.userDisabled);
|
||||
do_check_true(a6.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
}
|
||||
|
||||
function check_state_v2([a1, a2, a3, a4, a5, a6]) {
|
||||
do_check_neq(a1, null);
|
||||
do_check_true(a1.appDisabled);
|
||||
do_check_false(a1.userDisabled);
|
||||
do_check_false(a1.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a1.id));
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_false(a2.appDisabled);
|
||||
do_check_true(a2.userDisabled);
|
||||
do_check_false(a2.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_false(a3.appDisabled);
|
||||
do_check_false(a3.userDisabled);
|
||||
do_check_true(a3.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a3.id));
|
||||
do_check_eq(a3.version, "1.0");
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_false(a4.appDisabled);
|
||||
do_check_true(a4.userDisabled);
|
||||
do_check_false(a4.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.appDisabled);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_true(a5.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a5.id));
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_false(a6.appDisabled);
|
||||
do_check_false(a6.userDisabled);
|
||||
do_check_true(a6.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
}
|
||||
|
||||
function check_state_v3([a1, a2, a3, a4, a5, a6]) {
|
||||
do_check_neq(a1, null);
|
||||
do_check_true(a1.appDisabled);
|
||||
do_check_false(a1.userDisabled);
|
||||
do_check_false(a1.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a1.id));
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_true(a2.appDisabled);
|
||||
do_check_true(a2.userDisabled);
|
||||
do_check_false(a2.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_true(a3.appDisabled);
|
||||
do_check_false(a3.userDisabled);
|
||||
do_check_false(a3.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a3.id));
|
||||
do_check_eq(a3.version, "1.0");
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_false(a4.appDisabled);
|
||||
do_check_true(a4.userDisabled);
|
||||
do_check_false(a4.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.appDisabled);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_true(a5.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a5.id));
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_false(a6.appDisabled);
|
||||
do_check_false(a6.userDisabled);
|
||||
do_check_true(a6.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
}
|
||||
|
||||
function check_state_v3_2([a1, a2, a3, a4, a5, a6]) {
|
||||
do_check_neq(a1, null);
|
||||
do_check_true(a1.appDisabled);
|
||||
do_check_false(a1.userDisabled);
|
||||
do_check_false(a1.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a1.id));
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_true(a2.appDisabled);
|
||||
do_check_true(a2.userDisabled);
|
||||
do_check_false(a2.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_false(a3.appDisabled);
|
||||
do_check_false(a3.userDisabled);
|
||||
do_check_true(a3.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a3.id));
|
||||
do_check_eq(a3.version, "2.0");
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_false(a4.appDisabled);
|
||||
do_check_true(a4.userDisabled);
|
||||
do_check_false(a4.isActive);
|
||||
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.appDisabled);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_true(a5.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a5.id));
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_false(a6.appDisabled);
|
||||
do_check_false(a6.userDisabled);
|
||||
do_check_true(a6.isActive);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
}
|
||||
|
||||
// Install all the test add-ons, disable two of them and "upgrade" the app to
|
||||
// version 2 which will appDisable one.
|
||||
add_task(async function init() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_EM_SHOW_MISMATCH_UI, true);
|
||||
|
||||
// Add an extension to the profile to make sure the dialog doesn't show up
|
||||
// on new profiles
|
||||
var dest = writeInstallRDFForExtension({
|
||||
id: "addon1@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}],
|
||||
name: "Test Addon 1",
|
||||
}, profileDir);
|
||||
|
||||
// Create and configure the HTTP server.
|
||||
testserver = createHttpServer(4444);
|
||||
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||
|
||||
startupManager();
|
||||
|
||||
// Remove the add-on we installed directly in the profile directory;
|
||||
// this should show as uninstalled on next restart
|
||||
dest.remove(true);
|
||||
|
||||
// Load up an initial set of add-ons
|
||||
await promiseInstallAllFiles([do_get_addon("min1max1"),
|
||||
do_get_addon("min1max2"),
|
||||
do_get_addon("upgradeable1x2-3_1"),
|
||||
do_get_addon("min1max3"),
|
||||
do_get_addon("min1max3b"),
|
||||
do_get_addon("override1x2-1x3")]);
|
||||
await promiseRestartManager();
|
||||
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", []);
|
||||
check_startup_changes("uninstalled", ["addon1@tests.mozilla.org"]);
|
||||
check_startup_changes("disabled", []);
|
||||
check_startup_changes("enabled", []);
|
||||
|
||||
// user-disable two add-ons
|
||||
let [a2, a4] = await promiseAddonsByIDs(["min1max2@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org"]);
|
||||
do_check_true(a2 != null && a4 != null);
|
||||
a2.userDisabled = true;
|
||||
a4.userDisabled = true;
|
||||
await promiseRestartManager();
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", []);
|
||||
check_startup_changes("uninstalled", []);
|
||||
check_startup_changes("disabled", []);
|
||||
check_startup_changes("enabled", []);
|
||||
|
||||
let addons = await promiseAddonsByIDs(["min1max1@tests.mozilla.org",
|
||||
"min1max2@tests.mozilla.org",
|
||||
"upgradeable1x2-3@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org",
|
||||
"min1max3b@tests.mozilla.org",
|
||||
"override1x2-1x3@tests.mozilla.org"]);
|
||||
check_state_v1(addons);
|
||||
|
||||
// Restart as version 2, add-on _1 should become app-disabled
|
||||
WindowWatcher.expected = true;
|
||||
await promiseRestartManager("2");
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", []);
|
||||
check_startup_changes("uninstalled", []);
|
||||
check_startup_changes("disabled", ["min1max1@tests.mozilla.org"]);
|
||||
check_startup_changes("enabled", []);
|
||||
do_check_false(WindowWatcher.expected);
|
||||
|
||||
addons = await promiseAddonsByIDs(["min1max1@tests.mozilla.org",
|
||||
"min1max2@tests.mozilla.org",
|
||||
"upgradeable1x2-3@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org",
|
||||
"min1max3b@tests.mozilla.org",
|
||||
"override1x2-1x3@tests.mozilla.org"]);
|
||||
check_state_v2(addons);
|
||||
});
|
||||
|
||||
// Upgrade to version 3 which will appDisable addons
|
||||
// upgradeable1x2-3 and override1x2-1x3
|
||||
// Only the newly disabled add-ons should be passed to the
|
||||
// upgrade window
|
||||
add_task(async function run_test_1() {
|
||||
gCheckUpdates = true;
|
||||
WindowWatcher.expected = true;
|
||||
|
||||
await promiseRestartManager("3");
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", []);
|
||||
check_startup_changes("uninstalled", []);
|
||||
check_startup_changes("disabled", ["upgradeable1x2-3@tests.mozilla.org"]);
|
||||
check_startup_changes("enabled", []);
|
||||
do_check_false(WindowWatcher.expected);
|
||||
gCheckUpdates = false;
|
||||
|
||||
let addons = await promiseAddonsByIDs(["min1max1@tests.mozilla.org",
|
||||
"min1max2@tests.mozilla.org",
|
||||
"upgradeable1x2-3@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org",
|
||||
"min1max3b@tests.mozilla.org",
|
||||
"override1x2-1x3@tests.mozilla.org"]);
|
||||
check_state_v3(addons);
|
||||
|
||||
do_check_eq(WindowWatcher.args.length, 2);
|
||||
do_check_true(WindowWatcher.args.indexOf("upgradeable1x2-3@tests.mozilla.org") >= 0);
|
||||
do_check_true(WindowWatcher.args.indexOf("override1x2-1x3@tests.mozilla.org") >= 0);
|
||||
});
|
||||
|
||||
// Downgrade to version 2 which will remove appDisable from two add-ons
|
||||
// Still displays the compat window, because metadata is not recently updated
|
||||
add_task(async function run_test_2() {
|
||||
WindowWatcher.expected = true;
|
||||
await promiseRestartManager("2");
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", []);
|
||||
check_startup_changes("uninstalled", []);
|
||||
check_startup_changes("disabled", []);
|
||||
check_startup_changes("enabled", ["upgradeable1x2-3@tests.mozilla.org"]);
|
||||
do_check_false(WindowWatcher.expected);
|
||||
|
||||
let addons = await promiseAddonsByIDs(["min1max1@tests.mozilla.org",
|
||||
"min1max2@tests.mozilla.org",
|
||||
"upgradeable1x2-3@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org",
|
||||
"min1max3b@tests.mozilla.org",
|
||||
"override1x2-1x3@tests.mozilla.org"]);
|
||||
check_state_v2(addons);
|
||||
});
|
||||
|
||||
// Upgrade back to version 3 which should only appDisable
|
||||
// upgradeable1x2-3, because we already have the override
|
||||
// stored in our DB for override1x2-1x3. Ensure that when
|
||||
// the upgrade dialog updates an add-on no restart is necessary
|
||||
add_task(async function run_test_5() {
|
||||
Services.prefs.setBoolPref(PREF_EM_SHOW_MISMATCH_UI, true);
|
||||
// tell the mock compatibility window to install the available upgrade
|
||||
gInstallUpdate = true;
|
||||
|
||||
WindowWatcher.expected = true;
|
||||
await promiseRestartManager("3");
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", ["upgradeable1x2-3@tests.mozilla.org"]);
|
||||
check_startup_changes("uninstalled", []);
|
||||
check_startup_changes("disabled", []);
|
||||
check_startup_changes("enabled", []);
|
||||
do_check_false(WindowWatcher.expected);
|
||||
gInstallUpdate = false;
|
||||
|
||||
let addons = await promiseAddonsByIDs(["min1max1@tests.mozilla.org",
|
||||
"min1max2@tests.mozilla.org",
|
||||
"upgradeable1x2-3@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org",
|
||||
"min1max3b@tests.mozilla.org",
|
||||
"override1x2-1x3@tests.mozilla.org"]);
|
||||
check_state_v3_2(addons);
|
||||
|
||||
do_check_eq(WindowWatcher.args.length, 1);
|
||||
do_check_true(WindowWatcher.args.indexOf("upgradeable1x2-3@tests.mozilla.org") >= 0);
|
||||
});
|
||||
|
||||
// Downgrade to version 1 which will appEnable all the add-ons
|
||||
// except upgradeable1x2-3; the update we installed isn't compatible with 1
|
||||
add_task(async function run_test_6() {
|
||||
WindowWatcher.expected = true;
|
||||
await promiseRestartManager("1");
|
||||
check_startup_changes("installed", []);
|
||||
check_startup_changes("updated", []);
|
||||
check_startup_changes("uninstalled", []);
|
||||
check_startup_changes("disabled", ["upgradeable1x2-3@tests.mozilla.org"]);
|
||||
check_startup_changes("enabled", ["min1max1@tests.mozilla.org"]);
|
||||
do_check_false(WindowWatcher.expected);
|
||||
|
||||
let addons = await promiseAddonsByIDs(["min1max1@tests.mozilla.org",
|
||||
"min1max2@tests.mozilla.org",
|
||||
"upgradeable1x2-3@tests.mozilla.org",
|
||||
"min1max3@tests.mozilla.org",
|
||||
"min1max3b@tests.mozilla.org",
|
||||
"override1x2-1x3@tests.mozilla.org"]);
|
||||
check_state_v1_2(addons);
|
||||
});
|
|
@ -0,0 +1,159 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test whether we need to block start-up to check add-on compatibility,
|
||||
* based on how long since the last succesful metadata ping.
|
||||
* All tests depend on having one add-on installed in the profile
|
||||
*/
|
||||
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
const PREF_EM_SHOW_MISMATCH_UI = "extensions.showMismatchUI";
|
||||
|
||||
// Constants copied from AddonRepository.jsm
|
||||
const PREF_METADATA_LASTUPDATE = "extensions.getAddons.cache.lastUpdate";
|
||||
const PREF_METADATA_UPDATETHRESHOLD_SEC = "extensions.getAddons.cache.updateThreshold";
|
||||
const DEFAULT_METADATA_UPDATETHRESHOLD_SEC = 172800; // two days
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||
// None of this works without the add-on repository cache
|
||||
Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", true);
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
var Cr = Components.results;
|
||||
|
||||
Cu.import("resource://testing-common/MockRegistrar.jsm");
|
||||
var testserver;
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
// This will be called to show the compatibility update dialog.
|
||||
var WindowWatcher = {
|
||||
expected: false,
|
||||
|
||||
openWindow(parent, url, name, features, args) {
|
||||
do_check_true(Services.startup.interrupted);
|
||||
do_check_eq(url, URI_EXTENSION_UPDATE_DIALOG);
|
||||
do_check_true(this.expected);
|
||||
this.expected = false;
|
||||
},
|
||||
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIWindowWatcher)
|
||||
|| iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
MockRegistrar.register("@mozilla.org/embedcomp/window-watcher;1", WindowWatcher);
|
||||
|
||||
// Return Date.now() in seconds, rounded
|
||||
function now() {
|
||||
return Math.round(Date.now() / 1000);
|
||||
}
|
||||
|
||||
// First time with a new profile, so we don't have a cache.lastUpdate pref
|
||||
add_task(async function checkFirstMetadata() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_EM_SHOW_MISMATCH_UI, true);
|
||||
|
||||
// Create and configure the HTTP server.
|
||||
testserver = createHttpServer();
|
||||
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||
gPort = testserver.identity.primaryPort;
|
||||
const BASE_URL = "http://localhost:" + gPort;
|
||||
const GETADDONS_RESULTS = BASE_URL + "/data/test_AddonRepository_cache.xml";
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_RESULTS);
|
||||
|
||||
// Put an add-on in our profile so the metadata check will have something to do
|
||||
var min1max2 = {
|
||||
id: "min1max2@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon compatible with v1->v2",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "2"
|
||||
}]
|
||||
};
|
||||
writeInstallRDFForExtension(min1max2, profileDir);
|
||||
|
||||
startupManager();
|
||||
|
||||
// Make sure that updating metadata for the first time sets the lastUpdate preference
|
||||
await AddonRepository.repopulateCache();
|
||||
do_print("Update done, getting last update");
|
||||
let lastUpdate = Services.prefs.getIntPref(PREF_METADATA_LASTUPDATE);
|
||||
do_check_true(lastUpdate > 0);
|
||||
|
||||
// Make sure updating metadata again updates the preference
|
||||
let oldUpdate = lastUpdate - 2 * DEFAULT_METADATA_UPDATETHRESHOLD_SEC;
|
||||
Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, oldUpdate);
|
||||
await AddonRepository.repopulateCache();
|
||||
do_check_neq(oldUpdate, Services.prefs.getIntPref(PREF_METADATA_LASTUPDATE));
|
||||
});
|
||||
|
||||
// First upgrade with no lastUpdate pref and no add-ons changing shows UI
|
||||
add_task(async function upgrade_no_lastupdate() {
|
||||
Services.prefs.clearUserPref(PREF_METADATA_LASTUPDATE);
|
||||
|
||||
WindowWatcher.expected = true;
|
||||
await promiseRestartManager("2");
|
||||
do_check_false(WindowWatcher.expected);
|
||||
});
|
||||
|
||||
// Upgrade with lastUpdate more than default threshold and no add-ons changing shows UI
|
||||
add_task(async function upgrade_old_lastupdate() {
|
||||
let oldEnough = now() - DEFAULT_METADATA_UPDATETHRESHOLD_SEC - 1000;
|
||||
Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, oldEnough);
|
||||
|
||||
WindowWatcher.expected = true;
|
||||
// upgrade, downgrade, it has the same effect on the code path under test
|
||||
await promiseRestartManager("1");
|
||||
do_check_false(WindowWatcher.expected);
|
||||
});
|
||||
|
||||
// Upgrade with lastUpdate less than default threshold and no add-ons changing doesn't show
|
||||
add_task(async function upgrade_young_lastupdate() {
|
||||
let notOldEnough = now() - DEFAULT_METADATA_UPDATETHRESHOLD_SEC + 1000;
|
||||
Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, notOldEnough);
|
||||
|
||||
WindowWatcher.expected = false;
|
||||
await promiseRestartManager("2");
|
||||
do_check_false(WindowWatcher.expected);
|
||||
});
|
||||
|
||||
// Repeat more-than and less-than but with updateThreshold preference set
|
||||
// Upgrade with lastUpdate more than pref threshold and no add-ons changing shows UI
|
||||
const TEST_UPDATETHRESHOLD_SEC = 50000;
|
||||
add_task(async function upgrade_old_pref_lastupdate() {
|
||||
Services.prefs.setIntPref(PREF_METADATA_UPDATETHRESHOLD_SEC, TEST_UPDATETHRESHOLD_SEC);
|
||||
|
||||
let oldEnough = now() - TEST_UPDATETHRESHOLD_SEC - 1000;
|
||||
Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, oldEnough);
|
||||
|
||||
WindowWatcher.expected = true;
|
||||
await promiseRestartManager("1");
|
||||
do_check_false(WindowWatcher.expected);
|
||||
});
|
||||
|
||||
// Upgrade with lastUpdate less than pref threshold and no add-ons changing doesn't show
|
||||
add_task(async function upgrade_young_pref_lastupdate() {
|
||||
let notOldEnough = now() - TEST_UPDATETHRESHOLD_SEC + 1000;
|
||||
Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, notOldEnough);
|
||||
|
||||
WindowWatcher.expected = false;
|
||||
await promiseRestartManager("2");
|
||||
do_check_false(WindowWatcher.expected);
|
||||
});
|
|
@ -137,6 +137,8 @@ tags = blocklist
|
|||
[test_bug521905.js]
|
||||
[test_bug526598.js]
|
||||
[test_bug541420.js]
|
||||
[test_bug542391.js]
|
||||
run-sequentially = Uses hardcoded ports in xpi files.
|
||||
[test_bug554133.js]
|
||||
[test_bug559800.js]
|
||||
[test_bug564030.js]
|
||||
|
|
|
@ -22,6 +22,7 @@ run-if = addon_signing
|
|||
skip-if = appname != "firefox"
|
||||
[test_hotfix_cert.js]
|
||||
[test_isReady.js]
|
||||
[test_metadata_update.js]
|
||||
[test_pluginInfoURL.js]
|
||||
tags = blocklist
|
||||
[test_provider_markSafe.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче