mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Main patch - Bug 882007 - Restart notification is not shown when staging is enabled. r=bbondy
This commit is contained in:
parent
5c6db5dc34
commit
3e07312ff7
@ -352,7 +352,7 @@ interface nsIUpdateChecker : nsISupports
|
||||
* background update checks and provides utilities for selecting and
|
||||
* downloading update patches.
|
||||
*/
|
||||
[scriptable, uuid(900b4a18-3bef-4f3e-bcf5-84dce0021c6d)]
|
||||
[scriptable, uuid(814f185b-cac6-494b-8fd6-63cf7380d857)]
|
||||
interface nsIApplicationUpdateService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -394,14 +394,9 @@ interface nsIApplicationUpdateService : nsISupports
|
||||
*/
|
||||
AString downloadUpdate(in nsIUpdate update, in boolean background);
|
||||
|
||||
/**
|
||||
* Apply an update in the background.
|
||||
*/
|
||||
void applyUpdateInBackground(in nsIUpdate update);
|
||||
|
||||
/**
|
||||
* Get the Active Updates directory
|
||||
* @returns The active updates directory.
|
||||
* @returns An nsIFile for the active updates directory.
|
||||
*/
|
||||
nsIFile getUpdatesDirectory();
|
||||
|
||||
|
@ -43,7 +43,7 @@ const PREF_APP_UPDATE_POSTUPDATE = "app.update.postupdate";
|
||||
const PREF_APP_UPDATE_PROMPTWAITTIME = "app.update.promptWaitTime";
|
||||
const PREF_APP_UPDATE_SHOW_INSTALLED_UI = "app.update.showInstalledUI";
|
||||
const PREF_APP_UPDATE_SILENT = "app.update.silent";
|
||||
const PREF_APP_UPDATE_STAGE_ENABLED = "app.update.staging.enabled";
|
||||
const PREF_APP_UPDATE_STAGING_ENABLED = "app.update.staging.enabled";
|
||||
const PREF_APP_UPDATE_URL = "app.update.url";
|
||||
const PREF_APP_UPDATE_URL_DETAILS = "app.update.url.details";
|
||||
const PREF_APP_UPDATE_URL_OVERRIDE = "app.update.url.override";
|
||||
@ -81,11 +81,11 @@ const KEY_UPDATE_ARCHIVE_DIR = "UpdArchD"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define SKIP_STAGE_UPDATES_TEST
|
||||
#define CHECK_CAN_USE_SERVICE
|
||||
#elifdef MOZ_WIDGET_GONK
|
||||
// In Gonk, the updater will remount the /system partition to move staged files
|
||||
// into place, so we skip the test here to keep things isolated.
|
||||
#define SKIP_STAGE_UPDATES_TEST
|
||||
#define CHECK_CAN_USE_SERVICE
|
||||
#endif
|
||||
|
||||
const DIR_UPDATES = "updates";
|
||||
@ -455,7 +455,7 @@ function getPerInstallationMutexName(aGlobal) {
|
||||
hasher.init(hasher.SHA1);
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
var exeFile = Services.dirsvc.get("XREExeF", Components.interfaces.nsILocalFile);
|
||||
var exeFile = Services.dirsvc.get(KEY_EXECUTABLE, Components.interfaces.nsILocalFile);
|
||||
|
||||
let converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
@ -469,10 +469,11 @@ function getPerInstallationMutexName(aGlobal) {
|
||||
|
||||
/**
|
||||
* Whether or not the current instance has the update mutex. The update mutex
|
||||
* gives protection against 2 browsers from the same installation updating:
|
||||
* gives protection against 2 applications from the same installation updating:
|
||||
* 1) Running multiple profiles from the same installation path
|
||||
* 2) Running a Metro and Desktop browser at the same time from the same path
|
||||
* 3) 2 browsers running in 2 different user sessions from the same path
|
||||
* 2) Running a Metro and Desktop application at the same time from the same
|
||||
* path
|
||||
* 3) 2 applications running in 2 different user sessions from the same path
|
||||
*
|
||||
* @return true if this instance holds the update mutex
|
||||
*/
|
||||
@ -490,13 +491,13 @@ function hasUpdateMutex() {
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpdates() {
|
||||
function submitHasPermissionsTelemetryPing(val) {
|
||||
try {
|
||||
let h = Services.telemetry.getHistogramById("UPDATER_HAS_PERMISSIONS");
|
||||
h.add(+val);
|
||||
} catch(e) {
|
||||
// Don't allow any exception to be propagated.
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
try {
|
||||
let h = Services.telemetry.getHistogramById("UPDATER_HAS_PERMISSIONS");
|
||||
h.add(+val);
|
||||
} catch(e) {
|
||||
// Don't allow any exception to be propagated.
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@ -584,8 +585,9 @@ XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpda
|
||||
}
|
||||
|
||||
if (!hasUpdateMutex()) {
|
||||
LOG("gCanApplyUpdates - unable to apply updates because another " +
|
||||
"browser is already handling updates for this installation.");
|
||||
LOG("gCanApplyUpdates - unable to apply updates because another instance" +
|
||||
"of the application is already handling updates for this " +
|
||||
"installation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -594,54 +596,74 @@ XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpda
|
||||
return true;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gCanStageUpdates", function aus_gCanStageUpdates() {
|
||||
/**
|
||||
* Whether or not the application can stage an update.
|
||||
*
|
||||
* @return true if updates can be staged.
|
||||
*/
|
||||
function getCanStageUpdates() {
|
||||
// If background updates are disabled, then just bail out!
|
||||
if (!getPref("getBoolPref", PREF_APP_UPDATE_STAGE_ENABLED, false)) {
|
||||
LOG("gCanStageUpdates - staging updates is disabled by preference " + PREF_APP_UPDATE_STAGE_ENABLED);
|
||||
if (!getPref("getBoolPref", PREF_APP_UPDATE_STAGING_ENABLED, false)) {
|
||||
LOG("getCanStageUpdates - staging updates is disabled by preference " +
|
||||
PREF_APP_UPDATE_STAGING_ENABLED);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SKIP_STAGE_UPDATES_TEST
|
||||
#ifdef CHECK_CAN_USE_SERVICE
|
||||
if (getPref("getBoolPref", PREF_APP_UPDATE_SERVICE_ENABLED, false)) {
|
||||
// No need to perform directory write checks, the maintenance service will
|
||||
// be able to write to all directories.
|
||||
LOG("gCanStageUpdates - able to stage updates because we'll use the service");
|
||||
LOG("getCanStageUpdates - able to stage updates because we'll use the service");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
try {
|
||||
var updateTestFile = getInstallDirRoot();
|
||||
updateTestFile.append(FILE_PERMS_TEST);
|
||||
LOG("gCanStageUpdates - testing write access " + updateTestFile.path);
|
||||
testWriteAccess(updateTestFile, true);
|
||||
#ifndef XP_MACOSX
|
||||
// On all platforms except Mac, we need to test the parent directory as well,
|
||||
// as we need to be able to move files in that directory during the replacing
|
||||
// step.
|
||||
updateTestFile = getInstallDirRoot().parent;
|
||||
updateTestFile.append(FILE_PERMS_TEST);
|
||||
LOG("gCanStageUpdates - testing write access " + updateTestFile.path);
|
||||
updateTestFile.createUnique(Ci.nsILocalFile.DIRECTORY_TYPE,
|
||||
FileUtils.PERMS_DIRECTORY);
|
||||
updateTestFile.remove(false);
|
||||
#endif
|
||||
}
|
||||
catch (e) {
|
||||
LOG("gCanStageUpdates - unable to stage updates. Exception: " + e);
|
||||
// No write privileges
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasUpdateMutex()) {
|
||||
LOG("gCanStageUpdates - unable to stage updates because another " +
|
||||
"browser is already handling updates for this installation.");
|
||||
LOG("getCanStageUpdates - unable to apply updates because another " +
|
||||
"instance of the application is already handling updates for this " +
|
||||
"installation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("gCanStageUpdates - able to stage updates");
|
||||
return true;
|
||||
});
|
||||
/**
|
||||
* Whether or not the application can stage an update for the current session.
|
||||
* These checks are only performed once per session due to using a lazy getter.
|
||||
*
|
||||
* @return true if updates can be staged for this session.
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(this, "canStageUpdatesSession", function canStageUpdatesSession() {
|
||||
try {
|
||||
var updateTestFile = getInstallDirRoot();
|
||||
updateTestFile.append(FILE_PERMS_TEST);
|
||||
LOG("canStageUpdatesSession - testing write access " +
|
||||
updateTestFile.path);
|
||||
testWriteAccess(updateTestFile, true);
|
||||
#ifndef XP_MACOSX
|
||||
// On all platforms except Mac, we need to test the parent directory as
|
||||
// well, as we need to be able to move files in that directory during the
|
||||
// replacing step.
|
||||
updateTestFile = getInstallDirRoot().parent;
|
||||
updateTestFile.append(FILE_PERMS_TEST);
|
||||
LOG("canStageUpdatesSession - testing write access " +
|
||||
updateTestFile.path);
|
||||
updateTestFile.createUnique(Ci.nsILocalFile.DIRECTORY_TYPE,
|
||||
FileUtils.PERMS_DIRECTORY);
|
||||
updateTestFile.remove(false);
|
||||
#endif
|
||||
}
|
||||
catch (e) {
|
||||
LOG("canStageUpdatesSession - unable to stage updates. Exception: " +
|
||||
e);
|
||||
// No write privileges
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("canStageUpdatesSession - able to stage updates");
|
||||
return true;
|
||||
});
|
||||
|
||||
return canStageUpdatesSession;
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gIsMetro", function aus_gIsMetro() {
|
||||
#ifdef XP_WIN
|
||||
@ -663,8 +685,8 @@ XPCOMUtils.defineLazyGetter(this, "gMetroUpdatesEnabled", function aus_gMetroUpd
|
||||
if (gIsMetro) {
|
||||
let metroUpdate = getPref("getBoolPref", PREF_APP_UPDATE_METRO_ENABLED, true);
|
||||
if (!metroUpdate) {
|
||||
LOG("gMetroUpdatesEnabled - unable to automatically check for metro" +
|
||||
" updates, disabled by pref");
|
||||
LOG("gMetroUpdatesEnabled - unable to automatically check for metro " +
|
||||
"updates, disabled by pref");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -675,13 +697,13 @@ XPCOMUtils.defineLazyGetter(this, "gMetroUpdatesEnabled", function aus_gMetroUpd
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gCanCheckForUpdates", function aus_gCanCheckForUpdates() {
|
||||
// If the administrator has locked the app update functionality
|
||||
// OFF - this is not just a user setting, so disable the manual
|
||||
// UI too.
|
||||
// If the administrator has disabled app update and locked the preference so
|
||||
// users can't check for updates. This preference check is ok in this lazy
|
||||
// getter since locked prefs don't change until the application is restarted.
|
||||
var enabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
|
||||
if (!enabled && Services.prefs.prefIsLocked(PREF_APP_UPDATE_ENABLED)) {
|
||||
LOG("gCanCheckForUpdates - unable to automatically check for updates, " +
|
||||
"disabled by pref");
|
||||
"the preference is disabled and admistratively locked.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -704,7 +726,8 @@ XPCOMUtils.defineLazyGetter(this, "gCanCheckForUpdates", function aus_gCanCheckF
|
||||
|
||||
if (!hasUpdateMutex()) {
|
||||
LOG("gCanCheckForUpdates - unable to apply updates because another " +
|
||||
"browser is already handling updates for this installation.");
|
||||
"instance of the application is already handling updates for this " +
|
||||
"installation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -771,21 +794,22 @@ function getUpdateDirCreate(pathArray) {
|
||||
return FileUtils.getDir(KEY_UPDROOT, pathArray, true);
|
||||
}
|
||||
|
||||
/**
|
||||
# Gets the specified directory at the specified hierarchy under the
|
||||
# update root directory and without creating it if it doesn't exist.
|
||||
# @param pathArray
|
||||
# An array of path components to locate beneath the directory
|
||||
# specified by |key|
|
||||
# @return nsIFile object for the location specified.
|
||||
*/
|
||||
/**
|
||||
# Gets the specified directory at the specified hierarchy under the
|
||||
# update root directory and without creating it if it doesn't exist.
|
||||
# @param pathArray
|
||||
# An array of path components to locate beneath the directory
|
||||
# specified by |key|
|
||||
# @return nsIFile object for the location specified.
|
||||
*/
|
||||
function getUpdateDirNoCreate(pathArray) {
|
||||
return FileUtils.getDir(KEY_UPDROOT, pathArray, false);
|
||||
}
|
||||
|
||||
/**
|
||||
# Gets the application base directory.
|
||||
# @return nsIFile object for the application base directory.
|
||||
* Gets the application base directory.
|
||||
*
|
||||
* @return nsIFile object for the application base directory.
|
||||
*/
|
||||
function getAppBaseDir() {
|
||||
return Services.dirsvc.get(KEY_EXECUTABLE, Ci.nsIFile).parent;
|
||||
@ -1842,6 +1866,7 @@ const UpdateServiceFactory = {
|
||||
function UpdateService() {
|
||||
LOG("Creating UpdateService");
|
||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||
Services.prefs.addObserver("app.update.log", this, false);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// PowerManagerService::SyncProfile (which is called for Reboot, PowerOff
|
||||
// and Restart) sends the profile-change-net-teardown event. We can then
|
||||
@ -1895,11 +1920,17 @@ UpdateService.prototype = {
|
||||
case "network:offline-status-changed":
|
||||
this._offlineStatusChanged(data);
|
||||
break;
|
||||
case "nsPref:changed":
|
||||
if (data == PREF_APP_UPDATE_LOG) {
|
||||
gLogEnabled = getPref("getBoolPref", PREF_APP_UPDATE_LOG, false);
|
||||
}
|
||||
break;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
case "profile-change-net-teardown": // fall thru
|
||||
#endif
|
||||
case "xpcom-shutdown":
|
||||
Services.obs.removeObserver(this, topic);
|
||||
Services.prefs.removeObserver("app.update.log", this);
|
||||
|
||||
if (this._retryTimer) {
|
||||
this._retryTimer.cancel();
|
||||
@ -1923,7 +1954,7 @@ UpdateService.prototype = {
|
||||
|
||||
/**
|
||||
* Perform post-processing on updates lingering in the updates directory
|
||||
* from a previous browser session - either report install failures (and
|
||||
* from a previous application session - either report install failures (and
|
||||
* optionally attempt to fetch a different version if appropriate) or
|
||||
* notify the user of install success.
|
||||
*/
|
||||
@ -2065,7 +2096,7 @@ UpdateService.prototype = {
|
||||
"UPDATER_UPDATES_METRO_ENABLED");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_AUTO,
|
||||
"UPDATER_UPDATES_AUTOMATIC");
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGE_ENABLED,
|
||||
this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGING_ENABLED,
|
||||
"UPDATER_STAGE_ENABLED");
|
||||
|
||||
#ifdef XP_WIN
|
||||
@ -2688,7 +2719,7 @@ UpdateService.prototype = {
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
get canStageUpdates() {
|
||||
return gCanStageUpdates;
|
||||
return getCanStageUpdates();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2777,26 +2808,6 @@ UpdateService.prototype = {
|
||||
return this._downloader.downloadUpdate(update);
|
||||
},
|
||||
|
||||
applyUpdateInBackground: function AUS_applyUpdateInBackground(update) {
|
||||
// If we can't stage an update, then just bail out!
|
||||
if (!gCanStageUpdates) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("UpdateService:applyUpdateInBackground called with the following update: " +
|
||||
update.name);
|
||||
|
||||
// Initiate the update in the background
|
||||
try {
|
||||
Cc["@mozilla.org/updates/update-processor;1"].
|
||||
createInstance(Ci.nsIUpdateProcessor).
|
||||
processUpdate(update);
|
||||
} catch (e) {
|
||||
// Fail gracefully in case the application does not support the update
|
||||
// processor service.
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
@ -3127,6 +3138,7 @@ UpdateManager.prototype = {
|
||||
|
||||
// Do this after *everything* else, since it will likely cause the app
|
||||
// to shut down.
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (update.state == STATE_APPLIED) {
|
||||
// Notify the user that an update has been staged and is ready for
|
||||
// installation (i.e. that they should restart the application). We do
|
||||
@ -3137,6 +3149,23 @@ UpdateManager.prototype = {
|
||||
} else {
|
||||
releaseSDCardMountLock();
|
||||
}
|
||||
#else
|
||||
// Only prompt when the UI isn't already open.
|
||||
let windowType = getPref("getCharPref", PREF_APP_UPDATE_ALTWINDOWTYPE, null);
|
||||
if (Services.wm.getMostRecentWindow(UPDATE_WINDOW_NAME) ||
|
||||
windowType && Services.wm.getMostRecentWindow(windowType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.state == STATE_APPLIED || update.state == STATE_APPLIED_SVC ||
|
||||
update.state == STATE_PENDING || update.state == STATE_PENDING_SVC) {
|
||||
// Notify the user that an update has been staged and is ready for
|
||||
// installation (i.e. that they should restart the application).
|
||||
var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
|
||||
createInstance(Ci.nsIUpdatePrompt);
|
||||
prompter.showUpdateDownloaded(update, true);
|
||||
}
|
||||
#endif
|
||||
},
|
||||
|
||||
classID: Components.ID("{093C2356-4843-4C65-8709-D7DBCBBE7DFB}"),
|
||||
@ -3968,12 +3997,9 @@ Downloader.prototype = {
|
||||
if (Components.isSuccessCode(status)) {
|
||||
if (this._verifyDownload()) {
|
||||
state = shouldUseService() ? STATE_PENDING_SVC : STATE_PENDING
|
||||
|
||||
// We only need to explicitly show the prompt if this is a background
|
||||
// download, since otherwise some kind of UI is already visible and
|
||||
// that UI will notify.
|
||||
if (this.background)
|
||||
shouldShowPrompt = !getPref("getBoolPref", PREF_APP_UPDATE_STAGE_ENABLED, false);
|
||||
if (this.background) {
|
||||
shouldShowPrompt = !getCanStageUpdates();
|
||||
}
|
||||
|
||||
// Tell the updater.exe we're ready to apply.
|
||||
writeStatusFile(getUpdatesDir(), state);
|
||||
@ -3984,7 +4010,6 @@ Downloader.prototype = {
|
||||
else {
|
||||
LOG("Downloader:onStopRequest - download verification failed");
|
||||
state = STATE_DOWNLOAD_FAILED;
|
||||
|
||||
status = Cr.NS_ERROR_CORRUPTED_CONTENT;
|
||||
|
||||
// Yes, this code is a string.
|
||||
@ -4112,6 +4137,28 @@ Downloader.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == STATE_PENDING || state == STATE_PENDING_SVC) {
|
||||
if (getCanStageUpdates()) {
|
||||
LOG("Downloader:onStopRequest - attempting to stage update: " +
|
||||
this._update.name);
|
||||
|
||||
// Initiate the update in the background
|
||||
try {
|
||||
Cc["@mozilla.org/updates/update-processor;1"].
|
||||
createInstance(Ci.nsIUpdateProcessor).
|
||||
processUpdate(this._update);
|
||||
} catch (e) {
|
||||
// Fail gracefully in case the application does not support the update
|
||||
// processor service.
|
||||
LOG("Downloader:onStopRequest - failed to stage update. Exception: " +
|
||||
e);
|
||||
if (this.background) {
|
||||
shouldShowPrompt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do this after *everything* else, since it will likely cause the app
|
||||
// to shut down.
|
||||
if (shouldShowPrompt) {
|
||||
@ -4123,13 +4170,6 @@ Downloader.prototype = {
|
||||
prompter.showUpdateDownloaded(this._update, true);
|
||||
}
|
||||
|
||||
if (state == STATE_PENDING || state == STATE_PENDING_SVC) {
|
||||
// Initiate the background update job.
|
||||
Cc["@mozilla.org/updates/update-service;1"].
|
||||
getService(Ci.nsIApplicationUpdateService).
|
||||
applyUpdateInBackground(this._update);
|
||||
}
|
||||
|
||||
if (shouldRegisterOnlineObserver) {
|
||||
LOG("Downloader:onStopRequest - Registering online observer");
|
||||
this.updateService._registerOnlineObserver();
|
||||
|
Loading…
Reference in New Issue
Block a user