Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / installer / util / installation_state.cc
blobd6d06abc5b1f8ce1bd32bb166f368aab96685626
1 // Copyright (c) 2012 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.
5 #include "chrome/installer/util/installation_state.h"
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "base/version.h"
10 #include "base/win/registry.h"
11 #include "chrome/installer/util/google_update_constants.h"
12 #include "chrome/installer/util/install_util.h"
14 namespace installer {
16 ProductState::ProductState()
17 : uninstall_command_(CommandLine::NO_PROGRAM),
18 eula_accepted_(0),
19 usagestats_(0),
20 msi_(false),
21 multi_install_(false),
22 has_eula_accepted_(false),
23 has_oem_install_(false),
24 has_usagestats_(false) {
27 bool ProductState::Initialize(bool system_install,
28 BrowserDistribution::Type type) {
29 return Initialize(system_install,
30 BrowserDistribution::GetSpecificDistribution(type));
33 // Initializes |commands| from the "Commands" subkey of |version_key|.
34 // Returns false if there is no "Commands" subkey or on error.
35 // static
36 bool ProductState::InitializeCommands(const base::win::RegKey& version_key,
37 AppCommands* commands) {
38 static const DWORD kAccess = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE;
39 base::win::RegKey commands_key;
41 if (commands_key.Open(version_key.Handle(), google_update::kRegCommandsKey,
42 kAccess) == ERROR_SUCCESS)
43 return commands->Initialize(commands_key);
44 return false;
47 bool ProductState::Initialize(bool system_install,
48 BrowserDistribution* distribution) {
49 const std::wstring version_key(distribution->GetVersionKey());
50 const std::wstring state_key(distribution->GetStateKey());
51 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
52 base::win::RegKey key;
54 // Clear the runway.
55 Clear();
57 // Read from the Clients key.
58 if (key.Open(root_key, version_key.c_str(),
59 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
60 std::wstring version_str;
61 if (key.ReadValue(google_update::kRegVersionField,
62 &version_str) == ERROR_SUCCESS) {
63 version_.reset(new Version(WideToASCII(version_str)));
64 if (!version_->IsValid())
65 version_.reset();
68 // Attempt to read the other values even if the "pv" version value was
69 // absent. Note that ProductState instances containing these values will
70 // only be accessible via InstallationState::GetNonVersionedProductState.
71 if (key.ReadValue(google_update::kRegOldVersionField,
72 &version_str) == ERROR_SUCCESS) {
73 old_version_.reset(new Version(WideToASCII(version_str)));
74 if (!old_version_->IsValid())
75 old_version_.reset();
78 key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd_);
79 if (!InitializeCommands(key, &commands_))
80 commands_.Clear();
83 // Read from the ClientState key.
84 if (key.Open(root_key, state_key.c_str(),
85 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
86 std::wstring setup_path;
87 std::wstring uninstall_arguments;
88 // "ap" will be absent if not managed by Google Update.
89 channel_.Initialize(key);
91 // Read in the brand code, it may be absent
92 key.ReadValue(google_update::kRegBrandField, &brand_);
94 // "UninstallString" will be absent for the multi-installer package.
95 key.ReadValue(kUninstallStringField, &setup_path);
96 // "UninstallArguments" will be absent for the multi-installer package.
97 key.ReadValue(kUninstallArgumentsField, &uninstall_arguments);
98 InstallUtil::MakeUninstallCommand(setup_path, uninstall_arguments,
99 &uninstall_command_);
101 // "usagestats" may be absent, 0 (false), or 1 (true). On the chance that
102 // different values are permitted in the future, we'll simply hold whatever
103 // we find.
104 has_usagestats_ = (key.ReadValueDW(google_update::kRegUsageStatsField,
105 &usagestats_) == ERROR_SUCCESS);
106 // "oeminstall" may be present with any value or absent.
107 has_oem_install_ = (key.ReadValue(google_update::kRegOemInstallField,
108 &oem_install_) == ERROR_SUCCESS);
109 // "eulaaccepted" may be absent, 0 or 1.
110 has_eula_accepted_ = (key.ReadValueDW(google_update::kRegEULAAceptedField,
111 &eula_accepted_) == ERROR_SUCCESS);
112 // "msi" may be absent, 0 or 1
113 DWORD dw_value = 0;
114 msi_ = (key.ReadValueDW(google_update::kRegMSIField,
115 &dw_value) == ERROR_SUCCESS) && (dw_value != 0);
116 // Multi-install is implied or is derived from the command-line.
117 if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES)
118 multi_install_ = true;
119 else
120 multi_install_ = uninstall_command_.HasSwitch(switches::kMultiInstall);
123 // Read from the ClientStateMedium key. Values here override those in
124 // ClientState.
125 if (system_install &&
126 key.Open(root_key, distribution->GetStateMediumKey().c_str(),
127 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
128 DWORD dword_value = 0;
130 if (key.ReadValueDW(google_update::kRegUsageStatsField,
131 &dword_value) == ERROR_SUCCESS) {
132 has_usagestats_ = true;
133 usagestats_ = dword_value;
136 if (key.ReadValueDW(google_update::kRegEULAAceptedField,
137 &dword_value) == ERROR_SUCCESS) {
138 has_eula_accepted_ = true;
139 eula_accepted_ = dword_value;
143 return version_.get() != NULL;
146 base::FilePath ProductState::GetSetupPath() const {
147 return uninstall_command_.GetProgram();
150 const Version& ProductState::version() const {
151 DCHECK(version_.get() != NULL);
152 return *version_;
155 ProductState& ProductState::CopyFrom(const ProductState& other) {
156 channel_.set_value(other.channel_.value());
157 version_.reset(other.version_.get() ? new Version(*other.version_) : NULL);
158 old_version_.reset(
159 other.old_version_.get() ? new Version(*other.old_version_) : NULL);
160 brand_ = other.brand_;
161 rename_cmd_ = other.rename_cmd_;
162 uninstall_command_ = other.uninstall_command_;
163 oem_install_ = other.oem_install_;
164 commands_.CopyFrom(other.commands_);
165 eula_accepted_ = other.eula_accepted_;
166 usagestats_ = other.usagestats_;
167 msi_ = other.msi_;
168 multi_install_ = other.multi_install_;
169 has_eula_accepted_ = other.has_eula_accepted_;
170 has_oem_install_ = other.has_oem_install_;
171 has_usagestats_ = other.has_usagestats_;
173 return *this;
176 void ProductState::Clear() {
177 channel_.set_value(std::wstring());
178 version_.reset();
179 old_version_.reset();
180 brand_.clear();
181 rename_cmd_.clear();
182 oem_install_.clear();
183 uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM);
184 commands_.Clear();
185 eula_accepted_ = 0;
186 usagestats_ = 0;
187 msi_ = false;
188 multi_install_ = false;
189 has_eula_accepted_ = false;
190 has_oem_install_ = false;
191 has_usagestats_ = false;
194 bool ProductState::GetEulaAccepted(DWORD* eula_accepted) const {
195 DCHECK(eula_accepted);
196 if (!has_eula_accepted_)
197 return false;
198 *eula_accepted = eula_accepted_;
199 return true;
202 bool ProductState::GetOemInstall(std::wstring* oem_install) const {
203 DCHECK(oem_install);
204 if (!has_oem_install_)
205 return false;
206 *oem_install = oem_install_;
207 return true;
210 bool ProductState::GetUsageStats(DWORD* usagestats) const {
211 DCHECK(usagestats);
212 if (!has_usagestats_)
213 return false;
214 *usagestats = usagestats_;
215 return true;
218 InstallationState::InstallationState() {
221 // static
222 int InstallationState::IndexFromDistType(BrowserDistribution::Type type) {
223 COMPILE_ASSERT(BrowserDistribution::CHROME_BROWSER == CHROME_BROWSER_INDEX,
224 unexpected_chrome_browser_distribution_value_);
225 COMPILE_ASSERT(BrowserDistribution::CHROME_FRAME == CHROME_FRAME_INDEX,
226 unexpected_chrome_frame_distribution_value_);
227 COMPILE_ASSERT(BrowserDistribution::CHROME_BINARIES == CHROME_BINARIES_INDEX,
228 unexpected_chrome_frame_distribution_value_);
229 COMPILE_ASSERT(BrowserDistribution::CHROME_APP_HOST == CHROME_APP_HOST_INDEX,
230 unexpected_chrome_frame_distribution_value_);
231 DCHECK(type == BrowserDistribution::CHROME_BROWSER ||
232 type == BrowserDistribution::CHROME_FRAME ||
233 type == BrowserDistribution::CHROME_BINARIES ||
234 type == BrowserDistribution::CHROME_APP_HOST);
235 return type;
238 void InstallationState::Initialize() {
239 BrowserDistribution* distribution;
241 distribution = BrowserDistribution::GetSpecificDistribution(
242 BrowserDistribution::CHROME_BROWSER);
243 user_products_[CHROME_BROWSER_INDEX].Initialize(false, distribution);
244 system_products_[CHROME_BROWSER_INDEX].Initialize(true, distribution);
246 distribution = BrowserDistribution::GetSpecificDistribution(
247 BrowserDistribution::CHROME_FRAME);
248 user_products_[CHROME_FRAME_INDEX].Initialize(false, distribution);
249 system_products_[CHROME_FRAME_INDEX].Initialize(true, distribution);
251 distribution = BrowserDistribution::GetSpecificDistribution(
252 BrowserDistribution::CHROME_BINARIES);
253 user_products_[CHROME_BINARIES_INDEX].Initialize(false, distribution);
254 system_products_[CHROME_BINARIES_INDEX].Initialize(true, distribution);
256 distribution = BrowserDistribution::GetSpecificDistribution(
257 BrowserDistribution::CHROME_APP_HOST);
258 user_products_[CHROME_APP_HOST_INDEX].Initialize(false, distribution);
259 system_products_[CHROME_APP_HOST_INDEX].Initialize(true, distribution);
262 const ProductState* InstallationState::GetNonVersionedProductState(
263 bool system_install,
264 BrowserDistribution::Type type) const {
265 const ProductState& product_state = (system_install ? system_products_ :
266 user_products_)[IndexFromDistType(type)];
267 return &product_state;
270 const ProductState* InstallationState::GetProductState(
271 bool system_install,
272 BrowserDistribution::Type type) const {
273 const ProductState* product_state =
274 GetNonVersionedProductState(system_install, type);
275 return product_state->version_.get() == NULL ? NULL : product_state;
277 } // namespace installer