OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 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/sw_reporter_installer_win.h" | 5 #include "chrome/browser/component_updater/sw_reporter_installer_win.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "base/strings/string_tokenizer.h" | 29 #include "base/strings/string_tokenizer.h" |
30 #include "base/strings/string_util.h" | 30 #include "base/strings/string_util.h" |
31 #include "base/strings/utf_string_conversions.h" | 31 #include "base/strings/utf_string_conversions.h" |
32 #include "base/threading/thread_task_runner_handle.h" | 32 #include "base/threading/thread_task_runner_handle.h" |
33 #include "base/time/time.h" | 33 #include "base/time/time.h" |
34 #include "base/win/registry.h" | 34 #include "base/win/registry.h" |
35 #include "base/win/windows_version.h" | 35 #include "base/win/windows_version.h" |
36 #include "chrome/browser/browser_process.h" | 36 #include "chrome/browser/browser_process.h" |
37 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" | 37 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" |
38 #include "chrome/browser/safe_browsing/srt_field_trial_win.h" | 38 #include "chrome/browser/safe_browsing/srt_field_trial_win.h" |
| 39 #include "components/chrome_cleaner/public/constants/constants.h" |
39 #include "components/component_updater/component_updater_paths.h" | 40 #include "components/component_updater/component_updater_paths.h" |
40 #include "components/component_updater/component_updater_service.h" | 41 #include "components/component_updater/component_updater_service.h" |
41 #include "components/component_updater/pref_names.h" | 42 #include "components/component_updater/pref_names.h" |
42 #include "components/pref_registry/pref_registry_syncable.h" | 43 #include "components/pref_registry/pref_registry_syncable.h" |
43 #include "components/prefs/pref_registry_simple.h" | 44 #include "components/prefs/pref_registry_simple.h" |
44 #include "components/update_client/update_client.h" | 45 #include "components/update_client/update_client.h" |
45 #include "components/update_client/utils.h" | 46 #include "components/update_client/utils.h" |
46 #include "components/variations/variations_associated_data.h" | 47 #include "components/variations/variations_associated_data.h" |
47 #include "content/public/browser/browser_thread.h" | 48 #include "content/public/browser/browser_thread.h" |
48 | 49 |
(...skipping 16 matching lines...) Expand all Loading... |
65 // generated in Python with something like this: | 66 // generated in Python with something like this: |
66 // hashlib.sha256().update(open("<file>.crx").read()[16:16+294]).digest(). | 67 // hashlib.sha256().update(open("<file>.crx").read()[16:16+294]).digest(). |
67 const uint8_t kSha256Hash[] = {0x6a, 0xc6, 0x0e, 0xe8, 0xf3, 0x97, 0xc0, 0xd6, | 68 const uint8_t kSha256Hash[] = {0x6a, 0xc6, 0x0e, 0xe8, 0xf3, 0x97, 0xc0, 0xd6, |
68 0xf4, 0xc9, 0x78, 0x6c, 0x0c, 0x24, 0x73, 0x3e, | 69 0xf4, 0xc9, 0x78, 0x6c, 0x0c, 0x24, 0x73, 0x3e, |
69 0x05, 0xa5, 0x62, 0x4b, 0x2e, 0xc7, 0xb7, 0x1c, | 70 0x05, 0xa5, 0x62, 0x4b, 0x2e, 0xc7, 0xb7, 0x1c, |
70 0x5f, 0xea, 0xf0, 0x88, 0xf6, 0x97, 0x9b, 0xc7}; | 71 0x5f, 0xea, 0xf0, 0x88, 0xf6, 0x97, 0x9b, 0xc7}; |
71 | 72 |
72 const base::FilePath::CharType kSwReporterExeName[] = | 73 const base::FilePath::CharType kSwReporterExeName[] = |
73 FILE_PATH_LITERAL("software_reporter_tool.exe"); | 74 FILE_PATH_LITERAL("software_reporter_tool.exe"); |
74 | 75 |
75 constexpr char kSessionIdSwitch[] = "session-id"; | |
76 | |
77 // SRT registry keys and value names. | |
78 const wchar_t kCleanerSuffixRegistryKey[] = L"Cleaner"; | |
79 const wchar_t kExitCodeValueName[] = L"ExitCode"; | |
80 const wchar_t kUploadResultsValueName[] = L"UploadResults"; | |
81 const wchar_t kVersionValueName[] = L"Version"; | |
82 | |
83 constexpr base::Feature kExperimentalEngineFeature{ | 76 constexpr base::Feature kExperimentalEngineFeature{ |
84 "ExperimentalSwReporterEngine", base::FEATURE_DISABLED_BY_DEFAULT}; | 77 "ExperimentalSwReporterEngine", base::FEATURE_DISABLED_BY_DEFAULT}; |
85 constexpr base::Feature kExperimentalEngineAllArchsFeature{ | 78 constexpr base::Feature kExperimentalEngineAllArchsFeature{ |
86 "ExperimentalSwReporterEngineOnAllArchitectures", | 79 "ExperimentalSwReporterEngineOnAllArchitectures", |
87 base::FEATURE_DISABLED_BY_DEFAULT | 80 base::FEATURE_DISABLED_BY_DEFAULT |
88 }; | 81 }; |
89 | 82 |
90 void SRTHasCompleted(SRTCompleted value) { | 83 void SRTHasCompleted(SRTCompleted value) { |
91 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Cleaner.HasCompleted", value, | 84 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Cleaner.HasCompleted", value, |
92 SRT_COMPLETED_MAX); | 85 SRT_COMPLETED_MAX); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS); | 237 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS); |
245 return; | 238 return; |
246 } | 239 } |
247 if (!argument.empty()) | 240 if (!argument.empty()) |
248 argv.push_back(argument); | 241 argv.push_back(argument); |
249 } | 242 } |
250 | 243 |
251 base::CommandLine command_line(argv); | 244 base::CommandLine command_line(argv); |
252 | 245 |
253 // Add a random session id to link experimental reporter runs together. | 246 // Add a random session id to link experimental reporter runs together. |
254 command_line.AppendSwitchASCII(kSessionIdSwitch, session_id); | 247 command_line.AppendSwitchASCII(chrome_cleaner::kSessionIdSwitch, |
| 248 session_id); |
255 | 249 |
256 const std::string experiment_group = | 250 const std::string experiment_group = |
257 variations::GetVariationParamValueByFeature( | 251 variations::GetVariationParamValueByFeature( |
258 kExperimentalEngineFeature, "experiment_group_for_reporting"); | 252 kExperimentalEngineFeature, "experiment_group_for_reporting"); |
259 command_line.AppendSwitchNative("engine-experiment-group", | 253 command_line.AppendSwitchNative("engine-experiment-group", |
260 experiment_group.empty() | 254 experiment_group.empty() |
261 ? L"missing_experiment_group" | 255 ? L"missing_experiment_group" |
262 : base::UTF8ToUTF16(experiment_group)); | 256 : base::UTF8ToUTF16(experiment_group)); |
263 | 257 |
264 // Add the histogram suffix to the command-line as well, so that the | 258 // Add the histogram suffix to the command-line as well, so that the |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 const base::Version& version, | 317 const base::Version& version, |
324 const base::FilePath& install_dir, | 318 const base::FilePath& install_dir, |
325 std::unique_ptr<base::DictionaryValue> manifest) { | 319 std::unique_ptr<base::DictionaryValue> manifest) { |
326 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 320 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
327 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName)); | 321 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName)); |
328 if (IsExperimentalEngineEnabled()) { | 322 if (IsExperimentalEngineEnabled()) { |
329 RunExperimentalSwReporter(exe_path, version, std::move(manifest), | 323 RunExperimentalSwReporter(exe_path, version, std::move(manifest), |
330 reporter_runner_); | 324 reporter_runner_); |
331 } else { | 325 } else { |
332 base::CommandLine command_line(exe_path); | 326 base::CommandLine command_line(exe_path); |
333 command_line.AppendSwitchASCII(kSessionIdSwitch, GenerateSessionId()); | 327 command_line.AppendSwitchASCII(chrome_cleaner::kSessionIdSwitch, |
| 328 GenerateSessionId()); |
334 auto invocation = SwReporterInvocation::FromCommandLine(command_line); | 329 auto invocation = SwReporterInvocation::FromCommandLine(command_line); |
335 invocation.supported_behaviours = | 330 invocation.supported_behaviours = |
336 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS | | 331 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS | |
337 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT | | 332 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT | |
338 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; | 333 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS; |
339 | 334 |
340 safe_browsing::SwReporterQueue invocations; | 335 safe_browsing::SwReporterQueue invocations; |
341 invocations.push(invocation); | 336 invocations.push(invocation); |
342 reporter_runner_.Run(invocations, version); | 337 reporter_runner_.Run(invocations, version); |
343 } | 338 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 return is_experimental_engine_supported_ && | 385 return is_experimental_engine_supported_ && |
391 base::FeatureList::IsEnabled(kExperimentalEngineFeature); | 386 base::FeatureList::IsEnabled(kExperimentalEngineFeature); |
392 } | 387 } |
393 | 388 |
394 void RegisterSwReporterComponent(ComponentUpdateService* cus) { | 389 void RegisterSwReporterComponent(ComponentUpdateService* cus) { |
395 if (!safe_browsing::IsSwReporterEnabled()) | 390 if (!safe_browsing::IsSwReporterEnabled()) |
396 return; | 391 return; |
397 | 392 |
398 // Check if we have information from Cleaner and record UMA statistics. | 393 // Check if we have information from Cleaner and record UMA statistics. |
399 base::string16 cleaner_key_name( | 394 base::string16 cleaner_key_name( |
400 safe_browsing::kSoftwareRemovalToolRegistryKey); | 395 chrome_cleaner::kSoftwareRemovalToolRegistryKey); |
401 cleaner_key_name.append(1, L'\\').append(kCleanerSuffixRegistryKey); | 396 cleaner_key_name.append(1, L'\\').append(chrome_cleaner::kCleanerSubKey); |
402 base::win::RegKey cleaner_key( | 397 base::win::RegKey cleaner_key( |
403 HKEY_CURRENT_USER, cleaner_key_name.c_str(), KEY_ALL_ACCESS); | 398 HKEY_CURRENT_USER, cleaner_key_name.c_str(), KEY_ALL_ACCESS); |
404 // Cleaner is assumed to have run if we have a start time. | 399 // Cleaner is assumed to have run if we have a start time. |
405 if (cleaner_key.Valid()) { | 400 if (cleaner_key.Valid()) { |
406 if (cleaner_key.HasValue(safe_browsing::kStartTimeValueName)) { | 401 if (cleaner_key.HasValue(chrome_cleaner::kStartTimeValueName)) { |
407 // Get version number. | 402 // Get version number. |
408 if (cleaner_key.HasValue(kVersionValueName)) { | 403 if (cleaner_key.HasValue(chrome_cleaner::kVersionValueName)) { |
409 DWORD version; | 404 DWORD version; |
410 cleaner_key.ReadValueDW(kVersionValueName, &version); | 405 cleaner_key.ReadValueDW(chrome_cleaner::kVersionValueName, &version); |
411 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.Cleaner.Version", | 406 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.Cleaner.Version", |
412 version); | 407 version); |
413 cleaner_key.DeleteValue(kVersionValueName); | 408 cleaner_key.DeleteValue(chrome_cleaner::kVersionValueName); |
414 } | 409 } |
415 // Get start & end time. If we don't have an end time, we can assume the | 410 // Get start & end time. If we don't have an end time, we can assume the |
416 // cleaner has not completed. | 411 // cleaner has not completed. |
417 int64_t start_time_value; | 412 int64_t start_time_value; |
418 cleaner_key.ReadInt64(safe_browsing::kStartTimeValueName, | 413 cleaner_key.ReadInt64(chrome_cleaner::kStartTimeValueName, |
419 &start_time_value); | 414 &start_time_value); |
420 | 415 |
421 bool completed = cleaner_key.HasValue(safe_browsing::kEndTimeValueName); | 416 bool completed = cleaner_key.HasValue(chrome_cleaner::kEndTimeValueName); |
422 SRTHasCompleted(completed ? SRT_COMPLETED_YES : SRT_COMPLETED_NOT_YET); | 417 SRTHasCompleted(completed ? SRT_COMPLETED_YES : SRT_COMPLETED_NOT_YET); |
423 if (completed) { | 418 if (completed) { |
424 int64_t end_time_value; | 419 int64_t end_time_value; |
425 cleaner_key.ReadInt64(safe_browsing::kEndTimeValueName, | 420 cleaner_key.ReadInt64(chrome_cleaner::kEndTimeValueName, |
426 &end_time_value); | 421 &end_time_value); |
427 cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName); | 422 cleaner_key.DeleteValue(chrome_cleaner::kEndTimeValueName); |
428 base::TimeDelta run_time( | 423 base::TimeDelta run_time( |
429 base::Time::FromInternalValue(end_time_value) - | 424 base::Time::FromInternalValue(end_time_value) - |
430 base::Time::FromInternalValue(start_time_value)); | 425 base::Time::FromInternalValue(start_time_value)); |
431 UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.Cleaner.RunningTime", | 426 UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.Cleaner.RunningTime", |
432 run_time); | 427 run_time); |
433 } | 428 } |
434 // Get exit code. Assume nothing was found if we can't read the exit code. | 429 // Get exit code. Assume nothing was found if we can't read the exit code. |
435 DWORD exit_code = safe_browsing::kSwReporterNothingFound; | 430 DWORD exit_code = chrome_cleaner::kSwReporterNothingFound; |
436 if (cleaner_key.HasValue(kExitCodeValueName)) { | 431 if (cleaner_key.HasValue(chrome_cleaner::kExitCodeValueName)) { |
437 cleaner_key.ReadValueDW(kExitCodeValueName, &exit_code); | 432 cleaner_key.ReadValueDW(chrome_cleaner::kExitCodeValueName, &exit_code); |
438 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.Cleaner.ExitCode", | 433 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.Cleaner.ExitCode", |
439 exit_code); | 434 exit_code); |
440 cleaner_key.DeleteValue(kExitCodeValueName); | 435 cleaner_key.DeleteValue(chrome_cleaner::kExitCodeValueName); |
441 } | 436 } |
442 cleaner_key.DeleteValue(safe_browsing::kStartTimeValueName); | 437 cleaner_key.DeleteValue(chrome_cleaner::kStartTimeValueName); |
443 | 438 |
444 if (exit_code == safe_browsing::kSwReporterPostRebootCleanupNeeded || | 439 if (exit_code == chrome_cleaner::kSwReporterPostRebootCleanupNeeded || |
445 exit_code == | 440 exit_code == |
446 safe_browsing::kSwReporterDelayedPostRebootCleanupNeeded) { | 441 chrome_cleaner::kSwReporterDelayedPostRebootCleanupNeeded) { |
447 // Check if we are running after the user has rebooted. | 442 // Check if we are running after the user has rebooted. |
448 base::TimeDelta elapsed( | 443 base::TimeDelta elapsed( |
449 base::Time::Now() - | 444 base::Time::Now() - |
450 base::Time::FromInternalValue(start_time_value)); | 445 base::Time::FromInternalValue(start_time_value)); |
451 DCHECK_GT(elapsed.InMilliseconds(), 0); | 446 DCHECK_GT(elapsed.InMilliseconds(), 0); |
452 UMA_HISTOGRAM_BOOLEAN( | 447 UMA_HISTOGRAM_BOOLEAN( |
453 "SoftwareReporter.Cleaner.HasRebooted", | 448 "SoftwareReporter.Cleaner.HasRebooted", |
454 static_cast<uint64_t>(elapsed.InMilliseconds()) > ::GetTickCount()); | 449 static_cast<uint64_t>(elapsed.InMilliseconds()) > ::GetTickCount()); |
455 } | 450 } |
456 | 451 |
457 if (cleaner_key.HasValue(kUploadResultsValueName)) { | 452 if (cleaner_key.HasValue(chrome_cleaner::kUploadResultsValueName)) { |
458 base::string16 upload_results; | 453 base::string16 upload_results; |
459 cleaner_key.ReadValue(kUploadResultsValueName, &upload_results); | 454 cleaner_key.ReadValue(chrome_cleaner::kUploadResultsValueName, |
| 455 &upload_results); |
460 ReportUploadsWithUma(upload_results); | 456 ReportUploadsWithUma(upload_results); |
461 } | 457 } |
462 } else { | 458 } else { |
463 if (cleaner_key.HasValue(safe_browsing::kEndTimeValueName)) { | 459 if (cleaner_key.HasValue(chrome_cleaner::kEndTimeValueName)) { |
464 SRTHasCompleted(SRT_COMPLETED_LATER); | 460 SRTHasCompleted(SRT_COMPLETED_LATER); |
465 cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName); | 461 cleaner_key.DeleteValue(chrome_cleaner::kEndTimeValueName); |
466 } | 462 } |
467 } | 463 } |
468 } | 464 } |
469 | 465 |
470 // If the experiment is not explicitly enabled on all platforms, it | 466 // If the experiment is not explicitly enabled on all platforms, it |
471 // should be only enabled on x86. There's no way to check this in the | 467 // should be only enabled on x86. There's no way to check this in the |
472 // variations config so we'll hard-code it. | 468 // variations config so we'll hard-code it. |
473 const bool is_x86_architecture = | 469 const bool is_x86_architecture = |
474 base::win::OSInfo::GetInstance()->architecture() == | 470 base::win::OSInfo::GetInstance()->architecture() == |
475 base::win::OSInfo::X86_ARCHITECTURE; | 471 base::win::OSInfo::X86_ARCHITECTURE; |
(...skipping 19 matching lines...) Expand all Loading... |
495 } | 491 } |
496 | 492 |
497 void RegisterProfilePrefsForSwReporter( | 493 void RegisterProfilePrefsForSwReporter( |
498 user_prefs::PrefRegistrySyncable* registry) { | 494 user_prefs::PrefRegistrySyncable* registry) { |
499 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, ""); | 495 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, ""); |
500 | 496 |
501 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); | 497 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); |
502 } | 498 } |
503 | 499 |
504 } // namespace component_updater | 500 } // namespace component_updater |
OLD | NEW |