OLD | NEW |
---|---|
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 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 return state; | 109 return state; |
110 } | 110 } |
111 | 111 |
112 // Returns true if the incident reporting service field trial is enabled. | 112 // Returns true if the incident reporting service field trial is enabled. |
113 bool IsFieldTrialEnabled() { | 113 bool IsFieldTrialEnabled() { |
114 std::string group_name = base::FieldTrialList::FindFullName( | 114 std::string group_name = base::FieldTrialList::FindFullName( |
115 "SafeBrowsingIncidentReportingService"); | 115 "SafeBrowsingIncidentReportingService"); |
116 return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE); | 116 return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE); |
117 } | 117 } |
118 | 118 |
119 bool ProfileCanAcceptIncident(Profile* profile, const Incident& incident) { | |
120 if (profile->IsOffTheRecord()) | |
121 return false; | |
122 switch (incident.GetMinimumProfileConsent()) { | |
grt (UTC plus 2)
2016/02/15 16:46:50
i prefer the safer:
if (!profile->GetPrefs()->Ge
proberge
2016/02/16 16:56:22
Done.
| |
123 case MinimumProfileConsent::SAFE_BROWSING_ENABLED: | |
124 return profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled); | |
125 case MinimumProfileConsent::SAFE_BROWSING_EXTENDED_REPORTING_ENABLED: | |
126 return profile->GetPrefs()->GetBoolean( | |
127 prefs::kSafeBrowsingExtendedReportingEnabled); | |
128 default: | |
grt (UTC plus 2)
2016/02/15 16:46:50
note: it's best to omit the default case when the
proberge
2016/02/16 16:56:22
Done.
| |
129 NOTREACHED(); | |
130 return false; | |
131 } | |
132 } | |
133 | |
119 } // namespace | 134 } // namespace |
120 | 135 |
121 struct IncidentReportingService::ProfileContext { | 136 struct IncidentReportingService::ProfileContext { |
122 ProfileContext(); | 137 ProfileContext(); |
123 ~ProfileContext(); | 138 ~ProfileContext(); |
124 | 139 |
125 // Returns true if the profile has incidents to be uploaded or cleared. | 140 // Returns true if the profile has incidents to be uploaded or cleared. |
126 bool HasIncidents() const; | 141 bool HasIncidents() const; |
127 | 142 |
128 // The incidents collected for this profile pending creation and/or upload. | 143 // The incidents collected for this profile pending creation and/or upload. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 scoped_ptr<Incident> incident) { | 223 scoped_ptr<Incident> incident) { |
209 DCHECK(thread_runner_->BelongsToCurrentThread()); | 224 DCHECK(thread_runner_->BelongsToCurrentThread()); |
210 DCHECK(profile); | 225 DCHECK(profile); |
211 AddIncidentOnMainThread(service_, profile, std::move(incident)); | 226 AddIncidentOnMainThread(service_, profile, std::move(incident)); |
212 } | 227 } |
213 | 228 |
214 void IncidentReportingService::Receiver::AddIncidentForProcess( | 229 void IncidentReportingService::Receiver::AddIncidentForProcess( |
215 scoped_ptr<Incident> incident) { | 230 scoped_ptr<Incident> incident) { |
216 if (thread_runner_->BelongsToCurrentThread()) { | 231 if (thread_runner_->BelongsToCurrentThread()) { |
217 AddIncidentOnMainThread(service_, nullptr, std::move(incident)); | 232 AddIncidentOnMainThread(service_, nullptr, std::move(incident)); |
218 } else if (!thread_runner_->PostTask( | 233 } else { |
219 FROM_HERE, | 234 thread_runner_->PostTask( |
220 base::Bind(&IncidentReportingService::Receiver::AddIncidentOnMainThread, | 235 FROM_HERE, |
221 service_, nullptr, base::Passed(&incident)))) { | 236 base::Bind(&IncidentReportingService::Receiver::AddIncidentOnMainThread, |
222 LogIncidentDataType(DISCARDED, *incident); | 237 service_, nullptr, base::Passed(&incident))); |
223 } | 238 } |
224 } | 239 } |
225 | 240 |
226 void IncidentReportingService::Receiver::ClearIncidentForProcess( | 241 void IncidentReportingService::Receiver::ClearIncidentForProcess( |
227 scoped_ptr<Incident> incident) { | 242 scoped_ptr<Incident> incident) { |
228 if (thread_runner_->BelongsToCurrentThread()) { | 243 if (thread_runner_->BelongsToCurrentThread()) { |
229 ClearIncidentOnMainThread(service_, nullptr, std::move(incident)); | 244 ClearIncidentOnMainThread(service_, nullptr, std::move(incident)); |
230 } else { | 245 } else { |
231 thread_runner_->PostTask( | 246 thread_runner_->PostTask( |
232 FROM_HERE, | 247 FROM_HERE, |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 collation_timeout_pending_(), | 328 collation_timeout_pending_(), |
314 collation_timer_(FROM_HERE, | 329 collation_timer_(FROM_HERE, |
315 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs), | 330 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs), |
316 this, | 331 this, |
317 &IncidentReportingService::OnCollationTimeout), | 332 &IncidentReportingService::OnCollationTimeout), |
318 delayed_analysis_callbacks_( | 333 delayed_analysis_callbacks_( |
319 base::TimeDelta::FromMilliseconds(kDefaultCallbackIntervalMs), | 334 base::TimeDelta::FromMilliseconds(kDefaultCallbackIntervalMs), |
320 content::BrowserThread::GetBlockingPool() | 335 content::BrowserThread::GetBlockingPool() |
321 ->GetTaskRunnerWithShutdownBehavior( | 336 ->GetTaskRunnerWithShutdownBehavior( |
322 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | 337 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
338 extended_reporting_only_delayed_analysis_callbacks_( | |
339 base::TimeDelta::FromMilliseconds(kDefaultCallbackIntervalMs), | |
340 content::BrowserThread::GetBlockingPool() | |
341 ->GetTaskRunnerWithShutdownBehavior( | |
342 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | |
323 download_metadata_manager_(content::BrowserThread::GetBlockingPool()), | 343 download_metadata_manager_(content::BrowserThread::GetBlockingPool()), |
324 receiver_weak_ptr_factory_(this), | 344 receiver_weak_ptr_factory_(this), |
325 weak_ptr_factory_(this) { | 345 weak_ptr_factory_(this) { |
326 notification_registrar_.Add(this, | 346 notification_registrar_.Add(this, |
327 chrome::NOTIFICATION_PROFILE_ADDED, | 347 chrome::NOTIFICATION_PROFILE_ADDED, |
328 content::NotificationService::AllSources()); | 348 content::NotificationService::AllSources()); |
329 notification_registrar_.Add(this, | 349 notification_registrar_.Add(this, |
330 chrome::NOTIFICATION_PROFILE_DESTROYED, | 350 chrome::NOTIFICATION_PROFILE_DESTROYED, |
331 content::NotificationService::AllSources()); | 351 content::NotificationService::AllSources()); |
332 DownloadProtectionService* download_protection_service = | 352 DownloadProtectionService* download_protection_service = |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 delayed_analysis_callbacks_.RegisterCallback( | 400 delayed_analysis_callbacks_.RegisterCallback( |
381 base::Bind(callback, base::Passed(GetIncidentReceiver()))); | 401 base::Bind(callback, base::Passed(GetIncidentReceiver()))); |
382 | 402 |
383 // Start running the callbacks if any profiles are participating in safe | 403 // Start running the callbacks if any profiles are participating in safe |
384 // browsing. If none are now, running will commence if/when a participaing | 404 // browsing. If none are now, running will commence if/when a participaing |
385 // profile is added. | 405 // profile is added. |
386 if (FindEligibleProfile()) | 406 if (FindEligibleProfile()) |
387 delayed_analysis_callbacks_.Start(); | 407 delayed_analysis_callbacks_.Start(); |
388 } | 408 } |
389 | 409 |
410 void IncidentReportingService:: | |
411 RegisterExtendedReportingOnlyDelayedAnalysisCallback( | |
412 const DelayedAnalysisCallback& callback) { | |
413 DCHECK(thread_checker_.CalledOnValidThread()); | |
414 | |
415 // |callback| will be run on the blocking pool. The receiver will bounce back | |
416 // to the origin thread if needed. | |
417 extended_reporting_only_delayed_analysis_callbacks_.RegisterCallback( | |
418 base::Bind(callback, base::Passed(GetIncidentReceiver()))); | |
419 | |
420 // Start running the callbacks if any profiles have opted into Safebrowsing | |
421 // extended reporting. If none are now, running will commence if/when such a | |
422 // profile is added. | |
423 Profile* profile = FindEligibleProfile(); | |
424 if (profile && | |
425 profile->GetPrefs()->GetBoolean( | |
426 prefs::kSafeBrowsingExtendedReportingEnabled)) { | |
427 extended_reporting_only_delayed_analysis_callbacks_.Start(); | |
428 } | |
429 } | |
430 | |
390 void IncidentReportingService::AddDownloadManager( | 431 void IncidentReportingService::AddDownloadManager( |
391 content::DownloadManager* download_manager) { | 432 content::DownloadManager* download_manager) { |
392 download_metadata_manager_.AddDownloadManager(download_manager); | 433 download_metadata_manager_.AddDownloadManager(download_manager); |
393 } | 434 } |
394 | 435 |
395 IncidentReportingService::IncidentReportingService( | 436 IncidentReportingService::IncidentReportingService( |
396 SafeBrowsingService* safe_browsing_service, | 437 SafeBrowsingService* safe_browsing_service, |
397 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, | 438 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, |
398 base::TimeDelta delayed_task_interval, | 439 base::TimeDelta delayed_task_interval, |
399 const scoped_refptr<base::TaskRunner>& delayed_task_runner) | 440 const scoped_refptr<base::TaskRunner>& delayed_task_runner) |
400 : database_manager_(safe_browsing_service | 441 : database_manager_(safe_browsing_service |
401 ? safe_browsing_service->database_manager() | 442 ? safe_browsing_service->database_manager() |
402 : NULL), | 443 : NULL), |
403 url_request_context_getter_(request_context_getter), | 444 url_request_context_getter_(request_context_getter), |
404 collect_environment_data_fn_(&CollectEnvironmentData), | 445 collect_environment_data_fn_(&CollectEnvironmentData), |
405 environment_collection_task_runner_( | 446 environment_collection_task_runner_( |
406 content::BrowserThread::GetBlockingPool() | 447 content::BrowserThread::GetBlockingPool() |
407 ->GetTaskRunnerWithShutdownBehavior( | 448 ->GetTaskRunnerWithShutdownBehavior( |
408 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | 449 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
409 environment_collection_pending_(), | 450 environment_collection_pending_(), |
410 collation_timeout_pending_(), | 451 collation_timeout_pending_(), |
411 collation_timer_(FROM_HERE, | 452 collation_timer_(FROM_HERE, |
412 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs), | 453 base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs), |
413 this, | 454 this, |
414 &IncidentReportingService::OnCollationTimeout), | 455 &IncidentReportingService::OnCollationTimeout), |
415 delayed_analysis_callbacks_(delayed_task_interval, delayed_task_runner), | 456 delayed_analysis_callbacks_(delayed_task_interval, delayed_task_runner), |
457 extended_reporting_only_delayed_analysis_callbacks_(delayed_task_interval, | |
458 delayed_task_runner), | |
416 download_metadata_manager_(content::BrowserThread::GetBlockingPool()), | 459 download_metadata_manager_(content::BrowserThread::GetBlockingPool()), |
417 receiver_weak_ptr_factory_(this), | 460 receiver_weak_ptr_factory_(this), |
418 weak_ptr_factory_(this) { | 461 weak_ptr_factory_(this) { |
419 enabled_by_field_trial_ = IsFieldTrialEnabled(); | 462 enabled_by_field_trial_ = IsFieldTrialEnabled(); |
420 | 463 |
421 notification_registrar_.Add(this, | 464 notification_registrar_.Add(this, |
422 chrome::NOTIFICATION_PROFILE_ADDED, | 465 chrome::NOTIFICATION_PROFILE_ADDED, |
423 content::NotificationService::AllSources()); | 466 content::NotificationService::AllSources()); |
424 notification_registrar_.Add(this, | 467 notification_registrar_.Add(this, |
425 chrome::NOTIFICATION_PROFILE_DESTROYED, | 468 chrome::NOTIFICATION_PROFILE_DESTROYED, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 LogIncidentDataType(DROPPED, *incident); | 508 LogIncidentDataType(DROPPED, *incident); |
466 context->incidents.clear(); | 509 context->incidents.clear(); |
467 } | 510 } |
468 | 511 |
469 if (enabled_for_profile) { | 512 if (enabled_for_profile) { |
470 // Start processing delayed analysis callbacks if incident reporting is | 513 // Start processing delayed analysis callbacks if incident reporting is |
471 // enabled for this new profile. Start is idempotent, so this is safe even | 514 // enabled for this new profile. Start is idempotent, so this is safe even |
472 // if they're already running. | 515 // if they're already running. |
473 delayed_analysis_callbacks_.Start(); | 516 delayed_analysis_callbacks_.Start(); |
474 | 517 |
518 if (profile->GetPrefs()->GetBoolean( | |
519 prefs::kSafeBrowsingExtendedReportingEnabled)) { | |
520 extended_reporting_only_delayed_analysis_callbacks_.Start(); | |
521 } | |
522 | |
475 // Start a new report if there are process-wide incidents, or incidents for | 523 // Start a new report if there are process-wide incidents, or incidents for |
476 // this profile. | 524 // this profile. |
477 if ((GetProfileContext(nullptr) && | 525 if ((GetProfileContext(nullptr) && |
478 GetProfileContext(nullptr)->HasIncidents()) || | 526 GetProfileContext(nullptr)->HasIncidents()) || |
479 context->HasIncidents()) { | 527 context->HasIncidents()) { |
480 BeginReportProcessing(); | 528 BeginReportProcessing(); |
481 } | 529 } |
482 } | 530 } |
483 | 531 |
484 // TODO(grt): register for pref change notifications to start delayed analysis | 532 // TODO(grt): register for pref change notifications to start delayed analysis |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
901 // Associate the profile contexts and their incident data with the upload. | 949 // Associate the profile contexts and their incident data with the upload. |
902 UploadContext::PersistentIncidentStateCollection profiles_to_state; | 950 UploadContext::PersistentIncidentStateCollection profiles_to_state; |
903 for (auto& profile_and_context : profiles_) { | 951 for (auto& profile_and_context : profiles_) { |
904 // Bypass process-wide incidents that have not yet been associated with a | 952 // Bypass process-wide incidents that have not yet been associated with a |
905 // profile. | 953 // profile. |
906 if (!profile_and_context.first) | 954 if (!profile_and_context.first) |
907 continue; | 955 continue; |
908 ProfileContext* context = profile_and_context.second; | 956 ProfileContext* context = profile_and_context.second; |
909 if (context->incidents.empty()) | 957 if (context->incidents.empty()) |
910 continue; | 958 continue; |
911 if (!IsEnabledForProfile(profile_and_context.first)) { | |
912 for (const auto& incident : context->incidents) | |
913 LogIncidentDataType(DROPPED, *incident); | |
914 context->incidents.clear(); | |
915 continue; | |
916 } | |
917 StateStore::Transaction transaction(context->state_store.get()); | 959 StateStore::Transaction transaction(context->state_store.get()); |
918 std::vector<PersistentIncidentState> states; | 960 std::vector<PersistentIncidentState> states; |
919 // Prep persistent data and prune any incidents already sent. | 961 // Prep persistent data and prune any incidents already sent. |
920 for (const auto& incident : context->incidents) { | 962 for (const auto& incident : context->incidents) { |
921 const PersistentIncidentState state = ComputeIncidentState(*incident); | 963 const PersistentIncidentState state = ComputeIncidentState(*incident); |
922 if (context->state_store->HasBeenReported(state.type, state.key, | 964 if (context->state_store->HasBeenReported(state.type, state.key, |
923 state.digest)) { | 965 state.digest)) { |
924 LogIncidentDataType(PRUNED, *incident); | 966 LogIncidentDataType(PRUNED, *incident); |
967 } else if (!ProfileCanAcceptIncident(profile_and_context.first, | |
968 *incident)) { | |
969 LogIncidentDataType(DROPPED, *incident); | |
925 } else if (!has_download) { | 970 } else if (!has_download) { |
926 LogIncidentDataType(NO_DOWNLOAD, *incident); | 971 LogIncidentDataType(NO_DOWNLOAD, *incident); |
927 // Drop the incident and mark for future pruning since no executable | 972 // Drop the incident and mark for future pruning since no executable |
928 // download was found. | 973 // download was found. |
929 transaction.MarkAsReported(state.type, state.key, state.digest); | 974 transaction.MarkAsReported(state.type, state.key, state.digest); |
930 } else { | 975 } else { |
931 LogIncidentDataType(ACCEPTED, *incident); | 976 LogIncidentDataType(ACCEPTED, *incident); |
932 // Ownership of the payload is passed to the report. | 977 // Ownership of the payload is passed to the report. |
933 ClientIncidentReport_IncidentData* data = | 978 ClientIncidentReport_IncidentData* data = |
934 incident->TakePayload().release(); | 979 incident->TakePayload().release(); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1070 if (!profile->IsOffTheRecord()) | 1115 if (!profile->IsOffTheRecord()) |
1071 OnProfileDestroyed(profile); | 1116 OnProfileDestroyed(profile); |
1072 break; | 1117 break; |
1073 } | 1118 } |
1074 default: | 1119 default: |
1075 break; | 1120 break; |
1076 } | 1121 } |
1077 } | 1122 } |
1078 | 1123 |
1079 } // namespace safe_browsing | 1124 } // namespace safe_browsing |
OLD | NEW |