summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-03 19:51:29 +0000
committergrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-03 19:51:29 +0000
commitd33cf4d9172096757459781713b5cdf24d78cde5 (patch)
tree760ce1aedd936ad3c4df0b9084956ea3c3394062
parent5d26cf9520236ea4a9258abe5ca65b98861e2e70 (diff)
downloadchromium_src-d33cf4d9172096757459781713b5cdf24d78cde5.zip
chromium_src-d33cf4d9172096757459781713b5cdf24d78cde5.tar.gz
chromium_src-d33cf4d9172096757459781713b5cdf24d78cde5.tar.bz2
Unconditionally remove "-multifail" from "ap" values. Previously, "-multifail" was added if a --multi-install run failed for any reason. Now, setup.exe always removes it. As a result, it is only left behind when setup.exe crashes (it is added by mini_installer.exe).
BUG=70878 TEST=run a mini_installer.exe with --multi-install (e.g., --multi-install --system-level --chrome --verbose-logging) and try two things: 1) kill setup.exe and make sure that -multifail is left in an "ap" value; 2) cause setup.exe to fail in a non-crash way (e.g., bump up "pv" in Chrome's Clients key so that setup.exe exits with HIGHER_VERSION_EXISTS) then make sure that -multifail is not left in any "ap" value. Review URL: http://codereview.chromium.org/6286044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73648 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/installer/setup/setup_main.cc86
-rw-r--r--chrome/installer/util/browser_distribution.cc2
-rw-r--r--chrome/installer/util/browser_distribution.h2
-rw-r--r--chrome/installer/util/chrome_frame_distribution.cc6
-rw-r--r--chrome/installer/util/chrome_frame_distribution.h2
-rw-r--r--chrome/installer/util/google_chrome_binaries_distribution.cc6
-rw-r--r--chrome/installer/util/google_chrome_binaries_distribution.h2
-rw-r--r--chrome/installer/util/google_chrome_distribution.cc6
-rw-r--r--chrome/installer/util/google_chrome_distribution.h2
-rw-r--r--chrome/installer/util/google_chrome_distribution_dummy.cc2
-rw-r--r--chrome/installer/util/google_update_settings.cc67
-rw-r--r--chrome/installer/util/google_update_settings.h12
-rw-r--r--chrome/installer/util/google_update_settings_unittest.cc115
-rw-r--r--chrome/installer/util/util_constants.h7
14 files changed, 173 insertions, 144 deletions
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index 5d72757..b71dd5b 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -84,7 +84,8 @@ DWORD UnPackArchive(const FilePath& archive,
const InstallerState& installer_state,
const FilePath& temp_path,
const FilePath& output_directory,
- bool& incremental_install) {
+ installer::ArchiveType* archive_type) {
+ DCHECK(archive_type);
// First uncompress the payload. This could be a differential
// update (patch.7z) or full archive (chrome.7z). If this uncompress fails
// return with error.
@@ -102,7 +103,7 @@ DWORD UnPackArchive(const FilePath& archive,
// installer archive that should already be on the machine. We assume
// it is a differential installer if chrome.7z is not found.
if (!file_util::PathExists(uncompressed_archive)) {
- incremental_install = true;
+ *archive_type = installer::INCREMENTAL_ARCHIVE_TYPE;
VLOG(1) << "Differential patch found. Applying to existing archive.";
if (!archive_version.get()) {
LOG(ERROR) << "Can not use differential update when Chrome is not "
@@ -120,6 +121,8 @@ DWORD UnPackArchive(const FilePath& archive,
LOG(ERROR) << "Binary patching failed with error " << i;
return i;
}
+ } else {
+ *archive_type = installer::FULL_ARCHIVE_TYPE;
}
// Unpack the uncompressed archive.
@@ -338,6 +341,9 @@ void AddExistingMultiInstalls(const InstallationState& original_state,
// Also blocks simultaneous user-level and system-level installs. In the case
// of trying to install user-level Chrome when system-level exists, the
// existing system-level Chrome is launched.
+// When the pre-install conditions are not satisfied, the result is written to
+// the registry (via WriteInstallerResult), |status| is set appropriately, and
+// false is returned.
bool CheckPreInstallConditions(const InstallationState& original_state,
InstallerState* installer_state,
installer::InstallStatus* status) {
@@ -446,16 +452,15 @@ bool CheckPreInstallConditions(const InstallationState& original_state,
return true;
}
-installer::InstallStatus InstallProducts(
+installer::InstallStatus InstallProductsHelper(
const InstallationState& original_state,
const CommandLine& cmd_line,
const MasterPreferences& prefs,
- InstallerState* installer_state) {
- const bool system_install = installer_state->system_install();
+ const InstallerState& installer_state,
+ installer::ArchiveType* archive_type) {
+ DCHECK(archive_type);
+ const bool system_install = installer_state.system_install();
installer::InstallStatus install_status = installer::UNKNOWN_STATUS;
- if (!CheckPreInstallConditions(original_state, installer_state,
- &install_status))
- return install_status;
// For install the default location for chrome.packed.7z is in current
// folder, so get that value first.
@@ -468,7 +473,7 @@ installer::InstallStatus InstallProducts(
installer::switches::kInstallArchive);
}
VLOG(1) << "Archive found to install Chrome " << archive.value();
- const Products& products = installer_state->products();
+ const Products& products = installer_state.products();
// Create a temp folder where we will unpack Chrome archive. If it fails,
// then we are doomed, so return immediately and no cleanup is required.
@@ -476,19 +481,18 @@ installer::InstallStatus InstallProducts(
if (!file_util::CreateNewTempDirectory(L"chrome_", &temp_path)) {
LOG(ERROR) << "Could not create temporary path.";
InstallUtil::WriteInstallerResult(system_install,
- installer_state->state_key(), installer::TEMP_DIR_FAILED,
+ installer_state.state_key(), installer::TEMP_DIR_FAILED,
IDS_INSTALL_TEMP_DIR_FAILED_BASE, NULL);
return installer::TEMP_DIR_FAILED;
}
VLOG(1) << "created path " << temp_path.value();
FilePath unpack_path(temp_path.Append(installer::kInstallSourceDir));
- bool incremental_install = false;
- if (UnPackArchive(archive, *installer_state, temp_path, unpack_path,
- incremental_install)) {
+ if (UnPackArchive(archive, installer_state, temp_path, unpack_path,
+ archive_type)) {
install_status = installer::UNCOMPRESSION_FAILED;
InstallUtil::WriteInstallerResult(system_install,
- installer_state->state_key(), install_status,
+ installer_state.state_key(), install_status,
IDS_INSTALL_UNCOMPRESSION_FAILED_BASE, NULL);
} else {
VLOG(1) << "unpacked to " << unpack_path.value();
@@ -499,7 +503,7 @@ installer::InstallStatus InstallProducts(
LOG(ERROR) << "Did not find any valid version in installer.";
install_status = installer::INVALID_ARCHIVE;
InstallUtil::WriteInstallerResult(system_install,
- installer_state->state_key(), install_status,
+ installer_state.state_key(), install_status,
IDS_INSTALL_INVALID_ARCHIVE_BASE, NULL);
} else {
// TODO(tommi): Move towards having only a single version that is common
@@ -509,8 +513,8 @@ installer::InstallStatus InstallProducts(
// (or rather must) be upgraded.
VLOG(1) << "version to install: " << installer_version->GetString();
bool higher_version_installed = false;
- for (size_t i = 0; i < installer_state->products().size(); ++i) {
- const Product* product = installer_state->products()[i];
+ for (size_t i = 0; i < installer_state.products().size(); ++i) {
+ const Product* product = installer_state.products()[i];
const ProductState* product_state =
original_state.GetProductState(system_install,
product->distribution()->GetType());
@@ -524,11 +528,11 @@ installer::InstallStatus InstallProducts(
// TODO(robertshield): We should take the installer result text
// strings from the Product.
InstallUtil::WriteInstallerResult(system_install,
- installer_state->state_key(), install_status,
+ installer_state.state_key(), install_status,
IDS_INSTALL_HIGHER_VERSION_BASE, NULL);
} else {
InstallUtil::WriteInstallerResult(system_install,
- installer_state->state_key(), install_status,
+ installer_state.state_key(), install_status,
IDS_INSTALL_HIGHER_VERSION_CF_BASE, NULL);
}
}
@@ -541,25 +545,25 @@ installer::InstallStatus InstallProducts(
FilePath prefs_source_path(cmd_line.GetSwitchValueNative(
installer::switches::kInstallerData));
install_status = installer::InstallOrUpdateProduct(original_state,
- *installer_state, cmd_line.GetProgram(), archive_to_copy, temp_path,
+ installer_state, cmd_line.GetProgram(), archive_to_copy, temp_path,
prefs_source_path, prefs, *installer_version);
int install_msg_base = IDS_INSTALL_FAILED_BASE;
std::wstring chrome_exe;
if (install_status == installer::SAME_VERSION_REPAIR_FAILED) {
- if (installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)) {
+ if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
install_msg_base = IDS_SAME_VERSION_REPAIR_FAILED_CF_BASE;
} else {
install_msg_base = IDS_SAME_VERSION_REPAIR_FAILED_BASE;
}
} else if (install_status != installer::INSTALL_FAILED) {
- if (installer_state->target_path().empty()) {
+ if (installer_state.target_path().empty()) {
// If we failed to construct install path, it means the OS call to
// get %ProgramFiles% or %AppData% failed. Report this as failure.
install_msg_base = IDS_INSTALL_OS_ERROR_BASE;
install_status = installer::OS_ERROR;
} else {
- chrome_exe = installer_state->target_path()
+ chrome_exe = installer_state.target_path()
.Append(installer::kChromeExe).value();
chrome_exe = L"\"" + chrome_exe + L"\"";
install_msg_base = 0;
@@ -570,7 +574,7 @@ installer::InstallStatus InstallProducts(
// Chrome was specifically requested (rather than being upgraded as
// part of a multi-install).
const Product* chrome_install = prefs.install_chrome() ?
- installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER) :
+ installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) :
NULL;
bool value = false;
@@ -586,7 +590,7 @@ installer::InstallStatus InstallProducts(
(install_status != installer::IN_USE_UPDATED);
InstallUtil::WriteInstallerResult(system_install,
- installer_state->state_key(), install_status, install_msg_base,
+ installer_state.state_key(), install_status, install_msg_base,
write_chrome_launch_string ? &chrome_exe : NULL);
if (install_status == installer::FIRST_INSTALL_SUCCESS) {
@@ -598,7 +602,7 @@ installer::InstallStatus InstallProducts(
installer::master_preferences::kDoNotLaunchChrome,
&do_not_launch_chrome);
if (!system_install && !do_not_launch_chrome)
- chrome_install->LaunchChrome(installer_state->target_path());
+ chrome_install->LaunchChrome(installer_state.target_path());
}
} else if ((install_status == installer::NEW_VERSION_UPDATED) ||
(install_status == installer::IN_USE_UPDATED)) {
@@ -650,15 +654,35 @@ installer::InstallStatus InstallProducts(
}
}
+ return install_status;
+}
+
+installer::InstallStatus InstallProducts(
+ const InstallationState& original_state,
+ const CommandLine& cmd_line,
+ const MasterPreferences& prefs,
+ InstallerState* installer_state) {
+ DCHECK(installer_state);
+ installer::InstallStatus install_status = installer::UNKNOWN_STATUS;
+ installer::ArchiveType archive_type = installer::UNKNOWN_ARCHIVE_TYPE;
+ bool incremental_install = false;
+ if (CheckPreInstallConditions(original_state, installer_state,
+ &install_status)) {
+ install_status = InstallProductsHelper(
+ original_state, cmd_line, prefs, *installer_state, &archive_type);
+ }
+
+ const bool system_install = installer_state->system_install();
+ const Products& products = installer_state->products();
+
for (size_t i = 0; i < products.size(); ++i) {
const Product* product = products[i];
product->distribution()->UpdateInstallStatus(
- system_install, incremental_install, prefs.is_multi_install(),
- install_status);
+ system_install, archive_type, install_status);
}
if (installer_state->is_multi_install()) {
installer_state->multi_package_binaries_distribution()->UpdateInstallStatus(
- system_install, incremental_install, true, install_status);
+ system_install, archive_type, install_status);
}
return install_status;
@@ -922,10 +946,6 @@ class AutoCom {
bool initialized_;
};
-
-
-
-
// Returns the Custom information for the client identified by the exe path
// passed in. This information is used for crash reporting.
google_breakpad::CustomClientInfo* GetCustomInfo(const wchar_t* exe_path) {
diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc
index be452c5..251dd7e 100644
--- a/chrome/installer/util/browser_distribution.cc
+++ b/chrome/installer/util/browser_distribution.cc
@@ -216,7 +216,7 @@ bool BrowserDistribution::GetChromeChannel(std::wstring* channel) {
}
void BrowserDistribution::UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status) {
}
diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h
index 3fb1ded..71f9acf 100644
--- a/chrome/installer/util/browser_distribution.h
+++ b/chrome/installer/util/browser_distribution.h
@@ -91,7 +91,7 @@ class BrowserDistribution {
virtual bool GetChromeChannel(std::wstring* channel);
virtual void UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status);
// After an install or upgrade the user might qualify to participate in an
diff --git a/chrome/installer/util/chrome_frame_distribution.cc b/chrome/installer/util/chrome_frame_distribution.cc
index 86a1abc..6dc84ea 100644
--- a/chrome/installer/util/chrome_frame_distribution.cc
+++ b/chrome/installer/util/chrome_frame_distribution.cc
@@ -106,11 +106,11 @@ bool ChromeFrameDistribution::CanSetAsDefault() {
}
void ChromeFrameDistribution::UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status) {
#if defined(GOOGLE_CHROME_BUILD)
GoogleUpdateSettings::UpdateInstallStatus(system_install,
- incremental_install, multi_install,
- InstallUtil::GetInstallReturnCode(install_status), kChromeFrameGuid);
+ archive_type, InstallUtil::GetInstallReturnCode(install_status),
+ kChromeFrameGuid);
#endif
}
diff --git a/chrome/installer/util/chrome_frame_distribution.h b/chrome/installer/util/chrome_frame_distribution.h
index 043dc68..8f6150e 100644
--- a/chrome/installer/util/chrome_frame_distribution.h
+++ b/chrome/installer/util/chrome_frame_distribution.h
@@ -52,7 +52,7 @@ class ChromeFrameDistribution : public BrowserDistribution {
virtual bool CanSetAsDefault();
virtual void UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status);
protected:
diff --git a/chrome/installer/util/google_chrome_binaries_distribution.cc b/chrome/installer/util/google_chrome_binaries_distribution.cc
index 00229bf..d5b6d24 100644
--- a/chrome/installer/util/google_chrome_binaries_distribution.cc
+++ b/chrome/installer/util/google_chrome_binaries_distribution.cc
@@ -48,9 +48,9 @@ std::wstring GoogleChromeBinariesDistribution::GetVersionKey() {
}
void GoogleChromeBinariesDistribution::UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status) {
GoogleUpdateSettings::UpdateInstallStatus(system_install,
- incremental_install, multi_install,
- InstallUtil::GetInstallReturnCode(install_status), kChromeBinariesGuid);
+ archive_type, InstallUtil::GetInstallReturnCode(install_status),
+ kChromeBinariesGuid);
}
diff --git a/chrome/installer/util/google_chrome_binaries_distribution.h b/chrome/installer/util/google_chrome_binaries_distribution.h
index 3ddbf34..05de929 100644
--- a/chrome/installer/util/google_chrome_binaries_distribution.h
+++ b/chrome/installer/util/google_chrome_binaries_distribution.h
@@ -23,7 +23,7 @@ class GoogleChromeBinariesDistribution : public ChromiumBinariesDistribution {
virtual std::wstring GetVersionKey();
virtual void UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status);
protected:
diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc
index eff776b..aae4c9a 100644
--- a/chrome/installer/util/google_chrome_distribution.cc
+++ b/chrome/installer/util/google_chrome_distribution.cc
@@ -505,11 +505,11 @@ std::wstring GoogleChromeDistribution::GetVersionKey() {
// string (if it is present) regardless of whether installer failed or not.
// There is no fall-back for full installer :)
void GoogleChromeDistribution::UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status) {
GoogleUpdateSettings::UpdateInstallStatus(system_install,
- incremental_install, multi_install,
- InstallUtil::GetInstallReturnCode(install_status), product_guid());
+ archive_type, InstallUtil::GetInstallReturnCode(install_status),
+ product_guid());
}
// The functions below are not used by the 64-bit Windows binary -
diff --git a/chrome/installer/util/google_chrome_distribution.h b/chrome/installer/util/google_chrome_distribution.h
index 9610518..ac4a3d1 100644
--- a/chrome/installer/util/google_chrome_distribution.h
+++ b/chrome/installer/util/google_chrome_distribution.h
@@ -67,7 +67,7 @@ class GoogleChromeDistribution : public BrowserDistribution {
virtual std::wstring GetVersionKey();
virtual void UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status);
virtual void LaunchUserExperiment(installer::InstallStatus status,
diff --git a/chrome/installer/util/google_chrome_distribution_dummy.cc b/chrome/installer/util/google_chrome_distribution_dummy.cc
index 9b022be..28340bd 100644
--- a/chrome/installer/util/google_chrome_distribution_dummy.cc
+++ b/chrome/installer/util/google_chrome_distribution_dummy.cc
@@ -101,7 +101,7 @@ std::wstring GoogleChromeDistribution::GetVersionKey() {
}
void GoogleChromeDistribution::UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install,
+ installer::ArchiveType archive_type,
installer::InstallStatus install_status) {
NOTREACHED();
}
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc
index 76d13d2..598a3e3 100644
--- a/chrome/installer/util/google_update_settings.cc
+++ b/chrome/installer/util/google_update_settings.cc
@@ -249,8 +249,10 @@ bool GoogleUpdateSettings::GetChromeChannel(bool system_install,
}
void GoogleUpdateSettings::UpdateInstallStatus(bool system_install,
- bool incremental_install, bool multi_install, int install_return_code,
+ installer::ArchiveType archive_type, int install_return_code,
const std::wstring& product_guid) {
+ DCHECK(archive_type != installer::UNKNOWN_ARCHIVE_TYPE ||
+ install_return_code != 0);
HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
RegKey key;
@@ -260,45 +262,48 @@ void GoogleUpdateSettings::UpdateInstallStatus(bool system_install,
reg_key.append(product_guid);
LONG result = key.Open(reg_root, reg_key.c_str(),
KEY_QUERY_VALUE | KEY_SET_VALUE);
- if (result != ERROR_SUCCESS || !channel_info.Initialize(key)) {
- VLOG(1) << "Application key not found.";
- if (!incremental_install && !multi_install || !install_return_code) {
- VLOG(1) << "Returning without changing application key.";
- return;
- } else if (!key.Valid()) {
- reg_key.assign(google_update::kRegPathClientState);
- result = key.Open(reg_root, reg_key.c_str(), KEY_CREATE_SUB_KEY);
+ if (result == ERROR_SUCCESS)
+ channel_info.Initialize(key);
+ else if (result != ERROR_FILE_NOT_FOUND)
+ LOG(ERROR) << "Failed to open " << reg_key << "; Error: " << result;
+
+ if (UpdateGoogleUpdateApKey(archive_type, install_return_code,
+ &channel_info)) {
+ // We have a modified channel_info value to write.
+ // Create the app's ClientState key if it doesn't already exist.
+ if (!key.Valid()) {
+ result = key.Open(reg_root, google_update::kRegPathClientState,
+ KEY_CREATE_SUB_KEY);
if (result == ERROR_SUCCESS)
result = key.CreateKey(product_guid.c_str(), KEY_SET_VALUE);
if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed to create application key. Error: " << result;
+ LOG(ERROR) << "Failed to create " << reg_key << "; Error: " << result;
return;
}
}
- }
-
- if (UpdateGoogleUpdateApKey(incremental_install, multi_install,
- install_return_code, &channel_info) &&
- !channel_info.Write(&key)) {
- LOG(ERROR) << "Failed to write value " << channel_info.value()
- << " to the registry field " << google_update::kRegApField;
+ if (!channel_info.Write(&key)) {
+ LOG(ERROR) << "Failed to write to application's ClientState key "
+ << google_update::kRegApField << " = " << channel_info.value();
+ }
}
}
bool GoogleUpdateSettings::UpdateGoogleUpdateApKey(
- bool diff_install, bool multi_install, int install_return_code,
+ installer::ArchiveType archive_type, int install_return_code,
installer::ChannelInfo* value) {
+ DCHECK(archive_type != installer::UNKNOWN_ARCHIVE_TYPE ||
+ install_return_code != 0);
bool modified = false;
- if (!diff_install || !install_return_code) {
+ if (archive_type == installer::FULL_ARCHIVE_TYPE || !install_return_code) {
if (value->SetFullSuffix(false)) {
VLOG(1) << "Removed incremental installer failure key; "
"switching to channel: "
<< value->value();
modified = true;
}
- } else {
+ } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) {
if (value->SetFullSuffix(true)) {
VLOG(1) << "Incremental installer failed; switching to channel: "
<< value->value();
@@ -307,22 +312,16 @@ bool GoogleUpdateSettings::UpdateGoogleUpdateApKey(
VLOG(1) << "Incremental installer failure; already on channel: "
<< value->value();
}
+ } else {
+ // It's okay if we don't know the archive type. In this case, leave the
+ // "-full" suffix as we found it.
+ DCHECK_EQ(installer::UNKNOWN_ARCHIVE_TYPE, archive_type);
}
- if (!multi_install || !install_return_code) {
- if (value->SetMultiFailSuffix(false)) {
- VLOG(1) << "Removed multi-install failure key; switching to channel: "
- << value->value();
- modified = true;
- }
- } else {
- if (value->SetMultiFailSuffix(true)) {
- VLOG(1) << "Multi-install failed; switching to channel: "
- << value->value();
- modified = true;
- } else {
- VLOG(1) << "Multi-install failed; already on channel: " << value->value();
- }
+ if (value->SetMultiFailSuffix(false)) {
+ VLOG(1) << "Removed multi-install failure key; switching to channel: "
+ << value->value();
+ modified = true;
}
return modified;
diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h
index 12b5fa5..473b3cd 100644
--- a/chrome/installer/util/google_update_settings.h
+++ b/chrome/installer/util/google_update_settings.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/basictypes.h"
+#include "chrome/installer/util/util_constants.h"
namespace installer {
class ChannelInfo;
@@ -98,12 +99,10 @@ class GoogleUpdateSettings {
// - If we are currently running full installer, we remove this magic
// string (if it is present) regardless of whether installer failed or not.
// There is no fall-back for full installer :)
- // - If multi-install fails we append -multifail; otherwise, we remove it
- // (i.e., success or single-install).
+ // - Unconditionally remove "-multifail" since we haven't crashed.
// |state_key| should be obtained via InstallerState::state_key().
static void UpdateInstallStatus(bool system_install,
- bool incremental_install,
- bool multi_install,
+ installer::ArchiveType archive_type,
int install_return_code,
const std::wstring& product_guid);
@@ -116,12 +115,11 @@ class GoogleUpdateSettings {
// - If full installer failed, still remove this magic
// string (if it is present already).
//
- // diff_install: tells whether this is incremental install or not.
+ // archive_type: tells whether this is incremental install or not.
// install_return_code: if 0, means installation was successful.
// value: current value of Google Update "ap" key.
// Returns true if |value| is modified.
- static bool UpdateGoogleUpdateApKey(bool diff_install,
- bool multi_install,
+ static bool UpdateGoogleUpdateApKey(installer::ArchiveType archive_type,
int install_return_code,
installer::ChannelInfo* value);
diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc
index 2234192..747aeb5 100644
--- a/chrome/installer/util/google_update_settings_unittest.cc
+++ b/chrome/installer/util/google_update_settings_unittest.cc
@@ -229,13 +229,10 @@ TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesUser) {
// checking that the expected final "ap" value is generated by
// GoogleUpdateSettings::UpdateGoogleUpdateApKey.
TEST_F(GoogleUpdateSettingsTest, UpdateGoogleUpdateApKey) {
- const bool is_multi[] = {
- false,
- true
- };
- const bool is_diff[] = {
- false,
- true
+ const installer::ArchiveType archive_types[] = {
+ installer::UNKNOWN_ARCHIVE_TYPE,
+ installer::FULL_ARCHIVE_TYPE,
+ installer::INCREMENTAL_ARCHIVE_TYPE
};
const int results[] = {
installer::FIRST_INSTALL_SUCCESS,
@@ -273,51 +270,56 @@ TEST_F(GoogleUpdateSettingsTest, UpdateGoogleUpdateApKey) {
multifail_full
};
ChannelInfo v;
- for (int multi_idx = 0; multi_idx < arraysize(is_multi); ++multi_idx) {
- const bool multi = is_multi[multi_idx];
- for (int diff_idx = 0; diff_idx < arraysize(is_diff); ++diff_idx) {
- const bool diff = is_diff[diff_idx];
- for (int result_idx = 0; result_idx < arraysize(results); ++result_idx) {
- const int result = results[result_idx];
- const wchar_t* const* outputs;
- if (result == installer::FIRST_INSTALL_SUCCESS || !multi && !diff)
- outputs = plain;
- else if (!multi && diff)
- outputs = full;
- else if (multi && !diff)
- outputs = multifail;
- else
- outputs = multifail_full;
-
- for (int inputs_idx = 0; inputs_idx < arraysize(input_arrays);
- ++inputs_idx) {
- const wchar_t* const* inputs = input_arrays[inputs_idx];
- for (int input_idx = 0; input_idx < arraysize(plain); ++input_idx) {
- const wchar_t* input = inputs[input_idx];
- const wchar_t* output = outputs[input_idx];
-
- v.set_value(input);
- if (output == v.value()) {
- EXPECT_FALSE(GoogleUpdateSettings::UpdateGoogleUpdateApKey(
- diff, multi, result, &v))
- << "diff: " << diff
- << ", multi: " << multi
- << ", result: " << result
- << ", input ap value: " << input;
- } else {
- EXPECT_TRUE(GoogleUpdateSettings::UpdateGoogleUpdateApKey(
- diff, multi, result, &v))
- << "diff: " << diff
- << ", multi: " << multi
- << ", result: " << result
- << ", input ap value: " << input;
- }
- EXPECT_EQ(output, v.value())
- << "diff: " << diff
- << ", multi: " << multi
+ for (int type_idx = 0; type_idx < arraysize(archive_types); ++type_idx) {
+ const installer::ArchiveType archive_type = archive_types[type_idx];
+ for (int result_idx = 0; result_idx < arraysize(results); ++result_idx) {
+ const int result = results[result_idx];
+ // The archive type will/must always be known on install success.
+ if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE &&
+ result == installer::FIRST_INSTALL_SUCCESS) {
+ continue;
+ }
+ const wchar_t* const* outputs = NULL;
+ if (result == installer::FIRST_INSTALL_SUCCESS ||
+ archive_type == installer::FULL_ARCHIVE_TYPE) {
+ outputs = plain;
+ } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) {
+ outputs = full;
+ } // else if (archive_type == UNKNOWN) see below
+
+ for (int inputs_idx = 0; inputs_idx < arraysize(input_arrays);
+ ++inputs_idx) {
+ const wchar_t* const* inputs = input_arrays[inputs_idx];
+ if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE) {
+ // "-full" is untouched if the archive type is unknown.
+ // "-multifail" is unconditionally removed.
+ if (inputs == full || inputs == multifail_full)
+ outputs = full;
+ else
+ outputs = plain;
+ }
+ for (int input_idx = 0; input_idx < arraysize(plain); ++input_idx) {
+ const wchar_t* input = inputs[input_idx];
+ const wchar_t* output = outputs[input_idx];
+
+ v.set_value(input);
+ if (output == v.value()) {
+ EXPECT_FALSE(GoogleUpdateSettings::UpdateGoogleUpdateApKey(
+ archive_type, result, &v))
+ << "archive_type: " << archive_type
+ << ", result: " << result
+ << ", input ap value: " << input;
+ } else {
+ EXPECT_TRUE(GoogleUpdateSettings::UpdateGoogleUpdateApKey(
+ archive_type, result, &v))
+ << "archive_type: " << archive_type
<< ", result: " << result
<< ", input ap value: " << input;
}
+ EXPECT_EQ(output, v.value())
+ << "archive_type: " << archive_type
+ << ", result: " << result
+ << ", input ap value: " << input;
}
}
}
@@ -329,7 +331,8 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
// Test incremental install failure
ASSERT_TRUE(CreateApKey(work_item_list.get(), L""))
<< "Failed to create ap key.";
- GoogleUpdateSettings::UpdateInstallStatus(false, true, false,
+ GoogleUpdateSettings::UpdateInstallStatus(false,
+ installer::INCREMENTAL_ARCHIVE_TYPE,
installer::INSTALL_FAILED,
kTestProductGuid);
EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full");
@@ -339,7 +342,8 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
// Test incremental install success
ASSERT_TRUE(CreateApKey(work_item_list.get(), L""))
<< "Failed to create ap key.";
- GoogleUpdateSettings::UpdateInstallStatus(false, true, false,
+ GoogleUpdateSettings::UpdateInstallStatus(false,
+ installer::INCREMENTAL_ARCHIVE_TYPE,
installer::FIRST_INSTALL_SUCCESS,
kTestProductGuid);
EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
@@ -349,7 +353,7 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
// Test full install failure
ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full"))
<< "Failed to create ap key.";
- GoogleUpdateSettings::UpdateInstallStatus(false, false, false,
+ GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE,
installer::INSTALL_FAILED,
kTestProductGuid);
EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
@@ -359,7 +363,7 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
// Test full install success
ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full"))
<< "Failed to create ap key.";
- GoogleUpdateSettings::UpdateInstallStatus(false, false, false,
+ GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE,
installer::FIRST_INSTALL_SUCCESS,
kTestProductGuid);
EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
@@ -380,12 +384,13 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
ap_key_deleted = true;
}
// try differential installer
- GoogleUpdateSettings::UpdateInstallStatus(false, true, false,
+ GoogleUpdateSettings::UpdateInstallStatus(false,
+ installer::INCREMENTAL_ARCHIVE_TYPE,
installer::INSTALL_FAILED,
kTestProductGuid);
EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full");
// try full installer now
- GoogleUpdateSettings::UpdateInstallStatus(false, false, false,
+ GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE,
installer::INSTALL_FAILED,
kTestProductGuid);
EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index 7a632e8..3c20cc3 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -71,6 +71,13 @@ enum InstallStatus {
READY_MODE_REQUIRES_CHROME, // 40. Chrome Frame in ready-mode requires Chrome
};
+// The type of an update archive.
+enum ArchiveType {
+ UNKNOWN_ARCHIVE_TYPE, // Unknown or uninitialized.
+ FULL_ARCHIVE_TYPE, // Full chrome.7z archive.
+ INCREMENTAL_ARCHIVE_TYPE // Incremental or differential archive.
+};
+
namespace switches {
extern const char kCeee[];
extern const char kChrome[];