Bug 600500: About Dialog should check for updates automatically, but not trick the user into installing them if updates are set to manual. ui-review=faaborg and shorlander, r=felipe

This commit is contained in:
Steffen Wilberg 2013-12-12 00:01:17 +01:00
parent e925da2d12
commit f67501c363
4 changed files with 102 additions and 105 deletions

View File

@ -106,11 +106,6 @@ function appUpdater()
this.bundle = Services.strings. this.bundle = Services.strings.
createBundle("chrome://browser/locale/browser.properties"); 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 manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
let manualLink = document.getElementById("manualLink"); let manualLink = document.getElementById("manualLink");
manualLink.value = manualURL; manualLink.value = manualURL;
@ -123,8 +118,7 @@ function appUpdater()
} }
if (this.isPending || this.isApplied) { if (this.isPending || this.isApplied) {
this.setupUpdateButton("update.restart." + this.selectPanel("apply");
(this.isMajor ? "upgradeButton" : "updateButton"));
return; return;
} }
@ -135,15 +129,19 @@ function appUpdater()
if (this.isDownloading) { if (this.isDownloading) {
this.startDownload(); this.startDownload();
// selectPanel("downloading") is called from setupDownloadingUI().
return; return;
} }
if (this.updateEnabled && this.updateAuto) { // If app.update.enabled is false, we don't pop up an update dialog
this.selectPanel("checkingForUpdates"); // automatically, but opening the About dialog is considered manually
this.isChecking = true; // checking for updates, so we always check.
this.checker.checkForUpdates(this.updateCheckListener, true); // If app.update.auto is false, we ask before downloading though,
return; // in onCheckComplete.
} this.selectPanel("checkingForUpdates");
this.isChecking = true;
this.checker.checkForUpdates(this.updateCheckListener, true);
// after checking, onCheckComplete() is called
} }
appUpdater.prototype = appUpdater.prototype =
@ -180,13 +178,6 @@ appUpdater.prototype =
this.um.activeUpdate.state == "downloading"; 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. // true when updating is disabled by an administrator.
get updateDisabledAndLocked() { get updateDisabledAndLocked() {
return !this.updateEnabled && return !this.updateEnabled &&
@ -218,36 +209,55 @@ appUpdater.prototype =
}, },
/** /**
* Sets the deck's selected panel. * Sets the panel of the updateDeck.
* *
* @param aChildID * @param aChildID
* The id of the deck's child to select. * The id of the deck's child to select, e.g. "apply".
*/ */
selectPanel: function(aChildID) { selectPanel: function(aChildID) {
this.updateDeck.selectedPanel = document.getElementById(aChildID); let panel = document.getElementById(aChildID);
this.updateBtn.disabled = (aChildID != "updateButtonBox");
let button = panel.querySelector("button");
if (button) {
let button = panel.firstChild;
if (aChildID == "downloadAndInstall") {
let updateVersion = gAppUpdater.update.displayVersion;
button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1);
button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey");
}
this.updateDeck.selectedPanel = panel;
if (!document.commandDispatcher.focusedElement || // don't steal the focus
document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons
button.focus();
} else {
this.updateDeck.selectedPanel = panel;
}
}, },
/** /**
* Sets the update button's label and accesskey. * Check for addon compat, or start the download right away
*
* @param aKeyPrefix
* The prefix for the properties file entry to use for setting the
* label and accesskey.
*/ */
setupUpdateButton: function(aKeyPrefix) { doUpdate: function() {
this.updateBtn.label = this.bundle.GetStringFromName(aKeyPrefix + ".label"); // skip the compatibility check if the update doesn't provide appVersion,
this.updateBtn.accessKey = this.bundle.GetStringFromName(aKeyPrefix + ".accesskey"); // or the appVersion is unchanged, e.g. nightly update
if (!document.commandDispatcher.focusedElement || if (!this.update.appVersion ||
document.commandDispatcher.focusedElement == this.updateBtn) Services.vc.compare(gAppUpdater.update.appVersion,
this.updateBtn.focus(); Services.appinfo.version) == 0) {
this.startDownload();
} else {
this.checkAddonCompatibility();
}
}, },
/** /**
* Handles oncommand for the update button. * Handles oncommand for the "Restart to Update" button
* which is presented after the download has been downloaded.
*/ */
buttonOnCommand: function() { buttonRestartAfterDownload: function() {
if (this.isPending || this.isApplied) { if (!this.isPending && !this.isApplied)
return;
// Notify all windows that an application quit has been requested. // Notify all windows that an application quit has been requested.
let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]. let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
createInstance(Components.interfaces.nsISupportsPRBool); createInstance(Components.interfaces.nsISupportsPRBool);
@ -268,27 +278,21 @@ appUpdater.prototype =
appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit | appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
Components.interfaces.nsIAppStartup.eRestart); Components.interfaces.nsIAppStartup.eRestart);
return; },
}
/**
* Handles oncommand for the "Apply Update…" button
* which is presented if we need to show the billboard or license.
*/
buttonApplyBillboard: function() {
const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul"; const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
// Firefox no longer displays a license for updates and the licenseURL check var ary = null;
// is just in case a distibution does. ary = Components.classes["@mozilla.org/supports-array;1"].
if (this.update && (this.update.billboardURL || this.update.licenseURL || createInstance(Components.interfaces.nsISupportsArray);
this.addons.length != 0)) { ary.AppendElement(this.update);
var ary = null; var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
ary = Components.classes["@mozilla.org/supports-array;1"]. Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
createInstance(Components.interfaces.nsISupportsArray); window.close(); // close the "About" window; updates.xul takes over.
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);
}, },
/** /**
@ -326,21 +330,14 @@ appUpdater.prototype =
// Firefox no longer displays a license for updates and the licenseURL // Firefox no longer displays a license for updates and the licenseURL
// check is just in case a distibution does. // check is just in case a distibution does.
if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) { if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
gAppUpdater.selectPanel("updateButtonBox"); gAppUpdater.selectPanel("applyBillboard");
gAppUpdater.setupUpdateButton("update.openUpdateUI." +
(this.isMajor ? "upgradeButton"
: "applyButton"));
return; return;
} }
if (!gAppUpdater.update.appVersion || if (gAppUpdater.updateAuto) // automatically download and install
Services.vc.compare(gAppUpdater.update.appVersion, gAppUpdater.doUpdate();
Services.appinfo.version) == 0) { else // ask
gAppUpdater.startDownload(); gAppUpdater.selectPanel("downloadAndInstall");
return;
}
gAppUpdater.checkAddonCompatibility();
}, },
/** /**
@ -474,9 +471,7 @@ appUpdater.prototype =
return; return;
} }
this.selectPanel("updateButtonBox"); this.selectPanel("apply");
this.setupUpdateButton("update.openUpdateUI." +
(this.isMajor ? "upgradeButton" : "applyButton"));
}, },
/** /**
@ -553,11 +548,9 @@ appUpdater.prototype =
if (status == "applied" || status == "applied-service" || if (status == "applied" || status == "applied-service" ||
status == "pending" || status == "pending-service") { status == "pending" || status == "pending-service") {
// If the update is successfully applied, or if the updater has // If the update is successfully applied, or if the updater has
// fallen back to non-staged updates, show the Restart to Update // fallen back to non-staged updates, show the "Restart to Update"
// button. // button.
self.selectPanel("updateButtonBox"); self.selectPanel("apply");
self.setupUpdateButton("update.restart." +
(self.isMajor ? "upgradeButton" : "updateButton"));
} else if (status == "failed") { } else if (status == "failed") {
// Background update has failed, let's show the UI responsible for // Background update has failed, let's show the UI responsible for
// prompting the user to update manually. // prompting the user to update manually.
@ -572,9 +565,7 @@ appUpdater.prototype =
Services.obs.removeObserver(arguments.callee, "update-staged"); Services.obs.removeObserver(arguments.callee, "update-staged");
}, "update-staged", false); }, "update-staged", false);
} else { } else {
this.selectPanel("updateButtonBox"); this.selectPanel("apply");
this.setupUpdateButton("update.restart." +
(this.isMajor ? "upgradeButton" : "updateButton"));
} }
break; break;
default: default:
@ -582,7 +573,6 @@ appUpdater.prototype =
this.selectPanel("downloadFailed"); this.selectPanel("downloadFailed");
break; break;
} }
}, },
/** /**

View File

@ -50,17 +50,29 @@
<vbox id="updateBox"> <vbox id="updateBox">
#ifdef MOZ_UPDATER #ifdef MOZ_UPDATER
<deck id="updateDeck" orient="vertical"> <deck id="updateDeck" orient="vertical">
<hbox id="updateButtonBox" align="center"> <hbox id="downloadAndInstall" align="center">
<button id="downloadAndInstallButton" align="start"
oncommand="gAppUpdater.doUpdate();"/>
<!-- label and accesskey will be filled by JS -->
<spacer flex="1"/>
</hbox>
<hbox id="apply" align="center">
<button id="updateButton" align="start" <button id="updateButton" align="start"
oncommand="gAppUpdater.buttonOnCommand();"/> label="&update.updateButton.label;"
accesskey="&update.updateButton.accesskey;"
oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
<spacer flex="1"/>
</hbox>
<hbox id="applyBillboard" align="center">
<button id="applyButtonBillboard" align="start"
label="&update.applyButtonBillboard.label;"
accesskey="&update.applyButtonBillboard.accesskey;"
oncommand="gAppUpdater.buttonApplyBillboard();"/>
<spacer flex="1"/> <spacer flex="1"/>
</hbox> </hbox>
<hbox id="checkingForUpdates" align="center"> <hbox id="checkingForUpdates" align="center">
<image class="update-throbber"/><label>&update.checkingForUpdates;</label> <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
</hbox> </hbox>
<hbox id="checkingAddonCompat" align="center">
<image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
</hbox>
<hbox id="downloading" align="center"> <hbox id="downloading" align="center">
<image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label> <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
</hbox> </hbox>

View File

@ -3,6 +3,17 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY aboutDialog.title "About &brandFullName;"> <!ENTITY aboutDialog.title "About &brandFullName;">
<!-- LOCALIZATION NOTE update.applyButton.*, update.upgradeButton.*):
# Only one button is present at a time.
# The button when displayed is located directly under the Firefox version in
# the about dialog (see bug 596813 for screenshots).
-->
<!ENTITY update.updateButton.label "Restart to Update">
<!ENTITY update.updateButton.accesskey "R">
<!ENTITY update.applyButtonBillboard.label "Apply Update…">
<!ENTITY update.applyButtonBillboard.accesskey "A">
<!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. --> <!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. -->
<!ENTITY warningDesc.version "&brandShortName; is experimental and may be unstable."> <!ENTITY warningDesc.version "&brandShortName; is experimental and may be unstable.">
<!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. --> <!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. -->
@ -41,8 +52,6 @@
<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). --> <!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
<!ENTITY update.checkingForUpdates "Checking for updates…"> <!ENTITY update.checkingForUpdates "Checking for updates…">
<!-- LOCALIZATION NOTE (update.checkingAddonCompat): try to make the localized text short (see bug 596813 for screenshots). -->
<!ENTITY update.checkingAddonCompat "Checking Add-on compatibility…">
<!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). --> <!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). -->
<!ENTITY update.noUpdatesFound "&brandShortName; is up to date"> <!ENTITY update.noUpdatesFound "&brandShortName; is up to date">
<!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). --> <!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). -->

View File

@ -191,24 +191,10 @@ sanitizeEverythingWarning2=All history will be cleared.
# provided that the user has modified the default set of history items to clear. # provided that the user has modified the default set of history items to clear.
sanitizeSelectedWarning=All selected items will be cleared. sanitizeSelectedWarning=All selected items will be cleared.
# Check for Updates in the About Dialog - button labels and accesskeys # LOCALIZATION NOTE (downloadAndInstallButton.label): %S is replaced by the
# LOCALIZATION NOTE - all of the following update buttons labels will only be # version of the update: "Update to 28.0".
# displayed one at a time. So, if a button is displayed nothing else will update.downloadAndInstallButton.label=Update to %S
# be displayed alongside of the button. The button when displayed is located update.downloadAndInstallButton.accesskey=U
# directly under the Firefox version in the about dialog (see bug 596813 for
# screenshots).
update.checkInsideButton.label=Check for Updates
update.checkInsideButton.accesskey=C
update.resumeButton.label=Resume Downloading %S…
update.resumeButton.accesskey=D
update.openUpdateUI.applyButton.label=Apply Update…
update.openUpdateUI.applyButton.accesskey=A
update.restart.updateButton.label=Restart to Update
update.restart.updateButton.accesskey=R
update.openUpdateUI.upgradeButton.label=Upgrade Now…
update.openUpdateUI.upgradeButton.accesskey=U
update.restart.upgradeButton.label=Upgrade Now
update.restart.upgradeButton.accesskey=U
# RSS Pretty Print # RSS Pretty Print
feedShowFeedNew=Subscribe to '%S'… feedShowFeedNew=Subscribe to '%S'…