cloned_install_detector.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/metrics/cloned_install_detector.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/bind.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/location.h" 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/metrics/histogram.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/prefs/pref_registry_simple.h" 11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/prefs/pref_service.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/single_thread_task_runner.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/task_runner_util.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/metrics/cloned_install_detector.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/metrics/machine_id_provider.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/metrics/metrics_hashes.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/metrics/metrics_pref_names.h" 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace metrics { 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace { 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochuint32 HashRawId(const std::string& value) { 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uint64 hash = metrics::HashMetricName(value); 25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Only use 24 bits from the 64-bit hash. 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return hash & ((1 << 24) - 1); 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// State of the generated machine id in relation to the previously stored value. 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Note: UMA histogram enum - don't re-order or remove entries 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochenum MachineIdState { 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ID_GENERATION_FAILED, 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ID_NO_STORED_VALUE, 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ID_CHANGED, 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ID_UNCHANGED, 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ID_ENUM_SIZE 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Logs the state of generating a machine id and comparing it to a stored value. 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LogMachineIdState(MachineIdState state) { 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION("UMA.MachineIdState", state, ID_ENUM_SIZE); 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 47effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochClonedInstallDetector::ClonedInstallDetector(MachineIdProvider* raw_id_provider) 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : raw_id_provider_(raw_id_provider), weak_ptr_factory_(this) { 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ClonedInstallDetector::~ClonedInstallDetector() { 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ClonedInstallDetector::CheckForClonedInstall( 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state, 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> task_runner) { 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PostTaskAndReplyWithResult( 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) task_runner.get(), 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&metrics::MachineIdProvider::GetMachineId, raw_id_provider_), 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&metrics::ClonedInstallDetector::SaveMachineId, 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch local_state)); 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ClonedInstallDetector::SaveMachineId(PrefService* local_state, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string raw_id) { 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (raw_id.empty()) { 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogMachineIdState(ID_GENERATION_FAILED); 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch local_state->ClearPref(prefs::kMetricsMachineId); 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int hashed_id = HashRawId(raw_id); 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MachineIdState id_state = ID_NO_STORED_VALUE; 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (local_state->HasPrefPath(prefs::kMetricsMachineId)) { 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (local_state->GetInteger(prefs::kMetricsMachineId) != hashed_id) { 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch id_state = ID_CHANGED; 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(jwd): Use a callback to set the reset pref. That way 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // ClonedInstallDetector doesn't need to know about this pref. 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch local_state->SetBoolean(prefs::kMetricsResetIds, true); 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch id_state = ID_UNCHANGED; 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogMachineIdState(id_state); 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch local_state->SetInteger(prefs::kMetricsMachineId, hashed_id); 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ClonedInstallDetector::RegisterPrefs(PrefRegistrySimple* registry) { 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch registry->RegisterIntegerPref(prefs::kMetricsMachineId, 0); 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace metrics 99