author | Dave Hylands <dhylands@gmail.com> |
Tue, 15 Jan 2013 00:10:19 +0100 | |
changeset 118862 | 3eff445e4e91abc27fab7e27e8091033d7e67729 |
parent 118861 | c6f47473693423bb9c265b196af56544bd8ea4e7 |
child 118863 | 9eecc4f1a318bc5eddc0147ffdb522aa01b42d9f |
push id | 24180 |
push user | emorley@mozilla.com |
push date | Tue, 15 Jan 2013 22:58:27 +0000 |
treeherder | mozilla-central@72e34ce7fd92 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | marshall_law |
bugs | 825598 |
milestone | 21.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
b2g/app/b2g.js | file | annotate | diff | comparison | revisions | |
b2g/components/UpdatePrompt.js | file | annotate | diff | comparison | revisions |
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -450,16 +450,19 @@ pref("marionette.defaultPrefs.port", 282 #ifdef MOZ_UPDATER // When we're applying updates, we can't let anything hang us on // quit+restart. The user has no recourse. pref("shutdown.watchdog.timeoutSecs", 5); // Timeout before the update prompt automatically installs the update pref("b2g.update.apply-prompt-timeout", 60000); // milliseconds // Amount of time to wait after the user is idle before prompting to apply an update pref("b2g.update.apply-idle-timeout", 600000); // milliseconds +// Amount of time after which connection will be restarted if no progress +pref("b2g.update.download-watchdog-timeout", 120000); // milliseconds +pref("b2g.update.download-watchdog-max-retries", 5); pref("app.update.enabled", true); pref("app.update.auto", false); pref("app.update.silent", false); pref("app.update.mode", 0); pref("app.update.incompatible.mode", 0); pref("app.update.staging.enabled", true); pref("app.update.service.enabled", true);
--- a/b2g/components/UpdatePrompt.js +++ b/b2g/components/UpdatePrompt.js @@ -13,18 +13,20 @@ Cu.import("resource://gre/modules/XPCOMU Cu.import("resource://gre/modules/Services.jsm"); const VERBOSE = 1; let log = VERBOSE ? function log_dump(msg) { dump("UpdatePrompt: "+ msg +"\n"); } : function log_noop(msg) { }; -const PREF_APPLY_PROMPT_TIMEOUT = "b2g.update.apply-prompt-timeout"; -const PREF_APPLY_IDLE_TIMEOUT = "b2g.update.apply-idle-timeout"; +const PREF_APPLY_PROMPT_TIMEOUT = "b2g.update.apply-prompt-timeout"; +const PREF_APPLY_IDLE_TIMEOUT = "b2g.update.apply-idle-timeout"; +const PREF_DOWNLOAD_WATCHDOG_TIMEOUT = "b2g.update.download-watchdog-timeout"; +const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries"; const NETWORK_ERROR_OFFLINE = 111; const FILE_ERROR_TOO_BIG = 112; const HTTP_ERROR_OFFSET = 1000; const STATE_DOWNLOADING = 'downloading'; XPCOMUtils.defineLazyServiceGetter(Services, "aus", @@ -484,35 +486,102 @@ UpdatePrompt.prototype = { timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT); return timer; }, // nsIRequestObserver _startedSent: false, + _watchdogTimer: null, + _watchdogTimeout: 0, + + _autoRestartDownload: false, + _autoRestartCount: 0, + + watchdogTimerFired: function UP_watchdogTimerFired() { + log("Download watchdog fired"); + this._autoRestartDownload = true; + Services.aus.pauseDownload(); + }, + + startWatchdogTimer: function UP_startWatchdogTimer() { + if (this._watchdogTimer) { + this._watchdogTimer.cancel(); + } else { + this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + this._watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT); + } + this._watchdogTimer.initWithCallback(this.watchdogTimerFired.bind(this), + this._watchdogTimeout, + Ci.nsITimer.TYPE_ONE_SHOT); + }, + + stopWatchdogTimer: function UP_stopWatchdogTimer() { + if (this._watchdogTimer) { + this._watchdogTimer.cancel(); + this._watchdogTimer = null; + } + }, + + touchWatchdogTimer: function UP_touchWatchdogTimer() { + this.startWatchdogTimer(); + }, + onStartRequest: function UP_onStartRequest(aRequest, aContext) { // Wait until onProgress to send the update-download-started event, in case // this request turns out to fail for some reason this._startedSent = false; + this.startWatchdogTimer(); }, onStopRequest: function UP_onStopRequest(aRequest, aContext, aStatusCode) { + this.stopWatchdogTimer(); + Services.aus.removeDownloadListener(this); let paused = !Components.isSuccessCode(aStatusCode); + if (!paused) { + // The download was successful, no need to restart + this._autoRestartDownload = false; + } + if (this._autoRestartDownload) { + this._autoRestartDownload = false; + let watchdogMaxRetries = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES); + this._autoRestartCount++; + if (this._autoRestartCount > watchdogMaxRetries) { + log("Download - retry count exceeded - error"); + // We exceeded the max retries. Treat the download like an error, + // which will give the user a chance to restart manually later. + this._autoRestartCount = 0; + if (Services.um.activeUpdate) { + this.showUpdateError(Services.um.activeUpdate); + } + return; + } + log("Download - restarting download - attempt " + this._autoRestartCount); + this.downloadUpdate(null); + return; + } + this._autoRestartCount = 0; this.sendChromeEvent("update-download-stopped", { - paused: paused + paused: paused }); - - Services.aus.removeDownloadListener(this); }, // nsIProgressEventSink onProgress: function UP_onProgress(aRequest, aContext, aProgress, aProgressMax) { + if (aProgress == aProgressMax) { + // The update.mar validation done by onStopRequest may take + // a while before the onStopRequest callback is made, so stop + // the timer now. + this.stopWatchdogTimer(); + } else { + this.touchWatchdogTimer(); + } if (!this._startedSent) { this.sendChromeEvent("update-download-started", { total: aProgressMax }); this._startedSent = true; } this.sendChromeEvent("update-download-progress", {