| 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..3fe2f176f82edae86d126c5aee5c5eaf13168b20 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 StoreClientInfoCallback& store_client_info,
|
| + const LoadClientInfoCallback& retrieve_client_info)
|
| : local_state_(local_state),
|
| is_reporting_enabled_callback_(is_reporting_enabled_callback),
|
| + store_client_info_(store_client_info),
|
| + load_client_info_(retrieve_client_info),
|
| low_entropy_source_(kLowEntropySourceNotSet),
|
| entropy_source_returned_(ENTROPY_SOURCE_NONE) {
|
| ResetMetricsIDsIfNecessary();
|
| @@ -72,9 +76,52 @@ 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.
|
| + BackupCurrentClientInfo();
|
| + return;
|
| + }
|
| +
|
| + scoped_ptr<ClientInfo> client_info_backup = load_client_info_.Run();
|
| + if (client_info_backup) {
|
| + client_id_ = client_info_backup->client_id;
|
| +
|
| + const base::Time now(base::Time::Now());
|
| +
|
| + // Save the recovered client id and also try to reinstantiate the backup
|
| + // values for the dates corresponding with that 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,
|
| + client_info_backup->installation_date ?
|
| + client_info_backup->installation_date :
|
| + now.ToTimeT());
|
| + local_state_->SetInt64(prefs::kMetricsReportingEnabledTimestamp,
|
| + client_info_backup->reporting_enabled_date ?
|
| + client_info_backup->reporting_enabled_date :
|
| + now.ToTimeT());
|
| +
|
| + base::TimeDelta recovered_installation_age;
|
| + if (client_info_backup->installation_date != 0) {
|
| + recovered_installation_age =
|
| + now - base::Time::FromTimeT(client_info_backup->installation_date);
|
| + }
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("UMA.ClientIdBackupRecoveredWithAge",
|
| + recovered_installation_age,
|
| + base::TimeDelta::FromHours(0),
|
| + base::TimeDelta::FromDays(365),
|
| + 100);
|
| +
|
| + // Flush the backup back to persistent storage in case we re-generated
|
| + // missing data above.
|
| + BackupCurrentClientInfo();
|
| 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 +133,8 @@ void MetricsStateManager::ForceClientIdCreation() {
|
| UMA_HISTOGRAM_BOOLEAN("UMA.ClientIdMigrated", true);
|
| }
|
| local_state_->ClearPref(prefs::kMetricsOldClientID);
|
| +
|
| + BackupCurrentClientInfo();
|
| }
|
|
|
| void MetricsStateManager::CheckForClonedInstall(
|
| @@ -141,12 +190,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 StoreClientInfoCallback& store_client_info,
|
| + const LoadClientInfoCallback& 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,
|
| + store_client_info,
|
| + retrieve_client_info));
|
| }
|
| return result.Pass();
|
| }
|
| @@ -168,6 +221,15 @@ void MetricsStateManager::RegisterPrefs(PrefRegistrySimple* registry) {
|
| registry->RegisterIntegerPref(prefs::kMetricsOldLowEntropySource, 0);
|
| }
|
|
|
| +void MetricsStateManager::BackupCurrentClientInfo() {
|
| + ClientInfo client_info;
|
| + client_info.client_id = client_id_;
|
| + client_info.installation_date = local_state_->GetInt64(prefs::kInstallDate);
|
| + client_info.reporting_enabled_date =
|
| + local_state_->GetInt64(prefs::kMetricsReportingEnabledTimestamp);
|
| + store_client_info_.Run(client_info);
|
| +}
|
| +
|
| int MetricsStateManager::GetLowEntropySource() {
|
| // Note that the default value for the low entropy source and the default pref
|
| // value are both kLowEntropySourceNotSet, which is used to identify if the
|
|
|