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 "components/rappor/rappor_service.h" | 5 #include "components/rappor/rappor_service.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/prefs/pref_registry_simple.h" | 9 #include "base/prefs/pref_registry_simple.h" |
| 10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 | 56 |
| 57 RapporService::RapporService() : cohort_(-1) {} | 57 RapporService::RapporService() : cohort_(-1) {} |
| 58 | 58 |
| 59 RapporService::~RapporService() { | 59 RapporService::~RapporService() { |
| 60 STLDeleteValues(&metrics_map_); | 60 STLDeleteValues(&metrics_map_); |
| 61 } | 61 } |
| 62 | 62 |
| 63 void RapporService::Start(PrefService* pref_service, | 63 void RapporService::Start(PrefService* pref_service, |
| 64 net::URLRequestContextGetter* request_context) { | 64 net::URLRequestContextGetter* request_context) { |
| 65 const GURL server_url = GetServerUrl(); | 65 const GURL server_url = GetServerUrl(); |
| 66 if (!server_url.is_valid()) | 66 if (!server_url.is_valid()) { |
| 67 DVLOG(1) << "RapporService not started:" | |
|
Alexei Svitkine (slow)
2014/07/25 14:46:39
Nit: Add a space before the end ".
Steven Holte
2014/07/25 19:16:47
Done.
| |
| 68 << server_url.spec() << " is invalid."; | |
| 67 return; | 69 return; |
| 70 } | |
| 71 DVLOG(1) << "RapporService started. Reporting to " << server_url.spec(); | |
| 68 DCHECK(!uploader_); | 72 DCHECK(!uploader_); |
| 69 LoadSecret(pref_service); | 73 LoadSecret(pref_service); |
| 70 LoadCohort(pref_service); | 74 LoadCohort(pref_service); |
| 71 uploader_.reset(new LogUploader(server_url, kMimeType, request_context)); | 75 uploader_.reset(new LogUploader(server_url, kMimeType, request_context)); |
| 72 log_rotation_timer_.Start( | 76 log_rotation_timer_.Start( |
| 73 FROM_HERE, | 77 FROM_HERE, |
| 74 base::TimeDelta::FromSeconds(kInitialLogIntervalSeconds), | 78 base::TimeDelta::FromSeconds(kInitialLogIntervalSeconds), |
| 75 this, | 79 this, |
| 76 &RapporService::OnLogInterval); | 80 &RapporService::OnLogInterval); |
| 77 } | 81 } |
| 78 | 82 |
| 79 void RapporService::OnLogInterval() { | 83 void RapporService::OnLogInterval() { |
| 80 DCHECK(uploader_); | 84 DCHECK(uploader_); |
| 85 DVLOG(2) << "RapporService::OnLogInterval"; | |
| 81 RapporReports reports; | 86 RapporReports reports; |
| 82 if (ExportMetrics(&reports)) { | 87 if (ExportMetrics(&reports)) { |
| 83 std::string log_text; | 88 std::string log_text; |
| 84 bool success = reports.SerializeToString(&log_text); | 89 bool success = reports.SerializeToString(&log_text); |
| 85 DCHECK(success); | 90 DCHECK(success); |
| 91 DVLOG(1) << "RapporService sending a report of " | |
| 92 << reports.report_size() << " value(s)."; | |
| 86 uploader_->QueueLog(log_text); | 93 uploader_->QueueLog(log_text); |
| 87 } | 94 } |
| 88 log_rotation_timer_.Start(FROM_HERE, | 95 log_rotation_timer_.Start(FROM_HERE, |
| 89 base::TimeDelta::FromSeconds(kLogIntervalSeconds), | 96 base::TimeDelta::FromSeconds(kLogIntervalSeconds), |
| 90 this, | 97 this, |
| 91 &RapporService::OnLogInterval); | 98 &RapporService::OnLogInterval); |
| 92 } | 99 } |
| 93 | 100 |
| 94 // static | 101 // static |
| 95 void RapporService::RegisterPrefs(PrefRegistrySimple* registry) { | 102 void RapporService::RegisterPrefs(PrefRegistrySimple* registry) { |
| 96 registry->RegisterStringPref(prefs::kRapporSecret, std::string()); | 103 registry->RegisterStringPref(prefs::kRapporSecret, std::string()); |
| 97 registry->RegisterIntegerPref(prefs::kRapporCohortDeprecated, -1); | 104 registry->RegisterIntegerPref(prefs::kRapporCohortDeprecated, -1); |
| 98 registry->RegisterIntegerPref(prefs::kRapporCohortSeed, -1); | 105 registry->RegisterIntegerPref(prefs::kRapporCohortSeed, -1); |
| 99 } | 106 } |
| 100 | 107 |
| 101 void RapporService::LoadCohort(PrefService* pref_service) { | 108 void RapporService::LoadCohort(PrefService* pref_service) { |
| 102 DCHECK(!IsInitialized()); | 109 DCHECK(!IsInitialized()); |
| 103 // Ignore and delete old cohort parameter. | 110 // Ignore and delete old cohort parameter. |
| 104 pref_service->ClearPref(prefs::kRapporCohortDeprecated); | 111 pref_service->ClearPref(prefs::kRapporCohortDeprecated); |
| 105 | 112 |
| 106 cohort_ = pref_service->GetInteger(prefs::kRapporCohortSeed); | 113 cohort_ = pref_service->GetInteger(prefs::kRapporCohortSeed); |
| 107 // If the user is already assigned to a valid cohort, we're done. | 114 // If the user is already assigned to a valid cohort, we're done. |
| 108 if (cohort_ >= 0 && cohort_ < RapporParameters::kMaxCohorts) | 115 if (cohort_ >= 0 && cohort_ < RapporParameters::kMaxCohorts) |
| 109 return; | 116 return; |
| 110 | 117 |
| 111 // This is the first time the client has started the service (or their | 118 // This is the first time the client has started the service (or their |
| 112 // preferences were corrupted). Randomly assign them to a cohort. | 119 // preferences were corrupted). Randomly assign them to a cohort. |
| 120 DVLOG(2) << "Selected a new Rappor cohort."; | |
|
Alexei Svitkine (slow)
2014/07/25 14:46:39
Nit: Might as well log the cohort_.
Steven Holte
2014/07/25 19:16:47
Done.
| |
| 113 cohort_ = base::RandGenerator(RapporParameters::kMaxCohorts); | 121 cohort_ = base::RandGenerator(RapporParameters::kMaxCohorts); |
| 114 pref_service->SetInteger(prefs::kRapporCohortSeed, cohort_); | 122 pref_service->SetInteger(prefs::kRapporCohortSeed, cohort_); |
| 115 } | 123 } |
| 116 | 124 |
| 117 void RapporService::LoadSecret(PrefService* pref_service) { | 125 void RapporService::LoadSecret(PrefService* pref_service) { |
| 118 DCHECK(secret_.empty()); | 126 DCHECK(secret_.empty()); |
| 119 std::string secret_base64 = pref_service->GetString(prefs::kRapporSecret); | 127 std::string secret_base64 = pref_service->GetString(prefs::kRapporSecret); |
| 120 if (!secret_base64.empty()) { | 128 if (!secret_base64.empty()) { |
| 121 bool decoded = base::Base64Decode(secret_base64, &secret_); | 129 bool decoded = base::Base64Decode(secret_base64, &secret_); |
| 122 if (decoded && secret_.size() == HmacByteVectorGenerator::kEntropyInputSize) | 130 if (decoded && secret_.size() == HmacByteVectorGenerator::kEntropyInputSize) |
| 123 return; | 131 return; |
| 124 // If the preference fails to decode, or is the wrong size, it must be | 132 // If the preference fails to decode, or is the wrong size, it must be |
| 125 // corrupt, so continue as though it didn't exist yet and generate a new | 133 // corrupt, so continue as though it didn't exist yet and generate a new |
| 126 // one. | 134 // one. |
| 127 } | 135 } |
| 128 | 136 |
| 137 DVLOG(2) << "Generated a new Rappor secret."; | |
| 129 secret_ = HmacByteVectorGenerator::GenerateEntropyInput(); | 138 secret_ = HmacByteVectorGenerator::GenerateEntropyInput(); |
| 130 base::Base64Encode(secret_, &secret_base64); | 139 base::Base64Encode(secret_, &secret_base64); |
| 131 pref_service->SetString(prefs::kRapporSecret, secret_base64); | 140 pref_service->SetString(prefs::kRapporSecret, secret_base64); |
| 132 } | 141 } |
| 133 | 142 |
| 134 bool RapporService::ExportMetrics(RapporReports* reports) { | 143 bool RapporService::ExportMetrics(RapporReports* reports) { |
| 135 if (metrics_map_.empty()) | 144 if (metrics_map_.empty()) |
| 136 return false; | 145 return false; |
| 137 | 146 |
| 138 DCHECK_GE(cohort_, 0); | 147 DCHECK_GE(cohort_, 0); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 156 return cohort_ >= 0; | 165 return cohort_ >= 0; |
| 157 } | 166 } |
| 158 | 167 |
| 159 void RapporService::RecordSample(const std::string& metric_name, | 168 void RapporService::RecordSample(const std::string& metric_name, |
| 160 RapporType type, | 169 RapporType type, |
| 161 const std::string& sample) { | 170 const std::string& sample) { |
| 162 // Ignore the sample if the service hasn't started yet. | 171 // Ignore the sample if the service hasn't started yet. |
| 163 if (!IsInitialized()) | 172 if (!IsInitialized()) |
| 164 return; | 173 return; |
| 165 DCHECK_LT(type, NUM_RAPPOR_TYPES); | 174 DCHECK_LT(type, NUM_RAPPOR_TYPES); |
| 175 DVLOG(2) << "Recording sample \"" << sample | |
| 176 << "\" for metric \"" << metric_name | |
| 177 << "\" of type:" << type; | |
|
Alexei Svitkine (slow)
2014/07/25 14:46:39
Nit: Space after :
Steven Holte
2014/07/25 19:16:47
Done.
| |
| 166 RecordSampleInternal(metric_name, kRapporParametersForType[type], sample); | 178 RecordSampleInternal(metric_name, kRapporParametersForType[type], sample); |
| 167 } | 179 } |
| 168 | 180 |
| 169 void RapporService::RecordSampleInternal(const std::string& metric_name, | 181 void RapporService::RecordSampleInternal(const std::string& metric_name, |
| 170 const RapporParameters& parameters, | 182 const RapporParameters& parameters, |
| 171 const std::string& sample) { | 183 const std::string& sample) { |
| 172 DCHECK(IsInitialized()); | 184 DCHECK(IsInitialized()); |
| 173 RapporMetric* metric = LookUpMetric(metric_name, parameters); | 185 RapporMetric* metric = LookUpMetric(metric_name, parameters); |
| 174 metric->AddSample(sample); | 186 metric->AddSample(sample); |
| 175 } | 187 } |
| 176 | 188 |
| 177 RapporMetric* RapporService::LookUpMetric(const std::string& metric_name, | 189 RapporMetric* RapporService::LookUpMetric(const std::string& metric_name, |
| 178 const RapporParameters& parameters) { | 190 const RapporParameters& parameters) { |
| 179 DCHECK(IsInitialized()); | 191 DCHECK(IsInitialized()); |
| 180 std::map<std::string, RapporMetric*>::const_iterator it = | 192 std::map<std::string, RapporMetric*>::const_iterator it = |
| 181 metrics_map_.find(metric_name); | 193 metrics_map_.find(metric_name); |
| 182 if (it != metrics_map_.end()) { | 194 if (it != metrics_map_.end()) { |
| 183 RapporMetric* metric = it->second; | 195 RapporMetric* metric = it->second; |
| 184 DCHECK_EQ(parameters.ToString(), metric->parameters().ToString()); | 196 DCHECK_EQ(parameters.ToString(), metric->parameters().ToString()); |
| 185 return metric; | 197 return metric; |
| 186 } | 198 } |
| 187 | 199 |
| 188 RapporMetric* new_metric = new RapporMetric(metric_name, parameters, cohort_); | 200 RapporMetric* new_metric = new RapporMetric(metric_name, parameters, cohort_); |
| 189 metrics_map_[metric_name] = new_metric; | 201 metrics_map_[metric_name] = new_metric; |
| 190 return new_metric; | 202 return new_metric; |
| 191 } | 203 } |
| 192 | 204 |
| 193 } // namespace rappor | 205 } // namespace rappor |
| OLD | NEW |