| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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/safe_browsing/srt_fetcher_win.h" | 5 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 #include "net/base/load_flags.h" | 49 #include "net/base/load_flags.h" |
| 50 #include "net/http/http_status_code.h" | 50 #include "net/http/http_status_code.h" |
| 51 #include "net/url_request/url_fetcher.h" | 51 #include "net/url_request/url_fetcher.h" |
| 52 #include "net/url_request/url_fetcher_delegate.h" | 52 #include "net/url_request/url_fetcher_delegate.h" |
| 53 #include "net/url_request/url_request_context_getter.h" | 53 #include "net/url_request/url_request_context_getter.h" |
| 54 | 54 |
| 55 using content::BrowserThread; | 55 using content::BrowserThread; |
| 56 | 56 |
| 57 namespace safe_browsing { | 57 namespace safe_browsing { |
| 58 | 58 |
| 59 // TODO(b/647763) Change the registry key to properly handle cases when the user |
| 60 // runs Google Chrome stable alongside Google Chrome SxS. |
| 59 const wchar_t kSoftwareRemovalToolRegistryKey[] = | 61 const wchar_t kSoftwareRemovalToolRegistryKey[] = |
| 60 L"Software\\Google\\Software Removal Tool"; | 62 L"Software\\Google\\Software Removal Tool"; |
| 61 | 63 |
| 62 const wchar_t kCleanerSubKey[] = L"Cleaner"; | 64 const wchar_t kCleanerSubKey[] = L"Cleaner"; |
| 63 | 65 |
| 64 const wchar_t kEndTimeValueName[] = L"EndTime"; | 66 const wchar_t kEndTimeValueName[] = L"EndTime"; |
| 65 const wchar_t kStartTimeValueName[] = L"StartTime"; | 67 const wchar_t kStartTimeValueName[] = L"StartTime"; |
| 66 | 68 |
| 67 const char kExtendedSafeBrowsingEnabledSwitch[] = | 69 const char kExtendedSafeBrowsingEnabledSwitch[] = |
| 68 "extended-safebrowsing-enabled"; | 70 "extended-safebrowsing-enabled"; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 SW_REPORTER_NO_LOCAL_STATE = 9, | 107 SW_REPORTER_NO_LOCAL_STATE = 9, |
| 106 SW_REPORTER_NO_PROMPT_NEEDED = 10, | 108 SW_REPORTER_NO_PROMPT_NEEDED = 10, |
| 107 SW_REPORTER_NO_PROMPT_FIELD_TRIAL = 11, | 109 SW_REPORTER_NO_PROMPT_FIELD_TRIAL = 11, |
| 108 SW_REPORTER_ALREADY_PROMPTED = 12, | 110 SW_REPORTER_ALREADY_PROMPTED = 12, |
| 109 SW_REPORTER_RAN_DAILY = 13, | 111 SW_REPORTER_RAN_DAILY = 13, |
| 110 SW_REPORTER_ADDED_TO_MENU = 14, | 112 SW_REPORTER_ADDED_TO_MENU = 14, |
| 111 | 113 |
| 112 SW_REPORTER_MAX, | 114 SW_REPORTER_MAX, |
| 113 }; | 115 }; |
| 114 | 116 |
| 117 // Used to send UMA information showing whether uploading of Software Reporter |
| 118 // logs is enabled, or the reason why not. |
| 119 // Replicated in the histograms.xml file, so the order MUST NOT CHANGE. |
| 120 enum SwReporterLogsUploadsEnabled { |
| 121 REPORTER_LOGS_UPLOADS_ENABLED = 0, |
| 122 REPORTER_LOGS_UPLOADS_SBER_DISABLED = 1, |
| 123 REPORTER_LOGS_UPLOADS_RECENTLY_SENT_LOGS = 2, |
| 124 REPORTER_LOGS_UPLOADS_MAX, |
| 125 }; |
| 126 |
| 127 // Used to send UMA information about missing logs upload result in the registry |
| 128 // for the reporter. Replicated in the histograms.xml file, so the order |
| 129 // MUST NOT CHANGE. |
| 130 enum SwReporterLogsUploadResultRegistryError { |
| 131 REPORTER_LOGS_UPLOAD_RESULT_ERROR_NO_ERROR = 0, |
| 132 REPORTER_LOGS_UPLOAD_RESULT_ERROR_REGISTRY_KEY_INVALID = 1, |
| 133 REPORTER_LOGS_UPLOAD_RESULT_ERROR_VALUE_NOT_FOUND = 2, |
| 134 REPORTER_LOGS_UPLOAD_RESULT_ERROR_VALUE_OUT_OF_BOUNDS = 3, |
| 135 REPORTER_LOGS_UPLOAD_RESULT_ERROR_MAX, |
| 136 }; |
| 137 |
| 115 const char kRunningTimeErrorMetricName[] = | 138 const char kRunningTimeErrorMetricName[] = |
| 116 "SoftwareReporter.RunningTimeRegistryError"; | 139 "SoftwareReporter.RunningTimeRegistryError"; |
| 117 | 140 |
| 118 SwReporterTestingDelegate* g_testing_delegate_ = nullptr; | 141 SwReporterTestingDelegate* g_testing_delegate_ = nullptr; |
| 119 | 142 |
| 120 const wchar_t kScanTimesSubKey[] = L"ScanTimes"; | 143 const wchar_t kScanTimesSubKey[] = L"ScanTimes"; |
| 121 const wchar_t kFoundUwsValueName[] = L"FoundUws"; | 144 const wchar_t kFoundUwsValueName[] = L"FoundUws"; |
| 122 const wchar_t kMemoryUsedValueName[] = L"MemoryUsed"; | 145 const wchar_t kMemoryUsedValueName[] = L"MemoryUsed"; |
| 146 const wchar_t kLogsUploadResultValueName[] = L"LogsUploadResult"; |
| 123 | 147 |
| 124 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS"; | 148 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS"; |
| 125 const char kFoundUwsReadErrorMetricName[] = | 149 const char kFoundUwsReadErrorMetricName[] = |
| 126 "SoftwareReporter.FoundUwSReadError"; | 150 "SoftwareReporter.FoundUwSReadError"; |
| 127 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes"; | 151 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes"; |
| 128 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed"; | 152 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed"; |
| 153 const char kLogsUploadEnabledMetricName[] = |
| 154 "SoftwareReporter.LogsUploadEnabled"; |
| 155 const char kLogsUploadResultMetricName[] = "SoftwareReporter.LogsUploadResult"; |
| 156 const char kLogsUploadResultRegistryErrorMetricName[] = |
| 157 "SoftwareReporter.LogsUploadResultRegistryError"; |
| 158 |
| 159 // The max value for histogram SoftwareReporter.LogsUploadResult, which is used |
| 160 // to send UMA information about the result of Software Reporter's attempt to |
| 161 // upload logs, when logs are enabled. This value must be consistent with the |
| 162 // SoftwareReporterLogsUploadResult enum defined in the histograms.xml file. |
| 163 const int kSwReporterLogsUploadResultMax = 30; |
| 129 | 164 |
| 130 // Reports metrics about the software reporter via UMA (and sometimes Rappor). | 165 // Reports metrics about the software reporter via UMA (and sometimes Rappor). |
| 131 class UMAHistogramReporter { | 166 class UMAHistogramReporter { |
| 132 public: | 167 public: |
| 133 UMAHistogramReporter() : UMAHistogramReporter(std::string()) {} | 168 UMAHistogramReporter() : UMAHistogramReporter(std::string()) {} |
| 134 | 169 |
| 135 explicit UMAHistogramReporter(const std::string& suffix) | 170 explicit UMAHistogramReporter(const std::string& suffix) |
| 136 : suffix_(suffix), | 171 : suffix_(suffix), |
| 137 registry_key_(suffix.empty() ? kSoftwareRemovalToolRegistryKey | 172 registry_key_(suffix.empty() ? kSoftwareRemovalToolRegistryKey |
| 138 : base::StringPrintf( | 173 : base::StringPrintf( |
| (...skipping 29 matching lines...) Expand all Loading... |
| 168 } | 203 } |
| 169 RecordSparseHistogram("SoftwareReporter.MajorVersion", major_version); | 204 RecordSparseHistogram("SoftwareReporter.MajorVersion", major_version); |
| 170 } | 205 } |
| 171 | 206 |
| 172 void ReportExitCode(int exit_code) const { | 207 void ReportExitCode(int exit_code) const { |
| 173 RecordSparseHistogram("SoftwareReporter.ExitCode", exit_code); | 208 RecordSparseHistogram("SoftwareReporter.ExitCode", exit_code); |
| 174 } | 209 } |
| 175 | 210 |
| 176 // Reports UwS found by the software reporter tool via UMA and RAPPOR. | 211 // Reports UwS found by the software reporter tool via UMA and RAPPOR. |
| 177 void ReportFoundUwS(bool use_rappor) const { | 212 void ReportFoundUwS(bool use_rappor) const { |
| 178 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), | 213 base::win::RegKey reporter_key; |
| 179 KEY_QUERY_VALUE | KEY_SET_VALUE); | |
| 180 std::vector<base::string16> found_uws_strings; | 214 std::vector<base::string16> found_uws_strings; |
| 181 if (reporter_key.Valid() && | 215 if (reporter_key.Open(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 182 reporter_key.ReadValues(kFoundUwsValueName, &found_uws_strings) == | 216 KEY_QUERY_VALUE | KEY_SET_VALUE) != ERROR_SUCCESS || |
| 217 reporter_key.ReadValues(kFoundUwsValueName, &found_uws_strings) != |
| 183 ERROR_SUCCESS) { | 218 ERROR_SUCCESS) { |
| 184 rappor::RapporService* rappor_service = nullptr; | 219 return; |
| 185 if (use_rappor) | 220 } |
| 186 rappor_service = g_browser_process->rappor_service(); | |
| 187 | 221 |
| 188 bool parse_error = false; | 222 rappor::RapporService* rappor_service = nullptr; |
| 189 for (const base::string16& uws_string : found_uws_strings) { | 223 if (use_rappor) |
| 190 // All UwS ids are expected to be integers. | 224 rappor_service = g_browser_process->rappor_service(); |
| 191 uint32_t uws_id = 0; | 225 |
| 192 if (base::StringToUint(uws_string, &uws_id)) { | 226 bool parse_error = false; |
| 193 RecordSparseHistogram(kFoundUwsMetricName, uws_id); | 227 for (const base::string16& uws_string : found_uws_strings) { |
| 194 if (rappor_service) { | 228 // All UwS ids are expected to be integers. |
| 195 rappor_service->RecordSample(kFoundUwsMetricName, | 229 uint32_t uws_id = 0; |
| 196 rappor::COARSE_RAPPOR_TYPE, | 230 if (base::StringToUint(uws_string, &uws_id)) { |
| 197 base::UTF16ToUTF8(uws_string)); | 231 RecordSparseHistogram(kFoundUwsMetricName, uws_id); |
| 198 } | 232 if (rappor_service) { |
| 199 } else { | 233 rappor_service->RecordSample(kFoundUwsMetricName, |
| 200 parse_error = true; | 234 rappor::COARSE_RAPPOR_TYPE, |
| 235 base::UTF16ToUTF8(uws_string)); |
| 201 } | 236 } |
| 237 } else { |
| 238 parse_error = true; |
| 202 } | 239 } |
| 203 | 240 |
| 204 // Clean up the old value. | 241 // Clean up the old value. |
| 205 reporter_key.DeleteValue(kFoundUwsValueName); | 242 reporter_key.DeleteValue(kFoundUwsValueName); |
| 206 | 243 |
| 207 RecordBooleanHistogram(kFoundUwsReadErrorMetricName, parse_error); | 244 RecordBooleanHistogram(kFoundUwsReadErrorMetricName, parse_error); |
| 208 } | 245 } |
| 209 } | 246 } |
| 210 | 247 |
| 211 // Reports to UMA the memory usage of the software reporter tool as reported | 248 // Reports to UMA the memory usage of the software reporter tool as reported |
| 212 // by the tool itself in the Windows registry. | 249 // by the tool itself in the Windows registry. |
| 213 void ReportMemoryUsage() const { | 250 void ReportMemoryUsage() const { |
| 214 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), | 251 base::win::RegKey reporter_key; |
| 215 KEY_QUERY_VALUE | KEY_SET_VALUE); | |
| 216 DWORD memory_used = 0; | 252 DWORD memory_used = 0; |
| 217 if (reporter_key.Valid() && | 253 if (reporter_key.Open(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 218 reporter_key.ReadValueDW(kMemoryUsedValueName, &memory_used) == | 254 KEY_QUERY_VALUE | KEY_SET_VALUE) != ERROR_SUCCESS || |
| 255 reporter_key.ReadValueDW(kMemoryUsedValueName, &memory_used) != |
| 219 ERROR_SUCCESS) { | 256 ERROR_SUCCESS) { |
| 220 RecordMemoryKBHistogram(kMemoryUsedMetricName, memory_used); | 257 return; |
| 221 reporter_key.DeleteValue(kMemoryUsedValueName); | |
| 222 } | 258 } |
| 259 RecordMemoryKBHistogram(kMemoryUsedMetricName, memory_used); |
| 260 reporter_key.DeleteValue(kMemoryUsedValueName); |
| 223 } | 261 } |
| 224 | 262 |
| 225 // Reports the SwReporter run time with UMA both as reported by the tool via | 263 // Reports the SwReporter run time with UMA both as reported by the tool via |
| 226 // the registry and as measured by |ReporterRunner|. | 264 // the registry and as measured by |ReporterRunner|. |
| 227 void ReportRuntime(const base::TimeDelta& reporter_running_time) const { | 265 void ReportRuntime(const base::TimeDelta& reporter_running_time) const { |
| 228 RecordLongTimesHistogram("SoftwareReporter.RunningTimeAccordingToChrome", | 266 RecordLongTimesHistogram("SoftwareReporter.RunningTimeAccordingToChrome", |
| 229 reporter_running_time); | 267 reporter_running_time); |
| 230 | 268 |
| 231 // TODO(b/641081): This should only have KEY_QUERY_VALUE and KEY_SET_VALUE, | 269 // TODO(b/641081): This should only have KEY_QUERY_VALUE and KEY_SET_VALUE. |
| 232 // and use Open to avoid creating the key if it doesn't already exist. | 270 base::win::RegKey reporter_key; |
| 233 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), | 271 if (reporter_key.Open(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 234 KEY_ALL_ACCESS); | 272 KEY_ALL_ACCESS) != ERROR_SUCCESS) { |
| 235 if (!reporter_key.Valid()) { | |
| 236 RecordEnumerationHistogram( | 273 RecordEnumerationHistogram( |
| 237 kRunningTimeErrorMetricName, | 274 kRunningTimeErrorMetricName, |
| 238 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID, | 275 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID, |
| 239 REPORTER_RUNNING_TIME_ERROR_MAX); | 276 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 240 return; | 277 return; |
| 241 } | 278 } |
| 242 | 279 |
| 243 bool has_start_time = false; | 280 bool has_start_time = false; |
| 244 int64_t start_time_value = 0; | 281 int64_t start_time_value = 0; |
| 245 if (reporter_key.HasValue(kStartTimeValueName) && | 282 if (reporter_key.HasValue(kStartTimeValueName) && |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 RecordEnumerationHistogram(kRunningTimeErrorMetricName, | 317 RecordEnumerationHistogram(kRunningTimeErrorMetricName, |
| 281 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME, | 318 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME, |
| 282 REPORTER_RUNNING_TIME_ERROR_MAX); | 319 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 283 } | 320 } |
| 284 } | 321 } |
| 285 | 322 |
| 286 // Reports the UwS scan times of the software reporter tool via UMA. | 323 // Reports the UwS scan times of the software reporter tool via UMA. |
| 287 void ReportScanTimes() const { | 324 void ReportScanTimes() const { |
| 288 base::string16 scan_times_key_path = base::StringPrintf( | 325 base::string16 scan_times_key_path = base::StringPrintf( |
| 289 L"%ls\\%ls", registry_key_.c_str(), kScanTimesSubKey); | 326 L"%ls\\%ls", registry_key_.c_str(), kScanTimesSubKey); |
| 290 // TODO(b/641081): This should only have KEY_QUERY_VALUE and KEY_SET_VALUE, | 327 // TODO(b/641081): This should only have KEY_QUERY_VALUE and KEY_SET_VALUE. |
| 291 // and use Open to avoid creating the key if it doesn't already exist. | 328 base::win::RegKey scan_times_key; |
| 292 base::win::RegKey scan_times_key( | 329 if (scan_times_key.Open(HKEY_CURRENT_USER, scan_times_key_path.c_str(), |
| 293 HKEY_CURRENT_USER, scan_times_key_path.c_str(), KEY_ALL_ACCESS); | 330 KEY_ALL_ACCESS) != ERROR_SUCCESS) { |
| 294 if (!scan_times_key.Valid()) | |
| 295 return; | 331 return; |
| 332 } |
| 296 | 333 |
| 297 base::string16 value_name; | 334 base::string16 value_name; |
| 298 int uws_id = 0; | 335 int uws_id = 0; |
| 299 int64_t raw_scan_time = 0; | 336 int64_t raw_scan_time = 0; |
| 300 int num_scan_times = scan_times_key.GetValueCount(); | 337 int num_scan_times = scan_times_key.GetValueCount(); |
| 301 for (int i = 0; i < num_scan_times; ++i) { | 338 for (int i = 0; i < num_scan_times; ++i) { |
| 302 if (scan_times_key.GetValueNameAt(i, &value_name) == ERROR_SUCCESS && | 339 if (scan_times_key.GetValueNameAt(i, &value_name) == ERROR_SUCCESS && |
| 303 base::StringToInt(value_name, &uws_id) && | 340 base::StringToInt(value_name, &uws_id) && |
| 304 scan_times_key.ReadInt64(value_name.c_str(), &raw_scan_time) == | 341 scan_times_key.ReadInt64(value_name.c_str(), &raw_scan_time) == |
| 305 ERROR_SUCCESS) { | 342 ERROR_SUCCESS) { |
| 306 base::TimeDelta scan_time = | 343 base::TimeDelta scan_time = |
| 307 base::TimeDelta::FromInternalValue(raw_scan_time); | 344 base::TimeDelta::FromInternalValue(raw_scan_time); |
| 308 // We report the number of seconds plus one because it can take less | 345 // We report the number of seconds plus one because it can take less |
| 309 // than one second to scan some UwS and the count passed to |AddCount| | 346 // than one second to scan some UwS and the count passed to |AddCount| |
| 310 // must be at least one. | 347 // must be at least one. |
| 311 RecordSparseHistogramCount(kScanTimesMetricName, uws_id, | 348 RecordSparseHistogramCount(kScanTimesMetricName, uws_id, |
| 312 scan_time.InSeconds() + 1); | 349 scan_time.InSeconds() + 1); |
| 313 } | 350 } |
| 314 } | 351 } |
| 315 // Clean up by deleting the scan times key, which is a subkey of the main | 352 // Clean up by deleting the scan times key, which is a subkey of the main |
| 316 // reporter key. | 353 // reporter key. |
| 317 scan_times_key.Close(); | 354 scan_times_key.Close(); |
| 318 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), | 355 base::win::RegKey reporter_key; |
| 319 KEY_ENUMERATE_SUB_KEYS); | 356 if (reporter_key.Open(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 320 if (reporter_key.Valid()) | 357 KEY_ENUMERATE_SUB_KEYS) == ERROR_SUCCESS) { |
| 321 reporter_key.DeleteKey(kScanTimesSubKey); | 358 reporter_key.DeleteKey(kScanTimesSubKey); |
| 359 } |
| 322 } | 360 } |
| 323 | 361 |
| 324 void RecordReporterStep(SwReporterUmaValue value) { | 362 void RecordReporterStep(SwReporterUmaValue value) { |
| 325 RecordEnumerationHistogram("SoftwareReporter.Step", value, SW_REPORTER_MAX); | 363 RecordEnumerationHistogram("SoftwareReporter.Step", value, SW_REPORTER_MAX); |
| 326 } | 364 } |
| 327 | 365 |
| 366 void RecordLogsUploadEnabled(SwReporterLogsUploadsEnabled value) { |
| 367 RecordEnumerationHistogram(kLogsUploadEnabledMetricName, value, |
| 368 REPORTER_LOGS_UPLOADS_MAX); |
| 369 } |
| 370 |
| 371 void RecordLogsUploadResult() { |
| 372 base::win::RegKey reporter_key; |
| 373 DWORD logs_upload_result = 0; |
| 374 if (reporter_key.Open(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 375 KEY_QUERY_VALUE | KEY_SET_VALUE) != ERROR_SUCCESS) { |
| 376 RecordEnumerationHistogram( |
| 377 kLogsUploadResultRegistryErrorMetricName, |
| 378 REPORTER_LOGS_UPLOAD_RESULT_ERROR_REGISTRY_KEY_INVALID, |
| 379 REPORTER_LOGS_UPLOAD_RESULT_ERROR_MAX); |
| 380 return; |
| 381 } |
| 382 |
| 383 if (reporter_key.ReadValueDW(kLogsUploadResultValueName, |
| 384 &logs_upload_result) != ERROR_SUCCESS) { |
| 385 RecordEnumerationHistogram( |
| 386 kLogsUploadResultRegistryErrorMetricName, |
| 387 REPORTER_LOGS_UPLOAD_RESULT_ERROR_VALUE_NOT_FOUND, |
| 388 REPORTER_LOGS_UPLOAD_RESULT_ERROR_MAX); |
| 389 return; |
| 390 } |
| 391 |
| 392 if (logs_upload_result < 0 || |
| 393 logs_upload_result >= kSwReporterLogsUploadResultMax) { |
| 394 RecordEnumerationHistogram( |
| 395 kLogsUploadResultRegistryErrorMetricName, |
| 396 REPORTER_LOGS_UPLOAD_RESULT_ERROR_VALUE_OUT_OF_BOUNDS, |
| 397 REPORTER_LOGS_UPLOAD_RESULT_ERROR_MAX); |
| 398 return; |
| 399 } |
| 400 |
| 401 RecordEnumerationHistogram(kLogsUploadResultMetricName, |
| 402 static_cast<Sample>(logs_upload_result), |
| 403 kSwReporterLogsUploadResultMax); |
| 404 reporter_key.DeleteValue(kLogsUploadResultValueName); |
| 405 RecordEnumerationHistogram(kLogsUploadResultRegistryErrorMetricName, |
| 406 REPORTER_LOGS_UPLOAD_RESULT_ERROR_NO_ERROR, |
| 407 REPORTER_LOGS_UPLOAD_RESULT_ERROR_MAX); |
| 408 } |
| 409 |
| 328 private: | 410 private: |
| 329 using Sample = base::HistogramBase::Sample; | 411 using Sample = base::HistogramBase::Sample; |
| 330 | 412 |
| 331 static constexpr base::HistogramBase::Flags kUmaHistogramFlag = | 413 static constexpr base::HistogramBase::Flags kUmaHistogramFlag = |
| 332 base::HistogramBase::kUmaTargetedHistogramFlag; | 414 base::HistogramBase::kUmaTargetedHistogramFlag; |
| 333 | 415 |
| 334 // Helper functions to record histograms with an optional suffix added to the | 416 // Helper functions to record histograms with an optional suffix added to the |
| 335 // histogram name. The UMA_HISTOGRAM macros can't be used because they | 417 // histogram name. The UMA_HISTOGRAM macros can't be used because they |
| 336 // require a constant string. | 418 // require a constant string. |
| 337 | 419 |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 if (g_testing_delegate_) | 756 if (g_testing_delegate_) |
| 675 g_testing_delegate_->NotifyLaunchReady(); | 757 g_testing_delegate_->NotifyLaunchReady(); |
| 676 | 758 |
| 677 // Add switches for users who opted into extended Safe Browsing reporting. | 759 // Add switches for users who opted into extended Safe Browsing reporting. |
| 678 // The invocation object is changed locally right before the actual process | 760 // The invocation object is changed locally right before the actual process |
| 679 // is launched because user status can change between this and the next run | 761 // is launched because user status can change between this and the next run |
| 680 // for this ReporterRunner object. For example, the ReporterDone() callback | 762 // for this ReporterRunner object. For example, the ReporterDone() callback |
| 681 // schedules the next run for a few days later, and the user might have | 763 // schedules the next run for a few days later, and the user might have |
| 682 // changed settings in the meantime. | 764 // changed settings in the meantime. |
| 683 PrefService* local_state = g_browser_process->local_state(); | 765 PrefService* local_state = g_browser_process->local_state(); |
| 684 if (next_invocation.flags & SwReporterInvocation::FLAG_SEND_REPORTER_LOGS && | 766 if (next_invocation.BehaviourIsSupported( |
| 767 SwReporterInvocation::BEHAVIOUR_ALLOW_SEND_REPORTER_LOGS) && |
| 685 local_state && ShouldSendReporterLogs(*local_state)) { | 768 local_state && ShouldSendReporterLogs(*local_state)) { |
| 769 next_invocation.logs_upload_enabled = true; |
| 686 AddSwitchesForExtendedReporterUser(&next_invocation); | 770 AddSwitchesForExtendedReporterUser(&next_invocation); |
| 687 // Set the local state value before the first attempt to run the | 771 // Set the local state value before the first attempt to run the |
| 688 // reporter, because we only want to upload logs once in the window | 772 // reporter, because we only want to upload logs once in the window |
| 689 // defined by |kDaysBetweenReporterLogsSent|. If we set with other local | 773 // defined by |kDaysBetweenReporterLogsSent|. If we set with other local |
| 690 // state values after the reporter runs, we could send logs again too | 774 // state values after the reporter runs, we could send logs again too |
| 691 // quickly (for example, if Chrome stops before the reporter finishes). | 775 // quickly (for example, if Chrome stops before the reporter finishes). |
| 692 local_state->SetInt64(prefs::kSwReporterLastTimeSentReport, | 776 local_state->SetInt64(prefs::kSwReporterLastTimeSentReport, |
| 693 base::Time::Now().ToInternalValue()); | 777 base::Time::Now().ToInternalValue()); |
| 694 } | 778 } |
| 695 | 779 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 | 822 |
| 739 // If the reporter failed to launch, do not process the results. (The exit | 823 // If the reporter failed to launch, do not process the results. (The exit |
| 740 // code itself doesn't need to be logged in this case because | 824 // code itself doesn't need to be logged in this case because |
| 741 // SW_REPORTER_FAILED_TO_START is logged in |LaunchAndWaitForExit|.) | 825 // SW_REPORTER_FAILED_TO_START is logged in |LaunchAndWaitForExit|.) |
| 742 if (exit_code == kReporterFailureExitCode) | 826 if (exit_code == kReporterFailureExitCode) |
| 743 return; | 827 return; |
| 744 | 828 |
| 745 UMAHistogramReporter uma(finished_invocation.suffix); | 829 UMAHistogramReporter uma(finished_invocation.suffix); |
| 746 uma.ReportVersion(version); | 830 uma.ReportVersion(version); |
| 747 uma.ReportExitCode(exit_code); | 831 uma.ReportExitCode(exit_code); |
| 748 uma.ReportFoundUwS(finished_invocation.flags & | 832 uma.ReportFoundUwS(finished_invocation.BehaviourIsSupported( |
| 749 SwReporterInvocation::FLAG_LOG_TO_RAPPOR); | 833 SwReporterInvocation::BEHAVIOUR_LOG_TO_RAPPOR)); |
| 750 | 834 |
| 751 PrefService* local_state = g_browser_process->local_state(); | 835 PrefService* local_state = g_browser_process->local_state(); |
| 752 if (local_state) { | 836 if (local_state) { |
| 753 if (finished_invocation.flags & | 837 if (finished_invocation.BehaviourIsSupported( |
| 754 SwReporterInvocation::FLAG_LOG_EXIT_CODE_TO_PREFS) | 838 SwReporterInvocation::BEHAVIOUR_LOG_EXIT_CODE_TO_PREFS)) { |
| 755 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code); | 839 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code); |
| 840 } |
| 756 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, | 841 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, |
| 757 base::Time::Now().ToInternalValue()); | 842 base::Time::Now().ToInternalValue()); |
| 758 } | 843 } |
| 759 uma.ReportRuntime(reporter_running_time); | 844 uma.ReportRuntime(reporter_running_time); |
| 760 uma.ReportScanTimes(); | 845 uma.ReportScanTimes(); |
| 761 uma.ReportMemoryUsage(); | 846 uma.ReportMemoryUsage(); |
| 847 if (finished_invocation.logs_upload_enabled) |
| 848 uma.RecordLogsUploadResult(); |
| 762 | 849 |
| 763 if (!(finished_invocation.flags & | 850 if (!finished_invocation.BehaviourIsSupported( |
| 764 SwReporterInvocation::FLAG_TRIGGER_PROMPT)) | 851 SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT)) { |
| 765 return; | 852 return; |
| 853 } |
| 766 | 854 |
| 767 if (!IsInSRTPromptFieldTrialGroups()) { | 855 if (!IsInSRTPromptFieldTrialGroups()) { |
| 768 // Knowing about disabled field trial is more important than reporter not | 856 // Knowing about disabled field trial is more important than reporter not |
| 769 // finding anything to remove, so check this case first. | 857 // finding anything to remove, so check this case first. |
| 770 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL); | 858 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL); |
| 771 return; | 859 return; |
| 772 } | 860 } |
| 773 | 861 |
| 774 if (exit_code != kSwReporterPostRebootCleanupNeeded && | 862 if (exit_code != kSwReporterPostRebootCleanupNeeded && |
| 775 exit_code != kSwReporterCleanupNeeded) { | 863 exit_code != kSwReporterCleanupNeeded) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 FROM_HERE, | 921 FROM_HERE, |
| 834 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), | 922 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), |
| 835 next_trigger - now); | 923 next_trigger - now); |
| 836 } | 924 } |
| 837 } | 925 } |
| 838 | 926 |
| 839 // Returns true if the experiment to send reporter logs is enabled, the user | 927 // Returns true if the experiment to send reporter logs is enabled, the user |
| 840 // opted into Safe Browsing extended reporting, and logs have been sent at | 928 // opted into Safe Browsing extended reporting, and logs have been sent at |
| 841 // least |kSwReporterLastTimeSentReport| days ago. | 929 // least |kSwReporterLastTimeSentReport| days ago. |
| 842 bool ShouldSendReporterLogs(const PrefService& local_state) { | 930 bool ShouldSendReporterLogs(const PrefService& local_state) { |
| 843 if (!base::FeatureList::IsEnabled(kSwReporterExtendedSafeBrowsingFeature) || | 931 if (!base::FeatureList::IsEnabled(kSwReporterExtendedSafeBrowsingFeature)) |
| 844 !SafeBrowsingExtendedReportingEnabled()) { | 932 return false; |
| 933 |
| 934 UMAHistogramReporter uma; |
| 935 if (!SafeBrowsingExtendedReportingEnabled()) { |
| 936 uma.RecordLogsUploadEnabled(REPORTER_LOGS_UPLOADS_SBER_DISABLED); |
| 845 return false; | 937 return false; |
| 846 } | 938 } |
| 847 | 939 |
| 848 const base::Time now = base::Time::Now(); | 940 const base::Time now = base::Time::Now(); |
| 849 const base::Time last_time_sent_logs = base::Time::FromInternalValue( | 941 const base::Time last_time_sent_logs = base::Time::FromInternalValue( |
| 850 local_state.GetInt64(prefs::kSwReporterLastTimeSentReport)); | 942 local_state.GetInt64(prefs::kSwReporterLastTimeSentReport)); |
| 851 // Send the logs if the last send was in the future. This is intended as a | 943 const base::Time next_time_send_logs = |
| 852 // measure for failure recovery, in case the time in local state is | 944 last_time_sent_logs + |
| 853 // incorrectly set to the future. | 945 base::TimeDelta::FromDays(kDaysBetweenReporterLogsSent); |
| 854 if (last_time_sent_logs > now) | 946 // Send the logs if the last send is the future or if the interval has |
| 947 // passed. The former is intended as a measure for failure recovery, in |
| 948 // case the time in local state is incorrectly set to the future. |
| 949 if (last_time_sent_logs > now || next_time_send_logs <= now) { |
| 950 uma.RecordLogsUploadEnabled(REPORTER_LOGS_UPLOADS_ENABLED); |
| 855 return true; | 951 return true; |
| 856 // Otherwise, send them if the interval has passed. | 952 } |
| 857 return last_time_sent_logs + | 953 uma.RecordLogsUploadEnabled(REPORTER_LOGS_UPLOADS_RECENTLY_SENT_LOGS); |
| 858 base::TimeDelta::FromDays(kDaysBetweenReporterLogsSent) <= | 954 return false; |
| 859 now; | |
| 860 } | 955 } |
| 861 | 956 |
| 862 void AddSwitchesForExtendedReporterUser(SwReporterInvocation* invocation) { | 957 void AddSwitchesForExtendedReporterUser(SwReporterInvocation* invocation) { |
| 863 invocation->command_line.AppendSwitch(kExtendedSafeBrowsingEnabledSwitch); | 958 invocation->command_line.AppendSwitch(kExtendedSafeBrowsingEnabledSwitch); |
| 864 invocation->command_line.AppendSwitchASCII( | 959 invocation->command_line.AppendSwitchASCII( |
| 865 kChromeVersionSwitch, version_info::GetVersionNumber()); | 960 kChromeVersionSwitch, version_info::GetVersionNumber()); |
| 866 invocation->command_line.AppendSwitchNative( | 961 invocation->command_line.AppendSwitchNative( |
| 867 kChromeChannelSwitch, base::IntToString16(ChannelAsInt())); | 962 kChromeChannelSwitch, base::IntToString16(ChannelAsInt())); |
| 868 } | 963 } |
| 869 | 964 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 | 1002 |
| 908 SwReporterInvocation SwReporterInvocation::FromCommandLine( | 1003 SwReporterInvocation SwReporterInvocation::FromCommandLine( |
| 909 const base::CommandLine& command_line) { | 1004 const base::CommandLine& command_line) { |
| 910 SwReporterInvocation invocation; | 1005 SwReporterInvocation invocation; |
| 911 invocation.command_line = command_line; | 1006 invocation.command_line = command_line; |
| 912 return invocation; | 1007 return invocation; |
| 913 } | 1008 } |
| 914 | 1009 |
| 915 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const { | 1010 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const { |
| 916 return command_line.argv() == other.command_line.argv() && | 1011 return command_line.argv() == other.command_line.argv() && |
| 917 suffix == other.suffix && flags == other.flags; | 1012 suffix == other.suffix && |
| 1013 supported_behaviours == other.supported_behaviours && |
| 1014 logs_upload_enabled == other.logs_upload_enabled; |
| 1015 } |
| 1016 |
| 1017 bool SwReporterInvocation::BehaviourIsSupported( |
| 1018 SwReporterInvocation::Behaviours intended_behaviour) const { |
| 1019 return (supported_behaviours & intended_behaviour) != 0; |
| 918 } | 1020 } |
| 919 | 1021 |
| 920 void RunSwReporters(const SwReporterQueue& invocations, | 1022 void RunSwReporters(const SwReporterQueue& invocations, |
| 921 const base::Version& version, | 1023 const base::Version& version, |
| 922 scoped_refptr<base::TaskRunner> main_thread_task_runner, | 1024 scoped_refptr<base::TaskRunner> main_thread_task_runner, |
| 923 scoped_refptr<base::TaskRunner> blocking_task_runner) { | 1025 scoped_refptr<base::TaskRunner> blocking_task_runner) { |
| 924 DCHECK(!invocations.empty()); | 1026 DCHECK(!invocations.empty()); |
| 925 DCHECK(version.IsValid()); | 1027 DCHECK(version.IsValid()); |
| 926 ReporterRunner::ScheduleInvocations(invocations, version, | 1028 ReporterRunner::ScheduleInvocations(invocations, version, |
| 927 std::move(main_thread_task_runner), | 1029 std::move(main_thread_task_runner), |
| 928 std::move(blocking_task_runner)); | 1030 std::move(blocking_task_runner)); |
| 929 } | 1031 } |
| 930 | 1032 |
| 931 bool ReporterFoundUws() { | 1033 bool ReporterFoundUws() { |
| 932 PrefService* local_state = g_browser_process->local_state(); | 1034 PrefService* local_state = g_browser_process->local_state(); |
| 933 if (!local_state) | 1035 if (!local_state) |
| 934 return false; | 1036 return false; |
| 935 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode); | 1037 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode); |
| 936 return exit_code == kSwReporterCleanupNeeded; | 1038 return exit_code == kSwReporterCleanupNeeded; |
| 937 } | 1039 } |
| 938 | 1040 |
| 939 bool UserHasRunCleaner() { | 1041 bool UserHasRunCleaner() { |
| 940 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey); | 1042 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey); |
| 941 cleaner_key_path.append(L"\\").append(kCleanerSubKey); | 1043 cleaner_key_path.append(L"\\").append(kCleanerSubKey); |
| 942 | 1044 |
| 943 base::win::RegKey srt_cleaner_key(HKEY_CURRENT_USER, cleaner_key_path.c_str(), | 1045 base::win::RegKey srt_cleaner_key; |
| 944 KEY_QUERY_VALUE); | 1046 return srt_cleaner_key.Open(HKEY_CURRENT_USER, cleaner_key_path.c_str(), |
| 945 | 1047 KEY_QUERY_VALUE) == ERROR_SUCCESS && |
| 946 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; | 1048 srt_cleaner_key.GetValueCount() > 0; |
| 947 } | 1049 } |
| 948 | 1050 |
| 949 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { | 1051 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { |
| 950 g_testing_delegate_ = delegate; | 1052 g_testing_delegate_ = delegate; |
| 951 } | 1053 } |
| 952 | 1054 |
| 953 } // namespace safe_browsing | 1055 } // namespace safe_browsing |
| OLD | NEW |