Chromium Code Reviews| Index: components/metrics/metrics_state_manager.cc |
| diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc |
| index 3b71976581b30d789d37c05ea2f0cb1d86bfa658..60d1c665f083cfd633c9c770a7945a6aa9181c84 100644 |
| --- a/components/metrics/metrics_state_manager.cc |
| +++ b/components/metrics/metrics_state_manager.cc |
| @@ -45,9 +45,13 @@ bool MetricsStateManager::instance_exists_ = false; |
| MetricsStateManager::MetricsStateManager( |
| PrefService* local_state, |
| - const base::Callback<bool(void)>& is_reporting_enabled_callback) |
| + const base::Callback<bool(void)>& is_reporting_enabled_callback, |
| + const SaveClientInfoCallback& save_client_info, |
| + const RetrieveClientInfoCallback& retrieve_client_info) |
| : local_state_(local_state), |
| is_reporting_enabled_callback_(is_reporting_enabled_callback), |
| + save_client_info_(save_client_info), |
| + retrieve_client_info_(retrieve_client_info), |
| low_entropy_source_(kLowEntropySourceNotSet), |
| entropy_source_returned_(ENTROPY_SOURCE_NONE) { |
| ResetMetricsIDsIfNecessary(); |
| @@ -72,9 +76,46 @@ void MetricsStateManager::ForceClientIdCreation() { |
| return; |
| client_id_ = local_state_->GetString(prefs::kMetricsClientID); |
| - if (!client_id_.empty()) |
| + if (!client_id_.empty()) { |
| + // It is technically sufficient to only save a backup of the client id when |
| + // it is initially generated below, but since the backup was only introduced |
| + // in M38, seed it explicitly from here for some time. |
| + const int64 installation_date = local_state_->GetInt64(prefs::kInstallDate); |
| + save_client_info_.Run(client_id_, installation_date); |
| return; |
| + } |
| + std::string client_id_backup; |
| + int64 installation_date_backup = 0; |
| + if (retrieve_client_info_.Run(&client_id_backup, &installation_date_backup) && |
| + !client_id_backup.empty()) { |
| + client_id_ = client_id_backup; |
| + |
| + const base::Time now(base::Time::Now()); |
| + if (installation_date_backup == 0) |
| + installation_date_backup = now.ToTimeT(); |
| + // Save the recovered client id and set the install date to match the |
| + // recovered client id in order to avoid weird scenarios where we could |
| + // report an old client id with a recent install date. |
| + local_state_->SetString(prefs::kMetricsClientID, client_id_); |
| + local_state_->SetInt64(prefs::kInstallDate, installation_date_backup); |
| + local_state_->SetInt64(prefs::kMetricsReportingEnabledTimestamp, |
| + now.ToTimeT()); |
| + |
| + base::TimeDelta recovered_installation_age; |
| + if (installation_date_backup != 0) { |
|
Ilya Sherman
2014/07/08 01:10:22
Given lines 95-96, I don't think this check does a
|
| + recovered_installation_age = |
| + now - base::Time::FromTimeT(installation_date_backup); |
| + } |
| + UMA_HISTOGRAM_CUSTOM_TIMES("UMA.ClientIdBackupRecoveredWithAge", |
| + recovered_installation_age, |
| + base::TimeDelta::FromHours(0), |
| + base::TimeDelta::FromDays(365), |
| + 100); |
| + return; |
| + } |
| + |
| + // Failing attempts at getting an existing client ID, generate a new one. |
| client_id_ = base::GenerateGUID(); |
| local_state_->SetString(prefs::kMetricsClientID, client_id_); |
| @@ -86,6 +127,9 @@ void MetricsStateManager::ForceClientIdCreation() { |
| UMA_HISTOGRAM_BOOLEAN("UMA.ClientIdMigrated", true); |
| } |
| local_state_->ClearPref(prefs::kMetricsOldClientID); |
| + |
| + const int64 installation_date = local_state_->GetInt64(prefs::kInstallDate); |
| + save_client_info_.Run(client_id_, installation_date); |
| } |
| void MetricsStateManager::CheckForClonedInstall( |
| @@ -141,12 +185,16 @@ MetricsStateManager::CreateEntropyProvider() { |
| // static |
| scoped_ptr<MetricsStateManager> MetricsStateManager::Create( |
| PrefService* local_state, |
| - const base::Callback<bool(void)>& is_reporting_enabled_callback) { |
| + const base::Callback<bool(void)>& is_reporting_enabled_callback, |
| + const SaveClientInfoCallback& save_client_info, |
| + const RetrieveClientInfoCallback& retrieve_client_info) { |
| scoped_ptr<MetricsStateManager> result; |
| // Note: |instance_exists_| is updated in the constructor and destructor. |
| if (!instance_exists_) { |
| - result.reset( |
| - new MetricsStateManager(local_state, is_reporting_enabled_callback)); |
| + result.reset(new MetricsStateManager(local_state, |
| + is_reporting_enabled_callback, |
| + save_client_info, |
| + retrieve_client_info)); |
| } |
| return result.Pass(); |
| } |