summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util
diff options
context:
space:
mode:
authorgrt <grt@chromium.org>2015-06-02 10:33:09 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-02 17:33:38 +0000
commit53cc88da9a258bc4a34c4bff50025ee044c2e64d (patch)
treef780af9a433751021df9c17f04cb313851340c77 /chrome/installer/util
parentece99b7b319e515185cfce2ad71fd7f037eae927 (diff)
downloadchromium_src-53cc88da9a258bc4a34c4bff50025ee044c2e64d.zip
chromium_src-53cc88da9a258bc4a34c4bff50025ee044c2e64d.tar.gz
chromium_src-53cc88da9a258bc4a34c4bff50025ee044c2e64d.tar.bz2
Beacons for tracking default browser status.
BUG=488247 R=gab@chromium.org,wfh@chromium.org Review URL: https://codereview.chromium.org/1146843003 Cr-Commit-Position: refs/heads/master@{#332423}
Diffstat (limited to 'chrome/installer/util')
-rw-r--r--chrome/installer/util/BUILD.gn5
-rw-r--r--chrome/installer/util/beacons.cc151
-rw-r--r--chrome/installer/util/beacons.h126
-rw-r--r--chrome/installer/util/beacons_unittest.cc277
-rw-r--r--chrome/installer/util/shell_util.cc8
-rw-r--r--chrome/installer/util/shell_util.h7
-rw-r--r--chrome/installer/util/test_app_registration_data.cc27
-rw-r--r--chrome/installer/util/test_app_registration_data.h20
8 files changed, 615 insertions, 6 deletions
diff --git a/chrome/installer/util/BUILD.gn b/chrome/installer/util/BUILD.gn
index fe40610..1cafb58 100644
--- a/chrome/installer/util/BUILD.gn
+++ b/chrome/installer/util/BUILD.gn
@@ -82,6 +82,8 @@ static_library("util") {
"app_registration_data.h",
"auto_launch_util.cc",
"auto_launch_util.h",
+ "beacons.cc",
+ "beacons.h",
"browser_distribution.cc",
"browser_distribution.h",
"callback_work_item.cc",
@@ -214,6 +216,7 @@ if (is_win) {
"../setup/compat_checks_unittest.cc",
"../setup/setup_constants.cc",
"advanced_firewall_manager_win_unittest.cc",
+ "beacons_unittest.cc",
"callback_work_item_unittest.cc",
"channel_info_unittest.cc",
"copy_tree_work_item_unittest.cc",
@@ -250,6 +253,8 @@ if (is_win) {
"self_cleaning_temp_dir_unittest.cc",
"set_reg_value_work_item_unittest.cc",
"shell_util_unittest.cc",
+ "test_app_registration_data.cc",
+ "test_app_registration_data.h",
"uninstall_metrics_unittest.cc",
"wmi_unittest.cc",
"work_item_list_unittest.cc",
diff --git a/chrome/installer/util/beacons.cc b/chrome/installer/util/beacons.cc
new file mode 100644
index 0000000..9a06503
--- /dev/null
+++ b/chrome/installer/util/beacons.cc
@@ -0,0 +1,151 @@
+// Copyright 2015 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.
+
+#include "chrome/installer/util/beacons.h"
+
+#include "base/win/registry.h"
+#include "base/win/win_util.h"
+#include "chrome/installer/util/app_registration_data.h"
+#include "chrome/installer/util/browser_distribution.h"
+#include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/shell_util.h"
+
+void UpdateDefaultBrowserBeaconForPath(const base::FilePath& chrome_exe) {
+ // Getting Chrome's default state causes the beacon to be updated via a call
+ // to UpdateDefaultBrowserBeaconWithState below.
+ ignore_result(ShellUtil::GetChromeDefaultStateFromPath(chrome_exe));
+}
+
+void UpdateDefaultBrowserBeaconWithState(
+ const base::FilePath& chrome_exe,
+ BrowserDistribution* distribution,
+ ShellUtil::DefaultState default_state) {
+ const bool system_install = !InstallUtil::IsPerUserInstall(chrome_exe);
+ const AppRegistrationData& registration_data =
+ distribution->GetAppRegistrationData();
+ switch (default_state) {
+ case ShellUtil::NOT_DEFAULT:
+ installer_util::MakeFirstNotDefaultBeacon(system_install,
+ registration_data)->Update();
+ break;
+ case ShellUtil::IS_DEFAULT:
+ installer_util::MakeLastWasDefaultBeacon(system_install,
+ registration_data)->Update();
+ installer_util::MakeFirstNotDefaultBeacon(system_install,
+ registration_data)->Remove();
+ break;
+ case ShellUtil::UNKNOWN_DEFAULT:
+ break;
+ }
+}
+
+void UpdateOsUpgradeBeacon(bool system_install,
+ BrowserDistribution* distribution) {
+ installer_util::MakeLastOsUpgradeBeacon(
+ system_install, distribution->GetAppRegistrationData())->Update();
+}
+
+namespace installer_util {
+
+scoped_ptr<Beacon> MakeLastOsUpgradeBeacon(
+ bool system_install,
+ const AppRegistrationData& registration_data) {
+ return make_scoped_ptr(new Beacon(L"LastOsUpgrade", Beacon::BeaconType::LAST,
+ Beacon::BeaconScope::PER_INSTALL,
+ system_install, registration_data));
+}
+
+scoped_ptr<Beacon> MakeLastWasDefaultBeacon(
+ bool system_install,
+ const AppRegistrationData& registration_data) {
+ return make_scoped_ptr(new Beacon(L"LastWasDefault", Beacon::BeaconType::LAST,
+ Beacon::BeaconScope::PER_USER,
+ system_install, registration_data));
+}
+
+scoped_ptr<Beacon> MakeFirstNotDefaultBeacon(
+ bool system_install,
+ const AppRegistrationData& registration_data) {
+ return make_scoped_ptr(new Beacon(
+ L"FirstNotDefault", Beacon::BeaconType::FIRST,
+ Beacon::BeaconScope::PER_USER, system_install, registration_data));
+}
+
+// Beacon ----------------------------------------------------------------------
+
+Beacon::Beacon(base::StringPiece16 name,
+ BeaconType type,
+ BeaconScope scope,
+ bool system_install,
+ const AppRegistrationData& registration_data)
+ : type_(type),
+ root_(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
+ scope_(scope) {
+ Initialize(name, system_install, registration_data);
+}
+
+Beacon::~Beacon() {
+}
+
+void Beacon::Update() {
+ const REGSAM kAccess = KEY_WOW64_32KEY | KEY_QUERY_VALUE | KEY_SET_VALUE;
+ base::win::RegKey key;
+
+ // Nothing to update if the key couldn't be created. This should only be the
+ // case for a developer build.
+ if (key.Create(root_, key_path_.c_str(), kAccess) != ERROR_SUCCESS)
+ return;
+
+ // Nothing to do if this beacon is tracking the first occurrence of an event
+ // that has already been recorded.
+ if (type_ == BeaconType::FIRST && key.HasValue(value_name_.c_str()))
+ return;
+
+ int64_t now(base::Time::Now().ToInternalValue());
+ key.WriteValue(value_name_.c_str(), &now, sizeof(now), REG_QWORD);
+}
+
+void Beacon::Remove() {
+ const REGSAM kAccess = KEY_WOW64_32KEY | KEY_SET_VALUE;
+ base::win::RegKey key;
+
+ if (key.Open(root_, key_path_.c_str(), kAccess) == ERROR_SUCCESS)
+ key.DeleteValue(value_name_.c_str());
+}
+
+base::Time Beacon::Get() {
+ const REGSAM kAccess = KEY_WOW64_32KEY | KEY_QUERY_VALUE;
+ base::win::RegKey key;
+ int64_t now;
+
+ if (key.Open(root_, key_path_.c_str(), kAccess) != ERROR_SUCCESS ||
+ key.ReadInt64(value_name_.c_str(), &now) != ERROR_SUCCESS) {
+ return base::Time();
+ }
+
+ return base::Time::FromInternalValue(now);
+}
+
+void Beacon::Initialize(base::StringPiece16 name,
+ bool system_install,
+ const AppRegistrationData& registration_data) {
+ // When possible, beacons are located in the app's ClientState key. Per-user
+ // beacons for a per-machine install are located in a beacon-specific sub-key
+ // of the app's ClientStateMedium key.
+ if (!system_install || scope_ == BeaconScope::PER_INSTALL) {
+ key_path_ = registration_data.GetStateKey();
+ value_name_ = name.as_string();
+ } else {
+ key_path_ = registration_data.GetStateMediumKey();
+ key_path_.push_back(L'\\');
+ key_path_.append(name.data(), name.size());
+ // This should never fail. If it does, the beacon will be written in the
+ // key's default value, which is okay since the majority case is likely a
+ // machine with a single user.
+ if (!base::win::GetUserSidString(&value_name_))
+ NOTREACHED();
+ }
+}
+
+} // namespace installer_util
diff --git a/chrome/installer/util/beacons.h b/chrome/installer/util/beacons.h
new file mode 100644
index 0000000..bec393e
--- /dev/null
+++ b/chrome/installer/util/beacons.h
@@ -0,0 +1,126 @@
+// Copyright 2015 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.
+
+#ifndef CHROME_INSTALLER_UTIL_BEACONS_H_
+#define CHROME_INSTALLER_UTIL_BEACONS_H_
+
+#include <windows.h>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "base/time/time.h"
+#include "chrome/installer/util/shell_util.h"
+
+class AppRegistrationData;
+class BrowserDistribution;
+
+namespace base {
+class FilePath;
+}
+
+// Checks the default state of the browser for the current user and updates the
+// appropriate beacon (last was default or first not default).
+void UpdateDefaultBrowserBeaconForPath(const base::FilePath& chrome_exe);
+
+// Updates the last was default or first not default beacon for the current user
+// based on |default_state|.
+void UpdateDefaultBrowserBeaconWithState(const base::FilePath& chrome_exe,
+ BrowserDistribution* distribution,
+ ShellUtil::DefaultState default_state);
+
+// Updates the last OS upgrade beacon for the install.
+void UpdateOsUpgradeBeacon(bool system_install,
+ BrowserDistribution* distribution);
+
+namespace installer_util {
+
+class Beacon;
+
+// Returns a Beacon representing the last time the machine's OS was ugpraded.
+scoped_ptr<Beacon> MakeLastOsUpgradeBeacon(
+ bool system_install,
+ const AppRegistrationData& registration_data);
+
+// Returns a Beacon representing the last time Chrome was the user's default
+// browser.
+scoped_ptr<Beacon> MakeLastWasDefaultBeacon(
+ bool system_install,
+ const AppRegistrationData& registration_data);
+
+// Returns a Beacon representing the first time Chrome was not the user's
+// default browser.
+scoped_ptr<Beacon> MakeFirstNotDefaultBeacon(
+ bool system_install,
+ const AppRegistrationData& registration_data);
+
+// A named beacon stored in the registry representing the first or last time at
+// which some event took place. A beacon may apply to a per-user event or a
+// per-install event. In general, beacons should be created via factory methods
+// such as those above.
+class Beacon {
+ public:
+ enum class BeaconType {
+ // A beacon that marks the first occurrence of an event.
+ FIRST,
+ // A beacon that marks the last occurrence of an event.
+ LAST,
+ };
+
+ enum class BeaconScope {
+ // A beacon that applies to a per-user event.
+ PER_USER,
+ // A beacon that applies to a per-install event.
+ PER_INSTALL,
+ };
+
+ // Creates a beacon named |name| for the product identified by
+ // |registration_data| installed as either a per-user or a per-machine app
+ // according to |system_install|.
+ Beacon(base::StringPiece16 name,
+ BeaconType type,
+ BeaconScope scope,
+ bool system_install,
+ const AppRegistrationData& registration_data);
+ ~Beacon();
+
+ // Updates the beacon. For a type LAST beacon, the current time is written
+ // unconditionally. For a type FIRST beacon, the beacon is only updated if it
+ // does not already exist.
+ void Update();
+
+ // Removes the beacon.
+ void Remove();
+
+ // Returns the beacon's value or a null time if not found.
+ base::Time Get();
+
+ private:
+ // Initializes the key_path_ and value_name_ fields of the beacon.
+ void Initialize(base::StringPiece16 name,
+ bool system_install,
+ const AppRegistrationData& registration_data);
+
+ // The type of beacon.
+ const BeaconType type_;
+
+ // The root key in the registry where this beacon is stored.
+ const HKEY root_;
+
+ // The scope of the beacon.
+ const BeaconScope scope_;
+
+ // The path to the registry key holding the beacon.
+ base::string16 key_path_;
+
+ // The name of the registry value holding the beacon.
+ base::string16 value_name_;
+
+ DISALLOW_COPY_AND_ASSIGN(Beacon);
+};
+
+} // namespace installer_util
+
+#endif // CHROME_INSTALLER_UTIL_BEACONS_H_
diff --git a/chrome/installer/util/beacons_unittest.cc b/chrome/installer/util/beacons_unittest.cc
new file mode 100644
index 0000000..2465dd3
--- /dev/null
+++ b/chrome/installer/util/beacons_unittest.cc
@@ -0,0 +1,277 @@
+// Copyright 2015 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.
+
+#include "chrome/installer/util/beacons.h"
+
+#include "base/base_paths.h"
+#include "base/memory/scoped_vector.h"
+#include "base/path_service.h"
+#include "base/test/scoped_path_override.h"
+#include "base/test/test_reg_util_win.h"
+#include "base/test/test_timeouts.h"
+#include "base/threading/platform_thread.h"
+#include "base/win/registry.h"
+#include "base/win/win_util.h"
+#include "chrome/installer/util/browser_distribution.h"
+#include "chrome/installer/util/test_app_registration_data.h"
+#include "chrome/installer/util/util_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::Bool;
+using ::testing::Combine;
+using ::testing::Values;
+using BeaconType = installer_util::Beacon::BeaconType;
+using BeaconScope = installer_util::Beacon::BeaconScope;
+
+namespace installer_util {
+
+// A test fixture that exercises a beacon.
+class BeaconTest : public ::testing::TestWithParam<
+ ::testing::tuple<BeaconType, BeaconScope, bool>> {
+ protected:
+ static const base::char16 kBeaconName[];
+
+ BeaconTest()
+ : beacon_type_(::testing::get<0>(GetParam())),
+ beacon_scope_(::testing::get<1>(GetParam())),
+ system_install_(::testing::get<2>(GetParam())),
+ beacon_(kBeaconName,
+ beacon_type_,
+ beacon_scope_,
+ system_install_,
+ app_registration_data_) {
+ // Override the registry so that tests can freely push state to it.
+ registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
+ registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE);
+ }
+
+ TestAppRegistrationData app_registration_data_;
+ BeaconType beacon_type_;
+ BeaconScope beacon_scope_;
+ bool system_install_;
+ Beacon beacon_;
+
+ private:
+ registry_util::RegistryOverrideManager registry_override_manager_;
+};
+
+// static
+const base::char16 BeaconTest::kBeaconName[] = L"TestBeacon";
+
+// Nothing in the regsitry, so the beacon should not exist.
+TEST_P(BeaconTest, GetNonExistant) {
+ ASSERT_TRUE(beacon_.Get().is_null());
+}
+
+// Updating and then getting the beacon should return a value, and that it is
+// within range.
+TEST_P(BeaconTest, UpdateAndGet) {
+ base::Time before(base::Time::Now());
+ beacon_.Update();
+ base::Time after(base::Time::Now());
+ base::Time beacon_time(beacon_.Get());
+ ASSERT_FALSE(beacon_time.is_null());
+ ASSERT_LE(before, beacon_time);
+ ASSERT_GE(after, beacon_time);
+}
+
+// Tests that updating a first beacon only updates it the first time, but doing
+// so for a last beacon always updates.
+TEST_P(BeaconTest, UpdateTwice) {
+ beacon_.Update();
+ base::Time beacon_time(beacon_.Get());
+
+ base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
+
+ beacon_.Update();
+ if (beacon_type_ == BeaconType::FIRST) {
+ ASSERT_EQ(beacon_time, beacon_.Get());
+ } else {
+ ASSERT_NE(beacon_time, beacon_.Get());
+ }
+}
+
+// Tests that the beacon is written into the proper location in the registry.
+TEST_P(BeaconTest, Location) {
+ beacon_.Update();
+ HKEY right_root = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ HKEY wrong_root = system_install_ ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
+ base::string16 right_key;
+ base::string16 wrong_key;
+ base::string16 value_name;
+
+ if (beacon_scope_ == BeaconScope::PER_INSTALL || !system_install_) {
+ value_name = kBeaconName;
+ right_key = app_registration_data_.GetStateKey();
+ wrong_key = app_registration_data_.GetStateMediumKey();
+ } else {
+ ASSERT_TRUE(base::win::GetUserSidString(&value_name));
+ right_key =
+ app_registration_data_.GetStateMediumKey() + L"\\" + kBeaconName;
+ wrong_key = app_registration_data_.GetStateKey();
+ }
+
+ // Keys should not exist in the wrong root or in the right root but wrong key.
+ ASSERT_FALSE(base::win::RegKey(wrong_root, right_key.c_str(),
+ KEY_READ).Valid()) << right_key;
+ ASSERT_FALSE(base::win::RegKey(wrong_root, wrong_key.c_str(),
+ KEY_READ).Valid()) << wrong_key;
+ ASSERT_FALSE(base::win::RegKey(right_root, wrong_key.c_str(),
+ KEY_READ).Valid()) << wrong_key;
+ // The right key should exist.
+ base::win::RegKey key(right_root, right_key.c_str(), KEY_READ);
+ ASSERT_TRUE(key.Valid()) << right_key;
+ // And should have the value.
+ ASSERT_TRUE(key.HasValue(value_name.c_str())) << value_name;
+}
+
+// Run the tests for all combinations of beacon type, scope, and install level.
+INSTANTIATE_TEST_CASE_P(BeaconTest,
+ BeaconTest,
+ Combine(Values(BeaconType::FIRST, BeaconType::LAST),
+ Values(BeaconScope::PER_USER,
+ BeaconScope::PER_INSTALL),
+ Bool()));
+
+enum class DistributionVariant {
+ SYSTEM_LEVEL,
+ USER_LEVEL,
+ SXS,
+};
+
+class DefaultBrowserBeaconTest
+ : public ::testing::TestWithParam<DistributionVariant> {
+ protected:
+ using Super = ::testing::TestWithParam<DistributionVariant>;
+
+ DefaultBrowserBeaconTest()
+ : system_install_(GetParam() == DistributionVariant::SYSTEM_LEVEL),
+ chrome_sxs_(GetParam() == DistributionVariant::SXS),
+ chrome_exe_(GetChromePathForParams()),
+ distribution_(nullptr) {}
+
+ void SetUp() override {
+ Super::SetUp();
+
+ // Override FILE_EXE so that various InstallUtil functions will consider
+ // this to be a user/system Chrome or Chrome SxS.
+ path_overrides_.push_back(new base::ScopedPathOverride(
+ base::FILE_EXE, chrome_exe_, true /* is_absolute */,
+ false /* !create */));
+
+ // Override these paths with their own values so that they can be found
+ // after the registry override manager is in place. Getting them would
+ // otherwise fail since the underlying calls to the OS need to see the real
+ // contents of the registry.
+ static const int kPathKeys[] = {
+ base::DIR_PROGRAM_FILES,
+ base::DIR_PROGRAM_FILESX86,
+ base::DIR_LOCAL_APP_DATA,
+ };
+ for (int key : kPathKeys) {
+ base::FilePath temp;
+ PathService::Get(key, &temp);
+ path_overrides_.push_back(new base::ScopedPathOverride(key, temp));
+ }
+
+ // Override the registry so that tests can freely push state to it.
+ registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
+ registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE);
+
+ distribution_ = BrowserDistribution::GetDistribution();
+ }
+
+ bool system_install_;
+ bool chrome_sxs_;
+ base::FilePath chrome_exe_;
+ BrowserDistribution* distribution_;
+
+ private:
+ base::FilePath GetChromePathForParams() const {
+ base::FilePath chrome_exe;
+ int dir_key = base::DIR_LOCAL_APP_DATA;
+
+ if (system_install_) {
+#if defined(_WIN64)
+ static const int kSystemKey = base::DIR_PROGRAM_FILESX86;
+#else
+ static const int kSystemKey = base::DIR_PROGRAM_FILES;
+#endif
+ dir_key = kSystemKey;
+ }
+ PathService::Get(dir_key, &chrome_exe);
+#if defined(GOOGLE_CHROME_BUILD)
+ chrome_exe = chrome_exe.Append(installer::kGoogleChromeInstallSubDir1);
+ if (chrome_sxs_) {
+ chrome_exe = chrome_exe.Append(
+ base::string16(installer::kGoogleChromeInstallSubDir2) +
+ installer::kSxSSuffix);
+ } else {
+ chrome_exe = chrome_exe.Append(installer::kGoogleChromeInstallSubDir2);
+ }
+#else
+ chrome_exe = chrome_exe.AppendASCII("Chromium");
+#endif
+ chrome_exe = chrome_exe.Append(installer::kInstallBinaryDir);
+ return chrome_exe.Append(installer::kChromeExe);
+ }
+
+ ScopedVector<base::ScopedPathOverride> path_overrides_;
+ registry_util::RegistryOverrideManager registry_override_manager_;
+};
+
+// Tests that the default browser beacons work as expected.
+TEST_P(DefaultBrowserBeaconTest, All) {
+ scoped_ptr<Beacon> last_was_default(MakeLastWasDefaultBeacon(
+ system_install_, distribution_->GetAppRegistrationData()));
+ scoped_ptr<Beacon> first_not_default(MakeFirstNotDefaultBeacon(
+ system_install_, distribution_->GetAppRegistrationData()));
+
+ ASSERT_TRUE(last_was_default->Get().is_null());
+ ASSERT_TRUE(first_not_default->Get().is_null());
+
+ // Chrome is not default.
+ UpdateDefaultBrowserBeaconWithState(chrome_exe_, distribution_,
+ ShellUtil::NOT_DEFAULT);
+ ASSERT_TRUE(last_was_default->Get().is_null());
+ ASSERT_FALSE(first_not_default->Get().is_null());
+
+ // Then it is.
+ UpdateDefaultBrowserBeaconWithState(chrome_exe_, distribution_,
+ ShellUtil::IS_DEFAULT);
+ ASSERT_FALSE(last_was_default->Get().is_null());
+ ASSERT_TRUE(first_not_default->Get().is_null());
+
+ // It still is.
+ UpdateDefaultBrowserBeaconWithState(chrome_exe_, distribution_,
+ ShellUtil::IS_DEFAULT);
+ ASSERT_FALSE(last_was_default->Get().is_null());
+ ASSERT_TRUE(first_not_default->Get().is_null());
+
+ // Now it's not again.
+ UpdateDefaultBrowserBeaconWithState(chrome_exe_, distribution_,
+ ShellUtil::NOT_DEFAULT);
+ ASSERT_FALSE(last_was_default->Get().is_null());
+ ASSERT_FALSE(first_not_default->Get().is_null());
+
+ // And it still isn't.
+ UpdateDefaultBrowserBeaconWithState(chrome_exe_, distribution_,
+ ShellUtil::NOT_DEFAULT);
+ ASSERT_FALSE(last_was_default->Get().is_null());
+ ASSERT_FALSE(first_not_default->Get().is_null());
+}
+
+INSTANTIATE_TEST_CASE_P(SystemLevelChrome,
+ DefaultBrowserBeaconTest,
+ Values(DistributionVariant::SYSTEM_LEVEL));
+INSTANTIATE_TEST_CASE_P(UserLevelChrome,
+ DefaultBrowserBeaconTest,
+ Values(DistributionVariant::USER_LEVEL));
+#if 0 && defined(GOOGLE_CHROME_BUILD)
+// Disabled for now since InstallUtil::IsChromeSxSProcess makes this impossible.
+INSTANTIATE_TEST_CASE_P(ChromeSxS, DefaultBrowserBeaconTest,
+ Values(DistributionVariant::SXS));
+#endif
+
+} // namespace installer_util
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 5dd804a..0f25166 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -43,6 +43,7 @@
#include "base/win/windows_version.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/installer/util/beacons.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/installer_util_strings.h"
@@ -1963,9 +1964,10 @@ ShellUtil::DefaultState ShellUtil::GetChromeDefaultStateFromPath(
// flag. There is doubtless some other key we can hook into to cause "Repair"
// to show up in Add/Remove programs for us.
static const wchar_t* const kChromeProtocols[] = { L"http", L"https" };
- return ProbeProtocolHandlers(chrome_exe,
- kChromeProtocols,
- arraysize(kChromeProtocols));
+ DefaultState default_state = ProbeProtocolHandlers(
+ chrome_exe, kChromeProtocols, arraysize(kChromeProtocols));
+ UpdateDefaultBrowserBeaconWithState(chrome_exe, distribution, default_state);
+ return default_state;
}
ShellUtil::DefaultState ShellUtil::GetChromeDefaultProtocolClientState(
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index 64e5848..28a1647 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -410,11 +410,12 @@ class ShellUtil {
// Windows prior to Windows 8.
static bool CanMakeChromeDefaultUnattended();
- // Returns the DefaultState of Chrome for HTTP and HTTPS.
+ // Returns the DefaultState of Chrome for HTTP and HTTPS and updates the
+ // default browser beacons as appropriate.
static DefaultState GetChromeDefaultState();
- // Returns the DefaultState of the Chrome instance with the specified path
- // for HTTP and HTTPs.
+ // Returns the DefaultState of the Chrome instance with the specified path for
+ // HTTP and HTTPs and updates the default browser beacons as appropriate.
static DefaultState GetChromeDefaultStateFromPath(
const base::FilePath& chrome_exe);
diff --git a/chrome/installer/util/test_app_registration_data.cc b/chrome/installer/util/test_app_registration_data.cc
new file mode 100644
index 0000000..b370df3
--- /dev/null
+++ b/chrome/installer/util/test_app_registration_data.cc
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+
+#include "chrome/installer/util/test_app_registration_data.h"
+
+TestAppRegistrationData::TestAppRegistrationData() {
+}
+
+TestAppRegistrationData::~TestAppRegistrationData() {
+}
+
+base::string16 TestAppRegistrationData::GetAppGuid() const {
+ return L"test_app_guid";
+}
+
+base::string16 TestAppRegistrationData::GetStateKey() const {
+ return L"Software\\Chromium\\ClientState\\test_app_guid";
+}
+
+base::string16 TestAppRegistrationData::GetStateMediumKey() const {
+ return L"Software\\Chromium\\ClientStateMedium\\test_app_guid";
+}
+
+base::string16 TestAppRegistrationData::GetVersionKey() const {
+ return L"Software\\Chromium\\Clients\\test_app_guid";
+}
diff --git a/chrome/installer/util/test_app_registration_data.h b/chrome/installer/util/test_app_registration_data.h
new file mode 100644
index 0000000..9b5fb86
--- /dev/null
+++ b/chrome/installer/util/test_app_registration_data.h
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+#ifndef CHROME_INSTALLER_UTIL_TEST_APP_REGISTRATION_DATA_H_
+#define CHROME_INSTALLER_UTIL_TEST_APP_REGISTRATION_DATA_H_
+
+#include "chrome/installer/util/app_registration_data.h"
+
+class TestAppRegistrationData : public AppRegistrationData {
+ public:
+ TestAppRegistrationData();
+ ~TestAppRegistrationData() override;
+ base::string16 GetAppGuid() const override;
+ base::string16 GetStateKey() const override;
+ base::string16 GetStateMediumKey() const override;
+ base::string16 GetVersionKey() const override;
+};
+
+#endif // CHROME_INSTALLER_UTIL_TEST_APP_REGISTRATION_DATA_H_