Bug 522583 - nsUpdateService.js.in cleanup (remove previous update migration code, defineLazyServiceGetter for nsIObserverService, and other cleanup). r=dtownsend

This commit is contained in:
Robert Strong 2009-10-23 12:43:06 -07:00
parent aa401ff10e
commit deefa4cbc4

View File

@ -180,16 +180,20 @@ function LOG(module, string) {
}
}
function getObserverService()
{
return Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
function getObserverService() {
return Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
}
#ifdef MOZ_UPDATER
Components.utils.import("resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "gUpdateBundle", function() {
return Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle(URI_UPDATES_PROPERTIES);
});
// shared code for suppressing bad cert dialogs
XPCOMUtils.defineLazyGetter(this, "gCertUtils", function() {
let temp = { };
@ -309,18 +313,15 @@ function getUpdateFile(pathArray) {
* @returns A human readable status text string
*/
function getStatusTextFromCode(code, defaultCode) {
const updateBundle = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle(URI_UPDATES_PROPERTIES);
var reason;
try {
reason = updateBundle.GetStringFromName("check_error-" + code);
reason = gUpdateBundle.GetStringFromName("check_error-" + code);
LOG("General", "getStatusTextFromCode - transfer error: " + reason +
", code: " + code);
}
catch (e) {
// Use the default reason
reason = updateBundle.GetStringFromName("check_error-" + defaultCode);
reason = gUpdateBundle.GetStringFromName("check_error-" + defaultCode);
LOG("General", "getStatusTextFromCode - transfer error: " + reason +
", default code: " + defaultCode);
}
@ -329,33 +330,15 @@ function getStatusTextFromCode(code, defaultCode) {
/**
* Get the Active Updates directory
* @param key
* The Directory Service Key (optional).
* If used, don't search local appdata on Win32 and don't create dir.
* @returns The active updates directory, as a nsIFile object
*/
function getUpdatesDir(key) {
function getUpdatesDir() {
// Right now, we only support downloading one patch at a time, so we always
// use the same target directory.
var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
var updateDir;
if (key)
updateDir = fileLocator.get(key, Ci.nsIFile);
else {
updateDir = fileLocator.get(KEY_APPDIR, Ci.nsIFile);
#ifdef XP_WIN
#ifndef WINCE
try {
updateDir = fileLocator.get(KEY_UPDROOT, Ci.nsIFile);
} catch (e) {
}
#endif
#endif
}
var updateDir = getUpdateDir([]);
updateDir.append(DIR_UPDATES);
updateDir.append("0");
if (!updateDir.exists() && !key) {
if (!updateDir.exists()) {
LOG("General", "getUpdatesDir - update directory " + updateDir.path +
" doesn't exist, creating...");
updateDir.create(Ci.nsILocalFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
@ -418,16 +401,12 @@ function writeVersionFile(dir, version) {
}
/**
* Removes the Updates Directory
* @param key
* The Directory Service Key under which update directory resides
* (optional).
* Removes the contents of the Updates Directory
*/
function cleanUpUpdatesDir(key) {
function cleanUpUpdatesDir() {
// Bail out if we don't have appropriate permissions
var updateDir;
try {
updateDir = getUpdatesDir(key);
var updateDir = getUpdatesDir();
}
catch (e) {
return;
@ -473,11 +452,8 @@ function cleanUpUpdatesDir(key) {
/**
* Clean up updates list and the updates directory.
* @param key
* The Directory Service Key under which update directory resides
* (optional).
*/
function cleanupActiveUpdate(key) {
function cleanupActiveUpdate() {
// Move the update from the Active Update list into the Past Updates list.
var um = Cc["@mozilla.org/updates/update-manager;1"].
getService(Ci.nsIUpdateManager);
@ -485,7 +461,7 @@ function cleanupActiveUpdate(key) {
um.saveUpdates();
// Now trash the updates directory, since we're done with it
cleanUpUpdatesDir(key);
cleanUpUpdatesDir();
}
/**
@ -807,13 +783,12 @@ function Update(update) {
if (update.hasAttribute("name"))
name = update.getAttribute("name");
else {
var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService);
var brandBundle = sbs.createBundle(URI_BRAND_PROPERTIES);
var updateBundle = sbs.createBundle(URI_UPDATES_PROPERTIES);
var brandBundle = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle(URI_BRAND_PROPERTIES);
var appName = brandBundle.GetStringFromName("brandShortName");
name = updateBundle.formatStringFromName("updateName",
[appName, this.version], 2);
name = gUpdateBundle.formatStringFromName("updateName",
[appName, this.version], 2);
}
this.name = name;
}
@ -1029,18 +1004,24 @@ UpdateService.prototype = {
* update
*/
_start: function AUS__start() {
// Clean up any extant updates
this._postUpdateProcessing();
// Bail out if we don't have appropriate permissions
if (!this.canUpdate)
return;
// Resume fetching...
var um = Cc["@mozilla.org/updates/update-manager;1"].
getService(Ci.nsIUpdateManager);
var activeUpdate = um.activeUpdate;
if (activeUpdate && activeUpdate.state != STATE_SUCCEEDED) {
var status = this.downloadUpdate(activeUpdate, true);
if (status == STATE_NONE)
cleanupActiveUpdate();
var status = readStatusFile(getUpdatesDir());
// null status means the update.status file is not present, because either:
// 1) no update was performed, and so there's no UI to show
// 2) an update was attempted but failed during checking, transfer or
// verification, and was cleaned up at that point, and UI notifying of
// that error was shown at that stage.
if (status == STATE_NONE) {
LOG("UpdateService", "_postUpdateProcessing - no status, no update");
return;
}
// Clean up any extant updates
this._postUpdateProcessing(status);
},
/**
@ -1049,117 +1030,80 @@ UpdateService.prototype = {
* optionally attempt to fetch a different version if appropriate) or
* notify the user of install success.
*/
_postUpdateProcessing: function AUS__postUpdateProcessing() {
// Detect installation failures and notify
// Bail out if we don't have appropriate permissions
if (!this.canUpdate)
return;
var status = readStatusFile(getUpdatesDir());
// Make sure to cleanup after an update that failed for an unknown reason
if (status == "null")
status = null;
var updRootKey = null;
#ifdef XP_WIN
#ifndef WINCE
function findPreviousUpdate(key) {
var updateDir = getUpdatesDir(key);
if (updateDir.exists()) {
status = readStatusFile(updateDir);
// Previous download should succeed. Otherwise, we will not be here!
if (status == STATE_SUCCEEDED)
updRootKey = key;
else
status = null;
}
}
// required to migrate from older versions.
if (status == null)
findPreviousUpdate(KEY_APPDIR);
#endif
#endif
_postUpdateProcessing: function AUS__postUpdateProcessing(status) {
var um = Cc["@mozilla.org/updates/update-manager;1"].
getService(Ci.nsIUpdateManager);
var update = um.activeUpdate;
if (status == STATE_DOWNLOADING) {
LOG("UpdateService", "_postUpdateProcessing - patch found in " +
"downloading state");
if (update && update.state != STATE_SUCCEEDED) {
// Resume download
var status = this.downloadUpdate(update, true);
if (status == STATE_NONE)
cleanupActiveUpdate();
}
return;
}
else if (status != null) {
// null status means the update.status file is not present, because either:
// 1) no update was performed, and so there's no UI to show
// 2) an update was attempted but failed during checking, transfer or
// verification, and was cleaned up at that point, and UI notifying of
// that error was shown at that stage.
var um = Cc["@mozilla.org/updates/update-manager;1"].
getService(Ci.nsIUpdateManager);
var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
createInstance(Ci.nsIUpdatePrompt);
var update = um.activeUpdate;
if (!update) {
update = new Update(null);
}
update.state = status;
var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService);
var bundle = sbs.createBundle(URI_UPDATES_PROPERTIES);
if (status == STATE_SUCCEEDED) {
update.statusText = bundle.GetStringFromName("installSuccess");
if (!update)
update = new Update(null);
// Update the patch's metadata.
um.activeUpdate = update;
var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
createInstance(Ci.nsIUpdatePrompt);
prompter.showUpdateInstalled();
update.state = status;
if (status == STATE_SUCCEEDED) {
update.statusText = gUpdateBundle.GetStringFromName("installSuccess");
// 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);
writeVersionFile(getUpdatesDir(), update.extensionVersion);
return;
}
}
// Update the patch's metadata.
um.activeUpdate = update;
// Something went wrong with the patch application process.
cleanupActiveUpdate();
prompter.showUpdateInstalled();
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");
var status = this.downloadUpdate(update, true);
if (status == STATE_NONE)
cleanupActiveUpdate();
}
else {
LOG("UpdateService", "_postUpdateProcessing - install of complete or " +
"only one patch offered failed... showing error.");
}
update.QueryInterface(Ci.nsIWritablePropertyBag);
update.setProperty("patchingFailed", oldType);
prompter.showUpdateError(update);
}
// Done with this update. Clean it up.
cleanupActiveUpdate();
}
else {
LOG("UpdateService", "_postUpdateProcessing - no status, no update");
// 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);
writeVersionFile(getUpdatesDir(), update.extensionVersion);
return;
}
}
// Something went wrong with the patch application process.
cleanupActiveUpdate();
update.statusText = gUpdateBundle.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");
var status = this.downloadUpdate(update, true);
if (status == STATE_NONE)
cleanupActiveUpdate();
}
else {
LOG("UpdateService", "_postUpdateProcessing - install of complete or " +
"only one patch offered failed... showing error.");
}
update.QueryInterface(Ci.nsIWritablePropertyBag);
update.setProperty("patchingFailed", oldType);
prompter.showUpdateError(update);
}
},
@ -2539,9 +2483,6 @@ Downloader.prototype = {
const NS_BINDING_ABORTED = 0x804b0002;
const NS_ERROR_ABORT = 0x80004004;
if (Components.isSuccessCode(status)) {
var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService);
var updateStrings = sbs.createBundle(URI_UPDATES_PROPERTIES);
if (this._verifyDownload()) {
state = STATE_PENDING;
@ -2555,7 +2496,7 @@ Downloader.prototype = {
writeStatusFile(getUpdatesDir(), state);
writeVersionFile(getUpdatesDir(), this._update.extensionVersion);
this._update.installDate = (new Date()).getTime();
this._update.statusText = updateStrings.GetStringFromName("installPending");
this._update.statusText = gUpdateBundle.GetStringFromName("installPending");
}
else {
LOG("Downloader", "onStopRequest - download verification failed");
@ -2723,11 +2664,10 @@ UpdatePrompt.prototype = {
if (!this._enabled || this._getUpdateWindow())
return;
var bundle = this._updateBundle;
var stringsPrefix = "updateAvailable_" + update.type + ".";
var title = bundle.formatStringFromName(stringsPrefix + "title",
[update.name], 1);
var text = bundle.GetStringFromName(stringsPrefix + "text");
var title = gUpdateBundle.formatStringFromName(stringsPrefix + "title",
[update.name], 1);
var text = gUpdateBundle.GetStringFromName(stringsPrefix + "text");
var imageUrl = "";
this._showUnobtrusiveUI(null, URI_UPDATE_PROMPT_DIALOG, null,
UPDATE_WINDOW_NAME, "updatesavailable", update,
@ -2742,11 +2682,10 @@ UpdatePrompt.prototype = {
if (!this._enabled)
return;
var bundle = this._updateBundle;
var stringsPrefix = "updateDownloaded_" + update.type + ".";
var title = bundle.formatStringFromName(stringsPrefix + "title",
[update.name], 1);
var text = bundle.GetStringFromName(stringsPrefix + "text");
var title = gUpdateBundle.formatStringFromName(stringsPrefix + "title",
[update.name], 1);
var text = gUpdateBundle.GetStringFromName(stringsPrefix + "text");
var imageUrl = "";
this._showUnobtrusiveUI(null, URI_UPDATE_PROMPT_DIALOG, null,
UPDATE_WINDOW_NAME, "finishedBackground", update,
@ -2792,10 +2731,9 @@ UpdatePrompt.prototype = {
// In some cases, we want to just show a simple alert dialog:
if (update.state == STATE_FAILED && update.errorCode == WRITE_ERROR) {
var updateBundle = this._updateBundle;
var title = updateBundle.GetStringFromName("updaterIOErrorTitle");
var text = updateBundle.formatStringFromName("updaterIOErrorMsg",
[gApp.name, gApp.name], 2);
var title = gUpdateBundle.GetStringFromName("updaterIOErrorTitle");
var text = gUpdateBundle.formatStringFromName("updaterIOErrorMsg",
[gApp.name, gApp.name], 2);
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
ww.getNewPrompter(null).alert(title, text);
@ -2820,12 +2758,6 @@ UpdatePrompt.prototype = {
return !getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false);
},
get _updateBundle() {
return Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle(URI_UPDATES_PROPERTIES);
},
/**
* Returns the update window if present.
*/