OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/installer/util/beacons.h" |
| 6 |
| 7 #include "base/win/registry.h" |
| 8 #include "base/win/win_util.h" |
| 9 #include "chrome/installer/util/app_registration_data.h" |
| 10 #include "chrome/installer/util/browser_distribution.h" |
| 11 #include "chrome/installer/util/install_util.h" |
| 12 #include "chrome/installer/util/shell_util.h" |
| 13 |
| 14 void UpdateDefaultBrowserBeaconForPath(const base::FilePath& chrome_exe) { |
| 15 // Getting Chrome's default state causes the beacon to be updated via a call |
| 16 // to UpdateDefaultBrowserBeaconWithState below. |
| 17 ignore_result(ShellUtil::GetChromeDefaultStateFromPath(chrome_exe)); |
| 18 } |
| 19 |
| 20 void UpdateDefaultBrowserBeaconWithState( |
| 21 const base::FilePath& chrome_exe, |
| 22 BrowserDistribution* distribution, |
| 23 ShellUtil::DefaultState default_state) { |
| 24 const bool system_install = !InstallUtil::IsPerUserInstall(chrome_exe); |
| 25 const AppRegistrationData& registration_data = |
| 26 distribution->GetAppRegistrationData(); |
| 27 switch (default_state) { |
| 28 case ShellUtil::NOT_DEFAULT: |
| 29 installer_util::MakeFirstNotDefaultBeacon(system_install, |
| 30 registration_data)->Update(); |
| 31 break; |
| 32 case ShellUtil::IS_DEFAULT: |
| 33 installer_util::MakeLastWasDefaultBeacon(system_install, |
| 34 registration_data)->Update(); |
| 35 installer_util::MakeFirstNotDefaultBeacon(system_install, |
| 36 registration_data)->Remove(); |
| 37 break; |
| 38 case ShellUtil::UNKNOWN_DEFAULT: |
| 39 break; |
| 40 } |
| 41 } |
| 42 |
| 43 void UpdateOsUpgradeBeacon(bool system_install, |
| 44 BrowserDistribution* distribution) { |
| 45 installer_util::MakeLastOsUpgradeBeacon( |
| 46 system_install, distribution->GetAppRegistrationData())->Update(); |
| 47 } |
| 48 |
| 49 namespace installer_util { |
| 50 |
| 51 scoped_ptr<Beacon> MakeLastOsUpgradeBeacon( |
| 52 bool system_install, |
| 53 const AppRegistrationData& registration_data) { |
| 54 return make_scoped_ptr(new Beacon(L"LastOsUpgrade", Beacon::BeaconType::LAST, |
| 55 Beacon::BeaconScope::PER_INSTALL, |
| 56 system_install, registration_data)); |
| 57 } |
| 58 |
| 59 scoped_ptr<Beacon> MakeLastWasDefaultBeacon( |
| 60 bool system_install, |
| 61 const AppRegistrationData& registration_data) { |
| 62 return make_scoped_ptr(new Beacon(L"LastWasDefault", Beacon::BeaconType::LAST, |
| 63 Beacon::BeaconScope::PER_USER, |
| 64 system_install, registration_data)); |
| 65 } |
| 66 |
| 67 scoped_ptr<Beacon> MakeFirstNotDefaultBeacon( |
| 68 bool system_install, |
| 69 const AppRegistrationData& registration_data) { |
| 70 return make_scoped_ptr(new Beacon( |
| 71 L"FirstNotDefault", Beacon::BeaconType::FIRST, |
| 72 Beacon::BeaconScope::PER_USER, system_install, registration_data)); |
| 73 } |
| 74 |
| 75 // Beacon ---------------------------------------------------------------------- |
| 76 |
| 77 Beacon::Beacon(base::StringPiece16 name, |
| 78 BeaconType type, |
| 79 BeaconScope scope, |
| 80 bool system_install, |
| 81 const AppRegistrationData& registration_data) |
| 82 : type_(type), |
| 83 root_(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), |
| 84 scope_(scope) { |
| 85 Initialize(name, system_install, registration_data); |
| 86 } |
| 87 |
| 88 Beacon::~Beacon() { |
| 89 } |
| 90 |
| 91 void Beacon::Update() { |
| 92 const REGSAM kAccess = KEY_WOW64_32KEY | KEY_QUERY_VALUE | KEY_SET_VALUE; |
| 93 base::win::RegKey key; |
| 94 |
| 95 // Nothing to update if the key couldn't be created. This should only be the |
| 96 // case for a developer build. |
| 97 if (key.Create(root_, key_path_.c_str(), kAccess) != ERROR_SUCCESS) |
| 98 return; |
| 99 |
| 100 // Nothing to do if this beacon is tracking the first occurrence of an event |
| 101 // that has already been recorded. |
| 102 if (type_ == BeaconType::FIRST && key.HasValue(value_name_.c_str())) |
| 103 return; |
| 104 |
| 105 int64_t now(base::Time::Now().ToInternalValue()); |
| 106 key.WriteValue(value_name_.c_str(), &now, sizeof(now), REG_QWORD); |
| 107 } |
| 108 |
| 109 void Beacon::Remove() { |
| 110 const REGSAM kAccess = KEY_WOW64_32KEY | KEY_SET_VALUE; |
| 111 base::win::RegKey key; |
| 112 |
| 113 if (key.Open(root_, key_path_.c_str(), kAccess) == ERROR_SUCCESS) |
| 114 key.DeleteValue(value_name_.c_str()); |
| 115 } |
| 116 |
| 117 base::Time Beacon::Get() { |
| 118 const REGSAM kAccess = KEY_WOW64_32KEY | KEY_QUERY_VALUE; |
| 119 base::win::RegKey key; |
| 120 int64_t now; |
| 121 |
| 122 if (key.Open(root_, key_path_.c_str(), kAccess) != ERROR_SUCCESS || |
| 123 key.ReadInt64(value_name_.c_str(), &now) != ERROR_SUCCESS) { |
| 124 return base::Time(); |
| 125 } |
| 126 |
| 127 return base::Time::FromInternalValue(now); |
| 128 } |
| 129 |
| 130 void Beacon::Initialize(base::StringPiece16 name, |
| 131 bool system_install, |
| 132 const AppRegistrationData& registration_data) { |
| 133 // When possible, beacons are located in the app's ClientState key. Per-user |
| 134 // beacons for a per-machine install are located in a beacon-specific sub-key |
| 135 // of the app's ClientStateMedium key. |
| 136 if (!system_install || scope_ == BeaconScope::PER_INSTALL) { |
| 137 key_path_ = registration_data.GetStateKey(); |
| 138 value_name_ = name.as_string(); |
| 139 } else { |
| 140 key_path_ = registration_data.GetStateMediumKey(); |
| 141 key_path_.push_back(L'\\'); |
| 142 key_path_.append(name.data(), name.size()); |
| 143 // This should never fail. If it does, the beacon will be written in the |
| 144 // key's default value, which is okay since the majority case is likely a |
| 145 // machine with a single user. |
| 146 if (!base::win::GetUserSidString(&value_name_)) |
| 147 NOTREACHED(); |
| 148 } |
| 149 } |
| 150 |
| 151 } // namespace installer_util |
OLD | NEW |