diff options
author | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-12 21:21:18 +0000 |
---|---|---|
committer | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-12 21:21:18 +0000 |
commit | 5ac8aff8fd32ece193f0eb12f89a90599186ea13 (patch) | |
tree | c25cb22ccb09cea9ba22cc238a9916f5658186ce /chrome/installer/setup | |
parent | 6eac57a601d0f2e88390609b5716c08eb5f19b73 (diff) | |
download | chromium_src-5ac8aff8fd32ece193f0eb12f89a90599186ea13.zip chromium_src-5ac8aff8fd32ece193f0eb12f89a90599186ea13.tar.gz chromium_src-5ac8aff8fd32ece193f0eb12f89a90599186ea13.tar.bz2 |
Handle eulaaccepted and oeminstall mo betta for multi-install. During first install, these values (deposited by Google Update) are now mirrored from the product-specific ClientState key into the binaries' key. When the EULA is accepted, the modification is written to both the product's and binaries' ClientStateMedium key. As a result, multi-install OEM installs will start updating only when the EULA is accepted (as desired) and the EVENT_INSTALL_OEM_FIRST_CHECK ping is sent for both the product and the binaries.
BUG=88584
TEST=see bug
R=robertshield@chromium.org
Review URL: http://codereview.chromium.org/7346011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92234 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/setup')
-rw-r--r-- | chrome/installer/setup/install_worker.cc | 128 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.h | 12 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker_unittest.cc | 39 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 13 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 9 |
5 files changed, 175 insertions, 26 deletions
diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc index 552d39f..94c191c 100644 --- a/chrome/installer/setup/install_worker.cc +++ b/chrome/installer/setup/install_worker.cc @@ -250,6 +250,106 @@ void AddProductSpecificWorkItems(const InstallationState& original_state, } } +// Mirror oeminstall the first time anything is installed multi. There is no +// need to update the value on future install/update runs since this value never +// changes. Note that the value is removed by Google Update after EULA +// acceptance is processed. +void AddOemInstallWorkItems(const InstallationState& original_state, + const InstallerState& installer_state, + WorkItemList* install_list) { + DCHECK(installer_state.is_multi_install()); + const bool system_install = installer_state.system_install(); + if (!original_state.GetProductState(system_install, + BrowserDistribution::CHROME_BINARIES)) { + const HKEY root_key = installer_state.root_key(); + std::wstring multi_key( + installer_state.multi_package_binaries_distribution()->GetStateKey()); + + // Copy the value from Chrome unless Chrome isn't installed or being + // installed. + BrowserDistribution::Type source_type; + if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER)) { + source_type = BrowserDistribution::CHROME_BROWSER; + } else if (!installer_state.products().empty()) { + // Pick a product, any product. + source_type = installer_state.products()[0]->distribution()->GetType(); + } else { + // Nothing is being installed? Entirely unexpected, so do no harm. + LOG(ERROR) << "No products found in AddOemInstallWorkItems"; + return; + } + const ProductState* source_product = + original_state.GetNonVersionedProductState(system_install, source_type); + + std::wstring oem_install; + if (source_product->GetOemInstall(&oem_install)) { + VLOG(1) << "Mirroring oeminstall=\"" << oem_install << "\" from " + << BrowserDistribution::GetSpecificDistribution(source_type) + ->GetAppShortCutName(); + install_list->AddCreateRegKeyWorkItem(root_key, multi_key); + // Always overwrite an old value. + install_list->AddSetRegValueWorkItem(root_key, multi_key, + google_update::kRegOemInstallField, + oem_install, true); + } else { + // Clear any old value. + install_list->AddDeleteRegValueWorkItem( + root_key, multi_key, google_update::kRegOemInstallField); + } + } +} + +// Mirror eulaaccepted the first time anything is installed multi. There is no +// need to update the value on future install/update runs since +// GoogleUpdateSettings::SetEULAConsent will modify the value for both the +// relevant product and for the binaries. +void AddEulaAcceptedWorkItems(const InstallationState& original_state, + const InstallerState& installer_state, + WorkItemList* install_list) { + DCHECK(installer_state.is_multi_install()); + const bool system_install = installer_state.system_install(); + if (!original_state.GetProductState(system_install, + BrowserDistribution::CHROME_BINARIES)) { + const HKEY root_key = installer_state.root_key(); + std::wstring multi_key( + installer_state.multi_package_binaries_distribution()->GetStateKey()); + + // Copy the value from the product with the greatest value. + bool have_eula_accepted = false; + BrowserDistribution::Type product_type; + DWORD eula_accepted; + const Products& products = installer_state.products(); + for (size_t i = 0, count = products.size(); i != count; ++i) { + DWORD dword_value = 0; + BrowserDistribution::Type this_type = + products[i]->distribution()->GetType(); + const ProductState* product_state = + original_state.GetNonVersionedProductState( + system_install, this_type); + if (product_state->GetEulaAccepted(&dword_value) && + (!have_eula_accepted || dword_value > eula_accepted)) { + have_eula_accepted = true; + eula_accepted = dword_value; + product_type = this_type; + } + } + + if (have_eula_accepted) { + VLOG(1) << "Mirroring eulaaccepted=" << eula_accepted << " from " + << BrowserDistribution::GetSpecificDistribution(product_type) + ->GetAppShortCutName(); + install_list->AddCreateRegKeyWorkItem(root_key, multi_key); + install_list->AddSetRegValueWorkItem( + root_key, multi_key, google_update::kRegEULAAceptedField, + eula_accepted, true); + } else { + // Clear any old value. + install_list->AddDeleteRegValueWorkItem( + root_key, multi_key, google_update::kRegEULAAceptedField); + } + } +} + // Adds work items that make registry adjustments for Google Update. void AddGoogleUpdateWorkItems(const InstallationState& original_state, const InstallerState& installer_state, @@ -261,24 +361,34 @@ void AddGoogleUpdateWorkItems(const InstallationState& original_state, return; } + const bool system_install = installer_state.system_install(); + const HKEY root_key = installer_state.root_key(); + std::wstring multi_key( + installer_state.multi_package_binaries_distribution()->GetStateKey()); + + // For system-level installs, make sure the ClientStateMedium key for the + // binaries exists. + if (system_install) { + install_list->AddCreateRegKeyWorkItem( + root_key, + installer_state.multi_package_binaries_distribution()-> + GetStateMediumKey().c_str()); + } + // 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 (installer_state.state_type() != BrowserDistribution::CHROME_BINARIES) { - std::wstring multi_key( - installer_state.multi_package_binaries_distribution()->GetStateKey()); const ProductState* chrome_product_state = original_state.GetNonVersionedProductState( - installer_state.system_install(), - BrowserDistribution::CHROME_BROWSER); + system_install, BrowserDistribution::CHROME_BROWSER); const std::wstring& brand(chrome_product_state->brand()); if (!brand.empty()) { - install_list->AddCreateRegKeyWorkItem(installer_state.root_key(), - multi_key); + install_list->AddCreateRegKeyWorkItem(root_key, multi_key); // 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(installer_state.root_key(), + install_list->AddSetRegValueWorkItem(root_key, multi_key, google_update::kRegBrandField, brand, @@ -286,6 +396,10 @@ void AddGoogleUpdateWorkItems(const InstallationState& original_state, } } + AddOemInstallWorkItems(original_state, installer_state, install_list); + + AddEulaAcceptedWorkItems(original_state, installer_state, install_list); + AddUsageStatsWorkItems(original_state, installer_state, install_list); // TODO(grt): check for other keys/values we should put in the package's diff --git a/chrome/installer/setup/install_worker.h b/chrome/installer/setup/install_worker.h index 7e4e19f..82a4901 100644 --- a/chrome/installer/setup/install_worker.h +++ b/chrome/installer/setup/install_worker.h @@ -28,8 +28,18 @@ class InstallerState; class Package; class Product; +// Helper function for AddGoogleUpdateWorkItems that mirrors oeminstall. +void AddOemInstallWorkItems(const InstallationState& original_state, + const InstallerState& installer_state, + WorkItemList* install_list); + +// Helper function for AddGoogleUpdateWorkItems that mirrors eulaaccepted. +void AddEulaAcceptedWorkItems(const InstallationState& original_state, + const InstallerState& installer_state, + WorkItemList* install_list); + // Adds work items that make registry adjustments for Google Update; namely, -// copy a brand value and move a usagestats value. +// copy brand, oeminstall, and eulaaccepted values; and move a usagestats value. void AddGoogleUpdateWorkItems(const InstallationState& original_state, const InstallerState& installer_state, WorkItemList* install_list); diff --git a/chrome/installer/setup/install_worker_unittest.cc b/chrome/installer/setup/install_worker_unittest.cc index 4a99174..67ef806 100644 --- a/chrome/installer/setup/install_worker_unittest.cc +++ b/chrome/installer/setup/install_worker_unittest.cc @@ -93,11 +93,21 @@ class MockProductState : public ProductState { 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 set_eula_accepted(DWORD eula_accepted) { + has_eula_accepted_ = true; + eula_accepted_ = eula_accepted; + } + void clear_eula_accepted() { has_eula_accepted_ = false; } void set_usagestats(DWORD usagestats) { has_usagestats_ = true; usagestats_ = usagestats; } void clear_usagestats() { has_usagestats_ = false; } + void set_oem_install(const std::wstring& oem_install) { + has_oem_install_ = true; + oem_install_ = oem_install; + } + void clear_oem_install() { has_oem_install_ = false; } void SetUninstallProgram(const FilePath& setup_exe) { uninstall_command_ = CommandLine(setup_exe); } @@ -175,6 +185,7 @@ class InstallWorkerTest : public testing::Test { product_state.set_version(current_version_->Clone()); product_state.set_multi_install(multi_install); product_state.set_brand(L"TEST"); + product_state.set_eula_accepted(1); BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_BROWSER); @@ -543,14 +554,22 @@ TEST_F(InstallWorkerTest, GoogleUpdateWorkItemsTest) { BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_BINARIES); std::wstring multi_app_guid(multi_dist->GetAppGuid()); + std::wstring multi_client_state_suffix(L"ClientState\\" + multi_app_guid); EXPECT_CALL(work_item_list, - AddCreateRegKeyWorkItem(_, HasSubstr(multi_app_guid))).Times(1); + AddCreateRegKeyWorkItem(_, HasSubstr(multi_client_state_suffix))) + .Times(testing::AnyNumber()); + + // Expect ClientStateMedium to be created for system-level installs. + EXPECT_CALL(work_item_list, + AddCreateRegKeyWorkItem(_, HasSubstr(L"ClientStateMedium\\" + + multi_app_guid))) + .Times(system_level ? 1 : 0); // 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), + HasSubstr(multi_client_state_suffix), StrEq(google_update::kRegBrandField), StrEq(L"TEST"), _)).Times(1); @@ -561,6 +580,22 @@ TEST_F(InstallWorkerTest, GoogleUpdateWorkItemsTest) { StrEq(google_update::kRegApField), _, _)).Times(testing::AnyNumber()); + // Expect "oeminstall" to be cleared. + EXPECT_CALL(work_item_list, + AddDeleteRegValueWorkItem( + _, + HasSubstr(multi_client_state_suffix), + StrEq(google_update::kRegOemInstallField))).Times(1); + + // Expect "eulaaccepted" to set. + EXPECT_CALL(work_item_list, + AddSetRegDwordValueWorkItem( + _, + HasSubstr(multi_client_state_suffix), + StrEq(google_update::kRegEULAAceptedField), + Eq(static_cast<DWORD>(1)), + _)).Times(1); + AddGoogleUpdateWorkItems(*installation_state.get(), *installer_state.get(), &work_item_list); diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 7affe54..cbd6e33 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -147,14 +147,8 @@ DWORD UnPackArchive(const FilePath& archive, void AddExistingMultiInstalls(const InstallationState& original_state, InstallerState* installer_state) { if (installer_state->is_multi_install()) { - // TODO(grt): Find all occurrences of such arrays and generalize/centralize. - static const BrowserDistribution::Type product_checks[] = { - BrowserDistribution::CHROME_BROWSER, - BrowserDistribution::CHROME_FRAME - }; - - for (size_t i = 0; i < arraysize(product_checks); ++i) { - BrowserDistribution::Type type = product_checks[i]; + for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) { + BrowserDistribution::Type type = BrowserDistribution::kProductTypes[i]; if (!installer_state->FindProduct(type)) { const ProductState* state = original_state.GetProductState(installer_state->system_install(), @@ -347,7 +341,6 @@ bool CheckMultiInstallConditions(const InstallationState& original_state, const Products& products = installer_state->products(); DCHECK(products.size()); - bool is_first_install = true; const bool system_level = installer_state->system_install(); if (installer_state->is_multi_install()) { @@ -899,7 +892,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, cmd_line.GetSwitchValueNative(installer::switches::kShowEula); *exit_code = ShowEULADialog(inner_frame); if (installer::EULA_REJECTED != *exit_code) - GoogleUpdateSettings::SetEULAConsent(*installer_state, true); + GoogleUpdateSettings::SetEULAConsent(original_state, true); } else if (cmd_line.HasSwitch( installer::switches::kRegisterChromeBrowser)) { installer::InstallStatus status = installer::UNKNOWN_STATUS; diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index c2200ba..56f2bdd 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -801,13 +801,10 @@ InstallStatus UninstallProduct(const InstallationState& original_state, bool can_delete_files = true; if (installer_state.is_multi_install()) { - BrowserDistribution::Type types[] = { - BrowserDistribution::CHROME_BROWSER, - BrowserDistribution::CHROME_FRAME - }; ProductState prod_state; - for (int i = 0; i < arraysize(types); ++i) { - if (prod_state.Initialize(installer_state.system_install(), types[i]) && + for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) { + if (prod_state.Initialize(installer_state.system_install(), + BrowserDistribution::kProductTypes[i]) && prod_state.is_multi_install()) { can_delete_files = false; break; |