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

Unified Diff: chrome/browser/safe_browsing/incident_reporting_service.cc

Issue 441453002: Support for process-wide incidents in the safe browsing incident reporting service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/incident_reporting_service.cc
diff --git a/chrome/browser/safe_browsing/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting_service.cc
index 6c8ce1b9f562fb94fc295ca70e1b3993c8c8d856..fc08e92453f93819c8a85f0b2b25892ca6f47829 100644
--- a/chrome/browser/safe_browsing/incident_reporting_service.cc
+++ b/chrome/browser/safe_browsing/incident_reporting_service.cc
@@ -70,6 +70,9 @@ struct PersistentIncidentState {
// The amount of time the service will wait to collate incidents.
const int64 kDefaultUploadDelayMs = 1000 * 60; // one minute
+// The amount of time between running delayed analysis callbacks.
+const int64 kDefaultCallbackMs = 1000 * 20;
+
// Returns the number of incidents contained in |incident|. The result is
// expected to be 1. Used in DCHECKs.
size_t CountIncidents(const ClientIncidentReport_IncidentData& incident) {
@@ -225,6 +228,9 @@ IncidentReportingService::IncidentReportingService(
base::TimeDelta::FromMilliseconds(kDefaultUploadDelayMs),
this,
&IncidentReportingService::OnCollectionTimeout),
+ delayed_analysis_callbacks_(
+ base::TimeDelta::FromMilliseconds(kDefaultCallbackMs),
+ content::BrowserThread::GetBlockingPool()),
receiver_weak_ptr_factory_(this),
weak_ptr_factory_(this) {
notification_registrar_.Add(this,
@@ -270,6 +276,17 @@ IncidentReportingService::CreatePreferenceValidationDelegate(Profile* profile) {
new PreferenceValidationDelegate(GetAddIncidentCallback(profile)));
}
+void IncidentReportingService::RegisterDelayedAnalysisCallback(
+ const DelayedAnalysisCallback& callback) {
+ delayed_analysis_callbacks_.RegisterCallback(
+ base::Bind(callback, GetAddIncidentCallback(NULL)));
+
+ // Start running the callbacks if any profiles are participating in safe
+ // browsing.
+ if (FindEligibleProfile())
+ delayed_analysis_callbacks_.Start();
+}
+
void IncidentReportingService::SetCollectEnvironmentHook(
CollectEnvironmentDataFn collect_environment_data_hook,
const scoped_refptr<base::TaskRunner>& task_runner) {
@@ -294,17 +311,23 @@ void IncidentReportingService::OnProfileAdded(Profile* profile) {
ProfileContext* context = GetOrCreateProfileContext(profile);
context->added = true;
+ const bool safe_browsing_enabled =
+ profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled);
+
+ // Start processing delayed analysis callbacks if this new profile
+ // participates in safe browsing.
+ if (safe_browsing_enabled)
+ delayed_analysis_callbacks_.Start();
+
// Nothing else to do if a report is not being assembled.
if (!report_)
return;
- // Drop all incidents received prior to creation if the profile is not
- // participating in safe browsing.
- if (!context->incidents.empty() &&
- !profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
- for (size_t i = 0; i < context->incidents.size(); ++i) {
+ // Drop all incidents associated with this profile that were received prior to
+ // its addition if the profile is not participating in safe browsing.
+ if (!context->incidents.empty() && !safe_browsing_enabled) {
+ for (size_t i = 0; i < context->incidents.size(); ++i)
LogIncidentDataType(DROPPED, *context->incidents[i]);
- }
context->incidents.clear();
}
@@ -362,17 +385,39 @@ void IncidentReportingService::OnProfileDestroyed(Profile* profile) {
uploads_[i]->profiles_to_state.erase(profile);
}
+Profile* IncidentReportingService::FindEligibleProfile() const {
+ Profile* candidate = NULL;
+ for (ProfileContextCollection::const_iterator scan = profiles_.begin();
+ scan != profiles_.end();
+ ++scan) {
+ // Skip over profiles that have yet to be added to the profile manager.
+ // This will also skip over the NULL-profile context used to hold
+ // process-wide incidents.
+ if (!scan->second->added)
+ continue;
+ PrefService* prefs = scan->first->GetPrefs();
+ if (prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)) {
+ candidate = scan->first;
+ break;
+ }
+ if (!candidate && prefs->GetBoolean(prefs::kSafeBrowsingEnabled))
+ candidate = scan->first;
+ }
+ return candidate;
+}
+
void IncidentReportingService::AddIncident(
Profile* profile,
scoped_ptr<ClientIncidentReport_IncidentData> incident_data) {
DCHECK(thread_checker_.CalledOnValidThread());
- // Incidents outside the context of a profile are not supported at the moment.
- DCHECK(profile);
DCHECK_EQ(1U, CountIncidents(*incident_data));
ProfileContext* context = GetProfileContext(profile);
// It is forbidden to call this function with a destroyed profile.
DCHECK(context);
+ // 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);
// Drop the incident immediately if profile creation has completed and the
// profile is not participating in safe browsing. Preference evaluation is
@@ -490,12 +535,14 @@ void IncidentReportingService::OnCollectionTimeout() {
if (!collection_timeout_pending_)
return;
- // Wait another round if incidents have come in from a profile that has yet to
- // complete creation.
+ // Wait another round if profile-bound incidents have come in from a profile
+ // that has yet to complete creation.
for (ProfileContextCollection::iterator scan = profiles_.begin();
scan != profiles_.end();
++scan) {
- if (!scan->second->added && !scan->second->incidents.empty()) {
+ if (scan->first &&
+ !scan->second->added &&
+ !scan->second->incidents.empty()) {
upload_timer_.Reset();
return;
}
@@ -601,8 +648,28 @@ void IncidentReportingService::UploadIfCollectionComplete() {
prefs::kMetricsReportingEnabled));
}
- // Check for extended consent in any profile while collecting incidents.
- process->set_extended_consent(false);
+ // Find a profile suitable for tracking process-wide incidents.
+ Profile* analyses_profile = FindEligibleProfile();
+ process->set_extended_consent(
+ analyses_profile ? analyses_profile->GetPrefs()->GetBoolean(
+ prefs::kSafeBrowsingExtendedReportingEnabled) :
+ false);
+
+ // Associate process-wide incidents with the analyses profile.
+ ProfileContext* null_context = GetProfileContext(NULL);
+ if (null_context && analyses_profile) {
+ DCHECK(!null_context->incidents.empty());
+ ProfileContext* analyses_context = GetProfileContext(analyses_profile);
+ // Move the incidents to the target context.
+ analyses_context->incidents.insert(analyses_context->incidents.end(),
+ null_context->incidents.begin(),
+ null_context->incidents.end());
+ null_context->incidents.weak_clear();
+ // Delete the process-wide context.
+ delete null_context;
+ profiles_.erase(NULL);
+ }
+
// Collect incidents across all profiles participating in safe browsing. Drop
// incidents if the profile stopped participating before collection completed.
// Prune previously submitted incidents.
@@ -612,12 +679,11 @@ void IncidentReportingService::UploadIfCollectionComplete() {
for (ProfileContextCollection::iterator scan = profiles_.begin();
scan != profiles_.end();
++scan) {
+ // Bypass process-wide incidents that have not yet been associated with a
+ // profile.
+ if (!scan->first)
+ continue;
PrefService* prefs = scan->first->GetPrefs();
- if (process &&
- prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)) {
- process->set_extended_consent(true);
- process = NULL; // Don't check any more once one is found.
- }
ProfileContext* context = scan->second;
if (context->incidents.empty())
continue;

Powered by Google App Engine
This is Rietveld 408576698