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

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

Issue 341563003: Safe browsing incident reporting service improvements. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to r278347 Created 6 years, 6 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 | Annotate | Revision Log
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_service.h" 5 #include "chrome/browser/safe_browsing/incident_reporting_service.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/prefs/pref_service.h"
10 #include "base/process/process_info.h" 11 #include "base/process/process_info.h"
12 #include "base/stl_util.h"
11 #include "base/threading/sequenced_worker_pool.h" 13 #include "base/threading/sequenced_worker_pool.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h" 16 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h"
17 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/safe_browsing/database_manager.h" 18 #include "chrome/browser/safe_browsing/database_manager.h"
14 #include "chrome/browser/safe_browsing/environment_data_collection.h" 19 #include "chrome/browser/safe_browsing/environment_data_collection.h"
15 #include "chrome/browser/safe_browsing/incident_report_uploader_impl.h" 20 #include "chrome/browser/safe_browsing/incident_report_uploader_impl.h"
16 #include "chrome/browser/safe_browsing/preference_validation_delegate.h" 21 #include "chrome/browser/safe_browsing/preference_validation_delegate.h"
17 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 22 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
23 #include "chrome/common/pref_names.h"
18 #include "chrome/common/safe_browsing/csd.pb.h" 24 #include "chrome/common/safe_browsing/csd.pb.h"
19 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_service.h"
20 #include "net/url_request/url_request_context_getter.h" 27 #include "net/url_request/url_request_context_getter.h"
21 28
22 namespace safe_browsing { 29 namespace safe_browsing {
23 30
24 namespace { 31 namespace {
25 32
26 enum IncidentType { 33 enum IncidentType {
27 // Start with 1 rather than zero; otherwise there won't be enough buckets for 34 // Start with 1 rather than zero; otherwise there won't be enough buckets for
28 // the histogram. 35 // the histogram.
29 TRACKED_PREFERENCE = 1, 36 TRACKED_PREFERENCE = 1,
30 NUM_INCIDENT_TYPES 37 NUM_INCIDENT_TYPES
31 }; 38 };
32 39
40 enum IncidentDisposition {
41 DROPPED,
42 ACCEPTED,
43 };
44
33 const int64 kDefaultUploadDelayMs = 1000 * 60; // one minute 45 const int64 kDefaultUploadDelayMs = 1000 * 60; // one minute
34 46
35 void LogIncidentDataType( 47 void LogIncidentDataType(
48 IncidentDisposition disposition,
36 const ClientIncidentReport_IncidentData& incident_data) { 49 const ClientIncidentReport_IncidentData& incident_data) {
37 if (incident_data.has_tracked_preference()) { 50 static const char kAcceptedMetric[] = "SBIRS.Incident";
Alexei Svitkine (slow) 2014/06/19 14:25:03 Nit: It's fine to inline these into the macros, ra
38 UMA_HISTOGRAM_ENUMERATION( 51 static const char kDroppedMetric[] = "SBIRS.DroppedIncident";
39 "SBIRS.Incident", TRACKED_PREFERENCE, NUM_INCIDENT_TYPES); 52
53 IncidentType type = TRACKED_PREFERENCE;
54
55 // Add a switch statement once other types are supported.
56 DCHECK(incident_data.has_tracked_preference());
57
58 if (disposition == ACCEPTED) {
59 UMA_HISTOGRAM_ENUMERATION(kAcceptedMetric, type, NUM_INCIDENT_TYPES);
60 } else {
61 DCHECK_EQ(disposition, DROPPED);
62 UMA_HISTOGRAM_ENUMERATION(kDroppedMetric, type, NUM_INCIDENT_TYPES);
40 } 63 }
41 } 64 }
42 65
43 } // namespace 66 } // namespace
44 67
68 struct IncidentReportingService::ProfileContext {
69 ProfileContext();
70 ~ProfileContext();
71
72 // The incidents collected for this profile pending creation and/or upload.
73 ScopedVector<ClientIncidentReport_IncidentData> incidents;
74
75 // False until PROFILE_CREATED notification is received.
76 bool created;
77
78 private:
79 DISALLOW_COPY_AND_ASSIGN(ProfileContext);
80 };
81
45 class IncidentReportingService::UploadContext { 82 class IncidentReportingService::UploadContext {
46 public: 83 public:
47 explicit UploadContext(scoped_ptr<ClientIncidentReport> report); 84 explicit UploadContext(scoped_ptr<ClientIncidentReport> report);
48 ~UploadContext(); 85 ~UploadContext();
49 86
50 scoped_ptr<ClientIncidentReport> report; 87 scoped_ptr<ClientIncidentReport> report;
51 scoped_ptr<IncidentReportUploader> uploader; 88 scoped_ptr<IncidentReportUploader> uploader;
52 89
53 private: 90 private:
54 DISALLOW_COPY_AND_ASSIGN(UploadContext); 91 DISALLOW_COPY_AND_ASSIGN(UploadContext);
55 }; 92 };
56 93
94 IncidentReportingService::ProfileContext::ProfileContext() : created() {
95 }
96
97 IncidentReportingService::ProfileContext::~ProfileContext() {
98 }
99
57 IncidentReportingService::UploadContext::UploadContext( 100 IncidentReportingService::UploadContext::UploadContext(
58 scoped_ptr<ClientIncidentReport> report) 101 scoped_ptr<ClientIncidentReport> report)
59 : report(report.Pass()) { 102 : report(report.Pass()) {
60 } 103 }
61 104
62 IncidentReportingService::UploadContext::~UploadContext() { 105 IncidentReportingService::UploadContext::~UploadContext() {
63 } 106 }
64 107
65 IncidentReportingService::IncidentReportingService( 108 IncidentReportingService::IncidentReportingService(
66 SafeBrowsingService* safe_browsing_service, 109 SafeBrowsingService* safe_browsing_service,
67 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter) 110 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter)
68 : database_manager_(safe_browsing_service ? 111 : database_manager_(safe_browsing_service ?
69 safe_browsing_service->database_manager() : NULL), 112 safe_browsing_service->database_manager() : NULL),
70 url_request_context_getter_(request_context_getter), 113 url_request_context_getter_(request_context_getter),
71 collect_environment_data_fn_(&CollectEnvironmentData), 114 collect_environment_data_fn_(&CollectEnvironmentData),
72 environment_collection_task_runner_( 115 environment_collection_task_runner_(
73 content::BrowserThread::GetBlockingPool() 116 content::BrowserThread::GetBlockingPool()
74 ->GetTaskRunnerWithShutdownBehavior( 117 ->GetTaskRunnerWithShutdownBehavior(
75 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), 118 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
76 enabled_(),
77 environment_collection_pending_(), 119 environment_collection_pending_(),
78 collection_timeout_pending_(), 120 collection_timeout_pending_(),
79 upload_timer_(FROM_HERE, 121 upload_timer_(FROM_HERE,
80 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs), 122 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs),
81 this, 123 this,
82 &IncidentReportingService::OnCollectionTimeout), 124 &IncidentReportingService::OnCollectionTimeout),
83 receiver_weak_ptr_factory_(this), 125 receiver_weak_ptr_factory_(this),
84 weak_ptr_factory_(this) { 126 weak_ptr_factory_(this) {
127 notification_registrar_.Add(this,
128 chrome::NOTIFICATION_PROFILE_CREATED,
129 content::NotificationService::AllSources());
130 notification_registrar_.Add(this,
131 chrome::NOTIFICATION_PROFILE_DESTROYED,
132 content::NotificationService::AllSources());
85 } 133 }
86 134
87 IncidentReportingService::~IncidentReportingService() { 135 IncidentReportingService::~IncidentReportingService() {
88 if (enabled_) 136 CancelIncidentCollection();
89 SetEnabled(false); 137
138 // Cancel all internal asynchronous tasks.
139 weak_ptr_factory_.InvalidateWeakPtrs();
140
141 CancelEnvironmentCollection();
142 CancelAllReportUploads();
143
144 STLDeleteValues(&profiles_);
90 } 145 }
91 146
92 void IncidentReportingService::SetEnabled(bool enabled) { 147 AddIncidentCallback IncidentReportingService::GetAddIncidentCallback(
93 DCHECK(thread_checker_.CalledOnValidThread()); 148 Profile* profile) {
149 // Force the context to be created so that incidents added before
150 // OnProfileCreated is called are held until the profile's preferences can be
151 // queried.
152 ignore_result(GetOrCreateProfileContext(profile));
94 153
95 if (!enabled) {
96 CancelIncidentCollection();
97
98 // Cancel all internal asynchronous tasks.
99 weak_ptr_factory_.InvalidateWeakPtrs();
100
101 CancelEnvironmentCollection();
102 CancelAllReportUploads();
103 }
104
105 enabled_ = enabled;
106 }
107
108 AddIncidentCallback IncidentReportingService::GetAddIncidentCallback() {
109 return base::Bind(&IncidentReportingService::AddIncident, 154 return base::Bind(&IncidentReportingService::AddIncident,
110 receiver_weak_ptr_factory_.GetWeakPtr()); 155 receiver_weak_ptr_factory_.GetWeakPtr(),
156 profile);
111 } 157 }
112 158
113 scoped_ptr<TrackedPreferenceValidationDelegate> 159 scoped_ptr<TrackedPreferenceValidationDelegate>
114 IncidentReportingService::CreatePreferenceValidationDelegate() { 160 IncidentReportingService::CreatePreferenceValidationDelegate(Profile* profile) {
115 DCHECK(thread_checker_.CalledOnValidThread()); 161 DCHECK(thread_checker_.CalledOnValidThread());
162
163 if (profile->IsOffTheRecord())
164 return scoped_ptr<TrackedPreferenceValidationDelegate>();
116 return scoped_ptr<TrackedPreferenceValidationDelegate>( 165 return scoped_ptr<TrackedPreferenceValidationDelegate>(
117 new PreferenceValidationDelegate(GetAddIncidentCallback())); 166 new PreferenceValidationDelegate(GetAddIncidentCallback(profile)));
118 } 167 }
119 168
120 void IncidentReportingService::SetCollectEnvironmentHook( 169 void IncidentReportingService::SetCollectEnvironmentHook(
121 CollectEnvironmentDataFn collect_environment_data_hook, 170 CollectEnvironmentDataFn collect_environment_data_hook,
122 const scoped_refptr<base::TaskRunner>& task_runner) { 171 const scoped_refptr<base::TaskRunner>& task_runner) {
123 if (collect_environment_data_hook) { 172 if (collect_environment_data_hook) {
124 collect_environment_data_fn_ = collect_environment_data_hook; 173 collect_environment_data_fn_ = collect_environment_data_hook;
125 environment_collection_task_runner_ = task_runner; 174 environment_collection_task_runner_ = task_runner;
126 } else { 175 } else {
127 collect_environment_data_fn_ = &CollectEnvironmentData; 176 collect_environment_data_fn_ = &CollectEnvironmentData;
128 environment_collection_task_runner_ = 177 environment_collection_task_runner_ =
129 content::BrowserThread::GetBlockingPool() 178 content::BrowserThread::GetBlockingPool()
130 ->GetTaskRunnerWithShutdownBehavior( 179 ->GetTaskRunnerWithShutdownBehavior(
131 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 180 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
132 } 181 }
133 } 182 }
134 183
184 void IncidentReportingService::OnProfileCreated(Profile* profile) {
185 DCHECK(thread_checker_.CalledOnValidThread());
186
187 ProfileContext* context = GetOrCreateProfileContext(profile);
188 context->created = true;
189
190 // Drop all incidents if this profile is not participating in safe browsing.
191 if (!context->incidents.empty() &&
192 !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
193 for (size_t i = 0; i < context->incidents.size(); ++i) {
194 LogIncidentDataType(DROPPED, *context->incidents[i]);
195 }
196 context->incidents.clear();
197 }
198 }
199
135 scoped_ptr<IncidentReportUploader> IncidentReportingService::StartReportUpload( 200 scoped_ptr<IncidentReportUploader> IncidentReportingService::StartReportUpload(
136 const IncidentReportUploader::OnResultCallback& callback, 201 const IncidentReportUploader::OnResultCallback& callback,
137 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, 202 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
138 const ClientIncidentReport& report) { 203 const ClientIncidentReport& report) {
139 #if 0 204 #if 0
140 return IncidentReportUploaderImpl::UploadReport( 205 return IncidentReportUploaderImpl::UploadReport(
141 callback, request_context_getter, report).Pass(); 206 callback, request_context_getter, report).Pass();
142 #else 207 #else
143 // TODO(grt): Remove this temporary suppression of all uploads. 208 // TODO(grt): Remove this temporary suppression of all uploads.
144 return scoped_ptr<IncidentReportUploader>(); 209 return scoped_ptr<IncidentReportUploader>();
145 #endif 210 #endif
146 } 211 }
147 212
213 IncidentReportingService::ProfileContext*
214 IncidentReportingService::GetOrCreateProfileContext(Profile* profile) {
215 ProfileContextCollection::iterator it =
216 profiles_.insert(ProfileContextCollection::value_type(profile, NULL))
217 .first;
218 if (!it->second)
219 it->second = new ProfileContext();
220 return it->second;
221 }
222
223 IncidentReportingService::ProfileContext*
224 IncidentReportingService::GetProfileContext(Profile* profile) {
225 ProfileContextCollection::iterator it = profiles_.find(profile);
226 return it == profiles_.end() ? NULL : it->second;
227 }
228
229 void IncidentReportingService::OnProfileDestroyed(Profile* profile) {
230 DCHECK(thread_checker_.CalledOnValidThread());
231
232 ProfileContextCollection::iterator it = profiles_.find(profile);
233 if (it == profiles_.end())
234 return;
235
236 // TODO(grt): Persist incidents for upload on future profile load.
237
238 // Forget about this profile. Incidents not yet sent for upload are lost.
239 // No new incidents will be accepted for it.
240 delete it->second;
241 profiles_.erase(it);
242 }
243
148 void IncidentReportingService::AddIncident( 244 void IncidentReportingService::AddIncident(
245 Profile* profile,
149 scoped_ptr<ClientIncidentReport_IncidentData> incident_data) { 246 scoped_ptr<ClientIncidentReport_IncidentData> incident_data) {
150 DCHECK(thread_checker_.CalledOnValidThread()); 247 DCHECK(thread_checker_.CalledOnValidThread());
248 // Incidents outside the context of a profile are not supported at the moment.
249 DCHECK(profile);
151 250
152 // TODO(grt): Don't ignore incidents that arrive before 251 ProfileContext* context = GetProfileContext(profile);
153 // NOTIFICATION_PROFILE_CREATED; http://crbug.com/383365. 252 // It is forbidden to call this function with a destroyed profile.
154 if (!enabled_) 253 DCHECK(context);
254
255 // Drop the incident immediately if profile creation has completed and the
256 // profile is not participating in safe browsing.
257 if (context->created &&
258 !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
259 LogIncidentDataType(DROPPED, *incident_data);
155 return; 260 return;
261 }
156 262
263 // Create a new report if this is the first incident ever or first since last
264 // upload.
157 if (!report_) { 265 if (!report_) {
158 report_.reset(new ClientIncidentReport()); 266 report_.reset(new ClientIncidentReport());
159 first_incident_time_ = base::Time::Now(); 267 first_incident_time_ = base::Time::Now();
160 } 268 }
269
270 // Provide time to the new incident if the caller didn't provide it.
161 if (!incident_data->has_incident_time_msec()) 271 if (!incident_data->has_incident_time_msec())
162 incident_data->set_incident_time_msec(base::Time::Now().ToJavaTime()); 272 incident_data->set_incident_time_msec(base::Time::Now().ToJavaTime());
163 report_->mutable_incident()->AddAllocated(incident_data.release()); 273
274 // Take ownership of the incident.
275 context->incidents.push_back(incident_data.release());
164 276
165 if (!last_incident_time_.is_null()) { 277 if (!last_incident_time_.is_null()) {
166 UMA_HISTOGRAM_TIMES("SBIRS.InterIncidentTime", 278 UMA_HISTOGRAM_TIMES("SBIRS.InterIncidentTime",
167 base::TimeTicks::Now() - last_incident_time_); 279 base::TimeTicks::Now() - last_incident_time_);
168 } 280 }
169 last_incident_time_ = base::TimeTicks::Now(); 281 last_incident_time_ = base::TimeTicks::Now();
170 282
171 // Persist the incident data. 283 // Persist the incident data.
172 284
173 // Restart the delay timer to send the report upon expiration. 285 // Restart the delay timer to send the report upon expiration.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 report_.reset(); 348 report_.reset();
237 } 349 }
238 350
239 void IncidentReportingService::OnCollectionTimeout() { 351 void IncidentReportingService::OnCollectionTimeout() {
240 DCHECK(thread_checker_.CalledOnValidThread()); 352 DCHECK(thread_checker_.CalledOnValidThread());
241 353
242 // Exit early if collection was cancelled. 354 // Exit early if collection was cancelled.
243 if (!collection_timeout_pending_) 355 if (!collection_timeout_pending_)
244 return; 356 return;
245 357
358 // Wait another round if incidents have come in from a profile that has yet to
359 // complete creation.
360 for (ProfileContextCollection::iterator scan = profiles_.begin();
361 scan != profiles_.end();
362 ++scan) {
363 if (!scan->second->created && !scan->second->incidents.empty()) {
364 upload_timer_.Reset();
365 return;
366 }
367 }
368
246 collection_timeout_pending_ = false; 369 collection_timeout_pending_ = false;
247 370
248 UploadIfCollectionComplete(); 371 UploadIfCollectionComplete();
249 } 372 }
250 373
251 void IncidentReportingService::CollectDownloadDetails( 374 void IncidentReportingService::CollectDownloadDetails(
252 ClientIncidentReport_DownloadDetails* download_details) { 375 ClientIncidentReport_DownloadDetails* download_details) {
253 DCHECK(thread_checker_.CalledOnValidThread()); 376 DCHECK(thread_checker_.CalledOnValidThread());
254 // TODO(grt): collect download info; http://crbug.com/383042. 377 // TODO(grt): collect download info; http://crbug.com/383042.
255 } 378 }
(...skipping 10 matching lines...) Expand all
266 void IncidentReportingService::UploadIfCollectionComplete() { 389 void IncidentReportingService::UploadIfCollectionComplete() {
267 DCHECK(report_); 390 DCHECK(report_);
268 // Bail out if there are still outstanding collection tasks. 391 // Bail out if there are still outstanding collection tasks.
269 if (environment_collection_pending_ || collection_timeout_pending_) 392 if (environment_collection_pending_ || collection_timeout_pending_)
270 return; 393 return;
271 394
272 // Take ownership of the report and clear things for future reports. 395 // Take ownership of the report and clear things for future reports.
273 scoped_ptr<ClientIncidentReport> report(report_.Pass()); 396 scoped_ptr<ClientIncidentReport> report(report_.Pass());
274 last_incident_time_ = base::TimeTicks(); 397 last_incident_time_ = base::TimeTicks();
275 398
276 const int original_count = report->incident_size(); 399 ClientIncidentReport_EnvironmentData_Process* process =
277 UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", original_count); 400 report->mutable_environment()->mutable_process();
278 for (int i = 0; i < original_count; ++i) { 401
279 LogIncidentDataType(report->incident(i)); 402 // Not all platforms have a metrics reporting preference.
403 if (g_browser_process->local_state()->FindPreference(
404 prefs::kMetricsReportingEnabled)) {
405 process->set_metrics_consent(g_browser_process->local_state()->GetBoolean(
406 prefs::kMetricsReportingEnabled));
407 }
408 // Check for extended consent in any profile while collecting incidents.
409 process->set_extended_consent(false);
410 // Collect incidents across all profiles participating in safe browsing. Drop
411 // incidents if the profile stopped participating before collection completed.
412 for (ProfileContextCollection::iterator scan = profiles_.begin();
413 scan != profiles_.end();
414 ++scan) {
415 PrefService* prefs = scan->first->GetPrefs();
416 if (process &&
417 prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)) {
418 process->set_extended_consent(true);
419 process = NULL; // Don't check any more once one is found.
420 }
421 ProfileContext* context = scan->second;
422 if (context->incidents.empty())
423 continue;
424 if (prefs->GetBoolean(prefs::kSafeBrowsingEnabled)) {
425 for (size_t i = 0; i < context->incidents.size(); ++i) {
426 ClientIncidentReport_IncidentData* incident = context->incidents[i];
427 LogIncidentDataType(ACCEPTED, *incident);
428 // Ownership of the incident is passed to the report.
429 report->mutable_incident()->AddAllocated(incident);
430 }
431 context->incidents.weak_clear();
432 } else {
433 for (size_t i = 0; i < context->incidents.size(); ++i) {
434 LogIncidentDataType(DROPPED, *context->incidents[i]);
435 }
436 context->incidents.clear();
437 }
280 } 438 }
281 439
440 const int original_count = report->incident_size();
441 // Abandon the request if all incidents were dropped.
442 if (!original_count)
443 return;
444
445 UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", original_count);
446
282 PruneReportedIncidents(report.get()); 447 PruneReportedIncidents(report.get());
283 // TODO(grt): prune incidents from opted-out profiles; http://crbug.com/383039
284 448
285 int final_count = report->incident_size(); 449 int final_count = report->incident_size();
286 { 450 {
287 double prune_pct = static_cast<double>(original_count - final_count); 451 double prune_pct = static_cast<double>(original_count - final_count);
288 prune_pct = prune_pct * 100.0 / original_count; 452 prune_pct = prune_pct * 100.0 / original_count;
289 prune_pct = round(prune_pct); 453 prune_pct = round(prune_pct);
290 UMA_HISTOGRAM_PERCENTAGE("SBIRS.PruneRatio", static_cast<int>(prune_pct)); 454 UMA_HISTOGRAM_PERCENTAGE("SBIRS.PruneRatio", static_cast<int>(prune_pct));
291 } 455 }
292 // Abandon the report if all incidents were pruned. 456 // Abandon the report if all incidents were pruned.
293 if (!final_count) 457 if (!final_count)
294 return; 458 return;
295 459
296 scoped_ptr<UploadContext> context(new UploadContext(report.Pass())); 460 scoped_ptr<UploadContext> context(new UploadContext(report.Pass()));
297 scoped_refptr<base::RefCountedData<bool> > is_killswitch_on(
298 new base::RefCountedData<bool>(false));
299 if (!database_manager_) { 461 if (!database_manager_) {
300 // No database manager during testing. Take ownership of the context and 462 // No database manager during testing. Take ownership of the context and
301 // continue processing. 463 // continue processing.
302 UploadContext* temp_context = context.get(); 464 UploadContext* temp_context = context.get();
303 uploads_.push_back(context.release()); 465 uploads_.push_back(context.release());
304 IncidentReportingService::OnKillSwitchResult(temp_context, false); 466 IncidentReportingService::OnKillSwitchResult(temp_context, false);
305 } else { 467 } else {
306 if (content::BrowserThread::PostTaskAndReplyWithResult( 468 if (content::BrowserThread::PostTaskAndReplyWithResult(
307 content::BrowserThread::IO, 469 content::BrowserThread::IO,
308 FROM_HERE, 470 FROM_HERE,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 DCHECK(it != uploads_.end()); 533 DCHECK(it != uploads_.end());
372 scoped_ptr<UploadContext> upload(context); // == *it 534 scoped_ptr<UploadContext> upload(context); // == *it
373 *it = uploads_.back(); 535 *it = uploads_.back();
374 uploads_.weak_erase(uploads_.end() - 1); 536 uploads_.weak_erase(uploads_.end() - 1);
375 537
376 if (result == IncidentReportUploader::UPLOAD_SUCCESS) 538 if (result == IncidentReportUploader::UPLOAD_SUCCESS)
377 HandleResponse(upload->report.Pass(), response.Pass()); 539 HandleResponse(upload->report.Pass(), response.Pass());
378 // else retry? 540 // else retry?
379 } 541 }
380 542
543 void IncidentReportingService::Observe(
544 int type,
545 const content::NotificationSource& source,
546 const content::NotificationDetails& details) {
547 switch (type) {
548 case chrome::NOTIFICATION_PROFILE_CREATED: {
549 Profile* profile = content::Source<Profile>(source).ptr();
550 if (!profile->IsOffTheRecord())
551 OnProfileCreated(profile);
552 break;
553 }
554 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
555 Profile* profile = content::Source<Profile>(source).ptr();
556 if (!profile->IsOffTheRecord())
557 OnProfileDestroyed(profile);
558 break;
559 }
560 default:
561 break;
562 }
563 }
564
381 } // namespace safe_browsing 565 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698