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

Side by Side Diff: chrome/browser/safe_browsing/srt_fetcher_win.cc

Issue 2278013002: Add support for the ExperimentalSwReporterEngine field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplify comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <utility>
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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 112
112 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS"; 113 const char kFoundUwsMetricName[] = "SoftwareReporter.FoundUwS";
113 const char kFoundUwsReadErrorMetricName[] = 114 const char kFoundUwsReadErrorMetricName[] =
114 "SoftwareReporter.FoundUwSReadError"; 115 "SoftwareReporter.FoundUwSReadError";
115 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes"; 116 const char kScanTimesMetricName[] = "SoftwareReporter.UwSScanTimes";
116 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed"; 117 const char kMemoryUsedMetricName[] = "SoftwareReporter.MemoryUsed";
117 118
118 // Reports metrics about the software reporter via UMA (and sometimes Rappor). 119 // Reports metrics about the software reporter via UMA (and sometimes Rappor).
119 class UMAHistogramReporter { 120 class UMAHistogramReporter {
120 public: 121 public:
122 explicit UMAHistogramReporter(const std::string& suffix = std::string())
123 : suffix_(suffix),
124 registry_key_(suffix.empty() ? kSoftwareRemovalToolRegistryKey
125 : base::StringPrintf(
126 L"%ls\\%ls",
127 kSoftwareRemovalToolRegistryKey,
128 base::UTF8ToUTF16(suffix).c_str())) {
129 }
130
121 // Reports the software reporter tool's version via UMA. 131 // Reports the software reporter tool's version via UMA.
122 void ReportVersion(const base::Version& version) const { 132 void ReportVersion(const base::Version& version) const {
123 DCHECK(!version.components().empty()); 133 DCHECK(!version.components().empty());
124 // The minor version is the 2nd last component of the version, 134 // The minor version is the 2nd last component of the version,
125 // or just the first component if there is only 1. 135 // or just the first component if there is only 1.
126 uint32_t minor_version = 0; 136 uint32_t minor_version = 0;
127 if (version.components().size() > 1) 137 if (version.components().size() > 1)
128 minor_version = version.components()[version.components().size() - 2]; 138 minor_version = version.components()[version.components().size() - 2];
129 else 139 else
130 minor_version = version.components()[0]; 140 minor_version = version.components()[0];
131 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.MinorVersion", minor_version); 141 RecordSparseHistogram("SoftwareReporter.MinorVersion", minor_version);
132 142
133 // The major version for X.Y.Z is X*256^3+Y*256+Z. If there are additional 143 // The major version for X.Y.Z is X*256^3+Y*256+Z. If there are additional
134 // components, only the first three count, and if there are less than 3, the 144 // components, only the first three count, and if there are less than 3, the
135 // missing values are just replaced by zero. So 1 is equivalent 1.0.0. 145 // missing values are just replaced by zero. So 1 is equivalent 1.0.0.
136 DCHECK_LT(version.components()[0], 0x100U); 146 DCHECK_LT(version.components()[0], 0x100U);
137 uint32_t major_version = 0x1000000 * version.components()[0]; 147 uint32_t major_version = 0x1000000 * version.components()[0];
138 if (version.components().size() >= 2) { 148 if (version.components().size() >= 2) {
139 DCHECK_LT(version.components()[1], 0x10000U); 149 DCHECK_LT(version.components()[1], 0x10000U);
140 major_version += 0x100 * version.components()[1]; 150 major_version += 0x100 * version.components()[1];
141 } 151 }
142 if (version.components().size() >= 3) { 152 if (version.components().size() >= 3) {
143 DCHECK_LT(version.components()[2], 0x100U); 153 DCHECK_LT(version.components()[2], 0x100U);
144 major_version += version.components()[2]; 154 major_version += version.components()[2];
145 } 155 }
146 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.MajorVersion", major_version); 156 RecordSparseHistogram("SoftwareReporter.MajorVersion", major_version);
147 } 157 }
148 158
149 void ReportExitCode(int exit_code) const { 159 void ReportExitCode(int exit_code) const {
150 UMA_HISTOGRAM_SPARSE_SLOWLY("SoftwareReporter.ExitCode", exit_code); 160 RecordSparseHistogram("SoftwareReporter.ExitCode", exit_code);
151 } 161 }
152 162
153 // Reports UwS found by the software reporter tool via UMA and RAPPOR. 163 // Reports UwS found by the software reporter tool via UMA and RAPPOR.
154 void ReportFoundUwS() const { 164 void ReportFoundUwS(bool use_rappor) const {
155 base::win::RegKey reporter_key(HKEY_CURRENT_USER, 165 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(),
156 kSoftwareRemovalToolRegistryKey,
157 KEY_QUERY_VALUE | KEY_SET_VALUE); 166 KEY_QUERY_VALUE | KEY_SET_VALUE);
158 std::vector<base::string16> found_uws_strings; 167 std::vector<base::string16> found_uws_strings;
159 if (reporter_key.Valid() && 168 if (reporter_key.Valid() &&
160 reporter_key.ReadValues(kFoundUwsValueName, &found_uws_strings) == 169 reporter_key.ReadValues(kFoundUwsValueName, &found_uws_strings) ==
161 ERROR_SUCCESS) { 170 ERROR_SUCCESS) {
162 rappor::RapporService* rappor_service = 171 rappor::RapporService* rappor_service = nullptr;
163 g_browser_process->rappor_service(); 172 if (use_rappor)
173 rappor_service = g_browser_process->rappor_service();
164 174
165 bool parse_error = false; 175 bool parse_error = false;
166 for (const base::string16& uws_string : found_uws_strings) { 176 for (const base::string16& uws_string : found_uws_strings) {
167 // All UwS ids are expected to be integers. 177 // All UwS ids are expected to be integers.
168 uint32_t uws_id = 0; 178 uint32_t uws_id = 0;
169 if (base::StringToUint(uws_string, &uws_id)) { 179 if (base::StringToUint(uws_string, &uws_id)) {
170 UMA_HISTOGRAM_SPARSE_SLOWLY(kFoundUwsMetricName, uws_id); 180 RecordSparseHistogram(kFoundUwsMetricName, uws_id);
171 if (rappor_service) { 181 if (rappor_service) {
172 rappor_service->RecordSample(kFoundUwsMetricName, 182 rappor_service->RecordSample(kFoundUwsMetricName,
173 rappor::COARSE_RAPPOR_TYPE, 183 rappor::COARSE_RAPPOR_TYPE,
174 base::UTF16ToUTF8(uws_string)); 184 base::UTF16ToUTF8(uws_string));
175 } 185 }
176 } else { 186 } else {
177 parse_error = true; 187 parse_error = true;
178 } 188 }
179 } 189 }
180 190
181 // Clean up the old value. 191 // Clean up the old value.
182 reporter_key.DeleteValue(kFoundUwsValueName); 192 reporter_key.DeleteValue(kFoundUwsValueName);
183 193
184 UMA_HISTOGRAM_BOOLEAN(kFoundUwsReadErrorMetricName, parse_error); 194 RecordBooleanHistogram(kFoundUwsReadErrorMetricName, parse_error);
185 } 195 }
186 } 196 }
187 197
188 // Reports to UMA the memory usage of the software reporter tool as reported 198 // Reports to UMA the memory usage of the software reporter tool as reported
189 // by the tool itself in the Windows registry. 199 // by the tool itself in the Windows registry.
190 void ReportMemoryUsage() const { 200 void ReportMemoryUsage() const {
191 base::win::RegKey reporter_key(HKEY_CURRENT_USER, 201 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(),
192 kSoftwareRemovalToolRegistryKey,
193 KEY_QUERY_VALUE | KEY_SET_VALUE); 202 KEY_QUERY_VALUE | KEY_SET_VALUE);
194 DWORD memory_used = 0; 203 DWORD memory_used = 0;
195 if (reporter_key.Valid() && 204 if (reporter_key.Valid() &&
196 reporter_key.ReadValueDW(kMemoryUsedValueName, &memory_used) == 205 reporter_key.ReadValueDW(kMemoryUsedValueName, &memory_used) ==
197 ERROR_SUCCESS) { 206 ERROR_SUCCESS) {
198 UMA_HISTOGRAM_MEMORY_KB(kMemoryUsedMetricName, memory_used); 207 RecordMemoryKBHistogram(kMemoryUsedMetricName, memory_used);
199 reporter_key.DeleteValue(kMemoryUsedValueName); 208 reporter_key.DeleteValue(kMemoryUsedValueName);
200 } 209 }
201 } 210 }
202 211
203 // Report the SwReporter run time with UMA both as reported by the tool via 212 // Reports the SwReporter run time with UMA both as reported by the tool via
204 // the registry and as measured by |ReporterRunner|. 213 // the registry and as measured by |ReporterRunner|.
205 void ReportRuntime(const base::TimeDelta& reporter_running_time) const { 214 void ReportRuntime(const base::TimeDelta& reporter_running_time) const {
206 UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.RunningTimeAccordingToChrome", 215 RecordLongTimesHistogram("SoftwareReporter.RunningTimeAccordingToChrome",
207 reporter_running_time); 216 reporter_running_time);
208 217
209 base::win::RegKey reporter_key( 218 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(),
210 HKEY_CURRENT_USER, kSoftwareRemovalToolRegistryKey, KEY_ALL_ACCESS); 219 KEY_ALL_ACCESS);
211 if (!reporter_key.Valid()) { 220 if (!reporter_key.Valid()) {
212 UMA_HISTOGRAM_ENUMERATION( 221 RecordEnumerationHistogram(
213 kRunningTimeErrorMetricName, 222 kRunningTimeErrorMetricName,
214 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID, 223 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID,
215 REPORTER_RUNNING_TIME_ERROR_MAX); 224 REPORTER_RUNNING_TIME_ERROR_MAX);
216 return; 225 return;
217 } 226 }
218 227
219 bool has_start_time = false; 228 bool has_start_time = false;
220 int64_t start_time_value = 0; 229 int64_t start_time_value = 0;
221 if (reporter_key.HasValue(kStartTimeValueName) && 230 if (reporter_key.HasValue(kStartTimeValueName) &&
222 reporter_key.ReadInt64(kStartTimeValueName, &start_time_value) == 231 reporter_key.ReadInt64(kStartTimeValueName, &start_time_value) ==
223 ERROR_SUCCESS) { 232 ERROR_SUCCESS) {
224 has_start_time = true; 233 has_start_time = true;
225 reporter_key.DeleteValue(kStartTimeValueName); 234 reporter_key.DeleteValue(kStartTimeValueName);
226 } 235 }
227 236
228 bool has_end_time = false; 237 bool has_end_time = false;
229 int64_t end_time_value = 0; 238 int64_t end_time_value = 0;
230 if (reporter_key.HasValue(kEndTimeValueName) && 239 if (reporter_key.HasValue(kEndTimeValueName) &&
231 reporter_key.ReadInt64(kEndTimeValueName, &end_time_value) == 240 reporter_key.ReadInt64(kEndTimeValueName, &end_time_value) ==
232 ERROR_SUCCESS) { 241 ERROR_SUCCESS) {
233 has_end_time = true; 242 has_end_time = true;
234 reporter_key.DeleteValue(kEndTimeValueName); 243 reporter_key.DeleteValue(kEndTimeValueName);
235 } 244 }
236 245
237 if (has_start_time && has_end_time) { 246 if (has_start_time && has_end_time) {
238 base::TimeDelta registry_run_time = 247 base::TimeDelta registry_run_time =
239 base::Time::FromInternalValue(end_time_value) - 248 base::Time::FromInternalValue(end_time_value) -
240 base::Time::FromInternalValue(start_time_value); 249 base::Time::FromInternalValue(start_time_value);
241 UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.RunningTime", 250 RecordLongTimesHistogram("SoftwareReporter.RunningTime",
242 registry_run_time); 251 registry_run_time);
243 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, 252 RecordEnumerationHistogram(kRunningTimeErrorMetricName,
244 REPORTER_RUNNING_TIME_ERROR_NO_ERROR, 253 REPORTER_RUNNING_TIME_ERROR_NO_ERROR,
245 REPORTER_RUNNING_TIME_ERROR_MAX); 254 REPORTER_RUNNING_TIME_ERROR_MAX);
246 } else if (!has_start_time && !has_end_time) { 255 } else if (!has_start_time && !has_end_time) {
247 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, 256 RecordEnumerationHistogram(kRunningTimeErrorMetricName,
248 REPORTER_RUNNING_TIME_ERROR_MISSING_BOTH_TIMES, 257 REPORTER_RUNNING_TIME_ERROR_MISSING_BOTH_TIMES,
249 REPORTER_RUNNING_TIME_ERROR_MAX); 258 REPORTER_RUNNING_TIME_ERROR_MAX);
250 } else if (!has_start_time) { 259 } else if (!has_start_time) {
251 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, 260 RecordEnumerationHistogram(kRunningTimeErrorMetricName,
252 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME, 261 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME,
253 REPORTER_RUNNING_TIME_ERROR_MAX); 262 REPORTER_RUNNING_TIME_ERROR_MAX);
254 } else { 263 } else {
255 DCHECK(!has_end_time); 264 DCHECK(!has_end_time);
256 UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, 265 RecordEnumerationHistogram(kRunningTimeErrorMetricName,
257 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME, 266 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME,
258 REPORTER_RUNNING_TIME_ERROR_MAX); 267 REPORTER_RUNNING_TIME_ERROR_MAX);
259 } 268 }
260 } 269 }
261 270
262 // Report the UwS scan times of the software reporter tool via UMA. 271 // Reports the UwS scan times of the software reporter tool via UMA.
263 void ReportScanTimes() const { 272 void ReportScanTimes() const {
264 base::string16 scan_times_key_path = base::StringPrintf( 273 base::string16 scan_times_key_path = base::StringPrintf(
265 L"%ls\\%ls", kSoftwareRemovalToolRegistryKey, kScanTimesSubKey); 274 L"%ls\\%ls", registry_key_.c_str(), kScanTimesSubKey);
266 base::win::RegKey scan_times_key( 275 base::win::RegKey scan_times_key(
267 HKEY_CURRENT_USER, scan_times_key_path.c_str(), KEY_ALL_ACCESS); 276 HKEY_CURRENT_USER, scan_times_key_path.c_str(), KEY_ALL_ACCESS);
268 if (!scan_times_key.Valid()) 277 if (!scan_times_key.Valid())
269 return; 278 return;
270 279
271 base::string16 value_name; 280 base::string16 value_name;
272 int uws_id = 0; 281 int uws_id = 0;
273 int64_t raw_scan_time = 0; 282 int64_t raw_scan_time = 0;
274 int num_scan_times = scan_times_key.GetValueCount(); 283 int num_scan_times = scan_times_key.GetValueCount();
275 for (int i = 0; i < num_scan_times; ++i) { 284 for (int i = 0; i < num_scan_times; ++i) {
276 if (scan_times_key.GetValueNameAt(i, &value_name) == ERROR_SUCCESS && 285 if (scan_times_key.GetValueNameAt(i, &value_name) == ERROR_SUCCESS &&
277 base::StringToInt(value_name, &uws_id) && 286 base::StringToInt(value_name, &uws_id) &&
278 scan_times_key.ReadInt64(value_name.c_str(), &raw_scan_time) == 287 scan_times_key.ReadInt64(value_name.c_str(), &raw_scan_time) ==
279 ERROR_SUCCESS) { 288 ERROR_SUCCESS) {
280 base::TimeDelta scan_time = 289 base::TimeDelta scan_time =
281 base::TimeDelta::FromInternalValue(raw_scan_time); 290 base::TimeDelta::FromInternalValue(raw_scan_time);
282 base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( 291 // We report the number of seconds plus one because it can take less
283 kScanTimesMetricName, 292 // than one second to scan some UwS and the count passed to |AddCount|
284 base::HistogramBase::kUmaTargetedHistogramFlag); 293 // must be at least one.
285 if (histogram) { 294 RecordSparseHistogramCount(kScanTimesMetricName, uws_id,
286 // We report the number of seconds plus one because it can take less 295 scan_time.InSeconds() + 1);
287 // than one second to scan some UwS and the count passed to |AddCount|
288 // must be at least one.
289 histogram->AddCount(uws_id, scan_time.InSeconds() + 1);
290 }
291 } 296 }
292 } 297 }
293 // Clean up by deleting the scan times key, which is a subkey of the main 298 // Clean up by deleting the scan times key, which is a subkey of the main
294 // reporter key. 299 // reporter key.
295 scan_times_key.Close(); 300 scan_times_key.Close();
296 base::win::RegKey reporter_key(HKEY_CURRENT_USER, 301 base::win::RegKey reporter_key(HKEY_CURRENT_USER, registry_key_.c_str(),
297 kSoftwareRemovalToolRegistryKey,
298 KEY_ENUMERATE_SUB_KEYS); 302 KEY_ENUMERATE_SUB_KEYS);
299 if (reporter_key.Valid()) 303 if (reporter_key.Valid())
300 reporter_key.DeleteKey(kScanTimesSubKey); 304 reporter_key.DeleteKey(kScanTimesSubKey);
301 } 305 }
306
307 void RecordReporterStep(SwReporterUmaValue value) {
308 RecordEnumerationHistogram("SoftwareReporter.Step", value, SW_REPORTER_MAX);
309 }
310
311 private:
312 using Sample = base::HistogramBase::Sample;
313
314 static constexpr base::HistogramBase::Flags kUmaHistogramFlag =
315 base::HistogramBase::kUmaTargetedHistogramFlag;
316
317 // Helper functions to record histograms with an optional suffix added to the
318 // histogram name. The UMA_HISTOGRAM macros can't be used because they
319 // require a constant string.
320
321 std::string FullName(const std::string& name) const {
322 if (suffix_.empty())
323 return name;
324 return base::StringPrintf("%s_%s", name.c_str(), suffix_.c_str());
325 }
326
327 void RecordBooleanHistogram(const std::string& name, bool sample) const {
328 auto histogram =
329 base::BooleanHistogram::FactoryGet(FullName(name), kUmaHistogramFlag);
330 if (histogram)
331 histogram->AddBoolean(sample);
332 }
333
334 void RecordEnumerationHistogram(const std::string& name,
335 Sample sample,
336 Sample boundary) const {
337 // See HISTOGRAM_ENUMERATION_WITH_FLAG for the parameters to |FactoryGet|.
338 auto histogram = base::LinearHistogram::FactoryGet(
339 FullName(name), 1, boundary, boundary + 1, kUmaHistogramFlag);
340 if (histogram)
341 histogram->Add(sample);
342 }
343
344 void RecordLongTimesHistogram(const std::string& name,
345 const base::TimeDelta& sample) const {
346 // See UMA_HISTOGRAM_LONG_TIMES for the parameters to |FactoryTimeGet|.
347 auto histogram = base::Histogram::FactoryTimeGet(
348 FullName(name), base::TimeDelta::FromMilliseconds(1),
349 base::TimeDelta::FromHours(1), 100, kUmaHistogramFlag);
350 if (histogram)
351 histogram->AddTime(sample);
352 }
353
354 void RecordMemoryKBHistogram(const std::string& name, Sample sample) const {
355 // See UMA_HISTOGRAM_MEMORY_KB for the parameters to |FactoryGet|.
356 auto histogram = base::LinearHistogram::FactoryGet(
rkaplow 2016/09/30 18:43:10 this is incorrect - this is switching your memory
Joe Mason 2016/09/30 20:35:39 Thanks! Filed http://crbug.com/651903.
357 FullName(name), 1000, 500000, 50, kUmaHistogramFlag);
358 if (histogram)
359 histogram->Add(sample);
360 }
361
362 void RecordSparseHistogram(const std::string& name, Sample sample) const {
363 auto histogram =
364 base::SparseHistogram::FactoryGet(FullName(name), kUmaHistogramFlag);
365 if (histogram)
366 histogram->Add(sample);
367 }
368
369 void RecordSparseHistogramCount(const std::string& name,
370 Sample sample,
371 int count) const {
372 auto histogram =
373 base::SparseHistogram::FactoryGet(FullName(name), kUmaHistogramFlag);
374 if (histogram)
375 histogram->AddCount(sample, count);
376 }
377
378 const std::string suffix_;
379 const std::wstring registry_key_;
302 }; 380 };
303 381
382 // Records the reporter step without a suffix. (For steps that are never run by
383 // the experimental reporter.)
304 void RecordReporterStepHistogram(SwReporterUmaValue value) { 384 void RecordReporterStepHistogram(SwReporterUmaValue value) {
305 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Step", value, SW_REPORTER_MAX); 385 UMAHistogramReporter uma;
386 uma.RecordReporterStep(value);
306 } 387 }
307 388
308 void DisplaySRTPrompt(const base::FilePath& download_path) { 389 void DisplaySRTPrompt(const base::FilePath& download_path) {
309 // Find the last active browser, which may be NULL, in which case we won't 390 // Find the last active browser, which may be NULL, in which case we won't
310 // show the prompt this time and will wait until the next run of the 391 // show the prompt this time and will wait until the next run of the
311 // reporter. We can't use other ways of finding a browser because we don't 392 // reporter. We can't use other ways of finding a browser because we don't
312 // have a profile. 393 // have a profile.
313 Browser* browser = chrome::FindLastActive(); 394 Browser* browser = chrome::FindLastActive();
314 if (!browser) 395 if (!browser)
315 return; 396 return;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 // interrupted by a shutdown at any time, so it shouldn't depend on anything 440 // interrupted by a shutdown at any time, so it shouldn't depend on anything
360 // external that could be shut down beforehand. 441 // external that could be shut down beforehand.
361 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { 442 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) {
362 if (g_testing_delegate_) 443 if (g_testing_delegate_)
363 return g_testing_delegate_->LaunchReporter(invocation); 444 return g_testing_delegate_->LaunchReporter(invocation);
364 base::Process reporter_process = 445 base::Process reporter_process =
365 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); 446 base::LaunchProcess(invocation.command_line, base::LaunchOptions());
366 // This exit code is used to identify that a reporter run didn't happen, so 447 // This exit code is used to identify that a reporter run didn't happen, so
367 // the result should be ignored and a rerun scheduled for the usual delay. 448 // the result should be ignored and a rerun scheduled for the usual delay.
368 int exit_code = kReporterFailureExitCode; 449 int exit_code = kReporterFailureExitCode;
450 UMAHistogramReporter uma(invocation.suffix);
369 if (reporter_process.IsValid()) { 451 if (reporter_process.IsValid()) {
370 RecordReporterStepHistogram(SW_REPORTER_START_EXECUTION); 452 uma.RecordReporterStep(SW_REPORTER_START_EXECUTION);
371 bool success = reporter_process.WaitForExit(&exit_code); 453 bool success = reporter_process.WaitForExit(&exit_code);
372 DCHECK(success); 454 DCHECK(success);
373 } else { 455 } else {
374 RecordReporterStepHistogram(SW_REPORTER_FAILED_TO_START); 456 uma.RecordReporterStep(SW_REPORTER_FAILED_TO_START);
375 } 457 }
376 return exit_code; 458 return exit_code;
377 } 459 }
378 460
379 } // namespace 461 } // namespace
380 462
381 // Class that will attempt to download the SRT, showing the SRT notification 463 // Class that will attempt to download the SRT, showing the SRT notification
382 // bubble when the download operation is complete. Instances of SRTFetcher own 464 // bubble when the download operation is complete. Instances of SRTFetcher own
383 // themselves, they will self-delete on completion of the network request when 465 // themselves, they will self-delete on completion of the network request when
384 // OnURLFetchComplete is called. 466 // OnURLFetchComplete is called.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 instance_ = new ReporterRunner; 596 instance_ = new ReporterRunner;
515 DCHECK_CURRENTLY_ON(BrowserThread::UI); 597 DCHECK_CURRENTLY_ON(BrowserThread::UI);
516 // There's nothing to do if the path and version of the reporter has not 598 // There's nothing to do if the path and version of the reporter has not
517 // changed, we just keep running the tasks that are running now. 599 // changed, we just keep running the tasks that are running now.
518 if (instance_->invocation_ == invocation && instance_->version_.IsValid() && 600 if (instance_->invocation_ == invocation && instance_->version_.IsValid() &&
519 instance_->version_ == version) 601 instance_->version_ == version)
520 return; 602 return;
521 603
522 instance_->invocation_ = invocation; 604 instance_->invocation_ = invocation;
523 instance_->version_ = version; 605 instance_->version_ = version;
524 instance_->main_thread_task_runner_ = main_thread_task_runner; 606 instance_->main_thread_task_runner_ = std::move(main_thread_task_runner);
525 instance_->blocking_task_runner_ = blocking_task_runner; 607 instance_->blocking_task_runner_ = std::move(blocking_task_runner);
526 608
527 if (instance_->first_run_) { 609 if (instance_->first_run_) {
528 instance_->first_run_ = false; 610 instance_->first_run_ = false;
529 instance_->TryToRun(); 611 instance_->TryToRun();
530 } 612 }
531 } 613 }
532 614
533 private: 615 private:
534 ReporterRunner() {} 616 ReporterRunner() {}
535 ~ReporterRunner() override {} 617 ~ReporterRunner() override {}
536 618
537 // BrowserListObserver. 619 // BrowserListObserver.
538 void OnBrowserSetLastActive(Browser* browser) override {} 620 void OnBrowserSetLastActive(Browser* browser) override {}
539 void OnBrowserRemoved(Browser* browser) override {} 621 void OnBrowserRemoved(Browser* browser) override {}
540 void OnBrowserAdded(Browser* browser) override { 622 void OnBrowserAdded(Browser* browser) override {
541 DCHECK_CURRENTLY_ON(BrowserThread::UI); 623 DCHECK_CURRENTLY_ON(BrowserThread::UI);
542 DCHECK(browser); 624 DCHECK(browser);
543 MaybeFetchSRT(browser, version_); 625 MaybeFetchSRT(browser, version_);
544 BrowserList::RemoveObserver(this); 626 BrowserList::RemoveObserver(this);
545 } 627 }
546 628
547 // This method is called on the UI thread when the reporter run has completed. 629 // This method is called on the UI thread when the reporter run has completed.
548 // This is run as a task posted from an interruptible worker thread so should 630 // This is run as a task posted from an interruptible worker thread so should
549 // be resilient to unexpected shutdown. 631 // be resilient to unexpected shutdown.
550 void ReporterDone(const base::Time& reporter_start_time, 632 void ReporterDone(const base::Time& reporter_start_time,
551 const base::Version& version, 633 const base::Version& version,
634 const SwReporterInvocation& finished_invocation,
552 int exit_code) { 635 int exit_code) {
553 DCHECK_CURRENTLY_ON(BrowserThread::UI); 636 DCHECK_CURRENTLY_ON(BrowserThread::UI);
554 637
555 if (g_testing_delegate_) 638 if (g_testing_delegate_)
556 g_testing_delegate_->NotifyReporterDone(); 639 g_testing_delegate_->NotifyReporterDone();
557 640
558 base::TimeDelta reporter_running_time = 641 base::TimeDelta reporter_running_time =
559 base::Time::Now() - reporter_start_time; 642 base::Time::Now() - reporter_start_time;
560 // Don't continue when the reporter process failed to launch, but still try 643 // Don't continue when the reporter process failed to launch, but still try
561 // again after the regular delay. It's not worth retrying earlier, risking 644 // again after the regular delay. It's not worth retrying earlier, risking
562 // running too often if it always fails, since not many users fail here. 645 // running too often if it always fails, since not many users fail here.
563 main_thread_task_runner_->PostDelayedTask( 646 main_thread_task_runner_->PostDelayedTask(
564 FROM_HERE, 647 FROM_HERE,
565 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), 648 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)),
566 base::TimeDelta::FromDays(days_between_reporter_runs_)); 649 base::TimeDelta::FromDays(days_between_reporter_runs_));
567 if (exit_code == kReporterFailureExitCode) 650 if (exit_code == kReporterFailureExitCode)
568 return; 651 return;
569 652
570 UMAHistogramReporter uma; 653 UMAHistogramReporter uma(finished_invocation.suffix);
571 uma.ReportVersion(version); 654 uma.ReportVersion(version);
572 uma.ReportExitCode(exit_code); 655 uma.ReportExitCode(exit_code);
573 uma.ReportFoundUwS(); 656 uma.ReportFoundUwS(!finished_invocation.is_experimental /*use_rappor*/);
657
658 // Only save results from the canonical version of the software.
574 PrefService* local_state = g_browser_process->local_state(); 659 PrefService* local_state = g_browser_process->local_state();
575 if (local_state) { 660 if (local_state && !finished_invocation.is_experimental) {
576 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code); 661 local_state->SetInteger(prefs::kSwReporterLastExitCode, exit_code);
577 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, 662 local_state->SetInt64(prefs::kSwReporterLastTimeTriggered,
578 base::Time::Now().ToInternalValue()); 663 base::Time::Now().ToInternalValue());
579 } 664 }
580 uma.ReportRuntime(reporter_running_time); 665 uma.ReportRuntime(reporter_running_time);
581 uma.ReportScanTimes(); 666 uma.ReportScanTimes();
582 uma.ReportMemoryUsage(); 667 uma.ReportMemoryUsage();
583 668
669 // Only continue to launch the prompt for the canonical version.
670 if (finished_invocation.is_experimental)
671 return;
672
584 if (!IsInSRTPromptFieldTrialGroups()) { 673 if (!IsInSRTPromptFieldTrialGroups()) {
585 // Knowing about disabled field trial is more important than reporter not 674 // Knowing about disabled field trial is more important than reporter not
586 // finding anything to remove, so check this case first. 675 // finding anything to remove, so check this case first.
587 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL); 676 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_FIELD_TRIAL);
588 return; 677 return;
589 } 678 }
590 679
591 if (exit_code != kSwReporterPostRebootCleanupNeeded && 680 if (exit_code != kSwReporterPostRebootCleanupNeeded &&
592 exit_code != kSwReporterCleanupNeeded) { 681 exit_code != kSwReporterCleanupNeeded) {
593 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_NEEDED); 682 RecordReporterStepHistogram(SW_REPORTER_NO_PROMPT_NEEDED);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 g_testing_delegate_->NotifyLaunchReady(); 729 g_testing_delegate_->NotifyLaunchReady();
641 730
642 // It's OK to simply |PostTaskAndReplyWithResult| so that 731 // It's OK to simply |PostTaskAndReplyWithResult| so that
643 // |LaunchAndWaitForExit| doesn't need to access 732 // |LaunchAndWaitForExit| doesn't need to access
644 // |main_thread_task_runner_| since the callback is not delayed and the 733 // |main_thread_task_runner_| since the callback is not delayed and the
645 // test task runner won't need to force it. 734 // test task runner won't need to force it.
646 base::PostTaskAndReplyWithResult( 735 base::PostTaskAndReplyWithResult(
647 blocking_task_runner_.get(), FROM_HERE, 736 blocking_task_runner_.get(), FROM_HERE,
648 base::Bind(&LaunchAndWaitForExit, invocation_), 737 base::Bind(&LaunchAndWaitForExit, invocation_),
649 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), 738 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this),
650 base::Time::Now(), version_)); 739 base::Time::Now(), version_, invocation_));
651 } else { 740 } else {
652 main_thread_task_runner_->PostDelayedTask( 741 main_thread_task_runner_->PostDelayedTask(
653 FROM_HERE, 742 FROM_HERE,
654 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), 743 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)),
655 next_trigger_delay); 744 next_trigger_delay);
656 } 745 }
657 } 746 }
658 747
659 bool first_run_ = true; 748 bool first_run_ = true;
660 SwReporterInvocation invocation_; 749 SwReporterInvocation invocation_;
(...skipping 28 matching lines...) Expand all
689 } 778 }
690 779
691 SwReporterInvocation SwReporterInvocation::FromCommandLine( 780 SwReporterInvocation SwReporterInvocation::FromCommandLine(
692 const base::CommandLine& command_line) { 781 const base::CommandLine& command_line) {
693 SwReporterInvocation invocation; 782 SwReporterInvocation invocation;
694 invocation.command_line = command_line; 783 invocation.command_line = command_line;
695 return invocation; 784 return invocation;
696 } 785 }
697 786
698 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const { 787 bool SwReporterInvocation::operator==(const SwReporterInvocation& other) const {
699 return command_line.argv() == other.command_line.argv(); 788 return command_line.argv() == other.command_line.argv() &&
789 suffix == other.suffix && is_experimental == other.is_experimental;
700 } 790 }
701 791
702 void RunSwReporter(const SwReporterInvocation& invocation, 792 void RunSwReporter(const SwReporterInvocation& invocation,
703 const base::Version& version, 793 const base::Version& version,
704 scoped_refptr<base::TaskRunner> main_thread_task_runner, 794 scoped_refptr<base::TaskRunner> main_thread_task_runner,
705 scoped_refptr<base::TaskRunner> blocking_task_runner) { 795 scoped_refptr<base::TaskRunner> blocking_task_runner) {
706 ReporterRunner::Run(invocation, version, main_thread_task_runner, 796 ReporterRunner::Run(invocation, version, std::move(main_thread_task_runner),
707 blocking_task_runner); 797 std::move(blocking_task_runner));
708 } 798 }
709 799
710 bool ReporterFoundUws() { 800 bool ReporterFoundUws() {
711 PrefService* local_state = g_browser_process->local_state(); 801 PrefService* local_state = g_browser_process->local_state();
712 if (!local_state) 802 if (!local_state)
713 return false; 803 return false;
714 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode); 804 int exit_code = local_state->GetInteger(prefs::kSwReporterLastExitCode);
715 return exit_code == kSwReporterCleanupNeeded; 805 return exit_code == kSwReporterCleanupNeeded;
716 } 806 }
717 807
718 bool UserHasRunCleaner() { 808 bool UserHasRunCleaner() {
719 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey); 809 base::string16 cleaner_key_path(kSoftwareRemovalToolRegistryKey);
720 cleaner_key_path.append(L"\\").append(kCleanerSubKey); 810 cleaner_key_path.append(L"\\").append(kCleanerSubKey);
721 811
722 base::win::RegKey srt_cleaner_key(HKEY_CURRENT_USER, cleaner_key_path.c_str(), 812 base::win::RegKey srt_cleaner_key(HKEY_CURRENT_USER, cleaner_key_path.c_str(),
723 KEY_QUERY_VALUE); 813 KEY_QUERY_VALUE);
724 814
725 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; 815 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0;
726 } 816 }
727 817
728 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { 818 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) {
729 g_testing_delegate_ = delegate; 819 g_testing_delegate_ = delegate;
730 } 820 }
731 821
732 } // namespace safe_browsing 822 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698