author | Robert Strong <robert.bugzilla@gmail.com> |
Wed, 19 Apr 2017 15:07:11 -0700 | |
changeset 353991 | 31e942586dd8e73f1744e412be92db1634420525 |
parent 353990 | 72812cf49ddfb2203118986fca36c8048fb54918 |
child 353992 | 748b099ff0e967750e4fdda279a705a36fd13c0a |
push id | 31684 |
push user | cbook@mozilla.com |
push date | Thu, 20 Apr 2017 09:13:26 +0000 |
treeherder | mozilla-central@27311156637f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mhowell |
bugs | 1357685 |
milestone | 55.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
|
--- a/toolkit/mozapps/update/UpdateTelemetry.jsm +++ b/toolkit/mozapps/update/UpdateTelemetry.jsm @@ -169,17 +169,16 @@ this.AUSTLMY = { */ DWNLD_SUCCESS: 0, DWNLD_RETRY_OFFLINE: 1, DWNLD_RETRY_NET_TIMEOUT: 2, DWNLD_RETRY_CONNECTION_REFUSED: 3, DWNLD_RETRY_NET_RESET: 4, DWNLD_ERR_NO_UPDATE: 5, DWNLD_ERR_NO_UPDATE_PATCH: 6, - DWNLD_ERR_NO_PATCH_FILE: 7, DWNLD_ERR_PATCH_SIZE_LARGER: 8, DWNLD_ERR_PATCH_SIZE_NOT_EQUAL: 9, DWNLD_ERR_BINDING_ABORTED: 10, DWNLD_ERR_ABORT: 11, DWNLD_ERR_DOCUMENT_NOT_CACHED: 12, DWNLD_ERR_VERIFY_NO_REQUEST: 13, DWNLD_ERR_VERIFY_PATCH_SIZE_NOT_EQUAL: 14, DWNLD_ERR_VERIFY_NO_HASH_MATCH: 15,
--- a/toolkit/mozapps/update/common/errors.h +++ b/toolkit/mozapps/update/common/errors.h @@ -56,17 +56,17 @@ #define NO_INSTALLDIR_ERROR 34 #define WRITE_ERROR_ACCESS_DENIED 35 // #define WRITE_ERROR_SHARING_VIOLATION 36 // Replaced with errors 46-48 #define WRITE_ERROR_CALLBACK_APP 37 #define UNEXPECTED_BZIP_ERROR 39 #define UNEXPECTED_MAR_ERROR 40 #define UNEXPECTED_BSPATCH_ERROR 41 #define UNEXPECTED_FILE_OPERATION_ERROR 42 -#define FILESYSTEM_MOUNT_READWRITE_ERROR 43 +// #define FILESYSTEM_MOUNT_READWRITE_ERROR 43 // Removed support for gonk #define DELETE_ERROR_EXPECTED_DIR 46 #define DELETE_ERROR_EXPECTED_FILE 47 #define RENAME_ERROR_EXPECTED_FILE 48 // Error codes 24-33 and 49-51 are for the Windows maintenance service. #define SERVICE_COULD_NOT_COPY_UPDATER 49 #define SERVICE_STILL_APPLYING_TERMINATED 50 #define SERVICE_STILL_APPLYING_NO_EXIT_CODE 51
--- a/toolkit/mozapps/update/nsIUpdateService.idl +++ b/toolkit/mozapps/update/nsIUpdateService.idl @@ -179,22 +179,16 @@ interface nsIUpdate : nsISupports /** * Whether or not the update is a security update or not. If this is true, * then we present more serious sounding user interface messages to the * user. */ attribute boolean isSecurityUpdate; /** - * Whether or not the update being downloaded is an OS update. This is - * generally only possible in Gonk right now. - */ - attribute boolean isOSUpdate; - - /** * When the update was installed. */ attribute long long installDate; /** * A message associated with this update, if any. */ attribute AString statusText; @@ -382,24 +376,16 @@ interface nsIApplicationUpdateService : void removeDownloadListener(in nsIRequestObserver listener); /** * */ AString downloadUpdate(in nsIUpdate update, in boolean background); /** - * Apply the OS update which has been downloaded and staged as applied. - * @param update - * The update has been downloaded and staged as applied. - * @throws if the update object is not an OS update. - */ - void applyOsUpdate(in nsIUpdate update); - - /** * Get the Active Updates directory * @returns An nsIFile for the active updates directory. */ nsIFile getUpdatesDirectory(); /** * Pauses the active update download process */
--- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -55,18 +55,16 @@ const PREFBRANCH_APP_UPDATE_NEVER = "app const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties"; const URI_UPDATE_HISTORY_DIALOG = "chrome://mozapps/content/update/history.xul"; const URI_UPDATE_NS = "http://www.mozilla.org/2005/app-update"; const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul"; const URI_UPDATES_PROPERTIES = "chrome://mozapps/locale/update/updates.properties"; const KEY_UPDROOT = "UpdRootD"; const KEY_EXECUTABLE = "XREExeF"; -// Gonk only -const KEY_UPDATE_ARCHIVE_DIR = "UpdArchD"; const DIR_UPDATES = "updates"; const FILE_ACTIVE_UPDATE_XML = "active-update.xml"; const FILE_BACKUP_UPDATE_LOG = "backup-update.log"; const FILE_LAST_UPDATE_LOG = "last-update.log"; const FILE_UPDATES_XML = "updates.xml"; const FILE_UPDATE_LINK = "update.link"; @@ -78,17 +76,16 @@ const FILE_UPDATE_VERSION = "update.v const STATE_NONE = "null"; const STATE_DOWNLOADING = "downloading"; const STATE_PENDING = "pending"; const STATE_PENDING_SERVICE = "pending-service"; const STATE_PENDING_ELEVATE = "pending-elevate"; const STATE_APPLYING = "applying"; const STATE_APPLIED = "applied"; -const STATE_APPLIED_OS = "applied-os"; const STATE_APPLIED_SERVICE = "applied-service"; const STATE_SUCCEEDED = "succeeded"; const STATE_DOWNLOAD_FAILED = "download-failed"; const STATE_FAILED = "failed"; // The values below used by this code are from common/errors.h const WRITE_ERROR = 7; const ELEVATION_CANCELED = 9; @@ -198,27 +195,16 @@ const APPID_TO_TOPIC = { // Thunderbird "{3550f703-e582-4d05-9a08-453d09bdfdc6}": "mail-startup-done", // Instantbird "{33cb9019-c295-46dd-be21-8c4936574bee}": "xul-window-visible", }; var gUpdateMutexHandle = null; -// Gonk only -var gSDCardMountLock = null; - -// Gonk only -XPCOMUtils.defineLazyGetter(this, "gExtStorage", function aus_gExtStorage() { - if (AppConstants.platform != "gonk") { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - } - return Services.env.get("EXTERNAL_STORAGE"); -}); - XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"); XPCOMUtils.defineLazyGetter(this, "gLogEnabled", function aus_gLogEnabled() { return getPref("getBoolPref", PREF_APP_UPDATE_LOG, false); }); XPCOMUtils.defineLazyGetter(this, "gUpdateBundle", function aus_gUpdateBundle() { @@ -563,23 +549,16 @@ function getCanStageUpdates() { if (AppConstants.platform == "win" && shouldUseService()) { // No need to perform directory write checks, the maintenance service will // be able to write to all directories. LOG("getCanStageUpdates - able to stage updates using the service"); return true; } - // For Gonk, the updater will remount the /system partition to move staged - // files into place. - if (AppConstants.platform == "gonk") { - LOG("getCanStageUpdates - able to stage updates because this is gonk"); - return true; - } - if (!hasUpdateMutex()) { LOG("getCanStageUpdates - unable to apply updates because another " + "instance of the application is already handling updates for this " + "installation."); return false; } return gCanStageUpdatesSession; @@ -795,115 +774,16 @@ function writeStatusFile(dir, state) { */ function writeVersionFile(dir, version) { let versionFile = dir.clone(); versionFile.append(FILE_UPDATE_VERSION); writeStringToFile(versionFile, version); } /** - * Gonk only function that reads the link file specified in the update.link file - * in the specified directory and returns the nsIFile for the corresponding - * file. - * @param dir - * The dir to look for an update.link file in - * @return A nsIFile for the file path specified in the - * update.link file or null if the update.link file - * doesn't exist. - */ -function getFileFromUpdateLink(dir) { - if (AppConstants.platform != "gonk") { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - } - let linkFile = dir.clone(); - linkFile.append(FILE_UPDATE_LINK); - let link = readStringFromFile(linkFile); - LOG("getFileFromUpdateLink linkFile.path: " + linkFile.path + ", link: " + link); - if (!link) { - return null; - } - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - file.initWithPath(link); - return file; -} - -/** - * Gonk only function to create a link file. This allows the actual patch to - * live in a directory different from the update directory. - * @param dir - * The patch directory where the update.link file - * should be written. - * @param patchFile - * The fully qualified filename of the patchfile. - */ -function writeLinkFile(dir, patchFile) { - if (AppConstants.platform != "gonk") { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - } - let linkFile = dir.clone(); - linkFile.append(FILE_UPDATE_LINK); - writeStringToFile(linkFile, patchFile.path); - if (patchFile.path.indexOf(gExtStorage) == 0) { - // The patchfile is being stored on external storage. Try to lock it - // so that it doesn't get shared with the PC while we're downloading - // to it. - acquireSDCardMountLock(); - } -} - -/** - * Gonk only function to acquire a VolumeMountLock for the sdcard volume. - * - * This prevents the SDCard from being shared with the PC while - * we're downloading the update. - */ -function acquireSDCardMountLock() { - if (AppConstants.platform != "gonk") { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - } - let volsvc = Cc["@mozilla.org/telephony/volume-service;1"]. - getService(Ci.nsIVolumeService); - if (volsvc) { - gSDCardMountLock = volsvc.createMountLock("sdcard"); - } -} - -/** - * Gonk only function that determines if the state corresponds to an - * interrupted update. This could either be because the download was - * interrupted, or because staging the update was interrupted. - * - * @return true if the state corresponds to an interrupted - * update. - */ -function isInterruptedUpdate(status) { - if (AppConstants.platform != "gonk") { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - } - return (status == STATE_DOWNLOADING) || - (status == STATE_PENDING) || - (status == STATE_APPLYING); -} - -/** - * Releases any SDCard mount lock that we might have. - * - * This once again allows the SDCard to be shared with the PC. - */ -function releaseSDCardMountLock() { - if (AppConstants.platform != "gonk") { - throw Cr.NS_ERROR_UNEXPECTED; - } - if (gSDCardMountLock) { - gSDCardMountLock.unlock(); - gSDCardMountLock = null; - } -} - -/** * Determines if the service should be used to attempt an update * or not. * * @return true if the service should be used for updates. */ function shouldUseService() { // This function will return true if the mantenance service should be used if // all of the following conditions are met: @@ -1055,39 +935,27 @@ function cleanUpUpdatesDir(aRemovePatchF " to " + FILE_LAST_UPDATE_LOG); } } if (aRemovePatchFiles) { let dirEntries = updateDir.directoryEntries; while (dirEntries.hasMoreElements()) { let file = dirEntries.getNext().QueryInterface(Ci.nsIFile); - if (AppConstants.platform == "gonk") { - if (file.leafName == FILE_UPDATE_LINK) { - let linkedFile = getFileFromUpdateLink(updateDir); - if (linkedFile && linkedFile.exists()) { - linkedFile.remove(false); - } - } - } - // Now, recursively remove this file. The recursive removal is needed for // Mac OSX because this directory will contain a copy of updater.app, // which is itself a directory and the MozUpdater directory on platforms // other than Windows. try { file.remove(true); } catch (e) { LOG("cleanUpUpdatesDir - failed to remove file " + file.path); } } } - if (AppConstants.platform == "gonk") { - releaseSDCardMountLock(); - } } /** * Clean up updates list and the updates directory. */ function cleanupActiveUpdate() { // Move the update from the Active Update list into the Past Updates list. var um = Cc["@mozilla.org/updates/update-manager;1"]. @@ -1345,19 +1213,16 @@ function pingStateAndStatusCodes(aUpdate stateCode = 5; break; case STATE_APPLYING: stateCode = 6; break; case STATE_APPLIED: stateCode = 7; break; - case STATE_APPLIED_OS: - stateCode = 8; - break; case STATE_APPLIED_SERVICE: stateCode = 9; break; case STATE_SUCCEEDED: stateCode = 10; break; case STATE_DOWNLOAD_FAILED: stateCode = 11; @@ -1825,22 +1690,16 @@ const UpdateServiceFactory = { * UpdateService * A Service for managing the discovery and installation of software updates. * @constructor */ function UpdateService() { LOG("Creating UpdateService"); Services.obs.addObserver(this, "xpcom-shutdown"); Services.prefs.addObserver(PREF_APP_UPDATE_LOG, this); - if (AppConstants.platform == "gonk") { - // PowerManagerService::SyncProfile (which is called for Reboot, PowerOff - // and Restart) sends the profile-change-net-teardown event. We can then - // pause the download in a similar manner to xpcom-shutdown. - Services.obs.addObserver(this, "profile-change-net-teardown"); - } } UpdateService.prototype = { /** * The downloader we are using to download updates. There is only ever one of * these. */ _downloader: null, @@ -1912,17 +1771,16 @@ 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; - case "profile-change-net-teardown": // fall thru case "xpcom-shutdown": Services.obs.removeObserver(this, topic); Services.prefs.removeObserver(PREF_APP_UPDATE_LOG, this); if (AppConstants.platform == "win" && gUpdateMutexHandle) { // If we hold the update mutex, let it go! // The OS would clean this up sometime after shutdown, // but that would have no guarantee on timing. @@ -1978,33 +1836,16 @@ UpdateService.prototype = { // STATE_NONE status typically means that the update.status file is present // but a background download error occurred. if (status == STATE_NONE) { LOG("UpdateService:_postUpdateProcessing - no status, no update"); cleanupActiveUpdate(); return; } - if (AppConstants.platform == "gonk") { - // This code is called very early in the boot process, before we've even - // had a chance to setup the UI so we can give feedback to the user. - // - // Since the download may be occuring over a link which has associated - // cost, we want to require user-consent before resuming the download. - // Also, applying an already downloaded update now is undesireable, - // since the phone will look dead while the update is being applied. - // Applying the update can take several minutes. Instead we wait until - // the UI is initialized so it is possible to give feedback to and get - // consent to update from the user. - if (isInterruptedUpdate(status)) { - LOG("UpdateService:_postUpdateProcessing - interrupted update detected - wait for user consent"); - return; - } - } - if (status == STATE_DOWNLOADING) { LOG("UpdateService:_postUpdateProcessing - patch found in downloading " + "state"); if (update && update.state != STATE_SUCCEEDED) { // Resume download status = this.downloadUpdate(update, true); if (status == STATE_NONE) cleanupActiveUpdate(); @@ -2036,44 +1877,16 @@ UpdateService.prototype = { } else { // We get here even if we don't have an update object LOG("UpdateService:_postUpdateProcessing - patch found in applying " + "state for the second time"); cleanupActiveUpdate(); } return; } - if (AppConstants.platform == "gonk") { - // The update is only applied but not selected to be installed - if (status == STATE_APPLIED && update && update.isOSUpdate) { - LOG("UpdateService:_postUpdateProcessing - update staged as applied found"); - return; - } - - if (status == STATE_APPLIED_OS && update && update.isOSUpdate) { - // In gonk, we need to check for OS update status after startup, since - // the recovery partition won't write to update.status for us - let recoveryService = Cc["@mozilla.org/recovery-service;1"]. - getService(Ci.nsIRecoveryService); - let fotaStatus = recoveryService.getFotaUpdateStatus(); - switch (fotaStatus) { - case Ci.nsIRecoveryService.FOTA_UPDATE_SUCCESS: - status = STATE_SUCCEEDED; - break; - case Ci.nsIRecoveryService.FOTA_UPDATE_FAIL: - status = STATE_FAILED + ": " + FOTA_GENERAL_ERROR; - break; - case Ci.nsIRecoveryService.FOTA_UPDATE_UNKNOWN: - default: - status = STATE_FAILED + ": " + FOTA_UNKNOWN_ERROR; - break; - } - } - } - if (!update) { if (status != STATE_SUCCEEDED) { LOG("UpdateService:_postUpdateProcessing - previous patch failed " + "and no patch available"); cleanupActiveUpdate(); return; } update = new Update(null); @@ -2522,21 +2335,16 @@ UpdateService.prototype = { * An array of available updates */ _selectAndInstallUpdate: function AUS__selectAndInstallUpdate(updates) { // Return early if there's an active update. The user is already aware and // is downloading or performed some user action to prevent notification. var um = Cc["@mozilla.org/updates/update-manager;1"]. getService(Ci.nsIUpdateManager); if (um.activeUpdate) { - if (AppConstants.platform == "gonk") { - // For gonk, the user isn't necessarily aware of the update, so we need - // to show the prompt to make sure. - this._showPrompt(um.activeUpdate); - } AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_HAS_ACTIVEUPDATE); return; } var updateEnabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true); if (!updateEnabled) { AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_PREF_DISABLED); LOG("UpdateService:_selectAndInstallUpdate - not prompting because " + @@ -2729,31 +2537,16 @@ UpdateService.prototype = { if (update.isCompleteUpdate == this._downloader.isCompleteUpdate && background == this._downloader.background) { LOG("UpdateService:downloadUpdate - no support for downloading more " + "than one update at a time"); return readStatusFile(getUpdatesDir()); } this._downloader.cancel(); } - if (AppConstants.platform == "gonk") { - let um = Cc["@mozilla.org/updates/update-manager;1"]. - getService(Ci.nsIUpdateManager); - let activeUpdate = um.activeUpdate; - if (activeUpdate && - (activeUpdate.appVersion != update.appVersion || - activeUpdate.buildID != update.buildID)) { - // We have an activeUpdate (which presumably was interrupted), and are - // about start downloading a new one. Make sure we remove all traces - // of the active one (otherwise we'll start appending the new update.mar - // the the one that's been partially downloaded). - LOG("UpdateService:downloadUpdate - removing stale active update."); - cleanupActiveUpdate(); - } - } // Set the previous application version prior to downloading the update. update.previousAppVersion = Services.appinfo.version; this._downloader = new Downloader(background, this); return this._downloader.downloadUpdate(update); }, /** * See nsIUpdateService.idl @@ -2777,65 +2570,16 @@ UpdateService.prototype = { /** * See nsIUpdateService.idl */ get isDownloading() { return this._downloader && this._downloader.isBusy; }, - /** - * See nsIUpdateService.idl - */ - applyOsUpdate: function AUS_applyOsUpdate(aUpdate) { - if (!aUpdate.isOSUpdate || aUpdate.state != STATE_APPLIED) { - aUpdate.statusText = "fota-state-error"; - throw Cr.NS_ERROR_FAILURE; - } - - aUpdate.QueryInterface(Ci.nsIWritablePropertyBag); - let osApplyToDir = aUpdate.getProperty("osApplyToDir"); - - if (!osApplyToDir) { - LOG("UpdateService:applyOsUpdate - Error: osApplyToDir is not defined" + - "in the nsIUpdate!"); - pingStateAndStatusCodes(aUpdate, false, - STATE_FAILED + ": " + FOTA_FILE_OPERATION_ERROR); - handleUpdateFailure(aUpdate, FOTA_FILE_OPERATION_ERROR); - return; - } - - let updateFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - updateFile.initWithPath(osApplyToDir + "/update.zip"); - if (!updateFile.exists()) { - LOG("UpdateService:applyOsUpdate - Error: OS update is not found at " + - updateFile.path); - pingStateAndStatusCodes(aUpdate, false, - STATE_FAILED + ": " + FOTA_FILE_OPERATION_ERROR); - handleUpdateFailure(aUpdate, FOTA_FILE_OPERATION_ERROR); - return; - } - - writeStatusFile(getUpdatesDir(), aUpdate.state = STATE_APPLIED_OS); - LOG("UpdateService:applyOsUpdate - Rebooting into recovery to apply " + - "FOTA update: " + updateFile.path); - try { - let recoveryService = Cc["@mozilla.org/recovery-service;1"] - .getService(Ci.nsIRecoveryService); - recoveryService.installFotaUpdate(updateFile.path); - } catch (e) { - LOG("UpdateService:applyOsUpdate - Error: Couldn't reboot into recovery" + - " to apply FOTA update " + updateFile.path); - pingStateAndStatusCodes(aUpdate, false, - STATE_FAILED + ": " + FOTA_RECOVERY_ERROR); - writeStatusFile(getUpdatesDir(), aUpdate.state = STATE_APPLIED); - handleUpdateFailure(aUpdate, FOTA_RECOVERY_ERROR); - } - }, - classID: UPDATESERVICE_CID, classInfo: XPCOMUtils.generateCI({classID: UPDATESERVICE_CID, contractID: UPDATESERVICE_CONTRACTID, interfaces: [Ci.nsIApplicationUpdateService, Ci.nsITimerCallback, Ci.nsIObserver], flags: Ci.nsIClassInfo.SINGLETON}), @@ -3151,31 +2895,16 @@ UpdateManager.prototype = { } // Send an observer notification which the app update doorhanger uses to // display a restart notification LOG("UpdateManager:refreshUpdateStatus - Notifying observers that " + "the update was staged. topic: update-staged, status: " + update.state); Services.obs.notifyObservers(update, "update-staged", update.state); - if (AppConstants.platform == "gonk") { - // Do this after everything else, since it will likely cause the app to - // shut down. - 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 - // not notify on failed update attempts. - let prompter = Cc["@mozilla.org/updates/update-prompt;1"]. - createInstance(Ci.nsIUpdatePrompt); - prompter.showUpdateDownloaded(update, true); - } else { - releaseSDCardMountLock(); - } - return; - } // 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 || @@ -3517,19 +3246,16 @@ Downloader.prototype = { cancel: function Downloader_cancel(cancelError) { LOG("Downloader: cancel"); if (cancelError === undefined) { cancelError = Cr.NS_BINDING_ABORTED; } if (this._request && this._request instanceof Ci.nsIRequest) { this._request.cancel(cancelError); } - if (AppConstants.platform == "gonk") { - releaseSDCardMountLock(); - } }, /** * Whether or not a patch has been downloaded and staged for installation. */ get patchIsStaged() { var readState = readStatusFile(getUpdatesDir()); // Note that if we decide to download and apply new updates after another @@ -3648,29 +3374,20 @@ Downloader.prototype = { var useComplete = false; if (selectedPatch) { LOG("Downloader:_selectPatch - found existing patch with state: " + state); if (state == STATE_DOWNLOADING) { LOG("Downloader:_selectPatch - resuming download"); return selectedPatch; } - - if (AppConstants.platform == "gonk") { - if (state == STATE_PENDING || state == STATE_APPLYING) { - LOG("Downloader:_selectPatch - resuming interrupted apply"); - return selectedPatch; - } - if (state == STATE_APPLIED) { - LOG("Downloader:_selectPatch - already downloaded and staged"); - return null; - } - } else if (state == STATE_PENDING || state == STATE_PENDING_SERVICE || - state == STATE_PENDING_ELEVATE) { - LOG("Downloader:_selectPatch - already downloaded and staged"); + if (state == STATE_PENDING || state == STATE_PENDING_SERVICE || + state == STATE_PENDING_ELEVATE || state == STATE_APPLIED || + state == STATE_APPLIED_SERVICE) { + LOG("Downloader:_selectPatch - already downloaded"); return null; } if (update && selectedPatch.type == "complete") { // This is a pretty fatal error. Just bail. LOG("Downloader:_selectPatch - failed to apply complete patch!"); writeStatusFile(updateDir, STATE_NONE); writeVersionFile(getUpdatesDir(), null); @@ -3717,35 +3434,16 @@ Downloader.prototype = { /** * Whether or not we are currently downloading something. */ get isBusy() { return this._request != null; }, /** - * Get the nsIFile to use for downloading the active update's selected patch - */ - _getUpdateArchiveFile: function Downloader__getUpdateArchiveFile() { - var updateArchive; - if (AppConstants.platform == "gonk") { - try { - updateArchive = FileUtils.getDir(KEY_UPDATE_ARCHIVE_DIR, [], true); - } catch (e) { - return null; - } - } else { - updateArchive = getUpdatesDir().clone(); - } - - updateArchive.append(FILE_UPDATE_MAR); - return updateArchive; - }, - - /** * Download and stage the given update. * @param update * A nsIUpdate object to download a patch for. Cannot be null. */ downloadUpdate: function Downloader_downloadUpdate(update) { LOG("UpdateService:_downloadUpdate"); if (!update) { AUSTLMY.pingDownloadCode(undefined, AUSTLMY.DWNLD_ERR_NO_UPDATE); @@ -3761,106 +3459,18 @@ Downloader.prototype = { this._patch = this._selectPatch(update, updateDir); if (!this._patch) { LOG("Downloader:downloadUpdate - no patch to download"); AUSTLMY.pingDownloadCode(undefined, AUSTLMY.DWNLD_ERR_NO_UPDATE_PATCH); return readStatusFile(updateDir); } this.isCompleteUpdate = this._patch.type == "complete"; - let patchFile = null; - - // Only used by gonk - let status = STATE_NONE; - if (AppConstants.platform == "gonk") { - status = readStatusFile(updateDir); - if (isInterruptedUpdate(status)) { - LOG("Downloader:downloadUpdate - interruptted update"); - // The update was interrupted. Try to locate the existing patch file. - // For an interrupted download, this allows a resume rather than a - // re-download. - patchFile = getFileFromUpdateLink(updateDir); - if (!patchFile) { - // No link file. We'll just assume that the update.mar is in the - // update directory. - patchFile = updateDir.clone(); - patchFile.append(FILE_UPDATE_MAR); - } - if (patchFile.exists()) { - LOG("Downloader:downloadUpdate - resuming with patchFile " + patchFile.path); - if (patchFile.fileSize == this._patch.size) { - LOG("Downloader:downloadUpdate - patchFile appears to be fully downloaded"); - // Bump the status along so that we don't try to redownload again. - if (getElevationRequired()) { - status = STATE_PENDING_ELEVATE; - } else { - status = STATE_PENDING; - } - } - } else { - LOG("Downloader:downloadUpdate - patchFile " + patchFile.path + - " doesn't exist - performing full download"); - // The patchfile doesn't exist, we might as well treat this like - // a new download. - patchFile = null; - } - if (patchFile && status != STATE_DOWNLOADING) { - // It looks like the patch was downloaded, but got interrupted while it - // was being verified or applied. So we'll fake the downloading portion. - - if (getElevationRequired()) { - writeStatusFile(updateDir, STATE_PENDING_ELEVATE); - } else { - writeStatusFile(updateDir, STATE_PENDING); - } - - // Since the code expects the onStopRequest callback to happen - // asynchronously (And you have to call AUS_addDownloadListener - // after calling AUS_downloadUpdate) we need to defer this. - - this._downloadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._downloadTimer.initWithCallback(function() { - this._downloadTimer = null; - // Send a fake onStopRequest. Filling in the destination allows - // _verifyDownload to work, and then the update will be applied. - this._request = {destination: patchFile}; - this.onStopRequest(this._request, null, Cr.NS_OK); - }.bind(this), 0, Ci.nsITimer.TYPE_ONE_SHOT); - - // Returning STATE_DOWNLOADING makes UpdatePrompt think we're - // downloading. The onStopRequest that we spoofed above will make it - // look like the download finished. - return STATE_DOWNLOADING; - } - } - } - - if (!patchFile) { - // Find a place to put the patchfile that we're going to download. - patchFile = this._getUpdateArchiveFile(); - } - if (!patchFile) { - AUSTLMY.pingDownloadCode(this.isCompleteUpdate, - AUSTLMY.DWNLD_ERR_NO_PATCH_FILE); - return STATE_NONE; - } - - if (AppConstants.platform == "gonk") { - if (patchFile.path.indexOf(updateDir.path) != 0) { - // The patchFile is in a directory which is different from the - // updateDir, create a link file. - writeLinkFile(updateDir, patchFile); - - if (!isInterruptedUpdate(status) && patchFile.exists()) { - // Remove stale patchFile - patchFile.remove(false); - } - } - } - + let patchFile = getUpdatesDir().clone(); + patchFile.append(FILE_UPDATE_MAR); update.QueryInterface(Ci.nsIPropertyBag); let interval = this.background ? update.getProperty("backgroundInterval") : DOWNLOAD_FOREGROUND_INTERVAL; LOG("Downloader:downloadUpdate - url: " + this._patch.URL + ", path: " + patchFile.path + ", interval: " + interval); var uri = Services.io.newURI(this._patch.URL); @@ -4122,23 +3732,16 @@ Downloader.prototype = { state = STATE_DOWNLOAD_FAILED; // XXXben - if |request| (The Incremental Download) provided a means // for accessing the http channel we could do more here. this._update.statusText = getStatusTextFromCode(status, Cr.NS_BINDING_FAILED); - if (AppConstants.platform == "gonk") { - // bug891009: On FirefoxOS, manaully retry OTA download will reuse - // the Update object. We need to remove selected patch so that download - // can be triggered again successfully. - this._update.selectedPatch.selected = false; - } - // Destroy the updates directory, since we're done with it. cleanUpUpdatesDir(); deleteActiveUpdate = true; } LOG("Downloader:onStopRequest - setting state to: " + state); this._patch.state = state; var um = Cc["@mozilla.org/updates/update-manager;1"]. @@ -4208,23 +3811,16 @@ Downloader.prototype = { this._update.QueryInterface(Ci.nsIWritablePropertyBag); if (this._update.getProperty("foregroundDownload") == "true") { let prompter = Cc["@mozilla.org/updates/update-prompt;1"]. createInstance(Ci.nsIUpdatePrompt); prompter.showUpdateError(this._update); } } - if (AppConstants.platform == "gonk") { - // We always forward errors in B2G, since Gaia controls the update UI - let prompter = Cc["@mozilla.org/updates/update-prompt;1"]. - createInstance(Ci.nsIUpdatePrompt); - prompter.showUpdateError(this._update); - } - // Prevent leaking the update object (bug 454964). this._update = null; } // A complete download has been initiated or the failure was handled. return; } if (state == STATE_PENDING || state == STATE_PENDING_SERVICE ||