Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: chrome/browser/component_updater/recovery_component_installer.cc

Issue 846663003: Add UMA metrics to recovery component. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/component_updater/recovery_component_installer.h" 5 #include "chrome/browser/component_updater/recovery_component_installer.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <string> 8 #include <string>
9 9
10 #include "base/base_paths.h" 10 #include "base/base_paths.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
16 #include "base/json/json_file_value_serializer.h" 16 #include "base/json/json_file_value_serializer.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
19 #include "base/metrics/histogram.h"
19 #include "base/path_service.h" 20 #include "base/path_service.h"
20 #include "base/prefs/pref_registry_simple.h" 21 #include "base/prefs/pref_registry_simple.h"
21 #include "base/prefs/pref_service.h" 22 #include "base/prefs/pref_service.h"
22 #include "base/process/kill.h" 23 #include "base/process/kill.h"
23 #include "base/process/launch.h" 24 #include "base/process/launch.h"
24 #include "base/process/process.h" 25 #include "base/process/process.h"
25 #include "base/threading/worker_pool.h" 26 #include "base/threading/worker_pool.h"
26 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
28 #include "components/component_updater/component_updater_paths.h" 29 #include "components/component_updater/component_updater_paths.h"
(...skipping 23 matching lines...) Expand all
52 53
53 const char kRecoveryManifestName[] = "ChromeRecovery"; 54 const char kRecoveryManifestName[] = "ChromeRecovery";
54 55
55 // ChromeRecovery process exit codes. 56 // ChromeRecovery process exit codes.
56 enum ChromeRecoveryExitCode { 57 enum ChromeRecoveryExitCode {
57 EXIT_CODE_RECOVERY_SUCCEEDED = 0, 58 EXIT_CODE_RECOVERY_SUCCEEDED = 0,
58 EXIT_CODE_RECOVERY_SKIPPED = 1, 59 EXIT_CODE_RECOVERY_SKIPPED = 1,
59 EXIT_CODE_ELEVATION_NEEDED = 2, 60 EXIT_CODE_ELEVATION_NEEDED = 2,
60 }; 61 };
61 62
63 enum RecoveryComponentEvent {
gab 2015/01/09 20:08:44 If you make this an enum class (woot C++11!!) then
robertshield 2015/01/09 21:37:21 Sadly without the implicit conversion to int, that
gab 2015/01/09 22:41:22 Hmmm, really? I was sure I'd done this in the past
robertshield 2015/01/09 22:45:32 I tried it and it complained about requiring a cas
gab 2015/01/12 19:12:20 Ah ok, right, for some reason I thought I'd done t
robertshield 2015/01/12 23:04:19 Acknowledged.
64 RCE_RUN_NON_ELEVATED = 0,
65 RCE_ELEVATION_NEEDED = 1,
66 RCE_RUN_ELEVATED = 2,
67 RCE_COMPONENT_DOWNLOAD_ERROR = 3,
68 RCE_MAX = 4
gab 2015/01/09 20:08:44 Don't explicitly label the max. (I also prefer to
robertshield 2015/01/09 21:37:21 Done.
69 };
70
62 #if !defined(OS_CHROMEOS) 71 #if !defined(OS_CHROMEOS)
63 // Checks if elevated recovery simulation switch was present on the command 72 // Checks if elevated recovery simulation switch was present on the command
64 // line. This is for testing purpose. 73 // line. This is for testing purpose.
65 bool SimulatingElevatedRecovery() { 74 bool SimulatingElevatedRecovery() {
66 return base::CommandLine::ForCurrentProcess()->HasSwitch( 75 return base::CommandLine::ForCurrentProcess()->HasSwitch(
67 switches::kSimulateElevatedRecovery); 76 switches::kSimulateElevatedRecovery);
68 } 77 }
69 #endif 78 #endif // !defined(OS_CHROMEOS)
70 79
71 #if defined(OS_WIN) 80 #if defined(OS_WIN)
72 scoped_ptr<base::DictionaryValue> ReadManifest(const base::FilePath& manifest) { 81 scoped_ptr<base::DictionaryValue> ReadManifest(const base::FilePath& manifest) {
73 JSONFileValueSerializer serializer(manifest); 82 JSONFileValueSerializer serializer(manifest);
74 std::string error; 83 std::string error;
75 scoped_ptr<base::Value> root(serializer.Deserialize(NULL, &error)); 84 scoped_ptr<base::Value> root(serializer.Deserialize(NULL, &error));
76 if (root.get() && root->IsType(base::Value::TYPE_DICTIONARY)) { 85 if (root.get() && root->IsType(base::Value::TYPE_DICTIONARY)) {
77 return scoped_ptr<base::DictionaryValue>( 86 return scoped_ptr<base::DictionaryValue>(
78 static_cast<base::DictionaryValue*>(root.release())); 87 static_cast<base::DictionaryValue*>(root.release()));
79 } 88 }
(...skipping 21 matching lines...) Expand all
101 base::CommandLine cmdline(main_file); 110 base::CommandLine cmdline(main_file);
102 std::string arguments; 111 std::string arguments;
103 if (manifest->GetStringASCII("x-recovery-args", &arguments)) 112 if (manifest->GetStringASCII("x-recovery-args", &arguments))
104 cmdline.AppendArg(arguments); 113 cmdline.AppendArg(arguments);
105 std::string add_version; 114 std::string add_version;
106 if (manifest->GetStringASCII("x-recovery-add-version", &add_version) && 115 if (manifest->GetStringASCII("x-recovery-add-version", &add_version) &&
107 add_version == "yes") { 116 add_version == "yes") {
108 cmdline.AppendSwitchASCII("version", version.GetString()); 117 cmdline.AppendSwitchASCII("version", version.GetString());
109 } 118 }
110 119
120 UMA_HISTOGRAM_ENUMERATION("RecoveryComponent.Event", RCE_RUN_ELEVATED,
121 RCE_MAX);
gab 2015/01/09 20:08:44 This is slightly misleading, this event doesn't ac
robertshield 2015/01/09 21:37:21 Right, the intent of this patch initially was to r
122
111 base::LaunchOptions options; 123 base::LaunchOptions options;
112 options.start_hidden = true; 124 options.start_hidden = true;
113 base::LaunchElevatedProcess(cmdline, options); 125 base::LaunchElevatedProcess(cmdline, options);
114 } 126 }
115 127
116 void ElevatedInstallRecoveryComponent(const base::FilePath& installer_path) { 128 void ElevatedInstallRecoveryComponent(const base::FilePath& installer_path) {
117 base::WorkerPool::PostTask( 129 base::WorkerPool::PostTask(
118 FROM_HERE, 130 FROM_HERE,
119 base::Bind(&DoElevatedInstallRecoveryComponent, installer_path), 131 base::Bind(&DoElevatedInstallRecoveryComponent, installer_path),
120 true); 132 true);
121 } 133 }
122 #endif 134 #endif // defined(OS_WIN)
123 135
124 } // namespace 136 } // namespace
125 137
126 // Component installer that is responsible to repair the chrome installation 138 // Component installer that is responsible to repair the chrome installation
127 // or repair the Google update installation. This is a last resort safety 139 // or repair the Google update installation. This is a last resort safety
128 // mechanism. 140 // mechanism.
129 // For user Chrome, recovery component just installs silently. For machine 141 // For user Chrome, recovery component just installs silently. For machine
130 // Chrome, elevation may be needed. If that happens, the installer will set 142 // Chrome, elevation may be needed. If that happens, the installer will set
131 // preference flag prefs::kRecoveryComponentNeedsElevation to request that. 143 // preference flag prefs::kRecoveryComponentNeedsElevation to request that.
132 // There is a global error service monitors this flag and will pop up 144 // There is a global error service monitors this flag and will pop up
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, true); 199 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, true);
188 } 200 }
189 201
190 RecoveryComponentInstaller::RecoveryComponentInstaller(const Version& version, 202 RecoveryComponentInstaller::RecoveryComponentInstaller(const Version& version,
191 PrefService* prefs) 203 PrefService* prefs)
192 : current_version_(version), prefs_(prefs) { 204 : current_version_(version), prefs_(prefs) {
193 DCHECK(version.IsValid()); 205 DCHECK(version.IsValid());
194 } 206 }
195 207
196 void RecoveryComponentInstaller::OnUpdateError(int error) { 208 void RecoveryComponentInstaller::OnUpdateError(int error) {
209 UMA_HISTOGRAM_ENUMERATION("RecoveryComponent.Event",
210 RCE_COMPONENT_DOWNLOAD_ERROR, RCE_MAX);
197 NOTREACHED() << "Recovery component update error: " << error; 211 NOTREACHED() << "Recovery component update error: " << error;
198 } 212 }
199 213
200 #if defined(OS_WIN) 214 #if defined(OS_WIN)
201 void WaitForInstallToComplete(base::Process process, 215 void WaitForInstallToComplete(base::Process process,
202 const base::FilePath& installer_folder, 216 const base::FilePath& installer_folder,
203 PrefService* prefs) { 217 PrefService* prefs) {
204 int installer_exit_code = 0; 218 int installer_exit_code = 0;
205 const base::TimeDelta kMaxWaitTime = base::TimeDelta::FromSeconds(600); 219 const base::TimeDelta kMaxWaitTime = base::TimeDelta::FromSeconds(600);
206 if (process.WaitForExitWithTimeout(kMaxWaitTime, &installer_exit_code) && 220 if (process.WaitForExitWithTimeout(kMaxWaitTime, &installer_exit_code) &&
207 installer_exit_code == EXIT_CODE_ELEVATION_NEEDED) { 221 installer_exit_code == EXIT_CODE_ELEVATION_NEEDED) {
222 UMA_HISTOGRAM_ENUMERATION("RecoveryComponent.Event", RCE_ELEVATION_NEEDED,
223 RCE_MAX);
224
208 BrowserThread::PostTask( 225 BrowserThread::PostTask(
209 BrowserThread::UI, 226 BrowserThread::UI,
210 FROM_HERE, 227 FROM_HERE,
211 base::Bind(&SetPrefsForElevatedRecoveryInstall, 228 base::Bind(&SetPrefsForElevatedRecoveryInstall,
212 installer_folder, 229 installer_folder,
213 prefs)); 230 prefs));
214 } 231 }
215 } 232 }
216 233
217 bool RecoveryComponentInstaller::RunInstallCommand( 234 bool RecoveryComponentInstaller::RunInstallCommand(
218 const base::CommandLine& cmdline, 235 const base::CommandLine& cmdline,
219 const base::FilePath& installer_folder) const { 236 const base::FilePath& installer_folder) const {
237 UMA_HISTOGRAM_ENUMERATION("RecoveryComponent.Event", RCE_RUN_NON_ELEVATED,
238 RCE_MAX);
239
220 base::LaunchOptions options; 240 base::LaunchOptions options;
221 options.start_hidden = true; 241 options.start_hidden = true;
222 base::Process process = base::LaunchProcess(cmdline, options); 242 base::Process process = base::LaunchProcess(cmdline, options);
223 if (!process.IsValid()) 243 if (!process.IsValid())
224 return false; 244 return false;
225 245
226 // Let worker pool thread wait for us so we don't block Chrome shutdown. 246 // Let worker pool thread wait for us so we don't block Chrome shutdown.
227 base::WorkerPool::PostTask( 247 base::WorkerPool::PostTask(
228 FROM_HERE, 248 FROM_HERE,
229 base::Bind(&WaitForInstallToComplete, 249 base::Bind(&WaitForInstallToComplete,
230 base::Passed(&process), installer_folder, prefs_), 250 base::Passed(&process), installer_folder, prefs_),
231 true); 251 true);
232 252
233 // Returns true regardless of install result since from updater service 253 // Returns true regardless of install result since from updater service
234 // perspective the install is done, even we may need to do elevated 254 // perspective the install is done, even we may need to do elevated
235 // install later. 255 // install later.
236 return true; 256 return true;
237 } 257 }
238 #else 258 #else
239 bool RecoveryComponentInstaller::RunInstallCommand( 259 bool RecoveryComponentInstaller::RunInstallCommand(
240 const base::CommandLine& cmdline, 260 const base::CommandLine& cmdline,
241 const base::FilePath&) const { 261 const base::FilePath&) const {
242 return base::LaunchProcess(cmdline, base::LaunchOptions()).IsValid(); 262 return base::LaunchProcess(cmdline, base::LaunchOptions()).IsValid();
243 } 263 }
244 #endif 264 #endif // defined(OS_WIN)
245 265
246 bool RecoveryComponentInstaller::Install(const base::DictionaryValue& manifest, 266 bool RecoveryComponentInstaller::Install(const base::DictionaryValue& manifest,
247 const base::FilePath& unpack_path) { 267 const base::FilePath& unpack_path) {
248 std::string name; 268 std::string name;
249 manifest.GetStringASCII("name", &name); 269 manifest.GetStringASCII("name", &name);
250 if (name != kRecoveryManifestName) 270 if (name != kRecoveryManifestName)
251 return false; 271 return false;
252 std::string proposed_version; 272 std::string proposed_version;
253 manifest.GetStringASCII("version", &proposed_version); 273 manifest.GetStringASCII("version", &proposed_version);
254 Version version(proposed_version.c_str()); 274 Version version(proposed_version.c_str());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 base::Bind(&SimulateElevatedRecoveryHelper, prefs)); 335 base::Bind(&SimulateElevatedRecoveryHelper, prefs));
316 } 336 }
317 337
318 // We delay execute the registration because we are not required in 338 // We delay execute the registration because we are not required in
319 // the critical path during browser startup. 339 // the critical path during browser startup.
320 BrowserThread::PostDelayedTask( 340 BrowserThread::PostDelayedTask(
321 BrowserThread::UI, 341 BrowserThread::UI,
322 FROM_HERE, 342 FROM_HERE,
323 base::Bind(&RecoveryRegisterHelper, cus, prefs), 343 base::Bind(&RecoveryRegisterHelper, cus, prefs),
324 base::TimeDelta::FromSeconds(6)); 344 base::TimeDelta::FromSeconds(6));
325 #endif 345 #endif // !defined(OS_CHROMEOS)
326 } 346 }
327 347
328 void RegisterPrefsForRecoveryComponent(PrefRegistrySimple* registry) { 348 void RegisterPrefsForRecoveryComponent(PrefRegistrySimple* registry) {
329 registry->RegisterStringPref(prefs::kRecoveryComponentVersion, "0.0.0.0"); 349 registry->RegisterStringPref(prefs::kRecoveryComponentVersion, "0.0.0.0");
330 registry->RegisterFilePathPref(prefs::kRecoveryComponentUnpackPath, 350 registry->RegisterFilePathPref(prefs::kRecoveryComponentUnpackPath,
331 base::FilePath()); 351 base::FilePath());
332 registry->RegisterBooleanPref(prefs::kRecoveryComponentNeedsElevation, false); 352 registry->RegisterBooleanPref(prefs::kRecoveryComponentNeedsElevation, false);
333 } 353 }
334 354
335 void AcceptedElevatedRecoveryInstall(PrefService* prefs) { 355 void AcceptedElevatedRecoveryInstall(PrefService* prefs) {
336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
337 357
338 #if defined(OS_WIN) 358 #if defined(OS_WIN)
339 ElevatedInstallRecoveryComponent( 359 ElevatedInstallRecoveryComponent(
340 prefs->GetFilePath(prefs::kRecoveryComponentUnpackPath)); 360 prefs->GetFilePath(prefs::kRecoveryComponentUnpackPath));
341 #endif 361 #endif // OS_WIN
342 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, false); 362 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, false);
343 } 363 }
344 364
345 void DeclinedElevatedRecoveryInstall(PrefService* prefs) { 365 void DeclinedElevatedRecoveryInstall(PrefService* prefs) {
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
347 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, false); 367 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, false);
348 } 368 }
349 369
350 } // namespace component_updater 370 } // namespace component_updater
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698