зеркало из https://github.com/mozilla/gecko-dev.git
Main patch - Bug 596813 - Check for updates inside the About window without opening a new window. r=dtownsend, ui-r=beltzner, a=blocking2.0-beta7
This commit is contained in:
Родитель
8586a3757b
Коммит
17e54103a7
|
@ -88,6 +88,11 @@ pref("app.update.timer", 600000);
|
|||
// The interval to check for updates (app.update.interval) is defined in
|
||||
// firefox-branding.js
|
||||
|
||||
// Alternative windowtype for an application update user interface window. When
|
||||
// a window with this windowtype is open the application update service won't
|
||||
// open the normal application update user interface window.
|
||||
pref("app.update.altwindowtype", "Browser:About");
|
||||
|
||||
// Enables some extra Application Update Logging (can reduce performance)
|
||||
pref("app.update.log", false);
|
||||
|
||||
|
|
|
@ -52,13 +52,34 @@
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#checkForUpdatesButton,
|
||||
.text-blurb {
|
||||
margin-bottom: 10px;
|
||||
-moz-margin-start: 0;
|
||||
-moz-padding-start: 0;
|
||||
}
|
||||
|
||||
#updateBox {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#updateButton,
|
||||
#updateDeck > hbox > label {
|
||||
-moz-margin-start: 0;
|
||||
-moz-padding-start: 0;
|
||||
}
|
||||
|
||||
#updateDeck > hbox > label:not([class="text-link"]) {
|
||||
color: #909090;
|
||||
font-style:italic;
|
||||
}
|
||||
|
||||
.update-throbber {
|
||||
width: 16px;
|
||||
min-height: 16px;
|
||||
-moz-margin-end: 3px;
|
||||
list-style-image: url("chrome://global/skin/icons/loading_16.png");
|
||||
}
|
||||
|
||||
.trademark-label,
|
||||
.text-link,
|
||||
.text-link:focus {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
# Contributor(s):
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Margaret Leibovic <margaret.leibovic@gmail.com>
|
||||
# Robert Strong <robert.bugzilla@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -65,7 +66,7 @@ function init(aEvent)
|
|||
}
|
||||
|
||||
#ifdef MOZ_UPDATER
|
||||
initUpdates();
|
||||
gAppUpdater = new appUpdater();
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
@ -76,14 +77,462 @@ function init(aEvent)
|
|||
}
|
||||
|
||||
#ifdef MOZ_UPDATER
|
||||
/**
|
||||
* Sets up "Check for Updates..." button.
|
||||
*/
|
||||
function initUpdates()
|
||||
{
|
||||
var browserBundle = Services.strings.
|
||||
createBundle("chrome://browser/locale/browser.properties");
|
||||
var checkForUpdates = document.getElementById("checkForUpdatesButton");
|
||||
setupCheckForUpdates(checkForUpdates, browserBundle);
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
var gAppUpdater;
|
||||
|
||||
function onUnload(aEvent) {
|
||||
if (gAppUpdater.isChecking)
|
||||
gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
|
||||
// Safe to call even when there isn't a download in progress.
|
||||
gAppUpdater.removeDownloadListener();
|
||||
gAppUpdater = null;
|
||||
}
|
||||
|
||||
|
||||
function appUpdater()
|
||||
{
|
||||
this.updateDeck = document.getElementById("updateDeck");
|
||||
|
||||
// Hide the update deck when there is already an update window open to avoid
|
||||
// syncing issues between them.
|
||||
if (Services.wm.getMostRecentWindow("Update:Wizard")) {
|
||||
this.updateDeck.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "aus",
|
||||
"@mozilla.org/updates/update-service;1",
|
||||
"nsIApplicationUpdateService");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "checker",
|
||||
"@mozilla.org/updates/update-checker;1",
|
||||
"nsIUpdateChecker");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "um",
|
||||
"@mozilla.org/updates/update-manager;1",
|
||||
"nsIUpdateManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "bs",
|
||||
"@mozilla.org/extensions/blocklist;1",
|
||||
"nsIBlocklistService");
|
||||
|
||||
this.bundle = Services.strings.
|
||||
createBundle("chrome://browser/locale/browser.properties");
|
||||
|
||||
this.updateBtn = document.getElementById("updateButton");
|
||||
|
||||
// The button label value must be set so its height is correct.
|
||||
this.setupUpdateButton("update.checkInsideButton");
|
||||
|
||||
let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
|
||||
let manualLink = document.getElementById("manualLink");
|
||||
manualLink.value = manualURL;
|
||||
manualLink.href = manualURL;
|
||||
document.getElementById("failedLink").href = manualURL;
|
||||
|
||||
if (this.updateDisabledAndLocked) {
|
||||
this.selectPanel("adminDisabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isPending) {
|
||||
this.setupUpdateButton("update.restart." +
|
||||
(this.isMajor ? "upgradeButton" : "applyButton"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDownloading) {
|
||||
this.startDownload();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.updateEnabled && this.updateAuto) {
|
||||
this.selectPanel("checkingForUpdates");
|
||||
this.isChecking = true;
|
||||
this.checker.checkForUpdates(this.updateCheckListener, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
appUpdater.prototype =
|
||||
{
|
||||
// true when there is an update check in progress.
|
||||
isChecking: false,
|
||||
|
||||
// true when there is an update already staged / ready to be applied.
|
||||
get isPending() {
|
||||
if (this.update)
|
||||
return this.update.state == "pending";
|
||||
return this.um.activeUpdate && this.um.activeUpdate.state == "pending";
|
||||
},
|
||||
|
||||
// true when there is an update download in progress.
|
||||
get isDownloading() {
|
||||
if (this.update)
|
||||
return this.update.state == "downloading";
|
||||
return this.um.activeUpdate &&
|
||||
this.um.activeUpdate.state == "downloading";
|
||||
},
|
||||
|
||||
// true when the update type is major.
|
||||
get isMajor() {
|
||||
if (this.update)
|
||||
return this.update.type == "major";
|
||||
return this.um.activeUpdate.type == "major";
|
||||
},
|
||||
|
||||
// true when updating is disabled by an administrator.
|
||||
get updateDisabledAndLocked() {
|
||||
return !this.updateEnabled &&
|
||||
Services.prefs.prefIsLocked("app.update.enabled");
|
||||
},
|
||||
|
||||
// true when updating is enabled.
|
||||
get updateEnabled() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref("app.update.enabled");
|
||||
}
|
||||
catch (e) { }
|
||||
return true; // Firefox default is true
|
||||
},
|
||||
|
||||
// true when updating is automatic.
|
||||
get updateAuto() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref("app.update.auto");
|
||||
}
|
||||
catch (e) { }
|
||||
return true; // Firefox default is true
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the deck's selected panel.
|
||||
*
|
||||
* @param aChildID
|
||||
* The id of the deck's child to select.
|
||||
*/
|
||||
selectPanel: function(aChildID) {
|
||||
this.updateDeck.selectedPanel = document.getElementById(aChildID);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the update button's label and accesskey.
|
||||
*
|
||||
* @param aKeyPrefix
|
||||
* The prefix for the properties file entry to use for setting the
|
||||
* label and accesskey.
|
||||
*/
|
||||
setupUpdateButton: function(aKeyPrefix) {
|
||||
this.updateBtn.label = this.bundle.GetStringFromName(aKeyPrefix + ".label");
|
||||
this.updateBtn.accessKey = this.bundle.GetStringFromName(aKeyPrefix + ".accesskey");
|
||||
if (!document.commandDispatcher.focusedElement ||
|
||||
document.commandDispatcher.focusedElement.isSameNode(this.updateBtn))
|
||||
this.updateBtn.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles oncommand for the update button.
|
||||
*/
|
||||
buttonOnCommand: function() {
|
||||
if (this.isPending) {
|
||||
// Notify all windows that an application quit has been requested.
|
||||
let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
|
||||
createInstance(Components.interfaces.nsISupportsPRBool);
|
||||
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
||||
|
||||
// Something aborted the quit process.
|
||||
if (cancelQuit.data)
|
||||
return;
|
||||
|
||||
// If already in safe mode restart in safe mode (bug 327119)
|
||||
if (Services.appinfo.inSafeMode) {
|
||||
let env = Components.classes["@mozilla.org/process/environment;1"].
|
||||
getService(Components.interfaces.nsIEnvironment);
|
||||
env.set("MOZ_SAFE_MODE_RESTART", "1");
|
||||
}
|
||||
|
||||
Components.classes["@mozilla.org/toolkit/app-startup;1"].
|
||||
getService(Components.interfaces.nsIAppStartup).
|
||||
quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
|
||||
Components.interfaces.nsIAppStartup.eRestart);
|
||||
return;
|
||||
}
|
||||
|
||||
const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
|
||||
// Firefox no longer displays a license for updates and the licenseURL check
|
||||
// is just in case a distibution does.
|
||||
if (this.update && (this.update.billboardURL || this.update.licenseURL ||
|
||||
this.addons.length != 0)) {
|
||||
var ary = null;
|
||||
ary = Components.classes["@mozilla.org/supports-array;1"].
|
||||
createInstance(Components.interfaces.nsISupportsArray);
|
||||
ary.AppendElement(this.update);
|
||||
var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
|
||||
Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectPanel("checkingForUpdates");
|
||||
this.isChecking = true;
|
||||
this.checker.checkForUpdates(this.updateCheckListener, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements nsIUpdateCheckListener. The methods implemented by
|
||||
* nsIUpdateCheckListener have to be in a different scope from
|
||||
* nsIIncrementalDownload because both nsIUpdateCheckListener and
|
||||
* nsIIncrementalDownload implement onProgress.
|
||||
*/
|
||||
updateCheckListener: {
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
onProgress: function(aRequest, aPosition, aTotalSize) {
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
onCheckComplete: function(aRequest, aUpdates, aUpdateCount) {
|
||||
gAppUpdater.isChecking = false;
|
||||
gAppUpdater.update = gAppUpdater.aus.
|
||||
selectUpdate(aUpdates, aUpdates.length);
|
||||
if (!gAppUpdater.update) {
|
||||
gAppUpdater.selectPanel("noUpdatesFound");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gAppUpdater.aus.canApplyUpdates) {
|
||||
gAppUpdater.selectPanel("manualUpdate");
|
||||
return;
|
||||
}
|
||||
|
||||
// Firefox no longer displays a license for updates and the licenseURL
|
||||
// check is just in case a distibution does.
|
||||
if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
|
||||
gAppUpdater.selectPanel("updateButtonBox");
|
||||
gAppUpdater.setupUpdateButton("update.openUpdateUI." +
|
||||
(this.isMajor ? "upgradeButton"
|
||||
: "applyButton"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gAppUpdater.update.appVersion ||
|
||||
Services.vc.compare(gAppUpdater.update.appVersion,
|
||||
Services.appinfo.version) == 0) {
|
||||
gAppUpdater.startDownload();
|
||||
return;
|
||||
}
|
||||
|
||||
gAppUpdater.checkAddonCompatibility();
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
onError: function(aRequest, aUpdate) {
|
||||
// Errors in the update check are treated as no updates found. If the
|
||||
// update check fails repeatedly without a success the user will be
|
||||
// notified with the normal app update user interface so this is safe.
|
||||
gAppUpdater.isChecking = false;
|
||||
gAppUpdater.selectPanel("noUpdatesFound");
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsISupports.idl
|
||||
*/
|
||||
QueryInterface: function(aIID) {
|
||||
if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
|
||||
!aIID.equals(Components.interfaces.nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks the compatibility of add-ons for the application update.
|
||||
*/
|
||||
checkAddonCompatibility: function() {
|
||||
var self = this;
|
||||
AddonManager.getAllAddons(function(aAddons) {
|
||||
self.addons = [];
|
||||
self.addonsCheckedCount = 0;
|
||||
aAddons.forEach(function(aAddon) {
|
||||
// If an add-on isn't appDisabled and isn't userDisabled then it is
|
||||
// either active now or the user expects it to be active after the
|
||||
// restart. If that is the case and the add-on is not installed by the
|
||||
// application and is not compatible with the new application version
|
||||
// then the user should be warned that the add-on will become
|
||||
// incompatible. If an addon's type equals plugin it is skipped since
|
||||
// checking plugins compatibility information isn't supported and
|
||||
// getting the scope property of a plugin breaks in some environments
|
||||
// (see bug 566787).
|
||||
if (aAddon.type != "plugin" &&
|
||||
!aAddon.appDisabled && !aAddon.userDisabled &&
|
||||
aAddon.scope != AddonManager.SCOPE_APPLICATION &&
|
||||
aAddon.isCompatible &&
|
||||
!aAddon.isCompatibleWith(self.update.appVersion,
|
||||
self.update.platformVersion))
|
||||
self.addons.push(aAddon);
|
||||
});
|
||||
self.addonsTotalCount = self.addons.length;
|
||||
if (self.addonsTotalCount == 0) {
|
||||
self.startDownload();
|
||||
return;
|
||||
}
|
||||
|
||||
self.checkAddonsForUpdates();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if there are updates for add-ons that are incompatible with the
|
||||
* application update.
|
||||
*/
|
||||
checkAddonsForUpdates: function() {
|
||||
this.addons.forEach(function(aAddon) {
|
||||
aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
|
||||
this.update.appVersion,
|
||||
this.update.platformVersion);
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* See XPIProvider.jsm
|
||||
*/
|
||||
onCompatibilityUpdateAvailable: function(aAddon) {
|
||||
for (var i = 0; i < this.addons.length; ++i) {
|
||||
if (this.addons[i].id == aAddon.id) {
|
||||
this.addons.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See XPIProvider.jsm
|
||||
*/
|
||||
onUpdateAvailable: function(aAddon, aInstall) {
|
||||
if (!this.bs.isAddonBlocklisted(aAddon.id, aInstall.version,
|
||||
this.update.appVersion,
|
||||
this.update.platformVersion)) {
|
||||
// Compatibility or new version updates mean the same thing here.
|
||||
this.onCompatibilityUpdateAvailable(aAddon);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See XPIProvider.jsm
|
||||
*/
|
||||
onUpdateFinished: function(aAddon) {
|
||||
++this.addonsCheckedCount;
|
||||
|
||||
if (this.addonsCheckedCount < this.addonsTotalCount)
|
||||
return;
|
||||
|
||||
if (this.addons.length == 0) {
|
||||
// Compatibility updates or new version updates were found for all add-ons
|
||||
this.startDownload();
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectPanel("updateButtonBox");
|
||||
this.setupUpdateButton("update.openUpdateUI." +
|
||||
(this.isMajor ? "upgradeButton" : "applyButton"));
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts the download of an update mar.
|
||||
*/
|
||||
startDownload: function() {
|
||||
if (!this.update)
|
||||
this.update = this.um.activeUpdate;
|
||||
this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
|
||||
this.update.setProperty("foregroundDownload", "true");
|
||||
|
||||
this.aus.pauseDownload();
|
||||
let state = this.aus.downloadUpdate(this.update, false);
|
||||
if (state == "failed") {
|
||||
this.selectPanel("downloadFailed");
|
||||
return;
|
||||
}
|
||||
|
||||
this.downloadStatus = document.getElementById("downloadStatus");
|
||||
this.downloadStatus.value =
|
||||
DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size);
|
||||
this.selectPanel("downloading");
|
||||
this.aus.addDownloadListener(this);
|
||||
},
|
||||
|
||||
removeDownloadListener: function() {
|
||||
this.aus.removeDownloadListener(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIRequestObserver.idl
|
||||
*/
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIRequestObserver.idl
|
||||
*/
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
switch (aStatusCode) {
|
||||
case Components.results.NS_ERROR_UNEXPECTED:
|
||||
if (this.update.selectedPatch.state == "download-failed" &&
|
||||
(this.update.isCompleteUpdate || this.update.patchCount != 2)) {
|
||||
// Verification error of complete patch, informational text is held in
|
||||
// the update object.
|
||||
this.removeDownloadListener();
|
||||
this.selectPanel("downloadFailed");
|
||||
break;
|
||||
}
|
||||
// Verification failed for a partial patch, complete patch is now
|
||||
// downloading so return early and do NOT remove the download listener!
|
||||
break;
|
||||
case Components.results.NS_BINDING_ABORTED:
|
||||
// Do not remove UI listener since the user may resume downloading again.
|
||||
break;
|
||||
case Components.results.NS_OK:
|
||||
this.removeDownloadListener();
|
||||
this.selectPanel("updateButtonBox");
|
||||
this.setupUpdateButton("update.restart." +
|
||||
(this.isMajor ? "upgradeButton" : "applyButton"));
|
||||
break;
|
||||
default:
|
||||
this.removeDownloadListener();
|
||||
this.selectPanel("downloadFailed");
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIProgressEventSink.idl
|
||||
*/
|
||||
onStatus: function(aRequest, aContext, aStatus, aStatusArg) {
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIProgressEventSink.idl
|
||||
*/
|
||||
onProgress: function(aRequest, aContext, aProgress, aProgressMax) {
|
||||
this.downloadStatus.value =
|
||||
DownloadUtils.getTransferTotal(aProgress, aProgressMax);
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsISupports.idl
|
||||
*/
|
||||
QueryInterface: function(aIID) {
|
||||
if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
|
||||
!aIID.equals(Components.interfaces.nsIRequestObserver) &&
|
||||
!aIID.equals(Components.interfaces.nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
# Contributor(s):
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Margaret Leibovic <margaret.leibovic@gmail.com>
|
||||
# Robert Strong <robert.bugzilla@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -57,6 +58,9 @@
|
|||
id="aboutDialog"
|
||||
windowtype="Browser:About"
|
||||
onload="init(event);"
|
||||
#ifdef MOZ_UPDATER
|
||||
onunload="onUnload(event);"
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
inwindowmenu="false"
|
||||
#else
|
||||
|
@ -64,7 +68,6 @@
|
|||
#endif
|
||||
>
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/aboutDialog.js"/>
|
||||
|
||||
<vbox>
|
||||
|
@ -74,12 +77,38 @@
|
|||
#expand <label id="version" value="__MOZ_APP_VERSION__"/>
|
||||
<label id="distribution" class="text-blurb"/>
|
||||
<label id="distributionId" class="text-blurb"/>
|
||||
<vbox id="updateBox">
|
||||
#ifdef MOZ_UPDATER
|
||||
<hbox>
|
||||
<button id="checkForUpdatesButton" oncommand="checkForUpdates();" align="start"/>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
<deck id="updateDeck" orient="vertical">
|
||||
<hbox id="updateButtonBox" align="center">
|
||||
<button id="updateButton" align="start"
|
||||
oncommand="gAppUpdater.buttonOnCommand();"/>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
<hbox id="checkingForUpdates" align="center">
|
||||
<image class="update-throbber"/><label>&update.checkingForUpdates;</label>
|
||||
</hbox>
|
||||
<hbox id="checkingAddonCompat" align="center">
|
||||
<image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
|
||||
</hbox>
|
||||
<hbox id="downloading" align="center">
|
||||
<image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
|
||||
</hbox>
|
||||
<hbox id="downloadFailed" align="center">
|
||||
<label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
|
||||
</hbox>
|
||||
<hbox id="adminDisabled" align="center">
|
||||
<label>&update.adminDisabled;</label>
|
||||
</hbox>
|
||||
<hbox id="noUpdatesFound" align="center">
|
||||
<label>&update.noUpdatesFound;</label>
|
||||
</hbox>
|
||||
<hbox id="manualUpdate" align="center">
|
||||
<label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
|
||||
</hbox>
|
||||
</deck>
|
||||
#endif
|
||||
</vbox>
|
||||
<description class="text-blurb">
|
||||
&community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end2;
|
||||
</description>
|
||||
|
|
|
@ -1728,16 +1728,22 @@ var gFinishedPage = {
|
|||
gUpdates.wiz.getButton("extra1").disabled = true;
|
||||
|
||||
// Notify all windows that an application quit has been requested.
|
||||
var os = CoC["@mozilla.org/observer-service;1"].
|
||||
getService(CoI.nsIObserverService);
|
||||
var cancelQuit = CoC["@mozilla.org/supports-PRBool;1"].
|
||||
createInstance(CoI.nsISupportsPRBool);
|
||||
os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
||||
Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
|
||||
"restart");
|
||||
|
||||
// Something aborted the quit process.
|
||||
if (cancelQuit.data)
|
||||
return;
|
||||
|
||||
// If already in safe mode restart in safe mode (bug 327119)
|
||||
if (Services.appinfo.inSafeMode) {
|
||||
let env = CoC["@mozilla.org/process/environment;1"].
|
||||
getService(CoI.nsIEnvironment);
|
||||
env.set("MOZ_SAFE_MODE_RESTART", "1");
|
||||
}
|
||||
|
||||
// Restart the application
|
||||
CoC["@mozilla.org/toolkit/app-startup;1"].getService(CoI.nsIAppStartup).
|
||||
quit(CoI.nsIAppStartup.eAttemptQuit | CoI.nsIAppStartup.eRestart);
|
||||
|
|
|
@ -51,6 +51,7 @@ const Cc = Components.classes;
|
|||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
const PREF_APP_UPDATE_ALTWINDOWTYPE = "app.update.altwindowtype";
|
||||
const PREF_APP_UPDATE_AUTO = "app.update.auto";
|
||||
const PREF_APP_UPDATE_BACKGROUND_INTERVAL = "app.update.download.backgroundInterval";
|
||||
const PREF_APP_UPDATE_BACKGROUNDERRORS = "app.update.backgroundErrors";
|
||||
|
@ -2779,6 +2780,9 @@ UpdatePrompt.prototype = {
|
|||
* See nsIUpdateService.idl
|
||||
*/
|
||||
checkForUpdates: function UP_checkForUpdates() {
|
||||
if (this._getAltUpdateWindow())
|
||||
return;
|
||||
|
||||
this._showUI(null, URI_UPDATE_PROMPT_DIALOG, null, UPDATE_WINDOW_NAME,
|
||||
null, null);
|
||||
},
|
||||
|
@ -2788,7 +2792,7 @@ UpdatePrompt.prototype = {
|
|||
*/
|
||||
showUpdateAvailable: function UP_showUpdateAvailable(update) {
|
||||
if (getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false) ||
|
||||
this._getUpdateWindow())
|
||||
this._getUpdateWindow() || this._getAltUpdateWindow())
|
||||
return;
|
||||
|
||||
var stringsPrefix = "updateAvailable_" + update.type + ".";
|
||||
|
@ -2805,6 +2809,9 @@ UpdatePrompt.prototype = {
|
|||
* See nsIUpdateService.idl
|
||||
*/
|
||||
showUpdateDownloaded: function UP_showUpdateDownloaded(update, background) {
|
||||
if (this._getAltUpdateWindow())
|
||||
return;
|
||||
|
||||
if (background) {
|
||||
if (getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false))
|
||||
return;
|
||||
|
@ -2852,7 +2859,8 @@ UpdatePrompt.prototype = {
|
|||
* See nsIUpdateService.idl
|
||||
*/
|
||||
showUpdateError: function UP_showUpdateError(update) {
|
||||
if (getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false))
|
||||
if (getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false) ||
|
||||
this._getAltUpdateWindow())
|
||||
return;
|
||||
|
||||
// In some cases, we want to just show a simple alert dialog:
|
||||
|
@ -2892,6 +2900,18 @@ UpdatePrompt.prototype = {
|
|||
return Services.wm.getMostRecentWindow(UPDATE_WINDOW_NAME);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an alternative update window if present. When a window with this
|
||||
* windowtype is open the application update service won't open the normal
|
||||
* application update user interface window.
|
||||
*/
|
||||
_getAltUpdateWindow: function UP__getAltUpdateWindow() {
|
||||
let windowType = getPref("getCharPref", PREF_APP_UPDATE_ALTWINDOWTYPE, null);
|
||||
if (!windowType)
|
||||
return null;
|
||||
return Services.wm.getMostRecentWindow(windowType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiate a less obtrusive UI, starting with a non-modal notification alert
|
||||
* @param parent
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsPrintfCString.h"
|
||||
#include "prproces.h"
|
||||
#include "prlog.h"
|
||||
#include "prenv.h"
|
||||
#include "nsVersionComparator.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
@ -473,6 +474,10 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsILocalFile *statusFile,
|
|||
argc = 3;
|
||||
}
|
||||
|
||||
if (gSafeMode) {
|
||||
PR_SetEnv("MOZ_SAFE_MODE_RESTART=1");
|
||||
}
|
||||
|
||||
LOG(("spawning updater process [%s]\n", updaterPath.get()));
|
||||
|
||||
#if defined(USE_EXECV)
|
||||
|
|
Загрузка…
Ссылка в новой задаче