summaryrefslogtreecommitdiffstats
path: root/b2g/components/UpdatePrompt.js
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2018-02-03 06:25:10 -0500
committerMatt A. Tobin <email@mattatobin.com>2018-02-03 06:25:10 -0500
commit8b8c65072aedef94610748ce92c2ed3a19fd5517 (patch)
tree8614d386acf5db7a77b08d19a5854a7d75dab015 /b2g/components/UpdatePrompt.js
parent8c3a46bd13a0660a3ff1e0379dbf515873a852d2 (diff)
downloadUXP-8b8c65072aedef94610748ce92c2ed3a19fd5517.tar
UXP-8b8c65072aedef94610748ce92c2ed3a19fd5517.tar.gz
UXP-8b8c65072aedef94610748ce92c2ed3a19fd5517.tar.lz
UXP-8b8c65072aedef94610748ce92c2ed3a19fd5517.tar.xz
UXP-8b8c65072aedef94610748ce92c2ed3a19fd5517.zip
Purge b2g/
Diffstat (limited to 'b2g/components/UpdatePrompt.js')
-rw-r--r--b2g/components/UpdatePrompt.js783
1 files changed, 0 insertions, 783 deletions
diff --git a/b2g/components/UpdatePrompt.js b/b2g/components/UpdatePrompt.js
deleted file mode 100644
index 1df07204c..000000000
--- a/b2g/components/UpdatePrompt.js
+++ /dev/null
@@ -1,783 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* 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 Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const VERBOSE = 1;
-var 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_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 HTTP_ERROR_OFFSET = 1000;
-
-const STATE_DOWNLOADING = 'downloading';
-
-XPCOMUtils.defineLazyServiceGetter(Services, "aus",
- "@mozilla.org/updates/update-service;1",
- "nsIApplicationUpdateService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "um",
- "@mozilla.org/updates/update-manager;1",
- "nsIUpdateManager");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "idle",
- "@mozilla.org/widget/idleservice;1",
- "nsIIdleService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "settings",
- "@mozilla.org/settingsService;1",
- "nsISettingsService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'env',
- '@mozilla.org/process/environment;1',
- 'nsIEnvironment');
-
-function useSettings() {
- // When we're running in the real phone, then we can use settings.
- // But when we're running as part of xpcshell, there is no settings database
- // and trying to use settings in this scenario causes lots of weird
- // assertions at shutdown time.
- if (typeof useSettings.result === "undefined") {
- useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR");
- }
- return useSettings.result;
-}
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-function UpdateCheckListener(updatePrompt) {
- this._updatePrompt = updatePrompt;
-}
-
-UpdateCheckListener.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener]),
-
- _updatePrompt: null,
-
- onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) {
- if (Services.um.activeUpdate) {
- // We're actively downloading an update, that's the update the user should
- // see, even if a newer update is available.
- this._updatePrompt.setUpdateStatus("active-update");
- this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate);
- return;
- }
-
- if (updateCount == 0) {
- this._updatePrompt.setUpdateStatus("no-updates");
-
- if (this._updatePrompt._systemUpdateListener) {
- this._updatePrompt._systemUpdateListener.onError("no-updates");
- }
-
- return;
- }
-
- let update = Services.aus.selectUpdate(updates, updateCount);
- if (!update) {
- this._updatePrompt.setUpdateStatus("already-latest-version");
-
- if (this._updatePrompt._systemUpdateListener) {
- this._updatePrompt._systemUpdateListener.onError("already-latest-version");
- }
-
- return;
- }
-
- this._updatePrompt.setUpdateStatus("check-complete");
- this._updatePrompt.showUpdateAvailable(update);
- },
-
- onError: function UCL_onError(request, update) {
- // nsIUpdate uses a signed integer for errorCode while any platform errors
- // require all 32 bits.
- let errorCode = update.errorCode >>> 0;
- let isNSError = (errorCode >>> 31) == 1;
- let errorMsg = "check-error-";
-
- if (errorCode == NETWORK_ERROR_OFFLINE) {
- errorMsg = "retry-when-online";
- this._updatePrompt.setUpdateStatus(errorMsg);
- } else if (isNSError) {
- errorMsg = "check-error-" + errorCode;
- this._updatePrompt.setUpdateStatus(errorMsg);
- } else if (errorCode > HTTP_ERROR_OFFSET) {
- let httpErrorCode = errorCode - HTTP_ERROR_OFFSET;
- errorMsg = "check-error-http-" + httpErrorCode;
- this._updatePrompt.setUpdateStatus(errorMsg);
- }
-
- if (this._updatePrompt._systemUpdateListener) {
- this._updatePrompt._systemUpdateListener.onError(errorMsg);
- }
-
- Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
- Services.aus.onError(request, update);
- }
-};
-
-function UpdatePrompt() {
- this.wrappedJSObject = this;
- this._updateCheckListener = new UpdateCheckListener(this);
-}
-
-UpdatePrompt.prototype = {
- classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
- Ci.nsIUpdateCheckListener,
- Ci.nsIRequestObserver,
- Ci.nsIProgressEventSink,
- Ci.nsIObserver,
- Ci.nsISystemUpdateProvider]),
- _xpcom_factory: XPCOMUtils.generateSingletonFactory(UpdatePrompt),
-
- _update: null,
- _applyPromptTimer: null,
- _waitingForIdle: false,
- _updateCheckListner: null,
- _systemUpdateListener: null,
- _availableParameters: {
- "deviceinfo.last_updated": null,
- "gecko.updateStatus": null,
- "app.update.channel": null,
- "app.update.interval": null,
- "app.update.url": null,
- },
- _pendingUpdateAvailablePackageInfo: null,
- _isPendingUpdateReady: false,
- _updateErrorQueue: [ ],
- _receivedUpdatePromptReady: false,
-
- // nsISystemUpdateProvider
- checkForUpdate: function() {
- this.forceUpdateCheck();
- },
-
- startDownload: function() {
- this.downloadUpdate(this._update);
- },
-
- stopDownload: function() {
- this.handleDownloadCancel();
- },
-
- applyUpdate: function() {
- this.handleApplyPromptResult({result: "restart"});
- },
-
- setParameter: function(aName, aValue) {
- if (!this._availableParameters.hasOwnProperty(aName)) {
- return false;
- }
-
- this._availableParameters[aName] = aValue;
-
- switch (aName) {
- case "app.update.channel":
- case "app.update.url":
- Services.prefs.setCharPref(aName, aValue);
- break;
- case "app.update.interval":
- Services.prefs.setIntPref(aName, parseInt(aValue, 10));
- break;
- }
-
- return true;
- },
-
- getParameter: function(aName) {
- if (!this._availableParameters.hasOwnProperty(aName)) {
- return null;
- }
-
- return this._availableParameters[aName];
- },
-
- setListener: function(aListener) {
- this._systemUpdateListener = aListener;
-
- // If an update is available or ready, trigger the event right away at this point.
- if (this._pendingUpdateAvailablePackageInfo) {
- this._systemUpdateListener.onUpdateAvailable(this._pendingUpdateAvailablePackageInfo.type,
- this._pendingUpdateAvailablePackageInfo.version,
- this._pendingUpdateAvailablePackageInfo.description,
- this._pendingUpdateAvailablePackageInfo.buildDate,
- this._pendingUpdateAvailablePackageInfo.size);
- // Set null when the listener is attached.
- this._pendingUpdateAvailablePackageInfo = null;
- }
-
- if (this._isPendingUpdateReady) {
- this._systemUpdateListener.onUpdateReady();
- this._isPendingUpdateReady = false;
- }
- },
-
- unsetListener: function(aListener) {
- this._systemUpdateListener = null;
- },
-
- get applyPromptTimeout() {
- return Services.prefs.getIntPref(PREF_APPLY_PROMPT_TIMEOUT);
- },
-
- get applyIdleTimeout() {
- return Services.prefs.getIntPref(PREF_APPLY_IDLE_TIMEOUT);
- },
-
- handleContentStart: function UP_handleContentStart() {
- SystemAppProxy.addEventListener("mozContentEvent", this);
- },
-
- // nsIUpdatePrompt
-
- // FIXME/bug 737601: we should have users opt-in to downloading
- // updates when on a billed pipe. Initially, opt-in for 3g, but
- // that doesn't cover all cases.
- checkForUpdates: function UP_checkForUpdates() { },
-
- showUpdateAvailable: function UP_showUpdateAvailable(aUpdate) {
- let packageInfo = {};
- packageInfo.version = aUpdate.displayVersion;
- packageInfo.description = aUpdate.statusText;
- packageInfo.buildDate = aUpdate.buildID;
-
- let patch = aUpdate.selectedPatch;
- if (!patch && aUpdate.patchCount > 0) {
- // For now we just check the first patch to get size information if a
- // patch hasn't been selected yet.
- patch = aUpdate.getPatchAt(0);
- }
-
- if (patch) {
- packageInfo.size = patch.size;
- packageInfo.type = patch.type;
- } else {
- log("Warning: no patches available in update");
- }
-
- this._pendingUpdateAvailablePackageInfo = packageInfo;
-
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onUpdateAvailable(packageInfo.type,
- packageInfo.version,
- packageInfo.description,
- packageInfo.buildDate,
- packageInfo.size);
- // Set null since the event is fired.
- this._pendingUpdateAvailablePackageInfo = null;
- }
-
- if (!this.sendUpdateEvent("update-available", aUpdate)) {
-
- log("Unable to prompt for available update, forcing download");
- this.downloadUpdate(aUpdate);
- }
- },
-
- showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) {
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onUpdateReady();
- } else {
- this._isPendingUpdateReady = true;
- }
-
- // The update has been downloaded and staged. We send the update-downloaded
- // event right away. After the user has been idle for a while, we send the
- // update-prompt-restart event, increasing the chances that we can apply the
- // update quietly without user intervention.
- this.sendUpdateEvent("update-downloaded", aUpdate);
-
- if (Services.idle.idleTime >= this.applyIdleTimeout) {
- this.showApplyPrompt(aUpdate);
- return;
- }
-
- let applyIdleTimeoutSeconds = this.applyIdleTimeout / 1000;
- // We haven't been idle long enough, so register an observer
- log("Update is ready to apply, registering idle timeout of " +
- applyIdleTimeoutSeconds + " seconds before prompting.");
-
- this._update = aUpdate;
- this.waitForIdle();
- },
-
- storeUpdateError: function UP_storeUpdateError(aUpdate) {
- log("Storing update error for later use");
- this._updateErrorQueue.push(aUpdate);
- },
-
- sendStoredUpdateError: function UP_sendStoredUpdateError() {
- log("Sending stored update error");
- this._updateErrorQueue.forEach(aUpdate => {
- this.sendUpdateEvent("update-error", aUpdate);
- });
- this._updateErrorQueue = [ ];
- },
-
- showUpdateError: function UP_showUpdateError(aUpdate) {
- log("Update error, state: " + aUpdate.state + ", errorCode: " +
- aUpdate.errorCode);
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onError("update-error: " + aUpdate.errorCode + " " + aUpdate.statusText);
- }
-
- if (!this._receivedUpdatePromptReady) {
- this.storeUpdateError(aUpdate);
- } else {
- this.sendUpdateEvent("update-error", aUpdate);
- }
-
- this.setUpdateStatus(aUpdate.statusText);
- },
-
- showUpdateHistory: function UP_showUpdateHistory(aParent) { },
- showUpdateInstalled: function UP_showUpdateInstalled() {
- this.setParameter("deviceinfo.last_updated", Date.now());
-
- if (useSettings()) {
- let lock = Services.settings.createLock();
- lock.set("deviceinfo.last_updated", Date.now(), null, null);
- }
- },
-
- // Custom functions
-
- waitForIdle: function UP_waitForIdle() {
- if (this._waitingForIdle) {
- return;
- }
-
- this._waitingForIdle = true;
- Services.idle.addIdleObserver(this, this.applyIdleTimeout / 1000);
- Services.obs.addObserver(this, "quit-application", false);
- },
-
- setUpdateStatus: function UP_setUpdateStatus(aStatus) {
- this.setParameter("gecko.updateStatus", aStatus);
-
- if (useSettings()) {
- log("Setting gecko.updateStatus: " + aStatus);
-
- let lock = Services.settings.createLock();
- lock.set("gecko.updateStatus", aStatus, null);
- }
- },
-
- showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
- // Notify update package is ready to apply
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onUpdateReady();
- } else {
- // Set the flag to true and fire the onUpdateReady event when the listener is attached.
- this._isPendingUpdateReady = true;
- }
-
- if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
- log("Unable to prompt, forcing restart");
- this.restartProcess();
- return;
- }
-
- if (AppConstants.MOZ_B2G_RIL) {
- let window = Services.wm.getMostRecentWindow("navigator:browser");
- let pinReq = window.navigator.mozIccManager.getCardLock("pin");
- pinReq.onsuccess = function(e) {
- if (e.target.result.enabled) {
- // The SIM is pin locked. Don't use a fallback timer. This means that
- // the user has to press Install to apply the update. If we use the
- // timer, and the timer reboots the phone, then the phone will be
- // unusable until the SIM is unlocked.
- log("SIM is pin locked. Not starting fallback timer.");
- } else {
- // This means that no pin lock is enabled, so we go ahead and start
- // the fallback timer.
- this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
- }
- }.bind(this);
- pinReq.onerror = function(e) {
- this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
- }.bind(this);
- } else {
- // Schedule a fallback timeout in case the UI is unable to respond or show
- // a prompt for some reason.
- this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
- }
- },
-
- _copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
- "errorCode", "isOSUpdate", "platformVersion",
- "previousAppVersion", "state", "statusText"],
-
- sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
- let detail = {};
- for (let property of this._copyProperties) {
- detail[property] = aUpdate[property];
- }
-
- let patch = aUpdate.selectedPatch;
- if (!patch && aUpdate.patchCount > 0) {
- // For now we just check the first patch to get size information if a
- // patch hasn't been selected yet.
- patch = aUpdate.getPatchAt(0);
- }
-
- if (patch) {
- detail.size = patch.size;
- detail.updateType = patch.type;
- } else {
- log("Warning: no patches available in update");
- }
-
- this._update = aUpdate;
- return this.sendChromeEvent(aType, detail);
- },
-
- sendChromeEvent: function UP_sendChromeEvent(aType, aDetail) {
- let detail = aDetail || {};
- detail.type = aType;
-
- let sent = SystemAppProxy.dispatchEvent(detail);
- if (!sent) {
- log("Warning: Couldn't send update event " + aType +
- ": no content browser. Will send again when content becomes available.");
- return false;
- }
- return true;
- },
-
- handleAvailableResult: function UP_handleAvailableResult(aDetail) {
- // If the user doesn't choose "download", the updater will implicitly call
- // showUpdateAvailable again after a certain period of time
- switch (aDetail.result) {
- case "download":
- this.downloadUpdate(this._update);
- break;
- }
- },
-
- handleApplyPromptResult: function UP_handleApplyPromptResult(aDetail) {
- if (this._applyPromptTimer) {
- this._applyPromptTimer.cancel();
- this._applyPromptTimer = null;
- }
-
- switch (aDetail.result) {
- // Battery not okay, do not wait for idle to re-prompt
- case "low-battery":
- break;
- case "wait":
- // Wait until the user is idle before prompting to apply the update
- this.waitForIdle();
- break;
- case "restart":
- this.finishUpdate();
- this._update = null;
- break;
- }
- },
-
- downloadUpdate: function UP_downloadUpdate(aUpdate) {
- if (!aUpdate) {
- aUpdate = Services.um.activeUpdate;
- if (!aUpdate) {
- log("No active update found to download");
- return;
- }
- }
-
- let status = Services.aus.downloadUpdate(aUpdate, true);
- if (status == STATE_DOWNLOADING) {
- Services.aus.addDownloadListener(this);
- return;
- }
-
- // If the update has already been downloaded and applied, then
- // Services.aus.downloadUpdate will return immediately and not
- // call showUpdateDownloaded, so we detect this.
- if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
- this.showUpdateDownloaded(aUpdate, true);
- return;
- }
-
- log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
- let errorCode = aUpdate.errorCode >>> 0;
- if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) {
- aUpdate.statusText = "file-too-big";
- }
- this.showUpdateError(aUpdate);
- },
-
- handleDownloadCancel: function UP_handleDownloadCancel() {
- log("Pausing download");
- Services.aus.pauseDownload();
- },
-
- finishUpdate: function UP_finishUpdate() {
- if (!this._update.isOSUpdate) {
- // Standard gecko+gaia updates will just need to restart the process
- this.restartProcess();
- return;
- }
-
- try {
- Services.aus.applyOsUpdate(this._update);
- }
- catch (e) {
- this._update.errorCode = Cr.NS_ERROR_FAILURE;
- this.showUpdateError(this._update);
- }
- },
-
- restartProcess: function UP_restartProcess() {
- log("Update downloaded, restarting to apply it");
-
- let callbackAfterSet = function() {
- if (AppConstants.platform !== "gonk") {
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
- } else {
- // NB: on Gonk, we rely on the system process manager to restart us.
- let pmService = Cc["@mozilla.org/power/powermanagerservice;1"]
- .getService(Ci.nsIPowerManagerService);
- pmService.restart();
- }
- }
-
- if (useSettings()) {
- // Save current os version in deviceinfo.previous_os
- let lock = Services.settings.createLock({
- handle: callbackAfterSet,
- handleAbort: function(error) {
- log("Abort callback when trying to set previous_os: " + error);
- callbackAfterSet();
- }
- });
- lock.get("deviceinfo.os", {
- handle: function(name, value) {
- log("Set previous_os to: " + value);
- lock.set("deviceinfo.previous_os", value, null, null);
- }
- });
- }
- },
-
- forceUpdateCheck: function UP_forceUpdateCheck() {
- log("Forcing update check");
-
- let checker = Cc["@mozilla.org/updates/update-checker;1"]
- .createInstance(Ci.nsIUpdateChecker);
- checker.checkForUpdates(this._updateCheckListener, true);
- },
-
- handleEvent: function UP_handleEvent(evt) {
- if (evt.type !== "mozContentEvent") {
- return;
- }
-
- let detail = evt.detail;
- if (!detail) {
- return;
- }
-
- switch (detail.type) {
- case "force-update-check":
- this.forceUpdateCheck();
- break;
- case "update-available-result":
- this.handleAvailableResult(detail);
- // If we started the apply prompt timer, this means that we're waiting
- // for the user to press Later or Install Now. In this situation we
- // don't want to clear this._update, becuase handleApplyPromptResult
- // needs it.
- if (this._applyPromptTimer == null && !this._waitingForIdle) {
- this._update = null;
- }
- break;
- case "update-download-cancel":
- this.handleDownloadCancel();
- break;
- case "update-prompt-apply-result":
- this.handleApplyPromptResult(detail);
- break;
- case "update-prompt-ready":
- this._receivedUpdatePromptReady = true;
- this.sendStoredUpdateError();
- break;
- }
- },
-
- // nsIObserver
-
- observe: function UP_observe(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "idle":
- this._waitingForIdle = false;
- this.showApplyPrompt(this._update);
- // Fall through
- case "quit-application":
- Services.idle.removeIdleObserver(this, this.applyIdleTimeout / 1000);
- Services.obs.removeObserver(this, "quit-application");
- break;
- }
- },
-
- // nsITimerCallback
-
- notify: function UP_notify(aTimer) {
- if (aTimer == this._applyPromptTimer) {
- log("Timed out waiting for result, restarting");
- this._applyPromptTimer = null;
- this.finishUpdate();
- this._update = null;
- return;
- }
- if (aTimer == this._watchdogTimer) {
- log("Download watchdog fired");
- this._watchdogTimer = null;
- this._autoRestartDownload = true;
- Services.aus.pauseDownload();
- return;
- }
- },
-
- createTimer: function UP_createTimer(aTimeoutMs) {
- let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT);
- return timer;
- },
-
- // nsIRequestObserver
-
- _startedSent: false,
-
- _watchdogTimer: null,
-
- _autoRestartDownload: false,
- _autoRestartCount: 0,
-
- startWatchdogTimer: function UP_startWatchdogTimer() {
- let watchdogTimeout = 120000; // 120 seconds
- try {
- watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
- } catch (e) {
- // This means that the preference doesn't exist. watchdogTimeout will
- // retain its default assigned above.
- }
- if (watchdogTimeout <= 0) {
- // 0 implies don't bother using the watchdog timer at all.
- this._watchdogTimer = null;
- return;
- }
- if (this._watchdogTimer) {
- this._watchdogTimer.cancel();
- } else {
- this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- }
- this._watchdogTimer.initWithCallback(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
- });
- },
-
- // nsIProgressEventSink
-
- onProgress: function UP_onProgress(aRequest, aContext, aProgress,
- aProgressMax) {
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onProgress(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", {
- progress: aProgress,
- total: aProgressMax
- });
- },
-
- onStatus: function UP_onStatus(aRequest, aUpdate, aStatus, aStatusArg) { }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]);