📄 nsupdateservice.js
字号:
umUpdate.buildID == update.buildID) { umUpdate.statusText = update.statusText; break; } } LOG("UpdateService", "_postUpdateProcessing: Install Succeeded, Showing UI"); prompter.showUpdateInstalled(update);//@line 1214 "/c/builds/1813/mozilla/toolkit/mozapps/update/src/nsUpdateService.js.in" // Done with this update. Clean it up. cleanupActiveUpdate(updRootKey); } else { // If we hit an error, then the error code will be included in the // status string following a colon. If we had an I/O error, then we // assume that the patch is not invalid, and we restage the patch so // that it can be attempted again the next time we restart. var ary = status.split(": "); update.state = ary[0]; if (update.state == STATE_FAILED && ary[1]) { update.errorCode = ary[1]; if (update.errorCode == WRITE_ERROR) { prompter.showUpdateError(update); writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING); return; } } // Something went wrong with the patch application process. cleanupActiveUpdate(); update.statusText = bundle.GetStringFromName("patchApplyFailure"); var oldType = update.selectedPatch ? update.selectedPatch.type : "complete"; if (update.selectedPatch && oldType == "partial") { // Partial patch application failed, try downloading the complete // update in the background instead. LOG("UpdateService", "_postUpdateProcessing: Install of Partial Patch " + "failed, downloading Complete Patch and maybe showing UI"); var status = this.downloadUpdate(update, true); if (status == STATE_NONE) cleanupActiveUpdate(); } else { LOG("UpdateService", "_postUpdateProcessing: Install of Complete or " + "only patch failed. Showing error."); } update.QueryInterface(Components.interfaces.nsIWritablePropertyBag); update.setProperty("patchingFailed", oldType); prompter.showUpdateError(update); } } else { LOG("UpdateService", "_postUpdateProcessing: No Status, No Update"); } }, /** * Initialize Logging preferences, formatted like so: * app.update.log.<moduleName> = <true|false> */ _initLoggingPrefs: function() { try { var ps = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); var logBranch = ps.getBranch(PREF_APP_UPDATE_LOG_BRANCH); var modules = logBranch.getChildList("", { value: 0 }); for (var i = 0; i < modules.length; ++i) { if (logBranch.prefHasUserValue(modules[i])) gLogEnabled[modules[i]] = logBranch.getBoolPref(modules[i]); } } catch (e) { } }, /** * */ _needsToPromptForUpdate: function(updates) { // First, check for Extension incompatibilities. These trump any preference // settings. var em = Components.classes["@mozilla.org/extensions/manager;1"] .getService(Components.interfaces.nsIExtensionManager); var incompatibleList = { }; for (var i = 0; i < updates.length; ++i) { var count = {}; em.getIncompatibleItemList(gApp.ID, updates[i].extensionVersion, nsIUpdateItem.TYPE_ADDON, false, count); if (count.value > 0) return true; } // Now, inspect user preferences. // No prompt necessary, silently update... return false; }, /** * Notified when a timer fires * @param timer * The timer that fired */ notify: function(timer) { // If a download is in progress, then do nothing. if (this.isDownloading || this._downloader && this._downloader.patchIsStaged) return; var self = this; var listener = { /** * See nsIUpdateService.idl */ onProgress: function(request, position, totalSize) { }, /** * See nsIUpdateService.idl */ onCheckComplete: function(request, updates, updateCount) { self._selectAndInstallUpdate(updates); }, /** * See nsIUpdateService.idl */ onError: function(request, update) { LOG("Checker", "Error during background update: " + update.statusText); }, } this.backgroundChecker.checkForUpdates(listener, false); }, /** * Determine whether or not an update requires user confirmation before it * can be installed. * @param update * The update to be installed * @returns true if a prompt UI should be shown asking the user if they want * to install the update, false if the update should just be * silently downloaded and installed. */ _shouldPrompt: function(update) { // There are two possible outcomes here: // 1. download and install the update automatically // 2. alert the user about the presence of an update before doing anything // // The outcome we follow is determined as follows: // // Note: all Major updates require notification and confirmation // // Update Type Mode Incompatible Outcome // Major 0 Yes or No Notify and Confirm // Major 1 No Notify and Confirm // Major 1 Yes Notify and Confirm // Major 2 Yes or No Notify and Confirm // Minor 0 Yes or No Auto Install // Minor 1 No Auto Install // Minor 1 Yes Notify and Confirm // Minor 2 No Auto Install // Minor 2 Yes Notify and Confirm // // In addition, if there is a license associated with an update, regardless // of type it must be agreed to. // // If app.update.enabled is set to false, an update check is not performed // at all, and so none of the decision making above is entered into. // if (update.type == "major") { LOG("Checker", "_shouldPrompt: Prompting because it is a major update"); return true; } update.QueryInterface(Components.interfaces.nsIPropertyBag); try { var licenseAccepted = update.getProperty("licenseAccepted") == "true"; } catch (e) { licenseAccepted = false; } var updateEnabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true); if (!updateEnabled) { LOG("Checker", "_shouldPrompt: Not prompting because update is " + "disabled"); return false; } // User has turned off automatic download and install var autoEnabled = getPref("getBoolPref", PREF_APP_UPDATE_AUTO, true); if (!autoEnabled) { LOG("Checker", "_shouldPrompt: Prompting because auto install is disabled"); return true; } switch (getPref("getIntPref", PREF_APP_UPDATE_MODE, 1)) { case 1: // Mode 1 is do not prompt only if there are no incompatibilities // releases LOG("Checker", "_shouldPrompt: Prompting if there are incompatibilities"); return !isCompatible(update); case 2: // Mode 2 is do not prompt only if there are no incompatibilities LOG("Checker", "_shouldPrompt: Prompting if there are incompatibilities"); return !isCompatible(update); } // Mode 0 is do not prompt regardless of incompatibilities LOG("Checker", "_shouldPrompt: Not prompting the user - they choose to " + "ignore incompatibilities"); return false; }, /** * Determine which of the specified updates should be installed. * @param updates * An array of available updates */ selectUpdate: function(updates) { if (updates.length == 0) return null; // Choose the newest of the available minor and major updates. var majorUpdate = null, minorUpdate = null; var newestMinor = updates[0], newestMajor = updates[0]; var vc = Components.classes["@mozilla.org/xpcom/version-comparator;1"] .getService(Components.interfaces.nsIVersionComparator); for (var i = 0; i < updates.length; ++i) { if (updates[i].type == "major" && vc.compare(newestMajor.version, updates[i].version) <= 0) majorUpdate = newestMajor = updates[i]; if (updates[i].type == "minor" && vc.compare(newestMinor.version, updates[i].version) <= 0) minorUpdate = newestMinor = updates[i]; } // IMPORTANT // If there's a minor update, always try and fetch that one first, // otherwise use the newest major update. // selectUpdate() only returns one update. // if major were to trump minor, and we said "never" to the major // we'd never get the minor update, since selectUpdate() // would return the major update that the user said "never" to // (shadowing the important minor update with security fixes) return minorUpdate || majorUpdate; }, /** * Determine which of the specified updates should be installed and * begin the download/installation process, optionally prompting the * user for permission if required. * @param updates * An array of available updates */ _selectAndInstallUpdate: function(updates) { // Don't prompt if there's an active update - the user is already // aware and is downloading, or performed some user action to prevent // notification. var um = Components.classes["@mozilla.org/updates/update-manager;1"] .getService(Components.interfaces.nsIUpdateManager); if (um.activeUpdate) return; var update = this.selectUpdate(updates, updates.length); if (!update) return; // check if the user said "never" to this version // this check is done here, and not in selectUpdate() so that // the user can get an upgrade they said "never" to if they // manually do "Check for Updates..." // note, selectUpdate() only returns one update. // but in selectUpdate(), minor updates trump major updates // if major trumps minor, and we said "never" to the major // we'd never see the minor update. // // note, the never decision should only apply to major updates // see bug #350636 for a scenario where this could potentially // be an issue var neverPrefName = PREF_UPDATE_NEVER_BRANCH + update.version; var never = getPref("getBoolPref", neverPrefName, false); if (never && update.type == "major") return; if (this._shouldPrompt(update)) showPromptIfNoIncompatibilities(update); else { LOG("UpdateService", "_selectAndInstallUpdate: No need to show prompt, just download update"); var status = this.downloadUpdate(update, true); if (status == STATE_NONE) cleanupActiveUpdate(); } }, /** * The Checker used for background update checks. */ _backgroundChecker: null, /** * See nsIUpdateService.idl */ get backgroundChecker() { if (!this._backgroundChecker) this._backgroundChecker = new Checker(); return this._backgroundChecker; }, /** * See nsIUpdateService.idl */ get canUpdate() { try { var appDirFile = getUpdateFile([FILE_PERMS_TEST]); if (!appDirFile.exists()) { appDirFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE); appDirFile.remove(false); } var updateDir = getUpdatesDir(); var upDirFile = updateDir.clone(); upDirFile.append(FILE_PERMS_TEST); if (!upDirFile.exists()) { upDirFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE); upDirFile.remove(false); } } catch (e) { // No write privileges to install directory return false; } // If the administrator has locked the app update functionality // OFF - this is not just a user setting, so disable the manual // UI too. var enabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true); if (!enabled && gPref.prefIsLocked(PREF_APP_UPDATE_ENABLED)) return false; // If we don't know the binary platform we're updating, we can't update. if (!gABI) return false; // If we don't know the OS version we're updating, we can't update. if (!gOSVersion) return false; return true; }, /** * See nsIUpdateService.idl */ addDownloadListener: function(listener) { if (!this._downloader) { LOG("UpdateService", "addDownloadListener: no downloader!\n"); return; } this._downloader.addDownloadListener(listener); }, /** * See nsIUpdateService.idl */ removeDownloadListener: function(listener) { if (!this._downloader) { LOG("UpdateService", "removeDownloadListener: no downloader!\n"); return; } this._downloader.removeDownloadListener(listener); }, /** * See nsIUpdateService.idl */ downloadUpdate: function(update, background) { if (!update) throw Components.results.NS_ERROR_NULL_POINTER; if (this.isDownloading) { if (update.isCompleteUpdate == this._downloader.isCompleteUpdate && background == this._downloader.background) { LOG("UpdateService", "no support for downloading more than one update at a time"); return readStatusFile(getUpdatesDir()); } this._downloader.cancel(); } this._downloader = new Downloader(background); return this._downloader.downloadUpdate(update); }, /** * See nsIUpdateService.idl */ pauseDownload: function() { if (this.isDownloading) this._downloader.cancel(); }, /** * See nsIUpdateService.idl */ get isDownloading() { return this._downloader && this._downloader.isBusy; }, /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -