| 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 <memory> | 9 #include <memory> |
| 10 #include <queue> |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
| 14 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
| 15 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 16 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| 17 #include "base/macros.h" | 18 #include "base/macros.h" |
| 18 #include "base/metrics/field_trial.h" | 19 #include "base/metrics/field_trial.h" |
| 19 #include "base/metrics/histogram_macros.h" | 20 #include "base/metrics/histogram.h" |
| 20 #include "base/metrics/sparse_histogram.h" | 21 #include "base/metrics/sparse_histogram.h" |
| 21 #include "base/process/launch.h" | 22 #include "base/process/launch.h" |
| 22 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 23 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
| 25 #include "base/task_runner_util.h" | 26 #include "base/task_runner_util.h" |
| 26 #include "base/time/time.h" | 27 #include "base/time/time.h" |
| 27 #include "base/win/registry.h" | 28 #include "base/win/registry.h" |
| 28 #include "chrome/browser/browser_process.h" | 29 #include "chrome/browser/browser_process.h" |
| 29 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" | 30 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 const wchar_t kFoundUwsValueName[] = L"FoundUws"; | 114 const wchar_t kFoundUwsValueName[] = L"FoundUws"; |
| 114 const wchar_t kMemoryUsedValueName[] = L"MemoryUsed"; | 115 const wchar_t kMemoryUsedValueName[] = L"MemoryUsed"; |
| 115 | 116 |
| 116 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS"; | 117 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS"; |
| 117 const char kFoundUwsReadErrorMetricName[] = | 118 const char kFoundUwsReadErrorMetricName[] = |
| 118 "SoftwareReporter.FoundUwSReadError"; | 119 "SoftwareReporter.FoundUwSReadError"; |
| 119 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes"; | 120 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes"; |
| 120 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed"; | 121 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed"; |
| 121 | 122 |
| 122 // Reports metrics about the software reporter via UMA (and sometimes Rappor). | 123 // Reports metrics about the software reporter via UMA (and sometimes Rappor). |
| 124 // |
| 125 // This will format the names of the histograms at runtime by adding an |
| 126 // optional suffix, so the UMA_HISTOGRAM macros won't work. Use RecordHistogram |
| 127 // and related helper methods instead. |
| 123 class UMAHistogramReporter { | 128 class UMAHistogramReporter { |
| 124 public: | 129 public: |
| 130 UMAHistogramReporter(const std::string& suffix = std::string()) |
| 131 : suffix_(suffix), |
| 132 registry_key_(suffix.empty() |
| 133 ? kSoftwareRemovalToolRegistryKey |
| 134 : base::StringPrintf(L"%s\\%s", |
| 135 kSoftwareRemovalToolRegistryKey, |
| 136 base::UTF8ToUTF16(suffix))) {} |
| 137 |
| 125 // Reports the software reporter tool's version via UMA. | 138 // Reports the software reporter tool's version via UMA. |
| 126 void ReportVersion(const base::Version& version) const { | 139 void ReportVersion(const base::Version& version) const { |
| 127 DCHECK(!version.components().empty()); | 140 DCHECK(!version.components().empty()); |
| 128 // The minor version is the 2nd last component of the version, | 141 // The minor version is the 2nd last component of the version, |
| 129 // or just the first component if there is only 1. | 142 // or just the first component if there is only 1. |
| 130 uint32_t minor_version = 0; | 143 uint32_t minor_version = 0; |
| 131 if (version.components().size() > 1) | 144 if (version.components().size() > 1) |
| 132 minor_version = version.components()[version.components().size() - 2]; | 145 minor_version = version.components()[version.components().size() - 2]; |
| 133 else | 146 else |
| 134 minor_version = version.components()[0]; | 147 minor_version = version.components()[0]; |
| 135 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.MinorVersion", minor_version); | 148 RecordSparseHistogram("SoftwareReporter.MinorVersion", minor_version); |
| 136 | 149 |
| 137 // The major version for X.Y.Z is X*256^3+Y*256+Z. If there are additional | 150 // The major version for X.Y.Z is X*256^3+Y*256+Z. If there are additional |
| 138 // components, only the first three count, and if there are less than 3, the | 151 // components, only the first three count, and if there are less than 3, the |
| 139 // missing values are just replaced by zero. So 1 is equivalent 1.0.0. | 152 // missing values are just replaced by zero. So 1 is equivalent 1.0.0. |
| 140 DCHECK_LT(version.components()[0], 0x100U); | 153 DCHECK_LT(version.components()[0], 0x100U); |
| 141 uint32_t major_version = 0x1000000 * version.components()[0]; | 154 uint32_t major_version = 0x1000000 * version.components()[0]; |
| 142 if (version.components().size() >= 2) { | 155 if (version.components().size() >= 2) { |
| 143 DCHECK_LT(version.components()[1], 0x10000U); | 156 DCHECK_LT(version.components()[1], 0x10000U); |
| 144 major_version += 0x100 * version.components()[1]; | 157 major_version += 0x100 * version.components()[1]; |
| 145 } | 158 } |
| 146 if (version.components().size() >= 3) { | 159 if (version.components().size() >= 3) { |
| 147 DCHECK_LT(version.components()[2], 0x100U); | 160 DCHECK_LT(version.components()[2], 0x100U); |
| 148 major_version += version.components()[2]; | 161 major_version += version.components()[2]; |
| 149 } | 162 } |
| 150 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.MajorVersion", major_version); | 163 RecordSparseHistogram("SoftwareReporter.MajorVersion", major_version); |
| 151 } | 164 } |
| 152 | 165 |
| 153 void ReportExitCode(int exit_code) const { | 166 void ReportExitCode(int exit_code) const { |
| 154 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.ExitCode", exit_code); | 167 RecordSparseHistogram("SoftwareReporter.ExitCode", exit_code); |
| 155 } | 168 } |
| 156 | 169 |
| 157 // Reports UwS found by the software reporter tool via UMA and RAPPOR. | 170 // Reports UwS found by the software reporter tool via UMA and RAPPOR. |
| 158 void ReportFoundUwS() const { | 171 void ReportFoundUwS(bool use_rappor) const { |
| 159 base::win::RegKey reporter_key(HKEY_CURRENT_USER, | 172 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 160 kSoftwareRemovalToolRegistryKey, | |
| 161 KEY_QUERY_VALUE | KEY_SET_VALUE); | 173 KEY_QUERY_VALUE | KEY_SET_VALUE); |
| 162 std::vector<base::string16> found_uws_strings; | 174 std::vector<base::string16> found_uws_strings; |
| 163 if (reporter_key.Valid() && | 175 if (reporter_key.Valid() && |
| 164 reporter_key.ReadValues(kFoundUwsValueName, &found_uws_strings) == | 176 reporter_key.ReadValues(kFoundUwsValueName, &found_uws_strings) == |
| 165 ERROR_SUCCESS) { | 177 ERROR_SUCCESS) { |
| 166 rappor::RapporService* rappor_service = | 178 rappor::RapporService* rappor_service = nullptr; |
| 167 g_browser_process->rappor_service(); | 179 if (use_rappor) |
| 180 rappor_service = g_browser_process->rappor_service(); |
| 168 | 181 |
| 169 bool parse_error = false; | 182 bool parse_error = false; |
| 170 for (const base::string16& uws_string : found_uws_strings) { | 183 for (const base::string16& uws_string : found_uws_strings) { |
| 171 // All UwS ids are expected to be integers. | 184 // All UwS ids are expected to be integers. |
| 172 uint32_t uws_id = 0; | 185 uint32_t uws_id = 0; |
| 173 if (base::StringToUint(uws_string, &uws_id)) { | 186 if (base::StringToUint(uws_string, &uws_id)) { |
| 174 UMA_HISTOGRAM_SPARSE_SLOWLY(kFoundUwsMetricName, uws_id); | 187 RecordSparseHistogram(kFoundUwsMetricName, uws_id); |
| 175 if (rappor_service) { | 188 if (rappor_service) { |
| 176 rappor_service->RecordSample(kFoundUwsMetricName, | 189 rappor_service->RecordSample(kFoundUwsMetricName, |
| 177 rappor::COARSE_RAPPOR_TYPE, | 190 rappor::COARSE_RAPPOR_TYPE, |
| 178 base::UTF16ToUTF8(uws_string)); | 191 base::UTF16ToUTF8(uws_string)); |
| 179 } | 192 } |
| 180 } else { | 193 } else { |
| 181 parse_error = true; | 194 parse_error = true; |
| 182 } | 195 } |
| 183 } | 196 } |
| 184 | 197 |
| 185 // Clean up the old value. | 198 // Clean up the old value. |
| 186 reporter_key.DeleteValue(kFoundUwsValueName); | 199 reporter_key.DeleteValue(kFoundUwsValueName); |
| 187 | 200 |
| 188 UMA_HISTOGRAM_BOOLEAN(kFoundUwsReadErrorMetricName, parse_error); | 201 RecordBooleanHistogram(kFoundUwsReadErrorMetricName, parse_error); |
| 189 } | 202 } |
| 190 } | 203 } |
| 191 | 204 |
| 192 // Reports to UMA the memory usage of the software reporter tool as reported | 205 // Reports to UMA the memory usage of the software reporter tool as reported |
| 193 // by | 206 // by |
| 194 // the tool itself in the Windows registry. | 207 // the tool itself in the Windows registry. |
| 195 void ReportMemoryUsage() const { | 208 void ReportMemoryUsage() const { |
| 196 base::win::RegKey reporter_key(HKEY_CURRENT_USER, | 209 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 197 kSoftwareRemovalToolRegistryKey, | |
| 198 KEY_QUERY_VALUE | KEY_SET_VALUE); | 210 KEY_QUERY_VALUE | KEY_SET_VALUE); |
| 199 DWORD memory_used = 0; | 211 DWORD memory_used = 0; |
| 200 if (reporter_key.Valid() && | 212 if (reporter_key.Valid() && |
| 201 reporter_key.ReadValueDW(kMemoryUsedValueName, &memory_used) == | 213 reporter_key.ReadValueDW(kMemoryUsedValueName, &memory_used) == |
| 202 ERROR_SUCCESS) { | 214 ERROR_SUCCESS) { |
| 203 UMA_HISTOGRAM_MEMORY_KB(kMemoryUsedMetricName, memory_used); | 215 RecordMemoryKBHistogram(kMemoryUsedMetricName, memory_used); |
| 204 reporter_key.DeleteValue(kMemoryUsedValueName); | 216 reporter_key.DeleteValue(kMemoryUsedValueName); |
| 205 } | 217 } |
| 206 } | 218 } |
| 207 | 219 |
| 208 // Report the SwReporter run time with UMA both as reported by the tool via | 220 // Report the SwReporter run time with UMA both as reported by the tool via |
| 209 // the registry and as measured by |ReporterRunner|. | 221 // the registry and as measured by |ReporterRunner|. |
| 210 void ReportRuntime(const base::TimeDelta& reporter_running_time) const { | 222 void ReportRuntime(const base::TimeDelta& reporter_running_time) const { |
| 211 UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.RunningTimeAccordingToChrome", | 223 RecordLongTimesHistogram("SoftwareReporter.RunningTimeAccordingToChrome", |
| 212 reporter_running_time); | 224 reporter_running_time); |
| 213 | 225 |
| 214 base::win::RegKey reporter_key( | 226 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 215 HKEY_CURRENT_USER, kSoftwareRemovalToolRegistryKey, KEY_ALL_ACCESS); | 227 KEY_ALL_ACCESS); |
| 216 if (!reporter_key.Valid()) { | 228 if (!reporter_key.Valid()) { |
| 217 UMA_HISTOGRAM_ENUMERATION( | 229 RecordEnumerationHistogram( |
| 218 kRunningTimeErrorMetricName, | 230 kRunningTimeErrorMetricName, |
| 219 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID, | 231 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID, |
| 220 REPORTER_RUNNING_TIME_ERROR_MAX); | 232 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 221 return; | 233 return; |
| 222 } | 234 } |
| 223 | 235 |
| 224 bool has_start_time = false; | 236 bool has_start_time = false; |
| 225 int64_t start_time_value = 0; | 237 int64_t start_time_value = 0; |
| 226 if (reporter_key.HasValue(kStartTimeValueName) && | 238 if (reporter_key.HasValue(kStartTimeValueName) && |
| 227 reporter_key.ReadInt64(kStartTimeValueName, &start_time_value) == | 239 reporter_key.ReadInt64(kStartTimeValueName, &start_time_value) == |
| 228 ERROR_SUCCESS) { | 240 ERROR_SUCCESS) { |
| 229 has_start_time = true; | 241 has_start_time = true; |
| 230 reporter_key.DeleteValue(kStartTimeValueName); | 242 reporter_key.DeleteValue(kStartTimeValueName); |
| 231 } | 243 } |
| 232 | 244 |
| 233 bool has_end_time = false; | 245 bool has_end_time = false; |
| 234 int64_t end_time_value = 0; | 246 int64_t end_time_value = 0; |
| 235 if (reporter_key.HasValue(kEndTimeValueName) && | 247 if (reporter_key.HasValue(kEndTimeValueName) && |
| 236 reporter_key.ReadInt64(kEndTimeValueName, &end_time_value) == | 248 reporter_key.ReadInt64(kEndTimeValueName, &end_time_value) == |
| 237 ERROR_SUCCESS) { | 249 ERROR_SUCCESS) { |
| 238 has_end_time = true; | 250 has_end_time = true; |
| 239 reporter_key.DeleteValue(kEndTimeValueName); | 251 reporter_key.DeleteValue(kEndTimeValueName); |
| 240 } | 252 } |
| 241 | 253 |
| 242 if (has_start_time && has_end_time) { | 254 if (has_start_time && has_end_time) { |
| 243 base::TimeDelta registry_run_time = | 255 base::TimeDelta registry_run_time = |
| 244 base::Time::FromInternalValue(end_time_value) - | 256 base::Time::FromInternalValue(end_time_value) - |
| 245 base::Time::FromInternalValue(start_time_value); | 257 base::Time::FromInternalValue(start_time_value); |
| 246 UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.RunningTime", | 258 RecordLongTimesHistogram("SoftwareReporter.RunningTime", |
| 247 registry_run_time); | 259 registry_run_time); |
| 248 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, | 260 RecordEnumerationHistogram(kRunningTimeErrorMetricName, |
| 249 REPORTER_RUNNING_TIME_ERROR_NO_ERROR, | 261 REPORTER_RUNNING_TIME_ERROR_NO_ERROR, |
| 250 REPORTER_RUNNING_TIME_ERROR_MAX); | 262 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 251 } else if (!has_start_time && !has_end_time) { | 263 } else if (!has_start_time && !has_end_time) { |
| 252 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, | 264 RecordEnumerationHistogram(kRunningTimeErrorMetricName, |
| 253 REPORTER_RUNNING_TIME_ERROR_MISSING_BOTH_TIMES, | 265 REPORTER_RUNNING_TIME_ERROR_MISSING_BOTH_TIMES, |
| 254 REPORTER_RUNNING_TIME_ERROR_MAX); | 266 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 255 } else if (!has_start_time) { | 267 } else if (!has_start_time) { |
| 256 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, | 268 RecordEnumerationHistogram(kRunningTimeErrorMetricName, |
| 257 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME, | 269 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME, |
| 258 REPORTER_RUNNING_TIME_ERROR_MAX); | 270 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 259 } else { | 271 } else { |
| 260 DCHECK(!has_end_time); | 272 DCHECK(!has_end_time); |
| 261 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, | 273 RecordEnumerationHistogram(kRunningTimeErrorMetricName, |
| 262 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME, | 274 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME, |
| 263 REPORTER_RUNNING_TIME_ERROR_MAX); | 275 REPORTER_RUNNING_TIME_ERROR_MAX); |
| 264 } | 276 } |
| 265 } | 277 } |
| 266 | 278 |
| 267 // Report the UwS scan times of the software reporter tool via UMA. | 279 // Report the UwS scan times of the software reporter tool via UMA. |
| 268 void ReportScanTimes() const { | 280 void ReportScanTimes() const { |
| 269 base::string16 scan_times_key_path = base::StringPrintf( | 281 base::string16 scan_times_key_path = base::StringPrintf( |
| 270 L"%ls\\%ls", kSoftwareRemovalToolRegistryKey, kScanTimesSubKey); | 282 L"%ls\\%ls", registry_key_.c_str(), kScanTimesSubKey); |
| 271 base::win::RegKey scan_times_key( | 283 base::win::RegKey scan_times_key( |
| 272 HKEY_CURRENT_USER, scan_times_key_path.c_str(), KEY_ALL_ACCESS); | 284 HKEY_CURRENT_USER, scan_times_key_path.c_str(), KEY_ALL_ACCESS); |
| 273 if (!scan_times_key.Valid()) | 285 if (!scan_times_key.Valid()) |
| 274 return; | 286 return; |
| 275 | 287 |
| 276 base::string16 value_name; | 288 base::string16 value_name; |
| 277 int uws_id = 0; | 289 int uws_id = 0; |
| 278 int64_t raw_scan_time = 0; | 290 int64_t raw_scan_time = 0; |
| 279 int num_scan_times = scan_times_key.GetValueCount(); | 291 int num_scan_times = scan_times_key.GetValueCount(); |
| 280 for (int i = 0; i < num_scan_times; ++i) { | 292 for (int i = 0; i < num_scan_times; ++i) { |
| 281 if (scan_times_key.GetValueNameAt(i, &value_name) == ERROR_SUCCESS && | 293 if (scan_times_key.GetValueNameAt(i, &value_name) == ERROR_SUCCESS && |
| 282 base::StringToInt(value_name, &uws_id) && | 294 base::StringToInt(value_name, &uws_id) && |
| 283 scan_times_key.ReadInt64(value_name.c_str(), &raw_scan_time) == | 295 scan_times_key.ReadInt64(value_name.c_str(), &raw_scan_time) == |
| 284 ERROR_SUCCESS) { | 296 ERROR_SUCCESS) { |
| 285 base::TimeDelta scan_time = | 297 base::TimeDelta scan_time = |
| 286 base::TimeDelta::FromInternalValue(raw_scan_time); | 298 base::TimeDelta::FromInternalValue(raw_scan_time); |
| 287 base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( | 299 // We report the number of seconds plus one because it can take less |
| 288 kScanTimesMetricName, | 300 // than one second to scan some UwS and the count passed to |AddCount| |
| 289 base::HistogramBase::kUmaTargetedHistogramFlag); | 301 // must be at least one. |
| 290 if (histogram) { | 302 RecordSparseHistogramCount(kScanTimesMetricName, uws_id, |
| 291 // We report the number of seconds plus one because it can take less | 303 scan_time.InSeconds() + 1); |
| 292 // than one second to scan some UwS and the count passed to |AddCount| | |
| 293 // must be at least one. | |
| 294 histogram->AddCount(uws_id, scan_time.InSeconds() + 1); | |
| 295 } | |
| 296 } | 304 } |
| 297 } | 305 } |
| 298 // Clean up by deleting the scan times key, which is a subkey of the main | 306 // Clean up by deleting the scan times key, which is a subkey of the main |
| 299 // reporter key. | 307 // reporter key. |
| 300 scan_times_key.Close(); | 308 scan_times_key.Close(); |
| 301 base::win::RegKey reporter_key(HKEY_CURRENT_USER, | 309 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(), |
| 302 kSoftwareRemovalToolRegistryKey, | |
| 303 KEY_ENUMERATE_SUB_KEYS); | 310 KEY_ENUMERATE_SUB_KEYS); |
| 304 if (reporter_key.Valid()) | 311 if (reporter_key.Valid()) |
| 305 reporter_key.DeleteKey(kScanTimesSubKey); | 312 reporter_key.DeleteKey(kScanTimesSubKey); |
| 306 } | 313 } |
| 314 |
| 315 void RecordReporterStep(SwReporterUmaValue value) { |
| 316 RecordEnumerationHistogram("SoftwareReporter.Step", value, SW_REPORTER_MAX); |
| 317 } |
| 318 |
| 319 private: |
| 320 std::string FullName(const std::string& name) const { |
| 321 if (suffix_.empty()) |
| 322 return name; |
| 323 return base::StringPrintf("%s_%s", name, suffix_); |
| 324 } |
| 325 |
| 326 template <typename HistogramType, typename SampleType> |
| 327 void RecordHistogram(const std::string& name, SampleType sample) const { |
| 328 base::HistogramBase* histogram = HistogramType::FactoryGet( |
| 329 FullName(name), base::HistogramBase::kUmaTargetedHistogramFlag); |
| 330 if (histogram) |
| 331 histogram->Add(sample); |
| 332 } |
| 333 |
| 334 template <typename SampleType> |
| 335 void RecordBooleanHistogram(const std::string& name, |
| 336 SampleType sample) const { |
| 337 RecordHistogram<base::BooleanHistogram, SampleType>(name, sample); |
| 338 } |
| 339 |
| 340 template <typename SampleType> |
| 341 void RecordEnumerationHistogram(const std::string& name, |
| 342 SampleType sample, |
| 343 SampleType boundary) const { |
| 344 // See HISTOGRAM_ENUMERATION_WITH_FLAG. |
| 345 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
| 346 FullName(name), 1, boundary, boundary + 1, |
| 347 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 348 if (histogram) |
| 349 histogram->Add(sample); |
| 350 } |
| 351 |
| 352 template <typename SampleType> |
| 353 void RecordLongTimesHistogram(const std::string& name, |
| 354 SampleType sample) const { |
| 355 // See UMA_HISTOGRAM_LONG_TIMES. |
| 356 base::HistogramBase* histogram = base::Histogram::FactoryTimeGet( |
| 357 FullName(name), base::TimeDelta::FromMilliseconds(1), |
| 358 base::TimeDelta::FromHours(1), 100, |
| 359 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 360 if (histogram) |
| 361 histogram->AddTime(sample); |
| 362 } |
| 363 |
| 364 template <typename SampleType> |
| 365 void RecordMemoryKBHistogram(const std::string& name, |
| 366 SampleType sample) const { |
| 367 // See UMA_HISTOGRAM_MEMORY_KB. |
| 368 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
| 369 FullName(name), 1000, 500000, 50, |
| 370 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 371 if (histogram) |
| 372 histogram->Add(sample); |
| 373 } |
| 374 |
| 375 template <typename SampleType> |
| 376 void RecordSparseHistogram(const std::string& name, SampleType sample) const { |
| 377 RecordHistogram<base::SparseHistogram, SampleType>(name, sample); |
| 378 } |
| 379 |
| 380 template <typename SampleType> |
| 381 void RecordSparseHistogramCount(const std::string& name, |
| 382 SampleType sample, |
| 383 int count) const { |
| 384 base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( |
| 385 FullName(name), base::HistogramBase::kUmaTargetedHistogramFlag); |
| 386 if (histogram) |
| 387 histogram->AddCount(sample, count); |
| 388 } |
| 389 |
| 390 std::string suffix_; |
| 391 std::wstring registry_key_; |
| 307 }; | 392 }; |
| 308 | 393 |
| 309 void RecordReporterStepHistogram(SwReporterUmaValue value) { | 394 void RecordReporterStepHistogram(SwReporterUmaValue value) { |
| 310 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Step", value, SW_REPORTER_MAX); | 395 UMAHistogramReporter uma; |
| 396 uma.RecordReporterStep(value); |
| 311 } | 397 } |
| 312 | 398 |
| 313 void DisplaySRTPrompt(const base::FilePath& download_path) { | 399 void DisplaySRTPrompt(const base::FilePath& download_path) { |
| 314 // Find the last active browser, which may be NULL, in which case we won't | 400 // Find the last active browser, which may be NULL, in which case we won't |
| 315 // show the prompt this time and will wait until the next run of the | 401 // show the prompt this time and will wait until the next run of the |
| 316 // reporter. We can't use other ways of finding a browser because we don't | 402 // reporter. We can't use other ways of finding a browser because we don't |
| 317 // have a profile. | 403 // have a profile. |
| 318 Browser* browser = chrome::FindLastActive(); | 404 Browser* browser = chrome::FindLastActive(); |
| 319 if (!browser) | 405 if (!browser) |
| 320 return; | 406 return; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 // interrupted by a shutdown at any time, so it shouldn't depend on anything | 450 // interrupted by a shutdown at any time, so it shouldn't depend on anything |
| 365 // external that could be shut down beforehand. | 451 // external that could be shut down beforehand. |
| 366 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { | 452 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { |
| 367 if (!g_reporter_launcher_.is_null()) | 453 if (!g_reporter_launcher_.is_null()) |
| 368 return g_reporter_launcher_.Run(invocation); | 454 return g_reporter_launcher_.Run(invocation); |
| 369 base::Process reporter_process = | 455 base::Process reporter_process = |
| 370 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); | 456 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); |
| 371 // This exit code is used to identify that a reporter run didn't happen, so | 457 // This exit code is used to identify that a reporter run didn't happen, so |
| 372 // the result should be ignored and a rerun scheduled for the usual delay. | 458 // the result should be ignored and a rerun scheduled for the usual delay. |
| 373 int exit_code = kReporterFailureExitCode; | 459 int exit_code = kReporterFailureExitCode; |
| 460 UMAHistogramReporter uma(invocation.suffix); |
| 374 if (reporter_process.IsValid()) { | 461 if (reporter_process.IsValid()) { |
| 375 RecordReporterStepHistogram(SW_REPORTER_START_EXECUTION); | 462 uma.RecordReporterStep(SW_REPORTER_START_EXECUTION); |
| 376 bool success = reporter_process.WaitForExit(&exit_code); | 463 bool success = reporter_process.WaitForExit(&exit_code); |
| 377 DCHECK(success); | 464 DCHECK(success); |
| 378 } else { | 465 } else { |
| 379 RecordReporterStepHistogram(SW_REPORTER_FAILED_TO_START); | 466 uma.RecordReporterStep(SW_REPORTER_FAILED_TO_START); |
| 380 } | 467 } |
| 381 return exit_code; | 468 return exit_code; |
| 382 } | 469 } |
| 383 | 470 |
| 384 } // namespace | 471 } // namespace |
| 385 | 472 |
| 386 // Class that will attempt to download the SRT, showing the SRT notification | 473 // Class that will attempt to download the SRT, showing the SRT notification |
| 387 // bubble when the download operation is complete. Instances of SRTFetcher own | 474 // bubble when the download operation is complete. Instances of SRTFetcher own |
| 388 // themselves, they will self-delete on completion of the network request when | 475 // themselves, they will self-delete on completion of the network request when |
| 389 // OnURLFetchComplete is called. | 476 // OnURLFetchComplete is called. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 new SRTFetcher(profile); | 592 new SRTFetcher(profile); |
| 506 } | 593 } |
| 507 | 594 |
| 508 // This class tries to run the reporter and reacts to its exit code. It | 595 // This class tries to run the reporter and reacts to its exit code. It |
| 509 // schedules subsequent runs as needed, or retries as soon as a browser is | 596 // schedules subsequent runs as needed, or retries as soon as a browser is |
| 510 // available when none is on first try. | 597 // available when none is on first try. |
| 511 class ReporterRunner : public chrome::BrowserListObserver { | 598 class ReporterRunner : public chrome::BrowserListObserver { |
| 512 public: | 599 public: |
| 513 // Starts the sequence of attempts to run the reporter. | 600 // Starts the sequence of attempts to run the reporter. |
| 514 static void Run( | 601 static void Run( |
| 515 const SwReporterInvocation& invocation, | 602 const std::queue<SwReporterInvocation>& invocations, |
| 516 const base::Version& version, | 603 const base::Version& version, |
| 517 const scoped_refptr<base::TaskRunner>& main_thread_task_runner, | 604 const scoped_refptr<base::TaskRunner>& main_thread_task_runner, |
| 518 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { | 605 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { |
| 519 if (!instance_) | 606 if (!instance_) |
| 520 instance_ = new ReporterRunner; | 607 instance_ = new ReporterRunner; |
| 521 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 608 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 522 // There's nothing to do if the path and version of the reporter has not | 609 // There's nothing to do if the path and version of the reporter has not |
| 523 // changed, we just keep running the tasks that are running now. | 610 // changed, we just keep running the tasks that are running now. |
| 524 if (instance_->invocation_ == invocation && instance_->version_.IsValid() && | 611 if (instance_->invocations_ == invocations && |
| 525 instance_->version_ == version) | 612 instance_->version_.IsValid() && instance_->version_ == version) |
| 526 return; | 613 return; |
| 527 | 614 |
| 528 instance_->invocation_ = invocation; | 615 instance_->invocations_ = invocations; |
| 529 instance_->version_ = version; | 616 instance_->version_ = version; |
| 530 instance_->main_thread_task_runner_ = main_thread_task_runner; | 617 instance_->main_thread_task_runner_ = main_thread_task_runner; |
| 531 instance_->blocking_task_runner_ = blocking_task_runner; | 618 instance_->blocking_task_runner_ = blocking_task_runner; |
| 532 | 619 |
| 533 if (instance_->first_run_) { | 620 if (instance_->first_run_) { |
| 534 instance_->first_run_ = false; | 621 instance_->first_run_ = false; |
| 535 instance_->TryToRun(); | 622 instance_->TryToRun(); |
| 536 } | 623 } |
| 537 } | 624 } |
| 538 | 625 |
| 626 // Launch the command line at the head of the queue. |
| 627 void LaunchNextInvocation( |
| 628 const std::queue<SwReporterInvocation>& invocations) { |
| 629 DCHECK(!invocations.empty()); |
| 630 // Make a non-const copy of the queue so it can be manipulated. |
| 631 auto remaining_invocations = invocations; |
| 632 auto next_invocation = remaining_invocations.front(); |
| 633 remaining_invocations.pop(); |
| 634 |
| 635 // It's OK to simply |PostTaskAndReplyWithResult| so that |
| 636 // |LaunchAndWaitForExit| doesn't need to access |main_thread_task_runner_| |
| 637 // since the callback is not delayed and the test task runner won't need to |
| 638 // force it. |
| 639 base::PostTaskAndReplyWithResult( |
| 640 blocking_task_runner_.get(), FROM_HERE, |
| 641 |
| 642 // Send the head of the queue to the launch callback. |
| 643 base::Bind(&LaunchAndWaitForExit, next_invocation), |
| 644 |
| 645 // Send the tail of the queue to the next callback, which will handle |
| 646 // the |
| 647 // results of the first launch and then recursively launch everything in |
| 648 // the tail. |
| 649 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), |
| 650 base::Time::Now(), version_, next_invocation, |
| 651 remaining_invocations)); |
| 652 } |
| 653 |
| 539 private: | 654 private: |
| 540 ReporterRunner() : first_run_(true) {} | 655 ReporterRunner() : first_run_(true) {} |
| 541 ~ReporterRunner() override {} | 656 ~ReporterRunner() override {} |
| 542 | 657 |
| 543 // BrowserListObserver. | 658 // BrowserListObserver. |
| 544 void OnBrowserSetLastActive(Browser* browser) override {} | 659 void OnBrowserSetLastActive(Browser* browser) override {} |
| 545 void OnBrowserRemoved(Browser* browser) override {} | 660 void OnBrowserRemoved(Browser* browser) override {} |
| 546 void OnBrowserAdded(Browser* browser) override { | 661 void OnBrowserAdded(Browser* browser) override { |
| 547 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 662 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 548 DCHECK(browser); | 663 DCHECK(browser); |
| 549 MaybeFetchSRT(browser, version_); | 664 MaybeFetchSRT(browser, version_); |
| 550 BrowserList::RemoveObserver(this); | 665 BrowserList::RemoveObserver(this); |
| 551 } | 666 } |
| 552 | 667 |
| 553 // This method is called on the UI thread when the reporter run has completed. | 668 // This method is called on the UI thread when the reporter run has completed. |
| 554 // This is run as a task posted from an interruptible worker thread so should | 669 // This is run as a task posted from an interruptible worker thread so should |
| 555 // be resilient to unexpected shutdown. | 670 // be resilient to unexpected shutdown. |
| 556 void ReporterDone(const base::Time& reporter_start_time, | 671 void ReporterDone( |
| 557 const base::Version& version, | 672 const base::Time& reporter_start_time, |
| 558 int exit_code) { | 673 const base::Version& version, |
| 674 const SwReporterInvocation& finished_invocation, |
| 675 const std::queue<SwReporterInvocation>& remaining_invocations, |
| 676 int exit_code) { |
| 559 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 677 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 560 | 678 |
| 561 if (g_reporter_done_notifier_) | 679 if (g_reporter_done_notifier_) |
| 562 g_reporter_done_notifier_.Run(); | 680 g_reporter_done_notifier_.Run(); |
| 563 | 681 |
| 564 base::TimeDelta reporter_running_time = | 682 base::TimeDelta reporter_running_time = |
| 565 base::Time::Now() - reporter_start_time; | 683 base::Time::Now() - reporter_start_time; |
| 566 // Don't continue when the reporter process failed to launch, but still try | 684 // Don't continue when the reporter process failed to launch, but still try |
| 567 // again after the regular delay. It's not worth retrying earlier, risking | 685 // again after the regular delay. It's not worth retrying earlier, risking |
| 568 // running too often if it always fails, since not many users fail here. | 686 // running too often if it always fails, since not many users fail here. |
| 569 main_thread_task_runner_->PostDelayedTask( | 687 main_thread_task_runner_->PostDelayedTask( |
| 570 FROM_HERE, | 688 FROM_HERE, |
| 571 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), | 689 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), |
| 572 base::TimeDelta::FromDays(days_between_reporter_runs_)); | 690 base::TimeDelta::FromDays(days_between_reporter_runs_)); |
| 573 if (exit_code == kReporterFailureExitCode) | 691 if (exit_code == kReporterFailureExitCode) |
| 574 return; | 692 return; |
| 575 | 693 |
| 576 UMAHistogramReporter uma; | 694 UMAHistogramReporter uma(finished_invocation.suffix); |
| 577 uma.ReportVersion(version); | 695 uma.ReportVersion(version); |
| 578 uma.ReportExitCode(exit_code); | 696 uma.ReportExitCode(exit_code); |
| 579 uma.ReportFoundUwS(); | 697 uma.ReportFoundUwS(!finished_invocation.is_experimental /*use_rappor*/); |
| 698 |
| 699 // Only save results from the canonical version of the software. |
| 580 PrefService* local_state = g_browser_process->local_state(); | 700 PrefService* local_state = g_browser_process->local_state(); |
| 581 if (local_state) { | 701 if (local_state && !finished_invocation.is_experimental) { |
| 582 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code); | 702 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code); |
| 583 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, | 703 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, |
| 584 base::Time::Now().ToInternalValue()); | 704 base::Time::Now().ToInternalValue()); |
| 585 } | 705 } |
| 586 uma.ReportRuntime(reporter_running_time); | 706 uma.ReportRuntime(reporter_running_time); |
| 587 uma.ReportScanTimes(); | 707 uma.ReportScanTimes(); |
| 588 uma.ReportMemoryUsage(); | 708 uma.ReportMemoryUsage(); |
| 589 | 709 |
| 710 if (!remaining_invocations.empty()) { |
| 711 // Only the experimental version should have multiple invocations. |
| 712 DCHECK(finished_invocation.is_experimental); |
| 713 LaunchNextInvocation(remaining_invocations); |
| 714 } |
| 715 |
| 716 // Only continue to launch the prompt for the canonical version. |
| 717 if (finished_invocation.is_experimental) |
| 718 return; |
| 719 |
| 590 if (!IsInSRTPromptFieldTrialGroups()) { | 720 if (!IsInSRTPromptFieldTrialGroups()) { |
| 591 // Knowing about disabled field trial is more important than reporter not | 721 // Knowing about disabled field trial is more important than reporter not |
| 592 // finding anything to remove, so check this case first. | 722 // finding anything to remove, so check this case first. |
| 593 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL); | 723 uma.RecordReporterStep(SW_REPORTER_NO_PROMPT_FIELD_TRIAL); |
| 594 return; | 724 return; |
| 595 } | 725 } |
| 596 | 726 |
| 597 if (exit_code != kSwReporterPostRebootCleanupNeeded && | 727 if (exit_code != kSwReporterPostRebootCleanupNeeded && |
| 598 exit_code != kSwReporterCleanupNeeded) { | 728 exit_code != kSwReporterCleanupNeeded) { |
| 599 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_NEEDED); | 729 uma.RecordReporterStep(SW_REPORTER_NO_PROMPT_NEEDED); |
| 600 return; | 730 return; |
| 601 } | 731 } |
| 602 | 732 |
| 603 // Find the last active browser, which may be NULL, in which case we need | 733 // Find the last active browser, which may be NULL, in which case we need |
| 604 // to wait for one to be available. We can't use other ways of finding a | 734 // to wait for one to be available. We can't use other ways of finding a |
| 605 // browser because we don't have a profile. And we need a browser to get to | 735 // browser because we don't have a profile. And we need a browser to get to |
| 606 // a profile, which we need, to tell whether we should prompt or not. | 736 // a profile, which we need, to tell whether we should prompt or not. |
| 607 // TODO(mad): crbug.com/503269, investigate whether we should change how we | 737 // TODO(mad): crbug.com/503269, investigate whether we should change how we |
| 608 // decide when it's time to download the SRT and when to display the prompt. | 738 // decide when it's time to download the SRT and when to display the prompt. |
| 609 Browser* browser = chrome::FindLastActive(); | 739 Browser* browser = chrome::FindLastActive(); |
| 610 if (!browser) { | 740 if (!browser) { |
| 611 RecordReporterStepHistogram(SW_REPORTER_NO_BROWSER); | 741 uma.RecordReporterStep(SW_REPORTER_NO_BROWSER); |
| 612 BrowserList::AddObserver(this); | 742 BrowserList::AddObserver(this); |
| 613 } else { | 743 } else { |
| 614 MaybeFetchSRT(browser, version_); | 744 MaybeFetchSRT(browser, version_); |
| 615 } | 745 } |
| 616 } | 746 } |
| 617 | 747 |
| 618 void TryToRun() { | 748 void TryToRun() { |
| 619 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 749 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 620 PrefService* local_state = g_browser_process->local_state(); | 750 PrefService* local_state = g_browser_process->local_state(); |
| 621 if (!version_.IsValid() || !local_state) { | 751 if (!version_.IsValid() || !local_state) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 638 last_time_triggered + | 768 last_time_triggered + |
| 639 base::TimeDelta::FromDays(days_between_reporter_runs_) - | 769 base::TimeDelta::FromDays(days_between_reporter_runs_) - |
| 640 base::Time::Now()); | 770 base::Time::Now()); |
| 641 if (next_trigger_delay.ToInternalValue() <= 0 || | 771 if (next_trigger_delay.ToInternalValue() <= 0 || |
| 642 // Also make sure the kSwReporterLastTimeTriggered value is not set in | 772 // Also make sure the kSwReporterLastTimeTriggered value is not set in |
| 643 // the future. | 773 // the future. |
| 644 last_time_triggered > base::Time::Now()) { | 774 last_time_triggered > base::Time::Now()) { |
| 645 if (g_launch_ready_notifier_) | 775 if (g_launch_ready_notifier_) |
| 646 g_launch_ready_notifier_.Run(); | 776 g_launch_ready_notifier_.Run(); |
| 647 | 777 |
| 648 // It's OK to simply |PostTaskAndReplyWithResult| so that | 778 if (!invocations_.empty()) |
| 649 // |LaunchAndWaitForExit| doesn't need to access | 779 LaunchNextInvocation(invocations_); |
| 650 // |main_thread_task_runner_| since the callback is not delayed and the | |
| 651 // test task runner won't need to force it. | |
| 652 base::PostTaskAndReplyWithResult( | |
| 653 blocking_task_runner_.get(), FROM_HERE, | |
| 654 base::Bind(&LaunchAndWaitForExit, invocation_), | |
| 655 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), | |
| 656 base::Time::Now(), version_)); | |
| 657 } else { | 780 } else { |
| 658 main_thread_task_runner_->PostDelayedTask( | 781 main_thread_task_runner_->PostDelayedTask( |
| 659 FROM_HERE, | 782 FROM_HERE, |
| 660 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), | 783 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), |
| 661 next_trigger_delay); | 784 next_trigger_delay); |
| 662 } | 785 } |
| 663 } | 786 } |
| 664 | 787 |
| 665 bool first_run_; | 788 bool first_run_; |
| 666 SwReporterInvocation invocation_; | 789 std::queue<SwReporterInvocation> invocations_; |
| 667 base::Version version_; | 790 base::Version version_; |
| 668 scoped_refptr<base::TaskRunner> main_thread_task_runner_; | 791 scoped_refptr<base::TaskRunner> main_thread_task_runner_; |
| 669 scoped_refptr<base::TaskRunner> blocking_task_runner_; | 792 scoped_refptr<base::TaskRunner> blocking_task_runner_; |
| 670 | 793 |
| 671 // This value is used to identify how long to wait before starting a new run | 794 // This value is used to identify how long to wait before starting a new run |
| 672 // of the reporter. It's initialized with the default value and may be changed | 795 // of the reporter. It's initialized with the default value and may be changed |
| 673 // to a different value when a prompt is pending and the reporter should be | 796 // to a different value when a prompt is pending and the reporter should be |
| 674 // run before adding the global error to the Chrome menu. | 797 // run before adding the global error to the Chrome menu. |
| 675 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; | 798 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; |
| 676 | 799 |
| 677 // A single leaky instance. | 800 // A single leaky instance. |
| 678 static ReporterRunner* instance_; | 801 static ReporterRunner* instance_; |
| 679 | 802 |
| 680 DISALLOW_COPY_AND_ASSIGN(ReporterRunner); | 803 DISALLOW_COPY_AND_ASSIGN(ReporterRunner); |
| 681 }; | 804 }; |
| 682 | 805 |
| 683 ReporterRunner* ReporterRunner::instance_ = nullptr; | 806 ReporterRunner* ReporterRunner::instance_ = nullptr; |
| 684 | 807 |
| 685 } // namespace | 808 } // namespace |
| 686 | 809 |
| 687 SwReporterInvocation::SwReporterInvocation() : command_line(0, nullptr) {} | 810 SwReporterInvocation::SwReporterInvocation() |
| 811 : command_line(0, nullptr), is_experimental(false) {} |
| 688 | 812 |
| 689 SwReporterInvocation::SwReporterInvocation(const base::FilePath& exe_path) | 813 SwReporterInvocation::SwReporterInvocation(const base::FilePath& exe_path) |
| 690 : command_line(exe_path) {} | 814 : command_line(exe_path), is_experimental(false) {} |
| 691 | 815 |
| 692 SwReporterInvocation::SwReporterInvocation( | 816 SwReporterInvocation::SwReporterInvocation( |
| 693 const base::CommandLine& command_line) | 817 const base::CommandLine& command_line) |
| 694 : command_line(command_line) {} | 818 : command_line(command_line), is_experimental(false) {} |
| 695 | 819 |
| 696 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const { | 820 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const { |
| 697 return command_line.argv() == other.command_line.argv(); | 821 return command_line.argv() == other.command_line.argv() && |
| 822 suffix == other.suffix && is_experimental == other.is_experimental; |
| 698 } | 823 } |
| 699 | 824 |
| 700 void RunSwReporter(const SwReporterInvocation& invocation, | 825 void RunSwReporter(const SwReporterInvocation& invocation, |
| 701 const base::Version& version, | 826 const base::Version& version, |
| 702 scoped_refptr<base::TaskRunner> main_thread_task_runner, | 827 scoped_refptr<base::TaskRunner> main_thread_task_runner, |
| 703 scoped_refptr<base::TaskRunner> blocking_task_runner) { | 828 scoped_refptr<base::TaskRunner> blocking_task_runner) { |
| 704 ReporterRunner::Run(invocation, version, main_thread_task_runner, | 829 std::queue<SwReporterInvocation> invocations; |
| 830 invocations.push(invocation); |
| 831 ReporterRunner::Run(invocations, version, main_thread_task_runner, |
| 705 blocking_task_runner); | 832 blocking_task_runner); |
| 706 } | 833 } |
| 707 | 834 |
| 835 void RunSwReporters(const std::queue<SwReporterInvocation>& invocations, |
| 836 const base::Version& version, |
| 837 scoped_refptr<base::TaskRunner> main_thread_task_runner, |
| 838 scoped_refptr<base::TaskRunner> blocking_task_runner) { |
| 839 ReporterRunner::Run(invocations, version, main_thread_task_runner, |
| 840 blocking_task_runner); |
| 841 } |
| 842 |
| 708 bool ReporterFoundUws() { | 843 bool ReporterFoundUws() { |
| 709 PrefService* local_state = g_browser_process->local_state(); | 844 PrefService* local_state = g_browser_process->local_state(); |
| 710 if (!local_state) | 845 if (!local_state) |
| 711 return false; | 846 return false; |
| 712 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode); | 847 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode); |
| 713 return exit_code == kSwReporterCleanupNeeded; | 848 return exit_code == kSwReporterCleanupNeeded; |
| 714 } | 849 } |
| 715 | 850 |
| 716 bool UserHasRunCleaner() { | 851 bool UserHasRunCleaner() { |
| 717 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey); | 852 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 733 | 868 |
| 734 void SetLaunchReadyNotifierForTesting(const LaunchReadyNotifier& notifier) { | 869 void SetLaunchReadyNotifierForTesting(const LaunchReadyNotifier& notifier) { |
| 735 g_launch_ready_notifier_ = notifier; | 870 g_launch_ready_notifier_ = notifier; |
| 736 } | 871 } |
| 737 | 872 |
| 738 void SetReporterDoneNotifierForTesting(const ReporterDoneNotifier& notifier) { | 873 void SetReporterDoneNotifierForTesting(const ReporterDoneNotifier& notifier) { |
| 739 g_reporter_done_notifier_ = notifier; | 874 g_reporter_done_notifier_ = notifier; |
| 740 } | 875 } |
| 741 | 876 |
| 742 } // namespace safe_browsing | 877 } // namespace safe_browsing |
| OLD | NEW |