summaryrefslogtreecommitdiffstats
path: root/chrome/installer
diff options
context:
space:
mode:
authorgrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-12 21:21:18 +0000
committergrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-12 21:21:18 +0000
commit5ac8aff8fd32ece193f0eb12f89a90599186ea13 (patch)
treec25cb22ccb09cea9ba22cc238a9916f5658186ce /chrome/installer
parent6eac57a601d0f2e88390609b5716c08eb5f19b73 (diff)
downloadchromium_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')
-rw-r--r--chrome/installer/setup/install_worker.cc128
-rw-r--r--chrome/installer/setup/install_worker.h12
-rw-r--r--chrome/installer/setup/install_worker_unittest.cc39
-rw-r--r--chrome/installer/setup/setup_main.cc13
-rw-r--r--chrome/installer/setup/uninstall.cc9
-rw-r--r--chrome/installer/util/browser_distribution.cc10
-rw-r--r--chrome/installer/util/browser_distribution.h10
-rw-r--r--chrome/installer/util/browser_distribution_unittest.cc12
-rw-r--r--chrome/installer/util/google_update_constants.cc1
-rw-r--r--chrome/installer/util/google_update_constants.h1
-rw-r--r--chrome/installer/util/google_update_settings.cc75
-rw-r--r--chrome/installer/util/google_update_settings.h4
-rw-r--r--chrome/installer/util/google_update_settings_unittest.cc54
-rw-r--r--chrome/installer/util/installation_state.cc48
-rw-r--r--chrome/installer/util/installation_state.h21
15 files changed, 314 insertions, 123 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;
diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc
index ce4d1c6..535797a 100644
--- a/chrome/installer/util/browser_distribution.cc
+++ b/chrome/installer/util/browser_distribution.cc
@@ -54,6 +54,16 @@ BrowserDistribution::Type GetCurrentDistributionType() {
} // end namespace
+// CHROME_BINARIES represents the binaries shared by multi-install products and
+// is not a product in and of itself, so it is not present in this collection.
+const BrowserDistribution::Type BrowserDistribution::kProductTypes[] = {
+ BrowserDistribution::CHROME_BROWSER,
+ BrowserDistribution::CHROME_FRAME,
+};
+
+const size_t BrowserDistribution::kNumProductTypes =
+ arraysize(BrowserDistribution::kProductTypes);
+
BrowserDistribution::BrowserDistribution()
: type_(CHROME_BROWSER) {
}
diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h
index fa0c9d6..6d92501 100644
--- a/chrome/installer/util/browser_distribution.h
+++ b/chrome/installer/util/browser_distribution.h
@@ -30,8 +30,6 @@ class Product;
class BrowserDistribution {
public:
- virtual ~BrowserDistribution() {}
-
enum Type {
CHROME_BROWSER,
CHROME_FRAME,
@@ -52,6 +50,14 @@ class BrowserDistribution {
// experiment but does not participate.
};
+ // An array of the Types representing products;
+ static const Type kProductTypes[];
+
+ // The number of elements in the array |kProductTypes|.
+ static const size_t kNumProductTypes;
+
+ virtual ~BrowserDistribution() {}
+
static BrowserDistribution* GetDistribution();
static BrowserDistribution* GetSpecificDistribution(Type type);
diff --git a/chrome/installer/util/browser_distribution_unittest.cc b/chrome/installer/util/browser_distribution_unittest.cc
index 61c9652..942f62c 100644
--- a/chrome/installer/util/browser_distribution_unittest.cc
+++ b/chrome/installer/util/browser_distribution_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -24,14 +24,10 @@ class BrowserDistributionTest : public testing::Test {
// The distribution strings should not be empty. The unit tests are not linking
// with the chrome resources so we cannot test official build.
TEST(BrowserDistributionTest, StringsTest) {
- BrowserDistribution::Type browser_tests[] = {
- BrowserDistribution::CHROME_BROWSER,
- BrowserDistribution::CHROME_FRAME,
- };
-
- for (int i = 0; i < arraysize(browser_tests); ++i) {
+ for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) {
BrowserDistribution* dist =
- BrowserDistribution::GetSpecificDistribution(browser_tests[i]);
+ BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::kProductTypes[i]);
ASSERT_TRUE(dist != NULL);
std::wstring name = dist->GetApplicationName();
EXPECT_FALSE(name.empty());
diff --git a/chrome/installer/util/google_update_constants.cc b/chrome/installer/util/google_update_constants.cc
index 1380cc5..96204cd 100644
--- a/chrome/installer/util/google_update_constants.cc
+++ b/chrome/installer/util/google_update_constants.cc
@@ -32,6 +32,7 @@ const wchar_t kRegLastRunTimeField[] = L"lastrun";
const wchar_t kRegMetricsId[] = L"metricsid";
const wchar_t kRegMSIField[] = L"msi";
const wchar_t kRegNameField[] = L"name";
+const wchar_t kRegOemInstallField[] = L"oeminstall";
const wchar_t kRegOldVersionField[] = L"opv";
const wchar_t kRegOopcrashesField[] = L"oopcrashes";
const wchar_t kRegRLZBrandField[] = L"brand";
diff --git a/chrome/installer/util/google_update_constants.h b/chrome/installer/util/google_update_constants.h
index 26106e8..5e78b77 100644
--- a/chrome/installer/util/google_update_constants.h
+++ b/chrome/installer/util/google_update_constants.h
@@ -41,6 +41,7 @@ extern const wchar_t kRegLastCheckedField[];
extern const wchar_t kRegMetricsId[];
extern const wchar_t kRegMSIField[];
extern const wchar_t kRegNameField[];
+extern const wchar_t kRegOemInstallField[];
extern const wchar_t kRegOldVersionField[];
extern const wchar_t kRegOopcrashesField[];
extern const wchar_t kRegRLZBrandField[];
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc
index 4572494..45234c2 100644
--- a/chrome/installer/util/google_update_settings.cc
+++ b/chrome/installer/util/google_update_settings.cc
@@ -18,11 +18,11 @@
#include "chrome/installer/util/channel_info.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/install_util.h"
-#include "chrome/installer/util/installer_state.h"
+#include "chrome/installer/util/installation_state.h"
#include "chrome/installer/util/product.h"
using base::win::RegKey;
-using installer::InstallerState;
+using installer::InstallationState;
namespace {
@@ -268,49 +268,44 @@ bool GoogleUpdateSettings::SetMetricsId(const std::wstring& metrics_id) {
return WriteGoogleUpdateStrKey(google_update::kRegMetricsId, metrics_id);
}
+// EULA consent is only relevant for system-level installs.
bool GoogleUpdateSettings::SetEULAConsent(
- const InstallerState& installer_state,
+ const InstallationState& machine_state,
bool consented) {
- // If this is a multi install, Google Update will have put eulaaccepted=0 into
- // the ClientState key of the multi-installer. Conduct a brief search for
- // this value and store the consent in the corresponding location.
- HKEY root = installer_state.root_key();
- EulaSearchResult status = NO_SETTING;
- std::wstring reg_path;
- std::wstring fallback_reg_path;
-
- if (installer_state.package_type() == InstallerState::MULTI_PACKAGE) {
- BrowserDistribution* binaries_dist =
- installer_state.multi_package_binaries_distribution();
- fallback_reg_path = reg_path = binaries_dist->GetStateMediumKey();
- status = HasEULASetting(root, binaries_dist->GetStateKey(), !consented);
+ const DWORD eula_accepted = consented ? 1 : 0;
+ // This magical method will return the right instance based on such details as
+ // whether or not --chrome-frame is present on the command-line.
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ std::wstring reg_path = dist->GetStateMediumKey();
+ bool succeeded = true;
+ RegKey key;
+
+ // Write the consent value into the product's ClientStateMedium key.
+ if (key.Create(HKEY_LOCAL_MACHINE, reg_path.c_str(),
+ KEY_SET_VALUE) != ERROR_SUCCESS ||
+ key.WriteValue(google_update::kRegEULAAceptedField,
+ eula_accepted) != ERROR_SUCCESS) {
+ succeeded = false;
}
- if (status != FOUND_SAME_SETTING) {
- EulaSearchResult new_status = NO_SETTING;
- installer::Products::const_iterator scan =
- installer_state.products().begin();
- installer::Products::const_iterator end =
- installer_state.products().end();
- for (; status != FOUND_SAME_SETTING && scan != end; ++scan) {
- if (fallback_reg_path.empty())
- fallback_reg_path = (*scan)->distribution()->GetStateMediumKey();
- new_status = HasEULASetting(root, (*scan)->distribution()->GetStateKey(),
- !consented);
- if (new_status > status) {
- status = new_status;
- reg_path = (*scan)->distribution()->GetStateMediumKey();
- }
- }
- if (status == NO_SETTING) {
- LOG(WARNING)
- << "eulaaccepted value not found; setting consent in key "
- << fallback_reg_path;
- reg_path = fallback_reg_path;
+
+ // If this is a multi-install, also write it into the binaries' key.
+ // --mutli-install is not provided on the command-line, so deduce it from
+ // the product's state.
+ const installer::ProductState* product_state =
+ machine_state.GetProductState(true, dist->GetType());
+ if (product_state != NULL && product_state->is_multi_install()) {
+ dist = BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BINARIES);
+ reg_path = dist->GetStateMediumKey();
+ if (key.Create(HKEY_LOCAL_MACHINE, reg_path.c_str(),
+ KEY_SET_VALUE) != ERROR_SUCCESS ||
+ key.WriteValue(google_update::kRegEULAAceptedField,
+ eula_accepted) != ERROR_SUCCESS) {
+ succeeded = false;
}
}
- RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_SET_VALUE);
- return (key.WriteValue(google_update::kRegEULAAceptedField,
- consented ? 1 : 0) == ERROR_SUCCESS);
+
+ return succeeded;
}
int GoogleUpdateSettings::GetLastRunTime() {
diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h
index 888ba73..7e37e79 100644
--- a/chrome/installer/util/google_update_settings.h
+++ b/chrome/installer/util/google_update_settings.h
@@ -13,7 +13,7 @@
namespace installer {
class ChannelInfo;
-class InstallerState;
+class InstallationState;
}
// This class provides accessors to the Google Update 'ClientState' information
@@ -46,7 +46,7 @@ class GoogleUpdateSettings {
// Sets the machine-wide EULA consented flag required on OEM installs.
// Returns false if the setting could not be recorded.
- static bool SetEULAConsent(const installer::InstallerState& installer_state,
+ static bool SetEULAConsent(const installer::InstallationState& machine_state,
bool consented);
// Returns the last time chrome was run in days. It uses a recorded value
diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc
index e27309d..aed09d5 100644
--- a/chrome/installer/util/google_update_settings_unittest.cc
+++ b/chrome/installer/util/google_update_settings_unittest.cc
@@ -5,20 +5,14 @@
#include <windows.h>
#include <shlwapi.h> // For SHDeleteKey.
-#include <functional>
-#include <map>
-
-#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/registry.h"
+#include "chrome/common/chrome_constants.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/channel_info.h"
+#include "chrome/installer/util/fake_installation_state.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/google_update_settings.h"
-#include "chrome/installer/util/installation_state.h"
-#include "chrome/installer/util/installer_state.h"
-#include "chrome/installer/util/master_preferences.h"
-#include "chrome/installer/util/product.h"
#include "chrome/installer/util/work_item_list.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -427,50 +421,36 @@ TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
}
TEST_F(GoogleUpdateSettingsTest, SetEULAConsent) {
+ using installer::FakeInstallationState;
+
const bool multi_install = true;
const bool system_level = true;
- CommandLine cmd_line = CommandLine::FromString(
- std::wstring(L"setup.exe") +
- (multi_install ? L" --multi-install --chrome" : L"") +
- (system_level ? L" --system-level" : L""));
- installer::MasterPreferences prefs(cmd_line);
- installer::InstallationState machine_state;
- machine_state.Initialize();
- installer::InstallerState installer_state;
- installer_state.Initialize(cmd_line, prefs, machine_state);
- HKEY root = installer_state.root_key();
+ FakeInstallationState machine_state;
+
+ // Chrome is installed.
+ machine_state.AddChrome(system_level, multi_install,
+ Version::GetVersionFromString(chrome::kChromeVersion));
RegKey key;
DWORD value;
BrowserDistribution* binaries =
- installer_state.multi_package_binaries_distribution();
- EXPECT_EQ(BrowserDistribution::CHROME_BINARIES, binaries->GetType());
+ BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BINARIES);
BrowserDistribution* chrome =
- installer_state.products()[0]->distribution();
- EXPECT_EQ(BrowserDistribution::CHROME_BROWSER, chrome->GetType());
+ BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BROWSER);
- // By default, eulaconsent ends up on the package.
- EXPECT_TRUE(GoogleUpdateSettings::SetEULAConsent(installer_state, true));
+ // eulaconsent is set on both the product and the binaries.
+ EXPECT_TRUE(GoogleUpdateSettings::SetEULAConsent(machine_state, true));
EXPECT_EQ(ERROR_SUCCESS,
key.Open(HKEY_LOCAL_MACHINE, binaries->GetStateMediumKey().c_str(),
- KEY_QUERY_VALUE | KEY_SET_VALUE));
+ KEY_QUERY_VALUE));
EXPECT_EQ(ERROR_SUCCESS,
key.ReadValueDW(google_update::kRegEULAAceptedField, &value));
EXPECT_EQ(1U, value);
EXPECT_EQ(ERROR_SUCCESS,
- key.DeleteValue(google_update::kRegEULAAceptedField));
-
- // But it will end up on the product if needed
- EXPECT_EQ(ERROR_SUCCESS,
- key.Create(HKEY_LOCAL_MACHINE, chrome->GetStateKey().c_str(),
- KEY_SET_VALUE));
- EXPECT_EQ(ERROR_SUCCESS,
- key.WriteValue(google_update::kRegEULAAceptedField,
- static_cast<DWORD>(0)));
- EXPECT_TRUE(GoogleUpdateSettings::SetEULAConsent(installer_state, true));
- EXPECT_EQ(ERROR_SUCCESS,
key.Open(HKEY_LOCAL_MACHINE, chrome->GetStateMediumKey().c_str(),
- KEY_QUERY_VALUE | KEY_SET_VALUE));
+ KEY_QUERY_VALUE));
EXPECT_EQ(ERROR_SUCCESS,
key.ReadValueDW(google_update::kRegEULAAceptedField, &value));
EXPECT_EQ(1U, value);
diff --git a/chrome/installer/util/installation_state.cc b/chrome/installer/util/installation_state.cc
index ff46253..919db89 100644
--- a/chrome/installer/util/installation_state.cc
+++ b/chrome/installer/util/installation_state.cc
@@ -18,6 +18,8 @@ ProductState::ProductState()
usagestats_(0),
msi_(false),
multi_install_(false),
+ has_eula_accepted_(false),
+ has_oem_install_(false),
has_usagestats_(false) {
}
@@ -97,6 +99,12 @@ bool ProductState::Initialize(bool system_install,
// we find.
has_usagestats_ = (key.ReadValueDW(google_update::kRegUsageStatsField,
&usagestats_) == ERROR_SUCCESS);
+ // "oeminstall" may be present with any value or absent.
+ has_oem_install_ = (key.ReadValue(google_update::kRegOemInstallField,
+ &oem_install_) == ERROR_SUCCESS);
+ // "eulaaccepted" may be absent, 0 or 1.
+ has_eula_accepted_ = (key.ReadValueDW(google_update::kRegEULAAceptedField,
+ &eula_accepted_) == ERROR_SUCCESS);
// "msi" may be absent, 0 or 1
DWORD dw_value = 0;
msi_ = (key.ReadValueDW(google_update::kRegMSIField,
@@ -108,17 +116,23 @@ bool ProductState::Initialize(bool system_install,
multi_install_ = uninstall_command_.HasSwitch(switches::kMultiInstall);
}
- // Read from the ClientStateMedium key.
+ // Read from the ClientStateMedium key. Values here override those in
+ // ClientState.
if (system_install &&
key.Open(root_key, distribution->GetStateMediumKey().c_str(),
KEY_QUERY_VALUE) == ERROR_SUCCESS) {
- DWORD usagestats = 0;
+ DWORD dword_value = 0;
- // A usagestats value in ClientStateMedium overrides that in ClientState.
if (key.ReadValueDW(google_update::kRegUsageStatsField,
- &usagestats) == ERROR_SUCCESS) {
+ &dword_value) == ERROR_SUCCESS) {
has_usagestats_ = true;
- usagestats_ = usagestats;
+ usagestats_ = dword_value;
+ }
+
+ if (key.ReadValueDW(google_update::kRegEULAAceptedField,
+ &dword_value) == ERROR_SUCCESS) {
+ has_eula_accepted_ = true;
+ eula_accepted_ = dword_value;
}
}
@@ -142,10 +156,14 @@ ProductState& ProductState::CopyFrom(const ProductState& other) {
brand_ = other.brand_;
rename_cmd_ = other.rename_cmd_;
uninstall_command_ = other.uninstall_command_;
+ oem_install_ = other.oem_install_;
commands_.CopyFrom(other.commands_);
+ eula_accepted_ = other.eula_accepted_;
usagestats_ = other.usagestats_;
msi_ = other.msi_;
multi_install_ = other.multi_install_;
+ has_eula_accepted_ = other.has_eula_accepted_;
+ has_oem_install_ = other.has_oem_install_;
has_usagestats_ = other.has_usagestats_;
return *this;
@@ -157,14 +175,34 @@ void ProductState::Clear() {
old_version_.reset();
brand_.clear();
rename_cmd_.clear();
+ oem_install_.clear();
uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM);
commands_.Clear();
+ eula_accepted_ = 0;
usagestats_ = 0;
msi_ = false;
multi_install_ = false;
+ has_eula_accepted_ = false;
+ has_oem_install_ = false;
has_usagestats_ = false;
}
+bool ProductState::GetEulaAccepted(DWORD* eula_accepted) const {
+ DCHECK(eula_accepted);
+ if (!has_eula_accepted_)
+ return false;
+ *eula_accepted = eula_accepted_;
+ return true;
+}
+
+bool ProductState::GetOemInstall(std::wstring* oem_install) const {
+ DCHECK(oem_install);
+ if (!has_oem_install_)
+ return false;
+ *oem_install = oem_install_;
+ return true;
+}
+
bool ProductState::GetUsageStats(DWORD* usagestats) const {
DCHECK(usagestats);
if (!has_usagestats_)
diff --git a/chrome/installer/util/installation_state.h b/chrome/installer/util/installation_state.h
index 1ced729..889e64e 100644
--- a/chrome/installer/util/installation_state.h
+++ b/chrome/installer/util/installation_state.h
@@ -65,6 +65,17 @@ class ProductState {
// awaiting update; may be empty.
const std::wstring& rename_cmd() const { return rename_cmd_; }
+ // Returns true and populates |eula_accepted| if the product has such a value;
+ // otherwise, returns false and does not modify |eula_accepted|. Expected
+ // values are 0 (false) and 1 (true), although |eula_accepted| is given
+ // whatever is found.
+ bool GetEulaAccepted(DWORD* eula_accepted) const;
+
+ // Returns true and populates |oem_install| if the product has such a value;
+ // otherwise, returns false and does not modify |oem_install|. Expected
+ // value is "1", although |oem_install| is given whatever is found.
+ bool GetOemInstall(std::wstring* oem_install) const;
+
// Returns true and populates |usagestats| if the product has such a value;
// otherwise, returns false and does not modify |usagestats|. Expected values
// are 0 (false) and 1 (true), although |usagestats| is given whatever is
@@ -98,12 +109,16 @@ class ProductState {
scoped_ptr<Version> old_version_;
std::wstring brand_;
std::wstring rename_cmd_;
+ std::wstring oem_install_;
CommandLine uninstall_command_;
AppCommands commands_;
+ DWORD eula_accepted_;
DWORD usagestats_;
- bool msi_;
- bool multi_install_;
- bool has_usagestats_;
+ bool msi_ : 1;
+ bool multi_install_ : 1;
+ bool has_eula_accepted_ : 1;
+ bool has_oem_install_ : 1;
+ bool has_usagestats_ : 1;
private:
friend class InstallationState;