Chromium Code Reviews| 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 |