1. main patch - Bug 642765 - Add ability to channel change to the client. r=mossop

This commit is contained in:
Robert Strong 2011-04-11 21:24:16 -07:00
Родитель 629fdb4fa4
Коммит 29de84bc39
4 изменённых файлов: 106 добавлений и 10 удалений

Просмотреть файл

@ -62,6 +62,7 @@ const PREF_APP_UPDATE_CERT_ERRORS = "app.update.cert.errors";
const PREF_APP_UPDATE_CERT_MAXERRORS = "app.update.cert.maxErrors";
const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const PREF_APP_UPDATE_DESIREDCHANNEL = "app.update.desiredChannel";
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
const PREF_APP_UPDATE_INCOMPATIBLE_MODE = "app.update.incompatible.mode";
@ -105,6 +106,7 @@ const KEY_UPDROOT = "UpdRootD";
#endif
const DIR_UPDATES = "updates";
const FILE_CHANNELCHANGE = "channelchange";
const FILE_UPDATE_STATUS = "update.status";
const FILE_UPDATE_VERSION = "update.version";
#ifdef ANDROID
@ -494,6 +496,12 @@ function writeVersionFile(dir, version) {
writeStringToFile(versionFile, version);
}
function createChannelChangeFile(dir) {
var channelChangeFile = dir.clone();
channelChangeFile.append(FILE_CHANNELCHANGE);
channelChangeFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
}
/**
* Removes the contents of the Updates Directory
*/
@ -619,6 +627,19 @@ function getUpdateChannel() {
return channel;
}
function getDesiredChannel() {
let desiredChannel = getPref("getCharPref", PREF_APP_UPDATE_DESIREDCHANNEL, null);
if (!desiredChannel)
return null;
if (desiredChannel == getUpdateChannel()) {
Services.prefs.clearUserPref(PREF_APP_UPDATE_DESIREDCHANNEL);
return null;
}
LOG("getDesiredChannel - channel set to: " + desiredChannel);
return desiredChannel;
}
/* Get the distribution pref values, from defaults only */
function getDistributionPrefValue(aPrefName) {
var prefValue = "default";
@ -1123,6 +1144,9 @@ const UpdateServiceFactory = {
*/
function UpdateService() {
Services.obs.addObserver(this, "xpcom-shutdown", false);
// This will clear the preference if the channel is the same as the
// application's channel.
getDesiredChannel();
}
UpdateService.prototype = {
@ -1225,6 +1249,9 @@ UpdateService.prototype = {
// Done with this update. Clean it up.
cleanupActiveUpdate();
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_DESIREDCHANNEL))
Services.prefs.clearUserPref(PREF_APP_UPDATE_DESIREDCHANNEL);
}
else {
// If we hit an error, then the error code will be included in the status
@ -1242,12 +1269,10 @@ UpdateService.prototype = {
if (update.errorCode == WRITE_ERROR) {
prompter.showUpdateError(update);
writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
writeVersionFile(getUpdatesDir(), update.appVersion);
return;
}
else if (update.errorCode == ELEVATION_CANCELED) {
writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
writeVersionFile(getUpdatesDir(), update.appVersion);
return;
}
}
@ -1350,6 +1375,12 @@ UpdateService.prototype = {
if (updates.length == 0)
return null;
if (getDesiredChannel()) {
LOG("Checker:selectUpdate - skipping version checks for change change " +
"request");
return updates[0];
}
// Choose the newest of the available minor and major updates.
var majorUpdate = null;
var minorUpdate = null;
@ -1701,7 +1732,7 @@ UpdateService.prototype = {
// current application's version or the update's version is the same as the
// application's version and the build ID is the same as the application's
// build ID.
if (update.appVersion &&
if (!getDesiredChannel() && update.appVersion &&
(Services.vc.compare(update.appVersion, Services.appinfo.version) < 0 ||
update.buildID && update.buildID == Services.appinfo.appBuildID &&
update.appVersion == Services.appinfo.version)) {
@ -1902,8 +1933,9 @@ UpdateManager.prototype = {
* See nsIUpdateService.idl
*/
get activeUpdate() {
let currentChannel = getDesiredChannel() || getUpdateChannel();
if (this._activeUpdate &&
this._activeUpdate.channel != getUpdateChannel()) {
this._activeUpdate.channel != currentChannel) {
// User switched channels, clear out any old active updates and remove
// partial downloads
this._activeUpdate = null;
@ -2078,6 +2110,10 @@ Checker.prototype = {
getDistributionPrefValue(PREF_APP_DISTRIBUTION_VERSION));
url = url.replace(/\+/g, "%2B");
let desiredChannel = getDesiredChannel();
if (desiredChannel)
url += (url.indexOf("?") != -1 ? "&" : "?") + "newchannel=" + desiredChannel;
if (force)
url += (url.indexOf("?") != -1 ? "&" : "?") + "force=1";
@ -2159,7 +2195,7 @@ Checker.prototype = {
continue;
}
update.serviceURL = this.getUpdateURL(this._forced);
update.channel = getUpdateChannel();
update.channel = getDesiredChannel() || getUpdateChannel();
updates.push(update);
}
@ -2673,6 +2709,8 @@ Downloader.prototype = {
// Tell the updater.exe we're ready to apply.
writeStatusFile(getUpdatesDir(), state);
writeVersionFile(getUpdatesDir(), this._update.appVersion);
if (getDesiredChannel())
createChannelChangeFile(getUpdatesDir());
this._update.installDate = (new Date()).getTime();
this._update.statusText = gUpdateBundle.GetStringFromName("installPending");
}

Просмотреть файл

@ -53,6 +53,7 @@ const PREF_APP_UPDATE_CERT_ERRORS = "app.update.cert.errors";
const PREF_APP_UPDATE_CERT_MAXERRORS = "app.update.cert.maxErrors";
const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const PREF_APP_UPDATE_DESIREDCHANNEL = "app.update.desiredChannel";
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
const PREF_APP_UPDATE_LOG = "app.update.log";

Просмотреть файл

@ -274,11 +274,12 @@ function check_test_pt11() {
run_test_pt12();
}
// url constructed that doesn't have a parameter - bug 454357
// url with force param that doesn't already have a param - bug 454357
function run_test_pt12() {
gCheckFunc = check_test_pt12;
var url = URL_PREFIX;
logTestInfo("testing url constructed that doesn't have a parameter - " + url);
logTestInfo("testing url with force param that doesn't already have a " +
"param - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
@ -288,10 +289,11 @@ function check_test_pt12() {
run_test_pt13();
}
// url constructed that has a parameter - bug 454357
// url with force param that already has a param - bug 454357
function run_test_pt13() {
gCheckFunc = check_test_pt13;
var url = URL_PREFIX + "?extra=param";
logTestInfo("testing url with force param that already has a param - " + url);
logTestInfo("testing url constructed that has a parameter - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
@ -299,5 +301,52 @@ function run_test_pt13() {
function check_test_pt13() {
do_check_eq(getResult(gRequestURL), "?extra=param&force=1");
run_test_pt14();
}
// url with newchannel param that doesn't already have a param
function run_test_pt14() {
gCheckFunc = check_test_pt14;
Services.prefs.setCharPref(PREF_APP_UPDATE_DESIREDCHANNEL, "testchannel");
var url = URL_PREFIX;
logTestInfo("testing url with newchannel param that doesn't already have a " +
"param - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, false);
}
function check_test_pt14() {
do_check_eq(getResult(gRequestURL), "?newchannel=testchannel");
run_test_pt15();
}
// url with newchannel param that already has a param
function run_test_pt15() {
gCheckFunc = check_test_pt15;
Services.prefs.setCharPref(PREF_APP_UPDATE_DESIREDCHANNEL, "testchannel");
var url = URL_PREFIX + "?extra=param";
logTestInfo("testing url with newchannel param that already has a " +
"param - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, false);
}
function check_test_pt15() {
do_check_eq(getResult(gRequestURL), "?extra=param&newchannel=testchannel");
run_test_pt16();
}
// url with force and newchannel params
function run_test_pt16() {
gCheckFunc = check_test_pt16;
Services.prefs.setCharPref(PREF_APP_UPDATE_DESIREDCHANNEL, "testchannel");
var url = URL_PREFIX;
logTestInfo("testing url with force and newchannel params - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_pt16() {
do_check_eq(getResult(gRequestURL), "?newchannel=testchannel&force=1");
do_test_finished();
}

Просмотреть файл

@ -230,6 +230,12 @@ GetVersionFile(nsIFile *dir, nsCOMPtr<nsILocalFile> &result)
return GetFile(dir, NS_LITERAL_CSTRING("update.version"), result);
}
static PRBool
GetChannelChangeFile(nsIFile *dir, nsCOMPtr<nsILocalFile> &result)
{
return GetFile(dir, NS_LITERAL_CSTRING("channelchange"), result);
}
// Compares the current application version with the update's application
// version.
static PRBool
@ -513,11 +519,13 @@ ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir,
nsCOMPtr<nsILocalFile> statusFile;
if (GetStatusFile(updatesDir, statusFile) && IsPending(statusFile)) {
nsCOMPtr<nsILocalFile> versionFile;
nsCOMPtr<nsILocalFile> channelChangeFile;
// Remove the update if the update application version file doesn't exist
// or if the update's application version is less than the current
// application version.
if (!GetVersionFile(updatesDir, versionFile) ||
IsOlderVersion(versionFile, appVersion)) {
if (!GetChannelChangeFile(updatesDir, channelChangeFile) &&
(!GetVersionFile(updatesDir, versionFile) ||
IsOlderVersion(versionFile, appVersion))) {
updatesDir->Remove(PR_TRUE);
} else {
ApplyUpdate(greDir, updatesDir, statusFile, appDir, argc, argv);