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

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: linux_chromium_clang_dbg compile fix 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";
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;
(...skipping 10 matching lines...) Expand all
138 const ClientIncidentReport& report) { 187 const ClientIncidentReport& report) {
139 #if 0 188 #if 0
140 return IncidentReportUploaderImpl::UploadReport( 189 return IncidentReportUploaderImpl::UploadReport(
141 callback, request_context_getter, report).Pass(); 190 callback, request_context_getter, report).Pass();
142 #else 191 #else
143 // TODO(grt): Remove this temporary suppression of all uploads. 192 // TODO(grt): Remove this temporary suppression of all uploads.
144 return scoped_ptr<IncidentReportUploader>(); 193 return scoped_ptr<IncidentReportUploader>();
145 #endif 194 #endif
146 } 195 }
147 196
197 IncidentReportingService::ProfileContext*
198 IncidentReportingService::GetOrCreateProfileContext(Profile* profile) {
199 ProfileContextCollection::iterator it =
200 profiles_.insert(ProfileContextCollection::value_type(profile, NULL))
201 .first;
202 if (!it->second)
203 it->second = new ProfileContext();
204 return it->second;
205 }
206
207 IncidentReportingService::ProfileContext*
208 IncidentReportingService::GetProfileContext(Profile* profile) {
209 ProfileContextCollection::iterator it = profiles_.find(profile);
210 return it == profiles_.end() ? NULL : it->second;
211 }
212
213 void IncidentReportingService::OnProfileCreated(Profile* profile) {
214 DCHECK(thread_checker_.CalledOnValidThread());
215
216 ProfileContext* context = GetOrCreateProfileContext(profile);
217 context->created = true;
218
219 // Drop all incidents if this profile is not participating in safe browsing.
220 if (!context->incidents.empty() &&
221 !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
222 for (size_t i = 0; i < context->incidents.size(); ++i) {
223 LogIncidentDataType(DROPPED, *context->incidents[i]);
224 }
225 context->incidents.clear();
226 }
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 // The profile is unknown if it has already been destroyed.
mattm 2014/06/18 21:07:18 Probably not safe to allow this to be called after
grt (UTC plus 2) 2014/06/18 22:47:58 The only case where GetProfileContext would return
mattm 2014/06/18 23:05:38 yeah, that sounds good. You could replace it with
grt (UTC plus 2) 2014/06/19 02:24:39 Done.
154 if (!enabled_) 253 if (!context)
155 return; 254 return;
156 255
256 // Drop the incident immediately if profile creation has completed and the
257 // profile is not participating in safe browsing.
258 if (context->created &&
259 !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
260 LogIncidentDataType(DROPPED, *incident_data);
261 return;
262 }
263
264 // Create a new report if this is the first incident ever or first since last
265 // upload.
157 if (!report_) { 266 if (!report_) {
158 report_.reset(new ClientIncidentReport()); 267 report_.reset(new ClientIncidentReport());
159 first_incident_time_ = base::Time::Now(); 268 first_incident_time_ = base::Time::Now();
160 } 269 }
270
271 // Provide time to the new incident if the caller didn't provide it.
161 if (!incident_data->has_incident_time_msec()) 272 if (!incident_data->has_incident_time_msec())
162 incident_data->set_incident_time_msec(base::Time::Now().ToJavaTime()); 273 incident_data->set_incident_time_msec(base::Time::Now().ToJavaTime());
163 report_->mutable_incident()->AddAllocated(incident_data.release()); 274
275 // Take ownership of the incident.
276 context->incidents.push_back(incident_data.release());
164 277
165 if (!last_incident_time_.is_null()) { 278 if (!last_incident_time_.is_null()) {
166 UMA_HISTOGRAM_TIMES("SBIRS.InterIncidentTime", 279 UMA_HISTOGRAM_TIMES("SBIRS.InterIncidentTime",
167 base::TimeTicks::Now() - last_incident_time_); 280 base::TimeTicks::Now() - last_incident_time_);
168 } 281 }
169 last_incident_time_ = base::TimeTicks::Now(); 282 last_incident_time_ = base::TimeTicks::Now();
170 283
171 // Persist the incident data. 284 // Persist the incident data.
172 285
173 // Restart the delay timer to send the report upon expiration. 286 // 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(); 349 report_.reset();
237 } 350 }
238 351
239 void IncidentReportingService::OnCollectionTimeout() { 352 void IncidentReportingService::OnCollectionTimeout() {
240 DCHECK(thread_checker_.CalledOnValidThread()); 353 DCHECK(thread_checker_.CalledOnValidThread());
241 354
242 // Exit early if collection was cancelled. 355 // Exit early if collection was cancelled.
243 if (!collection_timeout_pending_) 356 if (!collection_timeout_pending_)
244 return; 357 return;
245 358
359 // Wait another round if incidents have come in from a profile that has yet to
360 // complete creation.
361 for (ProfileContextCollection::iterator scan = profiles_.begin();
362 scan != profiles_.end();
363 ++scan) {
364 if (!scan->second->created && !scan->second->incidents.empty()) {
365 upload_timer_.Reset();
366 return;
367 }
368 }
369
246 collection_timeout_pending_ = false; 370 collection_timeout_pending_ = false;
247 371
248 UploadIfCollectionComplete(); 372 UploadIfCollectionComplete();
249 } 373 }
250 374
251 void IncidentReportingService::CollectDownloadDetails( 375 void IncidentReportingService::CollectDownloadDetails(
252 ClientIncidentReport_DownloadDetails* download_details) { 376 ClientIncidentReport_DownloadDetails* download_details) {
253 DCHECK(thread_checker_.CalledOnValidThread()); 377 DCHECK(thread_checker_.CalledOnValidThread());
254 // TODO(grt): collect download info; http://crbug.com/383042. 378 // TODO(grt): collect download info; http://crbug.com/383042.
255 } 379 }
(...skipping 10 matching lines...) Expand all
266 void IncidentReportingService::UploadIfCollectionComplete() { 390 void IncidentReportingService::UploadIfCollectionComplete() {
267 DCHECK(report_); 391 DCHECK(report_);
268 // Bail out if there are still outstanding collection tasks. 392 // Bail out if there are still outstanding collection tasks.
269 if (environment_collection_pending_ || collection_timeout_pending_) 393 if (environment_collection_pending_ || collection_timeout_pending_)
270 return; 394 return;
271 395
272 // Take ownership of the report and clear things for future reports. 396 // Take ownership of the report and clear things for future reports.
273 scoped_ptr<ClientIncidentReport> report(report_.Pass()); 397 scoped_ptr<ClientIncidentReport> report(report_.Pass());
274 last_incident_time_ = base::TimeTicks(); 398 last_incident_time_ = base::TimeTicks();
275 399
276 const int original_count = report->incident_size(); 400 ClientIncidentReport_EnvironmentData_Process* process =
277 UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", original_count); 401 report->mutable_environment()->mutable_process();
278 for (int i = 0; i < original_count; ++i) { 402
279 LogIncidentDataType(report->incident(i)); 403 // Not all platforms have a metrics reporting preference.
404 if (g_browser_process->local_state()->FindPreference(
405 prefs::kMetricsReportingEnabled)) {
406 process->set_metrics_consent(g_browser_process->local_state()->GetBoolean(
407 prefs::kMetricsReportingEnabled));
408 }
409 // Check for extended consent in any profile while collecting incidents.
410 process->set_extended_consent(false);
411 // Collect incidents across all profiles participating in safe browsing. Drop
412 // incidents if the profile stopped participating before collection completed.
413 for (ProfileContextCollection::iterator scan = profiles_.begin();
414 scan != profiles_.end();
415 ++scan) {
416 PrefService* prefs = scan->first->GetPrefs();
417 if (process &&
418 prefs->GetBoolean(prefs::kSafeBrowsingDownloadFeedbackEnabled)) {
mattm 2014/06/18 21:07:17 kSafeBrowsingExtendedReportingEnabled now
grt (UTC plus 2) 2014/06/18 22:47:58 thanks for the pointer.
grt (UTC plus 2) 2014/06/19 02:24:39 Done.
419 process->set_extended_consent(true);
mattm 2014/06/18 21:07:18 is it okay that this isn't sent on a per-profile/i
grt (UTC plus 2) 2014/06/18 22:47:58 it is, thanks for checking.
420 process = NULL; // Don't check any more once one is found.
421 }
422 ProfileContext* context = scan->second;
423 if (context->incidents.empty())
424 continue;
425 if (prefs->GetBoolean(prefs::kSafeBrowsingEnabled)) {
426 for (size_t i = 0; i < context->incidents.size(); ++i) {
427 ClientIncidentReport_IncidentData* incident = context->incidents[i];
428 LogIncidentDataType(ACCEPTED, *incident);
429 // Ownership of the incident is passed to the report.
430 report->mutable_incident()->AddAllocated(incident);
431 }
432 context->incidents.weak_clear();
433 } else {
434 for (size_t i = 0; i < context->incidents.size(); ++i) {
435 LogIncidentDataType(DROPPED, *context->incidents[i]);
436 }
437 context->incidents.clear();
438 }
280 } 439 }
281 440
441 const int original_count = report->incident_size();
442 // Abandon the request if all incidents were dropped.
443 if (!original_count)
444 return;
445
446 UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", original_count);
447
282 PruneReportedIncidents(report.get()); 448 PruneReportedIncidents(report.get());
283 // TODO(grt): prune incidents from opted-out profiles; http://crbug.com/383039
284 449
285 int final_count = report->incident_size(); 450 int final_count = report->incident_size();
286 { 451 {
287 double prune_pct = static_cast<double>(original_count - final_count); 452 double prune_pct = static_cast<double>(original_count - final_count);
288 prune_pct = prune_pct * 100.0 / original_count; 453 prune_pct = prune_pct * 100.0 / original_count;
289 prune_pct = round(prune_pct); 454 prune_pct = round(prune_pct);
290 UMA_HISTOGRAM_PERCENTAGE("SBIRS.PruneRatio", static_cast<int>(prune_pct)); 455 UMA_HISTOGRAM_PERCENTAGE("SBIRS.PruneRatio", static_cast<int>(prune_pct));
291 } 456 }
292 // Abandon the report if all incidents were pruned. 457 // Abandon the report if all incidents were pruned.
293 if (!final_count) 458 if (!final_count)
294 return; 459 return;
295 460
296 scoped_ptr<UploadContext> context(new UploadContext(report.Pass())); 461 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_) { 462 if (!database_manager_) {
300 // No database manager during testing. Take ownership of the context and 463 // No database manager during testing. Take ownership of the context and
301 // continue processing. 464 // continue processing.
302 UploadContext* temp_context = context.get(); 465 UploadContext* temp_context = context.get();
303 uploads_.push_back(context.release()); 466 uploads_.push_back(context.release());
304 IncidentReportingService::OnKillSwitchResult(temp_context, false); 467 IncidentReportingService::OnKillSwitchResult(temp_context, false);
305 } else { 468 } else {
306 if (content::BrowserThread::PostTaskAndReplyWithResult( 469 if (content::BrowserThread::PostTaskAndReplyWithResult(
307 content::BrowserThread::IO, 470 content::BrowserThread::IO,
308 FROM_HERE, 471 FROM_HERE,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 DCHECK(it != uploads_.end()); 534 DCHECK(it != uploads_.end());
372 scoped_ptr<UploadContext> upload(context); // == *it 535 scoped_ptr<UploadContext> upload(context); // == *it
373 *it = uploads_.back(); 536 *it = uploads_.back();
374 uploads_.weak_erase(uploads_.end() - 1); 537 uploads_.weak_erase(uploads_.end() - 1);
375 538
376 if (result == IncidentReportUploader::UPLOAD_SUCCESS) 539 if (result == IncidentReportUploader::UPLOAD_SUCCESS)
377 HandleResponse(upload->report.Pass(), response.Pass()); 540 HandleResponse(upload->report.Pass(), response.Pass());
378 // else retry? 541 // else retry?
379 } 542 }
380 543
544 void IncidentReportingService::Observe(
545 int type,
546 const content::NotificationSource& source,
547 const content::NotificationDetails& details) {
548 switch (type) {
549 case chrome::NOTIFICATION_PROFILE_CREATED: {
550 Profile* profile = content::Source<Profile>(source).ptr();
551 if (!profile->IsOffTheRecord())
552 OnProfileCreated(profile);
553 break;
554 }
555 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
556 Profile* profile = content::Source<Profile>(source).ptr();
557 if (!profile->IsOffTheRecord())
558 OnProfileDestroyed(profile);
559 break;
560 }
561 default:
562 break;
563 }
564 }
565
381 } // namespace safe_browsing 566 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698