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 rappor::internal::LoadCohort(pref_service_), |
Alexei Svitkine (slow)
2015/01/14 17:29:06
Nit: No rappor:: prefix.
Steven Holte
2015/01/14 21:12:16
Done.
| |
110 LoadSecret()); | 107 rappor::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 rappor::internal::RegisterPrefs(registry); | |
Alexei Svitkine (slow)
2015/01/14 17:29:06
Ditto.
Steven Holte
2015/01/14 21:12:16
Done.
| |
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 |