| Index: chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
|
| diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
|
| index f5bafc5eee4fcd780873baaa5c2bcdadf1ca0065..44ab0b18c6c46796087c20656dcd31520b059f3d 100644
|
| --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
|
| +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
|
| @@ -26,6 +26,7 @@
|
| #include "chrome/browser/safe_browsing/database_manager.h"
|
| #include "chrome/browser/safe_browsing/incident_reporting/environment_data_collection.h"
|
| #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
|
| +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h"
|
| #include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.h"
|
| #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h"
|
| #include "chrome/browser/safe_browsing/safe_browsing_service.h"
|
| @@ -166,19 +167,6 @@ void CleanLegacyPruneState(Profile* profile) {
|
| pref_update.Get()->RemoveWithoutPathExpansion(incident_type, NULL);
|
| }
|
|
|
| -// Runs |callback| on the thread to which |thread_runner| belongs. The callback
|
| -// is run immediately if this function is called on |thread_runner|'s thread.
|
| -void AddIncidentOnOriginThread(
|
| - const AddIncidentCallback& callback,
|
| - scoped_refptr<base::SingleThreadTaskRunner> thread_runner,
|
| - scoped_ptr<Incident> incident) {
|
| - if (thread_runner->BelongsToCurrentThread())
|
| - callback.Run(incident.Pass());
|
| - else
|
| - thread_runner->PostTask(FROM_HERE,
|
| - base::Bind(callback, base::Passed(&incident)));
|
| -}
|
| -
|
| } // namespace
|
|
|
| struct IncidentReportingService::ProfileContext {
|
| @@ -217,6 +205,70 @@ class IncidentReportingService::UploadContext {
|
| DISALLOW_COPY_AND_ASSIGN(UploadContext);
|
| };
|
|
|
| +// An IncidentReceiver that is weakly-bound to the service and transparently
|
| +// bounces process-wide incidents back to the main thread for handling.
|
| +class IncidentReportingService::Receiver : public IncidentReceiver {
|
| + public:
|
| + explicit Receiver(const base::WeakPtr<IncidentReportingService>& service);
|
| + ~Receiver() override;
|
| +
|
| + // IncidentReceiver methods:
|
| + void AddIncidentForProfile(Profile* profile,
|
| + scoped_ptr<Incident> incident) override;
|
| + void AddIncidentForProcess(scoped_ptr<Incident> incident) override;
|
| +
|
| + private:
|
| + static void AddIncidentOnMainThread(
|
| + const base::WeakPtr<IncidentReportingService>& service,
|
| + Profile* profile,
|
| + scoped_ptr<Incident> incident);
|
| +
|
| + base::WeakPtr<IncidentReportingService> service_;
|
| + scoped_refptr<base::SingleThreadTaskRunner> thread_runner_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Receiver);
|
| +};
|
| +
|
| +IncidentReportingService::Receiver::Receiver(
|
| + const base::WeakPtr<IncidentReportingService>& service)
|
| + : service_(service),
|
| + thread_runner_(base::ThreadTaskRunnerHandle::Get()) {
|
| +}
|
| +
|
| +IncidentReportingService::Receiver::~Receiver() {
|
| +}
|
| +
|
| +void IncidentReportingService::Receiver::AddIncidentForProfile(
|
| + Profile* profile,
|
| + scoped_ptr<Incident> incident) {
|
| + DCHECK(thread_runner_->BelongsToCurrentThread());
|
| + DCHECK(profile);
|
| + AddIncidentOnMainThread(service_, profile, incident.Pass());
|
| +}
|
| +
|
| +void IncidentReportingService::Receiver::AddIncidentForProcess(
|
| + scoped_ptr<Incident> incident) {
|
| + if (thread_runner_->BelongsToCurrentThread()) {
|
| + AddIncidentOnMainThread(service_, nullptr, incident.Pass());
|
| + } else if (!thread_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&IncidentReportingService::Receiver::AddIncidentOnMainThread,
|
| + service_, nullptr, base::Passed(&incident)))) {
|
| + LogIncidentDataType(DISCARDED, *incident);
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void IncidentReportingService::Receiver::AddIncidentOnMainThread(
|
| + const base::WeakPtr<IncidentReportingService>& service,
|
| + Profile* profile,
|
| + scoped_ptr<Incident> incident) {
|
| + if (service)
|
| + service->AddIncident(profile, incident.Pass());
|
| + else
|
| + LogIncidentDataType(DISCARDED, *incident);
|
| +}
|
| +
|
| IncidentReportingService::ProfileContext::ProfileContext() : added() {
|
| }
|
|
|
| @@ -293,16 +345,8 @@ IncidentReportingService::~IncidentReportingService() {
|
| STLDeleteValues(&profiles_);
|
| }
|
|
|
| -AddIncidentCallback IncidentReportingService::GetAddIncidentCallback(
|
| - Profile* profile) {
|
| - // Force the context to be created so that incidents added before
|
| - // OnProfileAdded is called are held until the profile's preferences can be
|
| - // queried.
|
| - ignore_result(GetOrCreateProfileContext(profile));
|
| -
|
| - return base::Bind(&IncidentReportingService::AddIncident,
|
| - receiver_weak_ptr_factory_.GetWeakPtr(),
|
| - profile);
|
| +scoped_ptr<IncidentReceiver> IncidentReportingService::GetIncidentReceiver() {
|
| + return make_scoped_ptr(new Receiver(receiver_weak_ptr_factory_.GetWeakPtr()));
|
| }
|
|
|
| scoped_ptr<TrackedPreferenceValidationDelegate>
|
| @@ -312,21 +356,17 @@ IncidentReportingService::CreatePreferenceValidationDelegate(Profile* profile) {
|
| if (profile->IsOffTheRecord())
|
| return scoped_ptr<TrackedPreferenceValidationDelegate>();
|
| return scoped_ptr<TrackedPreferenceValidationDelegate>(
|
| - new PreferenceValidationDelegate(GetAddIncidentCallback(profile)));
|
| + new PreferenceValidationDelegate(profile, GetIncidentReceiver()));
|
| }
|
|
|
| void IncidentReportingService::RegisterDelayedAnalysisCallback(
|
| const DelayedAnalysisCallback& callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - // |callback| will be run on the blocking pool, so it will likely run the
|
| - // AddIncidentCallback there as well. Bounce the run of that callback back to
|
| - // the current thread via AddIncidentOnOriginThread.
|
| + // |callback| will be run on the blocking pool. The receiver will bounce back
|
| + // to the origin thread if needed.
|
| delayed_analysis_callbacks_.RegisterCallback(
|
| - base::Bind(callback,
|
| - base::Bind(&AddIncidentOnOriginThread,
|
| - GetAddIncidentCallback(NULL),
|
| - base::ThreadTaskRunnerHandle::Get())));
|
| + base::Bind(callback, base::Passed(GetIncidentReceiver())));
|
|
|
| // Start running the callbacks if any profiles are participating in safe
|
| // browsing. If none are now, running will commence if/when a participaing
|
| @@ -518,9 +558,11 @@ void IncidentReportingService::AddIncident(Profile* profile,
|
| scoped_ptr<Incident> incident) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - ProfileContext* context = GetProfileContext(profile);
|
| - // It is forbidden to call this function with a destroyed profile.
|
| - DCHECK(context);
|
| + // Ignore incidents from off-the-record profiles.
|
| + if (profile && profile->IsOffTheRecord())
|
| + return;
|
| +
|
| + ProfileContext* context = GetOrCreateProfileContext(profile);
|
| // If this is a process-wide incident, the context must not indicate that the
|
| // profile (which is NULL) has been added to the profile manager.
|
| DCHECK(profile || !context->added);
|
|
|