123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/metrics/cloned_install_detector.h"
- #include <stdint.h>
- #include <string>
- #include "base/bind.h"
- #include "base/location.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/metrics/metrics_hashes.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/task/task_runner_util.h"
- #include "base/task/thread_pool.h"
- #include "components/metrics/machine_id_provider.h"
- #include "components/metrics/metrics_pref_names.h"
- #include "components/prefs/pref_registry_simple.h"
- #include "components/prefs/pref_service.h"
- namespace metrics {
- namespace {
- uint32_t HashRawId(const std::string& value) {
- uint64_t hash = base::HashMetricName(value);
- // Only use 24 bits from the 64-bit hash.
- return hash & ((1 << 24) - 1);
- }
- // State of the generated machine id in relation to the previously stored value.
- // Note: UMA histogram enum - don't re-order or remove entries
- enum MachineIdState {
- ID_GENERATION_FAILED,
- ID_NO_STORED_VALUE,
- ID_CHANGED,
- ID_UNCHANGED,
- ID_ENUM_SIZE
- };
- // Logs the state of generating a machine id and comparing it to a stored value.
- void LogMachineIdState(MachineIdState state) {
- UMA_HISTOGRAM_ENUMERATION("UMA.MachineIdState", state, ID_ENUM_SIZE);
- }
- } // namespace
- ClonedInstallDetector::ClonedInstallDetector() {}
- ClonedInstallDetector::~ClonedInstallDetector() {
- }
- void ClonedInstallDetector::CheckForClonedInstall(PrefService* local_state) {
- if (!MachineIdProvider::HasId())
- return;
- base::ThreadPool::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- base::BindOnce(&MachineIdProvider::GetMachineId),
- base::BindOnce(&ClonedInstallDetector::SaveMachineId,
- weak_ptr_factory_.GetWeakPtr(), local_state));
- }
- void ClonedInstallDetector::SaveMachineId(PrefService* local_state,
- const std::string& raw_id) {
- if (raw_id.empty()) {
- LogMachineIdState(ID_GENERATION_FAILED);
- local_state->ClearPref(prefs::kMetricsMachineId);
- return;
- }
- int hashed_id = HashRawId(raw_id);
- MachineIdState id_state = ID_NO_STORED_VALUE;
- if (local_state->HasPrefPath(prefs::kMetricsMachineId)) {
- if (local_state->GetInteger(prefs::kMetricsMachineId) != hashed_id) {
- id_state = ID_CHANGED;
- detected_this_session_ = true;
- local_state->SetBoolean(prefs::kMetricsResetIds, true);
- } else {
- id_state = ID_UNCHANGED;
- }
- }
- LogMachineIdState(id_state);
- local_state->SetInteger(prefs::kMetricsMachineId, hashed_id);
- }
- bool ClonedInstallDetector::ShouldResetClientIds(PrefService* local_state) {
- // The existence of the pref indicates that it has been set when we saved the
- // MachineId and thus we need to update the member variable for this session
- // and clear the pref for future runs. We shouldn't clear the pref multiple
- // times because it may have been cloned again.
- if (!should_reset_client_ids_ &&
- local_state->HasPrefPath(prefs::kMetricsResetIds)) {
- should_reset_client_ids_ = local_state->GetBoolean(prefs::kMetricsResetIds);
- local_state->ClearPref(prefs::kMetricsResetIds);
- }
- return should_reset_client_ids_;
- }
- bool ClonedInstallDetector::ClonedInstallDetectedInCurrentSession() const {
- return detected_this_session_;
- }
- // static
- void ClonedInstallDetector::RegisterPrefs(PrefRegistrySimple* registry) {
- registry->RegisterBooleanPref(prefs::kMetricsResetIds, false);
- registry->RegisterIntegerPref(prefs::kMetricsMachineId, 0);
- registry->RegisterIntegerPref(prefs::kClonedResetCount, 0);
- registry->RegisterInt64Pref(prefs::kFirstClonedResetTimestamp, 0);
- registry->RegisterInt64Pref(prefs::kLastClonedResetTimestamp, 0);
- }
- ClonedInstallInfo ClonedInstallDetector::ReadClonedInstallInfo(
- PrefService* local_state) {
- return ClonedInstallInfo{
- .last_reset_timestamp =
- local_state->GetInt64(prefs::kLastClonedResetTimestamp),
- .first_reset_timestamp =
- local_state->GetInt64(prefs::kFirstClonedResetTimestamp),
- .reset_count = local_state->GetInteger(prefs::kClonedResetCount)};
- }
- void ClonedInstallDetector::ClearClonedInstallInfo(PrefService* local_state) {
- local_state->ClearPref(prefs::kClonedResetCount);
- local_state->ClearPref(prefs::kFirstClonedResetTimestamp);
- local_state->ClearPref(prefs::kLastClonedResetTimestamp);
- }
- void ClonedInstallDetector::RecordClonedInstallInfo(PrefService* local_state) {
- ClonedInstallInfo cloned = ReadClonedInstallInfo(local_state);
- // Make sure that at the first time of reset, the first_timestamp matches with
- // the last_timestamp.
- int64_t time = base::Time::Now().ToTimeT();
- // Only set |prefs::kFirstClonedResetTimestamp| when the client needs to be
- // reset due to cloned install for the first time.
- if (cloned.reset_count == 0) {
- local_state->SetInt64(prefs::kFirstClonedResetTimestamp, time);
- }
- local_state->SetInt64(prefs::kLastClonedResetTimestamp, time);
- local_state->SetInteger(prefs::kClonedResetCount, cloned.reset_count + 1);
- }
- } // namespace metrics
|