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 3f372045081ec9edd833ea6c3546a32aa9cd06e5..fb251f6065336310734dc3a5f72c95cc5dfeb4b9 100644 |
--- a/chrome/browser/safe_browsing/incident_reporting_service.cc |
+++ b/chrome/browser/safe_browsing/incident_reporting_service.cc |
@@ -6,6 +6,9 @@ |
#include <math.h> |
+#include <algorithm> |
+#include <vector> |
+ |
#include "base/metrics/histogram.h" |
#include "base/prefs/pref_service.h" |
#include "base/process/process_info.h" |
@@ -47,19 +50,17 @@ const int64 kDefaultUploadDelayMs = 1000 * 60; // one minute |
void LogIncidentDataType( |
IncidentDisposition disposition, |
const ClientIncidentReport_IncidentData& incident_data) { |
- static const char kAcceptedMetric[] = "SBIRS.Incident"; |
- static const char kDroppedMetric[] = "SBIRS.DroppedIncident"; |
- |
IncidentType type = TRACKED_PREFERENCE; |
// Add a switch statement once other types are supported. |
DCHECK(incident_data.has_tracked_preference()); |
if (disposition == ACCEPTED) { |
- UMA_HISTOGRAM_ENUMERATION(kAcceptedMetric, type, NUM_INCIDENT_TYPES); |
+ UMA_HISTOGRAM_ENUMERATION("SBIRS.Incident", type, NUM_INCIDENT_TYPES); |
} else { |
DCHECK_EQ(disposition, DROPPED); |
- UMA_HISTOGRAM_ENUMERATION(kDroppedMetric, type, NUM_INCIDENT_TYPES); |
+ UMA_HISTOGRAM_ENUMERATION("SBIRS.DroppedIncident", type, |
+ NUM_INCIDENT_TYPES); |
} |
} |
@@ -84,9 +85,15 @@ class IncidentReportingService::UploadContext { |
explicit UploadContext(scoped_ptr<ClientIncidentReport> report); |
~UploadContext(); |
+ // The report being uploaded. |
scoped_ptr<ClientIncidentReport> report; |
+ |
+ // The uploader in use. This is NULL until the CSD killswitch is checked. |
scoped_ptr<IncidentReportUploader> uploader; |
+ // The set of profiles from which incidents in |report| originated. |
+ std::vector<Profile*> profiles; |
+ |
private: |
DISALLOW_COPY_AND_ASSIGN(UploadContext); |
}; |
@@ -239,6 +246,18 @@ void IncidentReportingService::OnProfileDestroyed(Profile* profile) { |
// No new incidents will be accepted for it. |
delete it->second; |
profiles_.erase(it); |
+ |
+ // Remove the association with this profile from any pending uploads. |
+ for (size_t i = 0; i < uploads_.size(); ++i) { |
+ UploadContext* upload = uploads_[i]; |
+ std::vector<Profile*>::iterator it = |
+ std::find(upload->profiles.begin(), upload->profiles.end(), profile); |
+ if (it != upload->profiles.end()) { |
+ *it = upload->profiles.back(); |
+ upload->profiles.resize(upload->profiles.size() - 1); |
+ break; |
+ } |
+ } |
} |
void IncidentReportingService::AddIncident( |
@@ -377,15 +396,6 @@ void IncidentReportingService::CollectDownloadDetails( |
// TODO(grt): collect download info; http://crbug.com/383042. |
} |
-void IncidentReportingService::RecordReportedIncidents() { |
- // TODO(grt): store state about reported incidents. |
-} |
- |
-void IncidentReportingService::PruneReportedIncidents( |
- ClientIncidentReport* report) { |
- // TODO(grt): remove previously reported incidents; http://crbug.com/383043. |
-} |
- |
void IncidentReportingService::UploadIfCollectionComplete() { |
DCHECK(report_); |
// Bail out if there are still outstanding collection tasks. |
@@ -405,10 +415,15 @@ void IncidentReportingService::UploadIfCollectionComplete() { |
process->set_metrics_consent(g_browser_process->local_state()->GetBoolean( |
prefs::kMetricsReportingEnabled)); |
} |
+ |
// Check for extended consent in any profile while collecting incidents. |
process->set_extended_consent(false); |
// Collect incidents across all profiles participating in safe browsing. Drop |
// incidents if the profile stopped participating before collection completed. |
+ // Prune incidents if the profile has already submitted any incidents. |
+ // Associate the participating profiles with the upload. |
+ size_t prune_count = 0; |
+ std::vector<Profile*> profiles; |
for (ProfileContextCollection::iterator scan = profiles_.begin(); |
scan != profiles_.end(); |
++scan) { |
@@ -421,7 +436,18 @@ void IncidentReportingService::UploadIfCollectionComplete() { |
ProfileContext* context = scan->second; |
if (context->incidents.empty()) |
continue; |
- if (prefs->GetBoolean(prefs::kSafeBrowsingEnabled)) { |
+ if (!prefs->GetBoolean(prefs::kSafeBrowsingEnabled)) { |
+ for (size_t i = 0; i < context->incidents.size(); ++i) { |
+ LogIncidentDataType(DROPPED, *context->incidents[i]); |
+ } |
+ context->incidents.clear(); |
+ } else if (prefs->GetBoolean(prefs::kSafeBrowsingIncidentReportSent)) { |
+ // Prune all incidents. |
+ // TODO(grt): Only prune previously submitted incidents; |
+ // http://crbug.com/383043. |
+ prune_count += context->incidents.size(); |
+ context->incidents.clear(); |
+ } else { |
for (size_t i = 0; i < context->incidents.size(); ++i) { |
ClientIncidentReport_IncidentData* incident = context->incidents[i]; |
LogIncidentDataType(ACCEPTED, *incident); |
@@ -429,35 +455,29 @@ void IncidentReportingService::UploadIfCollectionComplete() { |
report->mutable_incident()->AddAllocated(incident); |
} |
context->incidents.weak_clear(); |
- } else { |
- for (size_t i = 0; i < context->incidents.size(); ++i) { |
- LogIncidentDataType(DROPPED, *context->incidents[i]); |
- } |
- context->incidents.clear(); |
+ profiles.push_back(scan->first); |
} |
} |
- const int original_count = report->incident_size(); |
- // Abandon the request if all incidents were dropped. |
- if (!original_count) |
+ const int count = report->incident_size(); |
+ // Abandon the request if all incidents were dropped with none pruned. |
+ if (!count && !prune_count) |
return; |
- UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", original_count); |
+ UMA_HISTOGRAM_COUNTS_100("SBIRS.IncidentCount", count + prune_count); |
- PruneReportedIncidents(report.get()); |
- |
- int final_count = report->incident_size(); |
{ |
- double prune_pct = static_cast<double>(original_count - final_count); |
- prune_pct = prune_pct * 100.0 / original_count; |
+ double prune_pct = static_cast<double>(prune_count); |
+ prune_pct = prune_pct * 100.0 / (count + prune_count); |
prune_pct = round(prune_pct); |
UMA_HISTOGRAM_PERCENTAGE("SBIRS.PruneRatio", static_cast<int>(prune_pct)); |
} |
// Abandon the report if all incidents were pruned. |
- if (!final_count) |
+ if (!count) |
return; |
scoped_ptr<UploadContext> context(new UploadContext(report.Pass())); |
+ context->profiles.swap(profiles); |
if (!database_manager_) { |
// No database manager during testing. Take ownership of the context and |
// continue processing. |
@@ -511,10 +531,11 @@ void IncidentReportingService::OnKillSwitchResult(UploadContext* context, |
} |
} |
-void IncidentReportingService::HandleResponse( |
- scoped_ptr<ClientIncidentReport> report, |
- scoped_ptr<ClientIncidentResponse> response) { |
- RecordReportedIncidents(); |
+void IncidentReportingService::HandleResponse(const UploadContext& context) { |
+ for (size_t i = 0; i < context.profiles.size(); ++i) { |
+ context.profiles[i]->GetPrefs()->SetBoolean( |
+ prefs::kSafeBrowsingIncidentReportSent, true); |
+ } |
} |
void IncidentReportingService::OnReportUploadResult( |
@@ -536,7 +557,7 @@ void IncidentReportingService::OnReportUploadResult( |
uploads_.weak_erase(uploads_.end() - 1); |
if (result == IncidentReportUploader::UPLOAD_SUCCESS) |
- HandleResponse(upload->report.Pass(), response.Pass()); |
+ HandleResponse(*upload); |
// else retry? |
} |