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

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

Powered by Google App Engine
This is Rietveld 408576698