| 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 |