| 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" | |
| 8 #include "base/metrics/field_trial.h" | 7 #include "base/metrics/field_trial.h" |
| 9 #include "base/prefs/pref_registry_simple.h" | |
| 10 #include "base/prefs/pref_service.h" | |
| 11 #include "base/rand_util.h" | |
| 12 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 13 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 14 #include "components/metrics/metrics_hashes.h" | 10 #include "components/metrics/metrics_hashes.h" |
| 15 #include "components/rappor/log_uploader.h" | 11 #include "components/rappor/log_uploader.h" |
| 16 #include "components/rappor/proto/rappor_metric.pb.h" | 12 #include "components/rappor/proto/rappor_metric.pb.h" |
| 17 #include "components/rappor/rappor_metric.h" | 13 #include "components/rappor/rappor_metric.h" |
| 18 #include "components/rappor/rappor_pref_names.h" | 14 #include "components/rappor/rappor_pref_names.h" |
| 15 #include "components/rappor/rappor_prefs.h" |
| 19 #include "components/variations/variations_associated_data.h" | 16 #include "components/variations/variations_associated_data.h" |
| 20 | 17 |
| 21 namespace rappor { | 18 namespace rappor { |
| 22 | 19 |
| 23 namespace { | 20 namespace { |
| 24 | 21 |
| 25 // Seconds before the initial log is generated. | 22 // Seconds before the initial log is generated. |
| 26 const int kInitialLogIntervalSeconds = 15; | 23 const int kInitialLogIntervalSeconds = 15; |
| 27 // Interval between ongoing logs. | 24 // Interval between ongoing logs. |
| 28 const int kLogIntervalSeconds = 30 * 60; | 25 const int kLogIntervalSeconds = 30 * 60; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 const GURL server_url = GetServerUrl(); | 96 const GURL server_url = GetServerUrl(); |
| 100 if (!server_url.is_valid()) { | 97 if (!server_url.is_valid()) { |
| 101 DVLOG(1) << server_url.spec() << " is invalid. " | 98 DVLOG(1) << server_url.spec() << " is invalid. " |
| 102 << "RapporService not started."; | 99 << "RapporService not started."; |
| 103 return; | 100 return; |
| 104 } | 101 } |
| 105 DVLOG(1) << "RapporService reporting to " << server_url.spec(); | 102 DVLOG(1) << "RapporService reporting to " << server_url.spec(); |
| 106 InitializeInternal(make_scoped_ptr(new LogUploader(server_url, | 103 InitializeInternal(make_scoped_ptr(new LogUploader(server_url, |
| 107 kMimeType, | 104 kMimeType, |
| 108 request_context)), | 105 request_context)), |
| 109 LoadCohort(), | 106 internal::LoadCohort(pref_service_), |
| 110 LoadSecret()); | 107 internal::LoadSecret(pref_service_)); |
| 111 } | 108 } |
| 112 | 109 |
| 113 void RapporService::Update(RecordingLevel recording_level, bool may_upload) { | 110 void RapporService::Update(RecordingLevel recording_level, bool may_upload) { |
| 114 DCHECK(IsInitialized()); | 111 DCHECK(IsInitialized()); |
| 115 if (recording_level_ != recording_level) { | 112 if (recording_level_ != recording_level) { |
| 116 if (recording_level == RECORDING_DISABLED) { | 113 if (recording_level == RECORDING_DISABLED) { |
| 117 DVLOG(1) << "Rappor service stopped due to RECORDING_DISABLED."; | 114 DVLOG(1) << "Rappor service stopped due to RECORDING_DISABLED."; |
| 118 recording_level_ = RECORDING_DISABLED; | 115 recording_level_ = RECORDING_DISABLED; |
| 119 CancelNextLogRotation(); | 116 CancelNextLogRotation(); |
| 120 } else if (recording_level_ == RECORDING_DISABLED) { | 117 } else if (recording_level_ == RECORDING_DISABLED) { |
| 121 DVLOG(1) << "RapporService started at recording level: " | 118 DVLOG(1) << "RapporService started at recording level: " |
| 122 << recording_level; | 119 << recording_level; |
| 123 recording_level_ = recording_level; | 120 recording_level_ = recording_level; |
| 124 ScheduleNextLogRotation( | 121 ScheduleNextLogRotation( |
| 125 base::TimeDelta::FromSeconds(kInitialLogIntervalSeconds)); | 122 base::TimeDelta::FromSeconds(kInitialLogIntervalSeconds)); |
| 126 } else { | 123 } else { |
| 127 DVLOG(1) << "RapporService recording_level changed:" << recording_level; | 124 DVLOG(1) << "RapporService recording_level changed:" << recording_level; |
| 128 recording_level_ = recording_level; | 125 recording_level_ = recording_level; |
| 129 } | 126 } |
| 130 } | 127 } |
| 131 | 128 |
| 132 DVLOG(1) << "RapporService may_upload=" << may_upload; | 129 DVLOG(1) << "RapporService may_upload=" << may_upload; |
| 133 if (may_upload) { | 130 if (may_upload) { |
| 134 uploader_->Start(); | 131 uploader_->Start(); |
| 135 } else { | 132 } else { |
| 136 uploader_->Stop(); | 133 uploader_->Stop(); |
| 137 } | 134 } |
| 138 } | 135 } |
| 139 | 136 |
| 137 // static |
| 138 void RapporService::RegisterPrefs(PrefRegistrySimple* registry) { |
| 139 internal::RegisterPrefs(registry); |
| 140 } |
| 141 |
| 140 void RapporService::InitializeInternal( | 142 void RapporService::InitializeInternal( |
| 141 scoped_ptr<LogUploaderInterface> uploader, | 143 scoped_ptr<LogUploaderInterface> uploader, |
| 142 int32_t cohort, | 144 int32_t cohort, |
| 143 const std::string& secret) { | 145 const std::string& secret) { |
| 144 DCHECK(!IsInitialized()); | 146 DCHECK(!IsInitialized()); |
| 145 DCHECK(secret_.empty()); | 147 DCHECK(secret_.empty()); |
| 146 uploader_.swap(uploader); | 148 uploader_.swap(uploader); |
| 147 cohort_ = cohort; | 149 cohort_ = cohort; |
| 148 secret_ = secret; | 150 secret_ = secret; |
| 149 } | 151 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 173 std::string log_text; | 175 std::string log_text; |
| 174 bool success = reports.SerializeToString(&log_text); | 176 bool success = reports.SerializeToString(&log_text); |
| 175 DCHECK(success); | 177 DCHECK(success); |
| 176 DVLOG(1) << "RapporService sending a report of " | 178 DVLOG(1) << "RapporService sending a report of " |
| 177 << reports.report_size() << " value(s)."; | 179 << reports.report_size() << " value(s)."; |
| 178 uploader_->QueueLog(log_text); | 180 uploader_->QueueLog(log_text); |
| 179 } | 181 } |
| 180 ScheduleNextLogRotation(base::TimeDelta::FromSeconds(kLogIntervalSeconds)); | 182 ScheduleNextLogRotation(base::TimeDelta::FromSeconds(kLogIntervalSeconds)); |
| 181 } | 183 } |
| 182 | 184 |
| 183 // static | |
| 184 void RapporService::RegisterPrefs(PrefRegistrySimple* registry) { | |
| 185 registry->RegisterStringPref(prefs::kRapporSecret, std::string()); | |
| 186 registry->RegisterIntegerPref(prefs::kRapporCohortDeprecated, -1); | |
| 187 registry->RegisterIntegerPref(prefs::kRapporCohortSeed, -1); | |
| 188 metrics::DailyEvent::RegisterPref(registry, prefs::kRapporLastDailySample); | |
| 189 } | |
| 190 | |
| 191 int32_t RapporService::LoadCohort() { | |
| 192 // Ignore and delete old cohort parameter. | |
| 193 pref_service_->ClearPref(prefs::kRapporCohortDeprecated); | |
| 194 | |
| 195 int32_t cohort = pref_service_->GetInteger(prefs::kRapporCohortSeed); | |
| 196 // If the user is already assigned to a valid cohort, we're done. | |
| 197 if (cohort >= 0 && cohort < RapporParameters::kMaxCohorts) | |
| 198 return cohort; | |
| 199 | |
| 200 // This is the first time the client has started the service (or their | |
| 201 // preferences were corrupted). Randomly assign them to a cohort. | |
| 202 cohort = base::RandGenerator(RapporParameters::kMaxCohorts); | |
| 203 DVLOG(2) << "Selected a new Rappor cohort: " << cohort; | |
| 204 pref_service_->SetInteger(prefs::kRapporCohortSeed, cohort); | |
| 205 return cohort; | |
| 206 } | |
| 207 | |
| 208 std::string RapporService::LoadSecret() { | |
| 209 std::string secret; | |
| 210 std::string secret_base64 = pref_service_->GetString(prefs::kRapporSecret); | |
| 211 if (!secret_base64.empty()) { | |
| 212 bool decoded = base::Base64Decode(secret_base64, &secret); | |
| 213 if (decoded && secret.size() == HmacByteVectorGenerator::kEntropyInputSize) | |
| 214 return secret; | |
| 215 // If the preference fails to decode, or is the wrong size, it must be | |
| 216 // corrupt, so continue as though it didn't exist yet and generate a new | |
| 217 // one. | |
| 218 } | |
| 219 | |
| 220 DVLOG(2) << "Generated a new Rappor secret."; | |
| 221 secret = HmacByteVectorGenerator::GenerateEntropyInput(); | |
| 222 base::Base64Encode(secret, &secret_base64); | |
| 223 pref_service_->SetString(prefs::kRapporSecret, secret_base64); | |
| 224 return secret; | |
| 225 } | |
| 226 | |
| 227 bool RapporService::ExportMetrics(RapporReports* reports) { | 185 bool RapporService::ExportMetrics(RapporReports* reports) { |
| 228 if (metrics_map_.empty()) { | 186 if (metrics_map_.empty()) { |
| 229 DVLOG(2) << "metrics_map_ is empty."; | 187 DVLOG(2) << "metrics_map_ is empty."; |
| 230 return false; | 188 return false; |
| 231 } | 189 } |
| 232 | 190 |
| 233 DCHECK_GE(cohort_, 0); | 191 DCHECK_GE(cohort_, 0); |
| 234 reports->set_cohort(cohort_); | 192 reports->set_cohort(cohort_); |
| 235 | 193 |
| 236 for (std::map<std::string, RapporMetric*>::const_iterator it = | 194 for (std::map<std::string, RapporMetric*>::const_iterator it = |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 DCHECK_EQ(parameters.ToString(), metric->parameters().ToString()); | 252 DCHECK_EQ(parameters.ToString(), metric->parameters().ToString()); |
| 295 return metric; | 253 return metric; |
| 296 } | 254 } |
| 297 | 255 |
| 298 RapporMetric* new_metric = new RapporMetric(metric_name, parameters, cohort_); | 256 RapporMetric* new_metric = new RapporMetric(metric_name, parameters, cohort_); |
| 299 metrics_map_[metric_name] = new_metric; | 257 metrics_map_[metric_name] = new_metric; |
| 300 return new_metric; | 258 return new_metric; |
| 301 } | 259 } |
| 302 | 260 |
| 303 } // namespace rappor | 261 } // namespace rappor |
| OLD | NEW |