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

Side by Side Diff: chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc

Issue 856543004: Replace incident type handlers with implementations of Incident. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: robertshield comments Created 5 years, 11 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_ser vice.h" 5 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_ser vice.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/scoped_user_pref_update.h" 14 #include "base/prefs/scoped_user_pref_update.h"
15 #include "base/process/process_info.h" 15 #include "base/process/process_info.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/thread_task_runner_handle.h" 19 #include "base/thread_task_runner_handle.h"
20 #include "base/threading/sequenced_worker_pool.h" 20 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/values.h" 21 #include "base/values.h"
22 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/chrome_notification_types.h" 23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h" 24 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h"
25 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/safe_browsing/database_manager.h" 26 #include "chrome/browser/safe_browsing/database_manager.h"
27 #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_incid ent_handlers.h"
28 #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_inciden t_handlers.h"
29 #include "chrome/browser/safe_browsing/incident_reporting/environment_data_colle ction.h" 27 #include "chrome/browser/safe_browsing/incident_reporting/environment_data_colle ction.h"
28 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
30 #include "chrome/browser/safe_browsing/incident_reporting/incident_report_upload er_impl.h" 29 #include "chrome/browser/safe_browsing/incident_reporting/incident_report_upload er_impl.h"
31 #include "chrome/browser/safe_browsing/incident_reporting/omnibox_incident_handl ers.h"
32 #include "chrome/browser/safe_browsing/incident_reporting/omnibox_watcher.h" 30 #include "chrome/browser/safe_browsing/incident_reporting/omnibox_watcher.h"
33 #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_ delegate.h" 31 #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_ delegate.h"
34 #include "chrome/browser/safe_browsing/incident_reporting/tracked_preference_inc ident_handlers.h"
35 #include "chrome/browser/safe_browsing/incident_reporting/variations_seed_signat ure_incident_handlers.h"
36 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 32 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
37 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
38 #include "chrome/common/safe_browsing/csd.pb.h" 34 #include "chrome/common/safe_browsing/csd.pb.h"
39 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
40 #include "content/public/browser/notification_service.h" 36 #include "content/public/browser/notification_service.h"
41 #include "net/url_request/url_request_context_getter.h" 37 #include "net/url_request/url_request_context_getter.h"
42 38
43 namespace safe_browsing { 39 namespace safe_browsing {
44 40
45 namespace { 41 namespace {
46 42
47 // The type of an incident. Used for user metrics and for pruning of
48 // previously-reported incidents.
49 enum IncidentType {
50 // Start with 1 rather than zero; otherwise there won't be enough buckets for
51 // the histogram.
52 TRACKED_PREFERENCE = 1,
53 BINARY_INTEGRITY = 2,
54 BLACKLIST_LOAD = 3,
55 OMNIBOX_INTERACTION = 4,
56 VARIATIONS_SEED_SIGNATURE = 5,
57 // Values for new incident types go here.
58 NUM_INCIDENT_TYPES = 6
59 };
60
61 // The action taken for an incident; used for user metrics (see 43 // The action taken for an incident; used for user metrics (see
62 // LogIncidentDataType). 44 // LogIncidentDataType).
63 enum IncidentDisposition { 45 enum IncidentDisposition {
64 RECEIVED, 46 RECEIVED,
65 DROPPED, 47 DROPPED,
66 ACCEPTED, 48 ACCEPTED,
67 PRUNED, 49 PRUNED,
68 DISCARDED, 50 DISCARDED,
69 NUM_DISPOSITIONS 51 NUM_DISPOSITIONS
70 }; 52 };
71 53
72 // The state persisted for a specific instance of an incident to enable pruning 54 // The state persisted for a specific instance of an incident to enable pruning
73 // of previously-reported incidents. 55 // of previously-reported incidents.
74 struct PersistentIncidentState { 56 struct PersistentIncidentState {
75 // The type of the incident. 57 // The type of the incident.
76 IncidentType type; 58 std::string type;
77 59
78 // The key for a specific instance of an incident. 60 // The key for a specific instance of an incident.
79 std::string key; 61 std::string key;
80 62
81 // A hash digest representing a specific instance of an incident. 63 // A hash digest representing a specific instance of an incident.
82 uint32_t digest; 64 uint32_t digest;
83 }; 65 };
84 66
85 // The amount of time the service will wait to collate incidents. 67 // The amount of time the service will wait to collate incidents.
86 const int64 kDefaultUploadDelayMs = 1000 * 60; // one minute 68 const int64 kDefaultUploadDelayMs = 1000 * 60; // one minute
87 69
88 // The amount of time between running delayed analysis callbacks. 70 // The amount of time between running delayed analysis callbacks.
89 const int64 kDefaultCallbackIntervalMs = 1000 * 20; 71 const int64 kDefaultCallbackIntervalMs = 1000 * 20;
90 72
91 // Returns the number of incidents contained in |incident|. The result is
92 // expected to be 1. Used in DCHECKs.
93 size_t CountIncidents(const ClientIncidentReport_IncidentData& incident) {
94 size_t result = 0;
95 if (incident.has_tracked_preference())
96 ++result;
97 if (incident.has_binary_integrity())
98 ++result;
99 if (incident.has_blacklist_load())
100 ++result;
101 if (incident.has_omnibox_interaction())
102 ++result;
103 if (incident.has_variations_seed_signature())
104 ++result;
105 // Add detection for new incident types here.
106 return result;
107 }
108
109 // Returns the type of incident contained in |incident_data|.
110 IncidentType GetIncidentType(
111 const ClientIncidentReport_IncidentData& incident_data) {
112 if (incident_data.has_tracked_preference())
113 return TRACKED_PREFERENCE;
114 if (incident_data.has_binary_integrity())
115 return BINARY_INTEGRITY;
116 if (incident_data.has_blacklist_load())
117 return BLACKLIST_LOAD;
118 if (incident_data.has_omnibox_interaction())
119 return OMNIBOX_INTERACTION;
120 if (incident_data.has_variations_seed_signature())
121 return VARIATIONS_SEED_SIGNATURE;
122
123 // Add detection for new incident types here.
124 static_assert(VARIATIONS_SEED_SIGNATURE + 1 == NUM_INCIDENT_TYPES,
125 "support for new types must be added");
126 NOTREACHED();
127 return NUM_INCIDENT_TYPES;
128 }
129
130 // Logs the type of incident in |incident_data| to a user metrics histogram. 73 // Logs the type of incident in |incident_data| to a user metrics histogram.
131 void LogIncidentDataType( 74 void LogIncidentDataType(IncidentDisposition disposition,
132 IncidentDisposition disposition, 75 const Incident& incident) {
133 const ClientIncidentReport_IncidentData& incident_data) {
134 static const char* const kHistogramNames[] = { 76 static const char* const kHistogramNames[] = {
135 "SBIRS.ReceivedIncident", 77 "SBIRS.ReceivedIncident",
136 "SBIRS.DroppedIncident", 78 "SBIRS.DroppedIncident",
137 "SBIRS.Incident", 79 "SBIRS.Incident",
138 "SBIRS.PrunedIncident", 80 "SBIRS.PrunedIncident",
139 "SBIRS.DiscardedIncident", 81 "SBIRS.DiscardedIncident",
140 }; 82 };
141 static_assert(arraysize(kHistogramNames) == NUM_DISPOSITIONS, 83 static_assert(arraysize(kHistogramNames) == NUM_DISPOSITIONS,
142 "Keep kHistogramNames in sync with enum IncidentDisposition."); 84 "Keep kHistogramNames in sync with enum IncidentDisposition.");
143 DCHECK_GE(disposition, 0); 85 DCHECK_GE(disposition, 0);
144 DCHECK_LT(disposition, NUM_DISPOSITIONS); 86 DCHECK_LT(disposition, NUM_DISPOSITIONS);
145 IncidentType type = GetIncidentType(incident_data);
146 base::LinearHistogram::FactoryGet( 87 base::LinearHistogram::FactoryGet(
147 kHistogramNames[disposition], 88 kHistogramNames[disposition],
148 1, // minimum 89 1, // minimum
149 NUM_INCIDENT_TYPES, // maximum 90 static_cast<int32_t>(IncidentType::NUM_TYPES), // maximum
150 NUM_INCIDENT_TYPES + 1, // bucket_count 91 static_cast<size_t>(IncidentType::NUM_TYPES) + 1, // bucket_count
151 base::HistogramBase::kUmaTargetedHistogramFlag)->Add(type); 92 base::HistogramBase::kUmaTargetedHistogramFlag)->Add(
93 static_cast<int32_t>(incident.GetType()));
152 } 94 }
153 95
154 // Computes the persistent state for an incident. 96 // Computes the persistent state for an incident.
155 PersistentIncidentState ComputeIncidentState( 97 PersistentIncidentState ComputeIncidentState(const Incident& incident) {
156 const ClientIncidentReport_IncidentData& incident) { 98 PersistentIncidentState state = {
157 PersistentIncidentState state = {GetIncidentType(incident)}; 99 base::IntToString(static_cast<int32_t>(incident.GetType())),
158 switch (state.type) { 100 incident.GetKey(),
159 case TRACKED_PREFERENCE: 101 incident.ComputeDigest(),
160 state.key = GetTrackedPreferenceIncidentKey(incident); 102 };
161 state.digest = GetTrackedPreferenceIncidentDigest(incident);
162 break;
163 case BINARY_INTEGRITY:
164 state.key = GetBinaryIntegrityIncidentKey(incident);
165 state.digest = GetBinaryIntegrityIncidentDigest(incident);
166 break;
167 case BLACKLIST_LOAD:
168 state.key = GetBlacklistLoadIncidentKey(incident);
169 state.digest = GetBlacklistLoadIncidentDigest(incident);
170 break;
171 case OMNIBOX_INTERACTION:
172 state.key = GetOmniboxIncidentKey(incident);
173 state.digest = GetOmniboxIncidentDigest(incident);
174 break;
175 case VARIATIONS_SEED_SIGNATURE:
176 state.key = GetVariationsSeedSignatureIncidentKey(incident);
177 state.digest = GetVariationsSeedSignatureIncidentDigest(incident);
178 break;
179 // Add handling for new incident types here.
180 case NUM_INCIDENT_TYPES:
181 NOTREACHED();
182 break;
183 }
184 return state; 103 return state;
185 } 104 }
186 105
187 // Returns true if the incident described by |state| has already been reported 106 // Returns true if the incident described by |state| has already been reported
188 // based on the bookkeeping in the |incidents_sent| preference dictionary. 107 // based on the bookkeeping in the |incidents_sent| preference dictionary.
189 bool IncidentHasBeenReported(const base::DictionaryValue* incidents_sent, 108 bool IncidentHasBeenReported(const base::DictionaryValue* incidents_sent,
190 const PersistentIncidentState& state) { 109 const PersistentIncidentState& state) {
191 const base::DictionaryValue* type_dict = NULL; 110 const base::DictionaryValue* type_dict = NULL;
192 std::string digest_string; 111 std::string digest_string;
193 return (incidents_sent && 112 return (incidents_sent &&
194 incidents_sent->GetDictionaryWithoutPathExpansion( 113 incidents_sent->GetDictionaryWithoutPathExpansion(state.type,
195 base::IntToString(state.type), &type_dict) && 114 &type_dict) &&
196 type_dict->GetStringWithoutPathExpansion(state.key, &digest_string) && 115 type_dict->GetStringWithoutPathExpansion(state.key, &digest_string) &&
197 digest_string == base::UintToString(state.digest)); 116 digest_string == base::UintToString(state.digest));
198 } 117 }
199 118
200 // Marks the incidents described by |states| as having been reported 119 // Marks the incidents described by |states| as having been reported
201 // in |incidents_set|. 120 // in |incidents_set|.
202 void MarkIncidentsAsReported(const std::vector<PersistentIncidentState>& states, 121 void MarkIncidentsAsReported(const std::vector<PersistentIncidentState>& states,
203 base::DictionaryValue* incidents_sent) { 122 base::DictionaryValue* incidents_sent) {
204 for (size_t i = 0; i < states.size(); ++i) { 123 for (size_t i = 0; i < states.size(); ++i) {
205 const PersistentIncidentState& data = states[i]; 124 const PersistentIncidentState& data = states[i];
206 base::DictionaryValue* type_dict = NULL; 125 base::DictionaryValue* type_dict = NULL;
207 const std::string type_string(base::IntToString(data.type)); 126 if (!incidents_sent->GetDictionaryWithoutPathExpansion(data.type,
208 if (!incidents_sent->GetDictionaryWithoutPathExpansion(type_string,
209 &type_dict)) { 127 &type_dict)) {
210 type_dict = new base::DictionaryValue(); 128 type_dict = new base::DictionaryValue();
211 incidents_sent->SetWithoutPathExpansion(type_string, type_dict); 129 incidents_sent->SetWithoutPathExpansion(data.type, type_dict);
212 } 130 }
213 type_dict->SetStringWithoutPathExpansion(data.key, 131 type_dict->SetStringWithoutPathExpansion(data.key,
214 base::UintToString(data.digest)); 132 base::UintToString(data.digest));
215 } 133 }
216 } 134 }
217 135
218 // Runs |callback| on the thread to which |thread_runner| belongs. The callback 136 // Runs |callback| on the thread to which |thread_runner| belongs. The callback
219 // is run immediately if this function is called on |thread_runner|'s thread. 137 // is run immediately if this function is called on |thread_runner|'s thread.
220 void AddIncidentOnOriginThread( 138 void AddIncidentOnOriginThread(
221 const AddIncidentCallback& callback, 139 const AddIncidentCallback& callback,
222 scoped_refptr<base::SingleThreadTaskRunner> thread_runner, 140 scoped_refptr<base::SingleThreadTaskRunner> thread_runner,
223 scoped_ptr<ClientIncidentReport_IncidentData> incident) { 141 scoped_ptr<Incident> incident) {
224 if (thread_runner->BelongsToCurrentThread()) 142 if (thread_runner->BelongsToCurrentThread())
225 callback.Run(incident.Pass()); 143 callback.Run(incident.Pass());
226 else 144 else
227 thread_runner->PostTask(FROM_HERE, 145 thread_runner->PostTask(FROM_HERE,
228 base::Bind(callback, base::Passed(&incident))); 146 base::Bind(callback, base::Passed(&incident)));
229 } 147 }
230 148
231 } // namespace 149 } // namespace
232 150
233 struct IncidentReportingService::ProfileContext { 151 struct IncidentReportingService::ProfileContext {
234 ProfileContext(); 152 ProfileContext();
235 ~ProfileContext(); 153 ~ProfileContext();
236 154
237 // The incidents collected for this profile pending creation and/or upload. 155 // The incidents collected for this profile pending creation and/or upload.
238 // Will contain null values for pruned incidents. 156 // Will contain null values for pruned incidents.
239 ScopedVector<ClientIncidentReport_IncidentData> incidents; 157 ScopedVector<Incident> incidents;
240 158
241 // Watches for suspicious omnibox interactions on this profile. 159 // Watches for suspicious omnibox interactions on this profile.
242 scoped_ptr<OmniboxWatcher> omnibox_watcher; 160 scoped_ptr<OmniboxWatcher> omnibox_watcher;
243 161
244 // False until PROFILE_ADDED notification is received. 162 // False until PROFILE_ADDED notification is received.
245 bool added; 163 bool added;
246 164
247 private: 165 private:
248 DISALLOW_COPY_AND_ASSIGN(ProfileContext); 166 DISALLOW_COPY_AND_ASSIGN(ProfileContext);
249 }; 167 };
(...skipping 16 matching lines...) Expand all
266 PersistentIncidentStateCollection profiles_to_state; 184 PersistentIncidentStateCollection profiles_to_state;
267 185
268 private: 186 private:
269 DISALLOW_COPY_AND_ASSIGN(UploadContext); 187 DISALLOW_COPY_AND_ASSIGN(UploadContext);
270 }; 188 };
271 189
272 IncidentReportingService::ProfileContext::ProfileContext() : added() { 190 IncidentReportingService::ProfileContext::ProfileContext() : added() {
273 } 191 }
274 192
275 IncidentReportingService::ProfileContext::~ProfileContext() { 193 IncidentReportingService::ProfileContext::~ProfileContext() {
276 for (ClientIncidentReport_IncidentData* incident : incidents) { 194 for (Incident* incident : incidents) {
277 if (incident) 195 if (incident)
278 LogIncidentDataType(DISCARDED, *incident); 196 LogIncidentDataType(DISCARDED, *incident);
279 } 197 }
280 } 198 }
281 199
282 IncidentReportingService::UploadContext::UploadContext( 200 IncidentReportingService::UploadContext::UploadContext(
283 scoped_ptr<ClientIncidentReport> report) 201 scoped_ptr<ClientIncidentReport> report)
284 : report(report.Pass()) { 202 : report(report.Pass()) {
285 } 203 }
286 204
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 NULL); 243 NULL);
326 if (download_protection_service) { 244 if (download_protection_service) {
327 client_download_request_subscription_ = 245 client_download_request_subscription_ =
328 download_protection_service->RegisterClientDownloadRequestCallback( 246 download_protection_service->RegisterClientDownloadRequestCallback(
329 base::Bind(&IncidentReportingService::OnClientDownloadRequest, 247 base::Bind(&IncidentReportingService::OnClientDownloadRequest,
330 base::Unretained(this))); 248 base::Unretained(this)));
331 } 249 }
332 } 250 }
333 251
334 IncidentReportingService::~IncidentReportingService() { 252 IncidentReportingService::~IncidentReportingService() {
253 DCHECK(thread_checker_.CalledOnValidThread());
335 CancelIncidentCollection(); 254 CancelIncidentCollection();
336 255
337 // Cancel all internal asynchronous tasks. 256 // Cancel all internal asynchronous tasks.
338 weak_ptr_factory_.InvalidateWeakPtrs(); 257 weak_ptr_factory_.InvalidateWeakPtrs();
339 258
340 CancelEnvironmentCollection(); 259 CancelEnvironmentCollection();
341 CancelDownloadCollection(); 260 CancelDownloadCollection();
342 CancelAllReportUploads(); 261 CancelAllReportUploads();
343 262
344 STLDeleteValues(&profiles_); 263 STLDeleteValues(&profiles_);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 // and/or report processing if sb is currently disabled but subsequently 391 // and/or report processing if sb is currently disabled but subsequently
473 // enabled. 392 // enabled.
474 393
475 // Nothing else to do if a report is not being assembled. 394 // Nothing else to do if a report is not being assembled.
476 if (!report_) 395 if (!report_)
477 return; 396 return;
478 397
479 // Drop all incidents associated with this profile that were received prior to 398 // Drop all incidents associated with this profile that were received prior to
480 // its addition if the profile is not participating in safe browsing. 399 // its addition if the profile is not participating in safe browsing.
481 if (!context->incidents.empty() && !safe_browsing_enabled) { 400 if (!context->incidents.empty() && !safe_browsing_enabled) {
482 for (ClientIncidentReport_IncidentData* incident : context->incidents) 401 for (Incident* incident : context->incidents)
483 LogIncidentDataType(DROPPED, *incident); 402 LogIncidentDataType(DROPPED, *incident);
484 context->incidents.clear(); 403 context->incidents.clear();
485 } 404 }
486 405
487 // Take another stab at finding the most recent download if a report is being 406 // Take another stab at finding the most recent download if a report is being
488 // assembled and one hasn't been found yet (the LastDownloadFinder operates 407 // assembled and one hasn't been found yet (the LastDownloadFinder operates
489 // only on profiles that have been added to the ProfileManager). 408 // only on profiles that have been added to the ProfileManager).
490 BeginDownloadCollection(); 409 BeginDownloadCollection();
491 } 410 }
492 411
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 candidate = scan->first; 480 candidate = scan->first;
562 if (prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)) { 481 if (prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)) {
563 candidate = scan->first; 482 candidate = scan->first;
564 break; 483 break;
565 } 484 }
566 } 485 }
567 } 486 }
568 return candidate; 487 return candidate;
569 } 488 }
570 489
571 void IncidentReportingService::AddIncident( 490 void IncidentReportingService::AddIncident(Profile* profile,
572 Profile* profile, 491 scoped_ptr<Incident> incident) {
573 scoped_ptr<ClientIncidentReport_IncidentData> incident_data) {
574 DCHECK(thread_checker_.CalledOnValidThread()); 492 DCHECK(thread_checker_.CalledOnValidThread());
575 DCHECK_EQ(1U, CountIncidents(*incident_data));
576 493
577 ProfileContext* context = GetProfileContext(profile); 494 ProfileContext* context = GetProfileContext(profile);
578 // It is forbidden to call this function with a destroyed profile. 495 // It is forbidden to call this function with a destroyed profile.
579 DCHECK(context); 496 DCHECK(context);
580 // If this is a process-wide incident, the context must not indicate that the 497 // If this is a process-wide incident, the context must not indicate that the
581 // profile (which is NULL) has been added to the profile manager. 498 // profile (which is NULL) has been added to the profile manager.
582 DCHECK(profile || !context->added); 499 DCHECK(profile || !context->added);
583 500
584 LogIncidentDataType(RECEIVED, *incident_data); 501 LogIncidentDataType(RECEIVED, *incident);
585 502
586 // Drop the incident immediately if the profile has already been added to the 503 // Drop the incident immediately if the profile has already been added to the
587 // manager and is not participating in safe browsing. Preference evaluation is 504 // manager and is not participating in safe browsing. Preference evaluation is
588 // deferred until OnProfileAdded() otherwise. 505 // deferred until OnProfileAdded() otherwise.
589 if (context->added && 506 if (context->added &&
590 !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) { 507 !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
591 LogIncidentDataType(DROPPED, *incident_data); 508 LogIncidentDataType(DROPPED, *incident);
592 return; 509 return;
593 } 510 }
594 511
595 // Provide time to the new incident if the caller didn't do so.
596 if (!incident_data->has_incident_time_msec())
597 incident_data->set_incident_time_msec(base::Time::Now().ToJavaTime());
598
599 // Take ownership of the incident. 512 // Take ownership of the incident.
600 context->incidents.push_back(incident_data.release()); 513 context->incidents.push_back(incident.release());
601 514
602 // Remember when the first incident for this report arrived. 515 // Remember when the first incident for this report arrived.
603 if (first_incident_time_.is_null()) 516 if (first_incident_time_.is_null())
604 first_incident_time_ = base::Time::Now(); 517 first_incident_time_ = base::Time::Now();
605 // Log the time between the previous incident and this one. 518 // Log the time between the previous incident and this one.
606 if (!last_incident_time_.is_null()) { 519 if (!last_incident_time_.is_null()) {
607 UMA_HISTOGRAM_TIMES("SBIRS.InterIncidentTime", 520 UMA_HISTOGRAM_TIMES("SBIRS.InterIncidentTime",
608 base::TimeTicks::Now() - last_incident_time_); 521 base::TimeTicks::Now() - last_incident_time_);
609 } 522 }
610 last_incident_time_ = base::TimeTicks::Now(); 523 last_incident_time_ = base::TimeTicks::Now();
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 ++scan) { 766 ++scan) {
854 // Bypass process-wide incidents that have not yet been associated with a 767 // Bypass process-wide incidents that have not yet been associated with a
855 // profile. 768 // profile.
856 if (!scan->first) 769 if (!scan->first)
857 continue; 770 continue;
858 PrefService* prefs = scan->first->GetPrefs(); 771 PrefService* prefs = scan->first->GetPrefs();
859 ProfileContext* context = scan->second; 772 ProfileContext* context = scan->second;
860 if (context->incidents.empty()) 773 if (context->incidents.empty())
861 continue; 774 continue;
862 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled)) { 775 if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled)) {
863 for (ClientIncidentReport_IncidentData* incident : context->incidents) 776 for (Incident* incident : context->incidents)
864 LogIncidentDataType(DROPPED, *incident); 777 LogIncidentDataType(DROPPED, *incident);
865 context->incidents.clear(); 778 context->incidents.clear();
866 continue; 779 continue;
867 } 780 }
868 std::vector<PersistentIncidentState> states; 781 std::vector<PersistentIncidentState> states;
869 const base::DictionaryValue* incidents_sent = 782 const base::DictionaryValue* incidents_sent =
870 prefs->GetDictionary(prefs::kSafeBrowsingIncidentsSent); 783 prefs->GetDictionary(prefs::kSafeBrowsingIncidentsSent);
871 // Prep persistent data and prune any incidents already sent. 784 // Prep persistent data and prune any incidents already sent.
872 for (ClientIncidentReport_IncidentData* incident : context->incidents) { 785 for (Incident* incident : context->incidents) {
873 const PersistentIncidentState state = ComputeIncidentState(*incident); 786 const PersistentIncidentState state = ComputeIncidentState(*incident);
874 if (IncidentHasBeenReported(incidents_sent, state)) { 787 if (IncidentHasBeenReported(incidents_sent, state)) {
875 LogIncidentDataType(PRUNED, *incident); 788 LogIncidentDataType(PRUNED, *incident);
876 ++prune_count; 789 ++prune_count;
877 delete incident;
878 } else { 790 } else {
879 LogIncidentDataType(ACCEPTED, *incident); 791 LogIncidentDataType(ACCEPTED, *incident);
880 // Ownership of the incident is passed to the report. 792 // Ownership of the payload is passed to the report.
881 report->mutable_incident()->AddAllocated(incident); 793 ClientIncidentReport_IncidentData* data =
794 incident->TakePayload().release();
795 DCHECK(data->has_incident_time_msec());
796 report->mutable_incident()->AddAllocated(data);
797 data = nullptr;
882 states.push_back(state); 798 states.push_back(state);
883 } 799 }
884 } 800 }
885 context->incidents.weak_clear(); 801 context->incidents.clear();
886 profiles_to_state[scan->first].swap(states); 802 profiles_to_state[scan->first].swap(states);
887 } 803 }
888 804
889 const int count = report->incident_size(); 805 const int count = report->incident_size();
890 // Abandon the request if all incidents were dropped with none pruned. 806 // Abandon the request if all incidents were dropped with none pruned.
891 if (!count && !prune_count) 807 if (!count && !prune_count)
892 return; 808 return;
893 809
894 UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", count + prune_count); 810 UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", count + prune_count);
895 811
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 if (!profile->IsOffTheRecord()) 931 if (!profile->IsOffTheRecord())
1016 OnProfileDestroyed(profile); 932 OnProfileDestroyed(profile);
1017 break; 933 break;
1018 } 934 }
1019 default: 935 default:
1020 break; 936 break;
1021 } 937 }
1022 } 938 }
1023 939
1024 } // namespace safe_browsing 940 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698