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

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

Issue 891793002: Take a Profile when adding an incident to the incident reporting service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: OnMainThread Created 5 years, 10 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/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" 28 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
29 #include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h"
29 #include "chrome/browser/safe_browsing/incident_reporting/incident_report_upload er_impl.h" 30 #include "chrome/browser/safe_browsing/incident_reporting/incident_report_upload er_impl.h"
30 #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_ delegate.h" 31 #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_ delegate.h"
31 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 32 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
32 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
33 #include "chrome/common/safe_browsing/csd.pb.h" 34 #include "chrome/common/safe_browsing/csd.pb.h"
34 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/notification_service.h" 36 #include "content/public/browser/notification_service.h"
36 #include "net/url_request/url_request_context_getter.h" 37 #include "net/url_request/url_request_context_getter.h"
37 38
38 namespace safe_browsing { 39 namespace safe_browsing {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 160 }
160 if (types_to_remove.empty()) 161 if (types_to_remove.empty())
161 return; 162 return;
162 163
163 DictionaryPrefUpdate pref_update(profile->GetPrefs(), 164 DictionaryPrefUpdate pref_update(profile->GetPrefs(),
164 prefs::kSafeBrowsingIncidentsSent); 165 prefs::kSafeBrowsingIncidentsSent);
165 for (const auto& incident_type : types_to_remove) 166 for (const auto& incident_type : types_to_remove)
166 pref_update.Get()->RemoveWithoutPathExpansion(incident_type, NULL); 167 pref_update.Get()->RemoveWithoutPathExpansion(incident_type, NULL);
167 } 168 }
168 169
169 // Runs |callback| on the thread to which |thread_runner| belongs. The callback
170 // is run immediately if this function is called on |thread_runner|'s thread.
171 void AddIncidentOnOriginThread(
172 const AddIncidentCallback& callback,
173 scoped_refptr<base::SingleThreadTaskRunner> thread_runner,
174 scoped_ptr<Incident> incident) {
175 if (thread_runner->BelongsToCurrentThread())
176 callback.Run(incident.Pass());
177 else
178 thread_runner->PostTask(FROM_HERE,
179 base::Bind(callback, base::Passed(&incident)));
180 }
181
182 } // namespace 170 } // namespace
183 171
184 struct IncidentReportingService::ProfileContext { 172 struct IncidentReportingService::ProfileContext {
185 ProfileContext(); 173 ProfileContext();
186 ~ProfileContext(); 174 ~ProfileContext();
187 175
188 // The incidents collected for this profile pending creation and/or upload. 176 // The incidents collected for this profile pending creation and/or upload.
189 // Will contain null values for pruned incidents. 177 // Will contain null values for pruned incidents.
190 ScopedVector<Incident> incidents; 178 ScopedVector<Incident> incidents;
191 179
(...skipping 18 matching lines...) Expand all
210 // The uploader in use. This is NULL until the CSD killswitch is checked. 198 // The uploader in use. This is NULL until the CSD killswitch is checked.
211 scoped_ptr<IncidentReportUploader> uploader; 199 scoped_ptr<IncidentReportUploader> uploader;
212 200
213 // A mapping of profiles to the data to be persisted upon successful upload. 201 // A mapping of profiles to the data to be persisted upon successful upload.
214 PersistentIncidentStateCollection profiles_to_state; 202 PersistentIncidentStateCollection profiles_to_state;
215 203
216 private: 204 private:
217 DISALLOW_COPY_AND_ASSIGN(UploadContext); 205 DISALLOW_COPY_AND_ASSIGN(UploadContext);
218 }; 206 };
219 207
208 // An IncidentReceiver that is weakly-bound to the service and transparently
209 // bounces process-wide incidents back to the main thread for handling.
210 class IncidentReportingService::Receiver : public IncidentReceiver {
211 public:
212 explicit Receiver(const base::WeakPtr<IncidentReportingService>& service);
213 ~Receiver() override;
214
215 // IncidentReceiver methods:
216 void AddIncidentForProfile(Profile* profile,
217 scoped_ptr<Incident> incident) override;
218 void AddIncidentForProcess(scoped_ptr<Incident> incident) override;
219
220 private:
221 static void AddIncidentOnMainThread(
222 const base::WeakPtr<IncidentReportingService>& service,
223 Profile* profile,
224 scoped_ptr<Incident> incident);
225
226 base::WeakPtr<IncidentReportingService> service_;
227 scoped_refptr<base::SingleThreadTaskRunner> thread_runner_;
228
229 DISALLOW_COPY_AND_ASSIGN(Receiver);
230 };
231
232 IncidentReportingService::Receiver::Receiver(
233 const base::WeakPtr<IncidentReportingService>& service)
234 : service_(service),
235 thread_runner_(base::ThreadTaskRunnerHandle::Get()) {
236 }
237
238 IncidentReportingService::Receiver::~Receiver() {
239 }
240
241 void IncidentReportingService::Receiver::AddIncidentForProfile(
242 Profile* profile,
243 scoped_ptr<Incident> incident) {
244 DCHECK(thread_runner_->BelongsToCurrentThread());
245 DCHECK(profile);
246 AddIncidentOnMainThread(service_, profile, incident.Pass());
247 }
248
249 void IncidentReportingService::Receiver::AddIncidentForProcess(
250 scoped_ptr<Incident> incident) {
251 if (thread_runner_->BelongsToCurrentThread()) {
252 AddIncidentOnMainThread(service_, nullptr, incident.Pass());
253 } else if (!thread_runner_->PostTask(
254 FROM_HERE,
255 base::Bind(&IncidentReportingService::Receiver::AddIncidentOnMainThread,
256 service_, nullptr, base::Passed(&incident)))) {
257 LogIncidentDataType(DISCARDED, *incident);
258 }
259 }
260
261 // static
262 void IncidentReportingService::Receiver::AddIncidentOnMainThread(
263 const base::WeakPtr<IncidentReportingService>& service,
264 Profile* profile,
265 scoped_ptr<Incident> incident) {
266 if (service)
267 service->AddIncident(profile, incident.Pass());
268 else
269 LogIncidentDataType(DISCARDED, *incident);
270 }
271
220 IncidentReportingService::ProfileContext::ProfileContext() : added() { 272 IncidentReportingService::ProfileContext::ProfileContext() : added() {
221 } 273 }
222 274
223 IncidentReportingService::ProfileContext::~ProfileContext() { 275 IncidentReportingService::ProfileContext::~ProfileContext() {
224 for (Incident* incident : incidents) { 276 for (Incident* incident : incidents) {
225 if (incident) 277 if (incident)
226 LogIncidentDataType(DISCARDED, *incident); 278 LogIncidentDataType(DISCARDED, *incident);
227 } 279 }
228 } 280 }
229 281
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 // Cancel all internal asynchronous tasks. 338 // Cancel all internal asynchronous tasks.
287 weak_ptr_factory_.InvalidateWeakPtrs(); 339 weak_ptr_factory_.InvalidateWeakPtrs();
288 340
289 CancelEnvironmentCollection(); 341 CancelEnvironmentCollection();
290 CancelDownloadCollection(); 342 CancelDownloadCollection();
291 CancelAllReportUploads(); 343 CancelAllReportUploads();
292 344
293 STLDeleteValues(&profiles_); 345 STLDeleteValues(&profiles_);
294 } 346 }
295 347
296 AddIncidentCallback IncidentReportingService::GetAddIncidentCallback( 348 scoped_ptr<IncidentReceiver> IncidentReportingService::GetIncidentReceiver() {
297 Profile* profile) { 349 return make_scoped_ptr(new Receiver(receiver_weak_ptr_factory_.GetWeakPtr()));
298 // Force the context to be created so that incidents added before
299 // OnProfileAdded is called are held until the profile's preferences can be
300 // queried.
301 ignore_result(GetOrCreateProfileContext(profile));
302
303 return base::Bind(&IncidentReportingService::AddIncident,
304 receiver_weak_ptr_factory_.GetWeakPtr(),
305 profile);
306 } 350 }
307 351
308 scoped_ptr<TrackedPreferenceValidationDelegate> 352 scoped_ptr<TrackedPreferenceValidationDelegate>
309 IncidentReportingService::CreatePreferenceValidationDelegate(Profile* profile) { 353 IncidentReportingService::CreatePreferenceValidationDelegate(Profile* profile) {
310 DCHECK(thread_checker_.CalledOnValidThread()); 354 DCHECK(thread_checker_.CalledOnValidThread());
311 355
312 if (profile->IsOffTheRecord()) 356 if (profile->IsOffTheRecord())
313 return scoped_ptr<TrackedPreferenceValidationDelegate>(); 357 return scoped_ptr<TrackedPreferenceValidationDelegate>();
314 return scoped_ptr<TrackedPreferenceValidationDelegate>( 358 return scoped_ptr<TrackedPreferenceValidationDelegate>(
315 new PreferenceValidationDelegate(GetAddIncidentCallback(profile))); 359 new PreferenceValidationDelegate(profile, GetIncidentReceiver()));
316 } 360 }
317 361
318 void IncidentReportingService::RegisterDelayedAnalysisCallback( 362 void IncidentReportingService::RegisterDelayedAnalysisCallback(
319 const DelayedAnalysisCallback& callback) { 363 const DelayedAnalysisCallback& callback) {
320 DCHECK(thread_checker_.CalledOnValidThread()); 364 DCHECK(thread_checker_.CalledOnValidThread());
321 365
322 // |callback| will be run on the blocking pool, so it will likely run the 366 // |callback| will be run on the blocking pool. The receiver will bounce back
323 // AddIncidentCallback there as well. Bounce the run of that callback back to 367 // to the origin thread if needed.
324 // the current thread via AddIncidentOnOriginThread.
325 delayed_analysis_callbacks_.RegisterCallback( 368 delayed_analysis_callbacks_.RegisterCallback(
326 base::Bind(callback, 369 base::Bind(callback, base::Passed(GetIncidentReceiver())));
327 base::Bind(&AddIncidentOnOriginThread,
328 GetAddIncidentCallback(NULL),
329 base::ThreadTaskRunnerHandle::Get())));
330 370
331 // Start running the callbacks if any profiles are participating in safe 371 // Start running the callbacks if any profiles are participating in safe
332 // browsing. If none are now, running will commence if/when a participaing 372 // browsing. If none are now, running will commence if/when a participaing
333 // profile is added. 373 // profile is added.
334 if (FindEligibleProfile()) 374 if (FindEligibleProfile())
335 delayed_analysis_callbacks_.Start(); 375 delayed_analysis_callbacks_.Start();
336 } 376 }
337 377
338 void IncidentReportingService::AddDownloadManager( 378 void IncidentReportingService::AddDownloadManager(
339 content::DownloadManager* download_manager) { 379 content::DownloadManager* download_manager) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 } 551 }
512 } 552 }
513 } 553 }
514 return candidate; 554 return candidate;
515 } 555 }
516 556
517 void IncidentReportingService::AddIncident(Profile* profile, 557 void IncidentReportingService::AddIncident(Profile* profile,
518 scoped_ptr<Incident> incident) { 558 scoped_ptr<Incident> incident) {
519 DCHECK(thread_checker_.CalledOnValidThread()); 559 DCHECK(thread_checker_.CalledOnValidThread());
520 560
521 ProfileContext* context = GetProfileContext(profile); 561 // Ignore incidents from off-the-record profiles.
522 // It is forbidden to call this function with a destroyed profile. 562 if (profile && profile->IsOffTheRecord())
523 DCHECK(context); 563 return;
564
565 ProfileContext* context = GetOrCreateProfileContext(profile);
524 // If this is a process-wide incident, the context must not indicate that the 566 // If this is a process-wide incident, the context must not indicate that the
525 // profile (which is NULL) has been added to the profile manager. 567 // profile (which is NULL) has been added to the profile manager.
526 DCHECK(profile || !context->added); 568 DCHECK(profile || !context->added);
527 569
528 LogIncidentDataType(RECEIVED, *incident); 570 LogIncidentDataType(RECEIVED, *incident);
529 571
530 // Drop the incident immediately if the profile has already been added to the 572 // Drop the incident immediately if the profile has already been added to the
531 // manager and is not participating in safe browsing. Preference evaluation is 573 // manager and is not participating in safe browsing. Preference evaluation is
532 // deferred until OnProfileAdded() otherwise. 574 // deferred until OnProfileAdded() otherwise.
533 if (context->added && 575 if (context->added &&
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 if (!profile->IsOffTheRecord()) 1000 if (!profile->IsOffTheRecord())
959 OnProfileDestroyed(profile); 1001 OnProfileDestroyed(profile);
960 break; 1002 break;
961 } 1003 }
962 default: 1004 default:
963 break; 1005 break;
964 } 1006 }
965 } 1007 }
966 1008
967 } // namespace safe_browsing 1009 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698