diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-06 20:42:39 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-06 20:42:39 +0000 |
commit | 5f27dc1b618add9874c21f47adc0f6a57d0c2208 (patch) | |
tree | ad2f004ec5103555499d4bb443c3e7f13d850b2c | |
parent | ada41253c96b1f86b4e84ff6765b043e34ec2f7c (diff) | |
download | chromium_src-5f27dc1b618add9874c21f47adc0f6a57d0c2208.zip chromium_src-5f27dc1b618add9874c21f47adc0f6a57d0c2208.tar.gz chromium_src-5f27dc1b618add9874c21f47adc0f6a57d0c2208.tar.bz2 |
Add brand-code migration to the Chrome installer when creating the new multi-install app guid.
When upgrading a product from single to multi, the installer will now check if a Chrome install at that level (user/system) had a brand code, and if so it will copy the brand code to the ClientState key for the multi-install.
Also, some yak de-hairing: alter InstallationState such that it can be queried for partial ProductStates for products that are in the process of being installed. This can be used to query e.g. the ap value and the brand code, but not the version (since a product won't have a version until its first install is complete). This removes the need to go and manually re-query the registry in a couple of places, makes the installer's actions based solely on the original InstallationState and generally removes some hackiness.
BUG=61609
TEST=setup_unittests.exe, also when upgrading from single to multi, observe that brand codes are copied over.
Review URL: http://codereview.chromium.org/6604010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77089 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/installer/setup/chrome_frame_quick_enable.cc | 3 | ||||
-rw-r--r-- | chrome/installer/setup/chrome_frame_ready_mode.cc | 2 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.cc | 74 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.h | 3 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker_unittest.cc | 62 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 21 | ||||
-rw-r--r-- | chrome/installer/util/google_update_constants.cc | 1 | ||||
-rw-r--r-- | chrome/installer/util/google_update_constants.h | 1 | ||||
-rw-r--r-- | chrome/installer/util/installation_state.cc | 115 | ||||
-rw-r--r-- | chrome/installer/util/installation_state.h | 14 | ||||
-rw-r--r-- | chrome/installer/util/installation_validator_unittest.cc | 1 | ||||
-rw-r--r-- | chrome/installer/util/installer_state.cc | 3 | ||||
-rw-r--r-- | chrome/installer/util/installer_state.h | 5 | ||||
-rw-r--r-- | chrome/installer/util/work_item_list.cc | 2 |
14 files changed, 220 insertions, 87 deletions
diff --git a/chrome/installer/setup/chrome_frame_quick_enable.cc b/chrome/installer/setup/chrome_frame_quick_enable.cc index 8743fc8..1df87f1 100644 --- a/chrome/installer/setup/chrome_frame_quick_enable.cc +++ b/chrome/installer/setup/chrome_frame_quick_enable.cc @@ -120,7 +120,8 @@ InstallStatus ChromeFrameQuickEnable(const InstallationState& machine_state, // all multi-installed products' channel values get updated. installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, *chrome_state); - AddGoogleUpdateWorkItems(*installer_state, item_list.get()); + AddGoogleUpdateWorkItems(machine_state, *installer_state, + item_list.get()); // Add the items to remove the quick-enable-cf command from the registry. AddQuickEnableWorkItems(*installer_state, machine_state, diff --git a/chrome/installer/setup/chrome_frame_ready_mode.cc b/chrome/installer/setup/chrome_frame_ready_mode.cc index c647a9b..82a6c68 100644 --- a/chrome/installer/setup/chrome_frame_ready_mode.cc +++ b/chrome/installer/setup/chrome_frame_ready_mode.cc @@ -106,7 +106,7 @@ InstallStatus ChromeFrameReadyModeOptIn( kChromeFrameReadyModeField); // Update the Google Update channel ("ap") value. - AddGoogleUpdateWorkItems(opt_in_state, item_list.get()); + AddGoogleUpdateWorkItems(machine_state, opt_in_state, item_list.get()); // Delete the command elevation registry keys std::wstring version_key(cf->distribution()->GetVersionKey()); diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc index 70e1ab6..24fbf6d 100644 --- a/chrome/installer/setup/install_worker.cc +++ b/chrome/installer/setup/install_worker.cc @@ -254,7 +254,8 @@ void AddProductSpecificWorkItems(const InstallationState& original_state, // In the multi-install case, this value is used as the basis upon which the // package's channel value is built (by adding the ordered list of installed // products and their options). -void AddGoogleUpdateWorkItems(const InstallerState& installer_state, +void AddGoogleUpdateWorkItems(const InstallationState& original_state, + const InstallerState& installer_state, WorkItemList* install_list) { // Is a multi-install product being installed or over-installed? if (installer_state.operation() != InstallerState::MULTI_INSTALL && @@ -263,16 +264,16 @@ void AddGoogleUpdateWorkItems(const InstallerState& installer_state, return; } - const HKEY reg_root = installer_state.root_key(); - const std::wstring key_path = installer_state.state_key(); - ChannelInfo channel_info; - - // Update the "ap" value for the product being installed/updated. - // It is completely acceptable for there to be no "ap" value or even no - // ClientState key. Note that we check the registry rather than an - // InstallationState instance since on a fresh install the "ap" value will be - // present sans "pv" value. - channel_info.Initialize(RegKey(reg_root, key_path.c_str(), KEY_QUERY_VALUE)); + // Update the "ap" value for the product being installed/updated. We get + // this via GetNonVersionedProductState since the product whose ap value + // we are querying may be in the process of being installed for the first + // time. + BrowserDistribution::Type client_state_distribution = + installer_state.state_type(); + const ProductState* target_product_state = + original_state.GetNonVersionedProductState( + installer_state.system_install(), client_state_distribution); + ChannelInfo channel_info(target_product_state->channel()); // This is a multi-install product. bool modified = channel_info.SetMultiInstall(true); @@ -282,6 +283,9 @@ void AddGoogleUpdateWorkItems(const InstallerState& installer_state, VLOG(1) << "ap: " << channel_info.value(); + const HKEY reg_root = installer_state.root_key(); + const std::wstring& key_path(installer_state.state_key()); + // Write the results if needed. if (modified) { install_list->AddSetRegValueWorkItem(reg_root, key_path, @@ -292,26 +296,27 @@ void AddGoogleUpdateWorkItems(const InstallerState& installer_state, } // Synchronize the other products and the package with this one. - std::wstring other_key; - std::vector<std::wstring> keys; + std::vector<std::wstring> state_key_paths; + + state_key_paths.reserve(installer_state.products().size()); + std::wstring multi_key( + installer_state.multi_package_binaries_distribution()->GetStateKey()); + if (multi_key != key_path) + state_key_paths.push_back(multi_key); - keys.reserve(installer_state.products().size()); - other_key = - installer_state.multi_package_binaries_distribution()->GetStateKey(); - if (other_key != key_path) - keys.push_back(other_key); + std::wstring other_key; Products::const_iterator scan = installer_state.products().begin(); Products::const_iterator end = installer_state.products().end(); for (; scan != end; ++scan) { other_key = (*scan)->distribution()->GetStateKey(); if (other_key != key_path) - keys.push_back(other_key); + state_key_paths.push_back(other_key); } RegKey key; ChannelInfo other_info; - std::vector<std::wstring>::const_iterator kscan = keys.begin(); - std::vector<std::wstring>::const_iterator kend = keys.end(); + std::vector<std::wstring>::const_iterator kscan = state_key_paths.begin(); + std::vector<std::wstring>::const_iterator kend = state_key_paths.end(); for (; kscan != kend; ++kscan) { // Handle the case where the ClientState key doesn't exist by creating it. // This takes care of the multi-installer's package key, which is not @@ -321,13 +326,36 @@ void AddGoogleUpdateWorkItems(const InstallerState& installer_state, other_info.set_value(std::wstring()); } if (!other_info.Equals(channel_info)) { - if (!key.Valid()) + if (!key.Valid()) { install_list->AddCreateRegKeyWorkItem(reg_root, *kscan); + } install_list->AddSetRegValueWorkItem(reg_root, *kscan, google_update::kRegApField, channel_info.value(), true); } } + + // Creating the ClientState key for binaries, if we're migrating to multi then + // copy over Chrome's brand code if it has one. Chrome Frame currently never + // has a brand code. + if (multi_key != key_path) { + const ProductState* chrome_product_state = + original_state.GetNonVersionedProductState( + installer_state.system_install(), + BrowserDistribution::CHROME_BROWSER); + + const std::wstring& brand(chrome_product_state->brand()); + if (!brand.empty()) { + // Write Chrome's brand code to the multi key. Never overwrite the value + // if one is already present (although this shouldn't happen). + install_list->AddSetRegValueWorkItem(reg_root, + multi_key, + google_update::kRegBrandField, + brand, + false); + } + } + // TODO(grt): check for other keys/values we should put in the package's // ClientState and/or Clients key. } @@ -598,7 +626,7 @@ void AddInstallWorkItems(const InstallationState& original_state, AddProductSpecificWorkItems(original_state, installer_state, setup_path, new_version, install_list); - AddGoogleUpdateWorkItems(installer_state, install_list); + AddGoogleUpdateWorkItems(original_state, installer_state, install_list); AddQuickEnableWorkItems(installer_state, original_state, &setup_path, &new_version, install_list); diff --git a/chrome/installer/setup/install_worker.h b/chrome/installer/setup/install_worker.h index 414510d..9df76d8 100644 --- a/chrome/installer/setup/install_worker.h +++ b/chrome/installer/setup/install_worker.h @@ -34,7 +34,8 @@ class Product; // In the multi-install case, this value is used as the basis upon which the // package's channel value is built (by adding the ordered list of installed // products and their options). -void AddGoogleUpdateWorkItems(const InstallerState& installer_state, +void AddGoogleUpdateWorkItems(const InstallationState& original_state, + const InstallerState& installer_state, WorkItemList* install_list); // After a successful copying of all the files, this function is called to diff --git a/chrome/installer/setup/install_worker_unittest.cc b/chrome/installer/setup/install_worker_unittest.cc index ea040b1..b2fca07 100644 --- a/chrome/installer/setup/install_worker_unittest.cc +++ b/chrome/installer/setup/install_worker_unittest.cc @@ -10,6 +10,7 @@ #include "chrome/installer/util/delete_reg_key_work_item.h" #include "chrome/installer/util/create_reg_key_work_item.h" #include "chrome/installer/util/helper.h" +#include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/installation_state.h" #include "chrome/installer/util/installer_state.h" #include "chrome/installer/util/set_reg_value_work_item.h" @@ -26,6 +27,7 @@ using installer::ProductState; using ::testing::_; using ::testing::AtLeast; +using ::testing::HasSubstr; using ::testing::AtMost; using ::testing::Eq; using ::testing::Return; @@ -91,6 +93,7 @@ class MockProductState : public ProductState { // Takes ownership of |version|. void set_version(Version* version) { version_.reset(version); } void set_multi_install(bool multi) { multi_install_ = multi; } + void set_brand(const std::wstring& brand) { brand_ = brand; } void SetUninstallProgram(const FilePath& setup_exe) { uninstall_command_ = CommandLine(setup_exe); } @@ -125,6 +128,10 @@ class MockInstallerState : public InstallerState { state_key_ = state_key; } + void set_state_type(BrowserDistribution::Type state_type) { + state_type_ = state_type; + } + void set_package_type(PackageType type) { InstallerState::set_package_type(type); } @@ -163,6 +170,7 @@ class InstallWorkerTest : public testing::Test { MockProductState product_state; product_state.set_version(current_version_->Clone()); product_state.set_multi_install(multi_install); + product_state.set_brand(L"TEST"); BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_BROWSER); @@ -243,6 +251,7 @@ class InstallWorkerTest : public testing::Test { installer_state->set_operation(operation); // Hope this next one isn't checked for now. installer_state->set_state_key(L"PROBABLY_INVALID_REG_PATH"); + installer_state->set_state_type(BrowserDistribution::CHROME_BROWSER); installer_state->set_package_type(multi_install ? InstallerState::MULTI_PACKAGE : InstallerState::SINGLE_PACKAGE); @@ -349,7 +358,7 @@ TEST_F(InstallWorkerTest, TestInstallChromeSingleSystem) { // Set up some expectations. // TODO(robertshield): Set up some real expectations. - EXPECT_CALL(work_item_list, AddCopyTreeWorkItem(_,_,_,_,_)) + EXPECT_CALL(work_item_list, AddCopyTreeWorkItem(_, _, _, _, _)) .Times(AtLeast(1)); AddInstallWorkItems(*installation_state.get(), @@ -447,7 +456,6 @@ TEST_F(InstallWorkerTest, ElevationPolicyUninstall) { TEST_F(InstallWorkerTest, ElevationPolicySingleNoop) { const bool system_level = true; - const HKEY root = HKEY_LOCAL_MACHINE; const bool multi_install = false; // nothing should be done for single. MockWorkItemList work_item_list; @@ -474,7 +482,6 @@ TEST_F(InstallWorkerTest, ElevationPolicySingleNoop) { TEST_F(InstallWorkerTest, ElevationPolicyExistingSingleCFNoop) { const bool system_level = true; - const HKEY root = HKEY_LOCAL_MACHINE; const bool multi_install = true; MockWorkItemList work_item_list; @@ -506,6 +513,55 @@ TEST_F(InstallWorkerTest, ElevationPolicyExistingSingleCFNoop) { &work_item_list); } +TEST_F(InstallWorkerTest, GoogleUpdateWorkItemsTest) { + const bool system_level = true; + const bool multi_install = true; + MockWorkItemList work_item_list; + + scoped_ptr<MockInstallationState> installation_state( + BuildChromeInstallationState(system_level, multi_install)); + + MockProductState cf_state; + cf_state.set_version(current_version_->Clone()); + cf_state.set_multi_install(false); + + installation_state->SetProductState(system_level, + BrowserDistribution::CHROME_FRAME, cf_state); + + scoped_ptr<MockInstallerState> installer_state( + BuildChromeInstallerState(system_level, multi_install, + *installation_state, + InstallerState::MULTI_INSTALL)); + + // Expect the multi Client State key to be created. + BrowserDistribution* multi_dist = + BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_BINARIES); + std::wstring multi_app_guid(multi_dist->GetAppGuid()); + EXPECT_CALL(work_item_list, + AddCreateRegKeyWorkItem(_, HasSubstr(multi_app_guid))).Times(1); + + // Expect to see a set value for the "TEST" brand code in the multi Client + // State key. + EXPECT_CALL(work_item_list, + AddSetRegStringValueWorkItem(_, + HasSubstr(multi_app_guid), + StrEq(google_update::kRegBrandField), + StrEq(L"TEST"), + _)).Times(1); + + // There may also be some calls to set 'ap' values. + EXPECT_CALL(work_item_list, + AddSetRegStringValueWorkItem(_, _, + StrEq(google_update::kRegApField), + _, _)).Times(testing::AnyNumber()); + + AddGoogleUpdateWorkItems(*installation_state.get(), + *installer_state.get(), + &work_item_list); +} + + // Test scenarios under which the quick-enable-cf command should not exist after // the run. We're permissive in that we allow the DeleteRegKeyWorkItem even if // it isn't strictly needed. diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index b8a841d..e6df28a 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -250,16 +250,17 @@ bool CheckMultiInstallConditions(const InstallationState& original_state, original_state.GetProductState(system_level, BrowserDistribution::CHROME_BROWSER); if (chrome_state != NULL) { - base::win::RegKey key; - installer::ChannelInfo cf_channel; - // Chrome Frame may not yet be installed, so peek into the registry - // directly to see what channel Google Update has specified. There will - // be no value if we're not being managed by Google Update. - if (key.Open(installer_state->root_key(), - chrome_frame->distribution()->GetStateKey().c_str(), - KEY_QUERY_VALUE) == ERROR_SUCCESS) { - cf_channel.Initialize(key); - } + // Chrome Frame may not yet be installed if this is a first install, so + // use InstallationState's GetNonVersionedProductState() which will lets + // us access the ap value from the partially constructed product state. + // There will be no value if we're not being managed by Google Update. + const ProductState* cf_non_versioned_state = + original_state.GetNonVersionedProductState( + system_level, BrowserDistribution::CHROME_FRAME); + DCHECK(cf_non_versioned_state); + const installer::ChannelInfo& cf_channel( + cf_non_versioned_state->channel()); + // Fail if Chrome is already installed but is on a different update // channel. if (!cf_channel.EqualsBaseOf(chrome_state->channel())) { diff --git a/chrome/installer/util/google_update_constants.cc b/chrome/installer/util/google_update_constants.cc index d3ac0fe..a8fec38 100644 --- a/chrome/installer/util/google_update_constants.cc +++ b/chrome/installer/util/google_update_constants.cc @@ -17,6 +17,7 @@ const wchar_t kRegPathClientStateMedium[] const wchar_t kRegCommandsKey[] = L"Commands"; const wchar_t kRegApField[] = L"ap"; +const wchar_t kRegBrandField[] = L"brand"; const wchar_t kRegBrowserField[] = L"browser"; const wchar_t kRegCFEndTempOptOutCmdField[] = L"CFEndTempOptOutCmd"; const wchar_t kRegCFOptInCmdField[] = L"CFOptInCmd"; diff --git a/chrome/installer/util/google_update_constants.h b/chrome/installer/util/google_update_constants.h index 825fcbd..4ed18af 100644 --- a/chrome/installer/util/google_update_constants.h +++ b/chrome/installer/util/google_update_constants.h @@ -30,6 +30,7 @@ extern const wchar_t kRegPathClientStateMedium[]; extern const wchar_t kRegCommandsKey[]; extern const wchar_t kRegApField[]; +extern const wchar_t kRegBrandField[]; extern const wchar_t kRegBrowserField[]; extern const wchar_t kRegCFEndTempOptOutCmdField[]; extern const wchar_t kRegCFOptInCmdField[]; diff --git a/chrome/installer/util/installation_state.cc b/chrome/installer/util/installation_state.cc index 4d315ff..5d2ab89 100644 --- a/chrome/installer/util/installation_state.cc +++ b/chrome/installer/util/installation_state.cc @@ -33,6 +33,12 @@ bool ProductState::InitializeCommands(const base::win::RegKey& version_key, static const DWORD kAccess = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE; base::win::RegKey commands_key; + if (!version_key.Valid()) { + // Version key may be invalid if we're not running under Google Update. + LOG(WARNING) << "Could not InitializeCommands, version_key is invalid."; + return false; + } + if (commands_key.Open(version_key.Handle(), google_update::kRegCommandsKey, kAccess) == ERROR_SUCCESS) return commands->Initialize(commands_key); @@ -49,53 +55,60 @@ bool ProductState::Initialize(bool system_install, if (key.ReadValue(google_update::kRegVersionField, &version_str) == ERROR_SUCCESS) { version_.reset(Version::GetVersionFromString(WideToASCII(version_str))); - if (version_.get() != NULL) { - // The product is installed. - if (key.ReadValue(google_update::kRegOldVersionField, - &version_str) == ERROR_SUCCESS) { - old_version_.reset( - Version::GetVersionFromString(WideToASCII(version_str))); - } else { - old_version_.reset(); - } - if (key.ReadValue(google_update::kRegRenameCmdField, - &rename_cmd_) != ERROR_SUCCESS) - rename_cmd_.clear(); - if (!InitializeCommands(key, &commands_)) - commands_.Clear(); - // Read from the ClientState key. - channel_.set_value(std::wstring()); - uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM); - msi_ = false; - multi_install_ = false; - if (key.Open(root_key, state_key.c_str(), - KEY_QUERY_VALUE) == ERROR_SUCCESS) { - std::wstring setup_path; - std::wstring uninstall_arguments; - // "ap" will be absent if not managed by Google Update. - channel_.Initialize(key); - // "UninstallString" will be absent for the multi-installer package. - key.ReadValue(kUninstallStringField, &setup_path); - // "UninstallArguments" will be absent for the multi-installer package. - key.ReadValue(kUninstallArgumentsField, &uninstall_arguments); - InstallUtil::MakeUninstallCommand(setup_path, uninstall_arguments, - &uninstall_command_); - // "msi" may be absent, 0 or 1 - DWORD dw_value = 0; - msi_ = (key.ReadValueDW(google_update::kRegMSIField, - &dw_value) == ERROR_SUCCESS) && (dw_value != 0); - // Multi-install is implied or is derived from the command-line. - if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES) { - multi_install_ = true; - } else { - multi_install_ = uninstall_command_.HasSwitch( - switches::kMultiInstall); - } - } + } + + // Attempt to read the other values even if the "pv" version value was absent. + // Note that ProductState instances containing these values will only be + // accessible via InstallationState::GetNonVersionedProductState. + if (key.ReadValue(google_update::kRegOldVersionField, + &version_str) == ERROR_SUCCESS) { + old_version_.reset( + Version::GetVersionFromString(WideToASCII(version_str))); + } + + if (key.ReadValue(google_update::kRegRenameCmdField, + &rename_cmd_) != ERROR_SUCCESS) + rename_cmd_.clear(); + + if (!InitializeCommands(key, &commands_)) + commands_.Clear(); + + // Read from the ClientState key. + channel_.set_value(std::wstring()); + uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM); + brand_.clear(); + msi_ = false; + multi_install_ = false; + if (key.Open(root_key, state_key.c_str(), + KEY_QUERY_VALUE) == ERROR_SUCCESS) { + std::wstring setup_path; + std::wstring uninstall_arguments; + // "ap" will be absent if not managed by Google Update. + channel_.Initialize(key); + + // Read in the brand code, it may be absent + key.ReadValue(google_update::kRegBrandField, &brand_); + + // "UninstallString" will be absent for the multi-installer package. + key.ReadValue(kUninstallStringField, &setup_path); + // "UninstallArguments" will be absent for the multi-installer package. + key.ReadValue(kUninstallArgumentsField, &uninstall_arguments); + InstallUtil::MakeUninstallCommand(setup_path, uninstall_arguments, + &uninstall_command_); + + // "msi" may be absent, 0 or 1 + DWORD dw_value = 0; + msi_ = (key.ReadValueDW(google_update::kRegMSIField, + &dw_value) == ERROR_SUCCESS) && (dw_value != 0); + // Multi-install is implied or is derived from the command-line. + if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES) { + multi_install_ = true; + } else { + multi_install_ = uninstall_command_.HasSwitch( + switches::kMultiInstall); } - } else { - version_.reset(); } + return version_.get() != NULL; } @@ -113,6 +126,7 @@ ProductState& ProductState::CopyFrom(const ProductState& other) { version_.reset(other.version_.get() == NULL ? NULL : other.version_->Clone()); old_version_.reset( other.old_version_.get() == NULL ? NULL : other.old_version_->Clone()); + brand_ = other.brand_; rename_cmd_ = other.rename_cmd_; uninstall_command_ = other.uninstall_command_; commands_.CopyFrom(other.commands_); @@ -158,12 +172,19 @@ void InstallationState::Initialize() { system_products_[CHROME_BINARIES_INDEX].Initialize(true, distribution); } -const ProductState* InstallationState::GetProductState( +const ProductState* InstallationState::GetNonVersionedProductState( bool system_install, BrowserDistribution::Type type) const { const ProductState& product_state = (system_install ? system_products_ : user_products_)[IndexFromDistType(type)]; - return product_state.version_.get() == NULL ? NULL : &product_state; + return &product_state; } +const ProductState* InstallationState::GetProductState( + bool system_install, + BrowserDistribution::Type type) const { + const ProductState* product_state = + GetNonVersionedProductState(system_install, type); + return product_state->version_.get() == NULL ? NULL : product_state; +} } // namespace installer diff --git a/chrome/installer/util/installation_state.h b/chrome/installer/util/installation_state.h index a63627c..a623992 100644 --- a/chrome/installer/util/installation_state.h +++ b/chrome/installer/util/installation_state.h @@ -58,6 +58,9 @@ class ProductState { // caller. const Version* old_version() const { return old_version_.get(); } + // Returns the brand code the product is currently installed with. + const std::wstring& brand() const { return brand_; } + // Returns the command to be used to update to the new version that is // awaiting update; may be empty. const std::wstring& rename_cmd() const { return rename_cmd_; } @@ -84,6 +87,7 @@ class ProductState { ChannelInfo channel_; scoped_ptr<Version> version_; scoped_ptr<Version> old_version_; + std::wstring brand_; std::wstring rename_cmd_; CommandLine uninstall_command_; AppCommands commands_; @@ -110,6 +114,16 @@ class InstallationState { const ProductState* GetProductState(bool system_install, BrowserDistribution::Type type) const; + // Returns the state of a product, even one that has not yet been installed. + // This is useful during first install, when some but not all ProductState + // information has been written by Omaha. Notably absent from the + // ProductState returned here are the version numbers. Do NOT try to access + // the version numbers from a ProductState returned by this method. + // Caller does NOT assume ownership of returned pointer. This method will + // never return NULL. + const ProductState* GetNonVersionedProductState( + bool system_install, BrowserDistribution::Type type) const; + protected: enum { CHROME_BROWSER_INDEX, diff --git a/chrome/installer/util/installation_validator_unittest.cc b/chrome/installer/util/installation_validator_unittest.cc index 4992dc76a..619238e 100644 --- a/chrome/installer/util/installation_validator_unittest.cc +++ b/chrome/installer/util/installation_validator_unittest.cc @@ -148,6 +148,7 @@ void FakeProductState::Clear() { channel_.set_value(std::wstring()); version_.reset(); old_version_.reset(); + brand_.clear(); rename_cmd_.clear(); uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM); commands_.Clear(); diff --git a/chrome/installer/util/installer_state.cc b/chrome/installer/util/installer_state.cc index 65bc51e..df2da8d 100644 --- a/chrome/installer/util/installer_state.cc +++ b/chrome/installer/util/installer_state.cc @@ -69,6 +69,7 @@ InstallerState::InstallerState() multi_package_distribution_(NULL), level_(UNKNOWN_LEVEL), package_type_(UNKNOWN_PACKAGE_TYPE), + state_type_(BrowserDistribution::CHROME_BROWSER), root_key_(NULL), msi_(false), verbose_logging_(false) { @@ -79,6 +80,7 @@ InstallerState::InstallerState(Level level) multi_package_distribution_(NULL), level_(UNKNOWN_LEVEL), package_type_(UNKNOWN_PACKAGE_TYPE), + state_type_(BrowserDistribution::CHROME_BROWSER), root_key_(NULL), msi_(false), verbose_logging_(false) { @@ -149,6 +151,7 @@ void InstallerState::Initialize(const CommandLine& command_line, } state_key_ = operand->GetStateKey(); + state_type_ = operand->GetType(); } void InstallerState::set_level(Level level) { diff --git a/chrome/installer/util/installer_state.h b/chrome/installer/util/installer_state.h index 05b8626..8a2dbea 100644 --- a/chrome/installer/util/installer_state.h +++ b/chrome/installer/util/installer_state.h @@ -122,6 +122,10 @@ class InstallerState { // The ClientState key by which we interact with Google Update. const std::wstring& state_key() const { return state_key_; } + // Convenience method to return the type of the BrowserDistribution associated + // with the ClientState key we will be interacting with. + BrowserDistribution::Type state_type() const { return state_type_; } + // Returns the BrowserDistribution instance corresponding to the binaries for // this run if we're operating on a multi-package product. BrowserDistribution* multi_package_binaries_distribution() const { @@ -176,6 +180,7 @@ class InstallerState { Operation operation_; FilePath target_path_; std::wstring state_key_; + BrowserDistribution::Type state_type_; ScopedVector<Product> products_; BrowserDistribution* multi_package_distribution_; Level level_; diff --git a/chrome/installer/util/work_item_list.cc b/chrome/installer/util/work_item_list.cc index 958d478..e3ccc32 100644 --- a/chrome/installer/util/work_item_list.cc +++ b/chrome/installer/util/work_item_list.cc @@ -94,7 +94,7 @@ WorkItem* WorkItemList::AddCreateDirWorkItem(const FilePath& path) { } WorkItem* WorkItemList::AddCreateRegKeyWorkItem(HKEY predefined_root, - const std::wstring& path) { + const std::wstring& path) { WorkItem* item = WorkItem::CreateCreateRegKeyWorkItem(predefined_root, path); AddWorkItem(item); return item; |