1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#ifndef COMPONENTS_METRICS_METRICS_STATE_MANAGER_H_ 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define COMPONENTS_METRICS_METRICS_STATE_MANAGER_H_ 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string> 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/basictypes.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/gtest_prod_util.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/macros.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/metrics/field_trial.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/metrics/client_info.h" 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class PrefService; 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class PrefRegistrySimple; 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace metrics { 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ClonedInstallDetector; 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Responsible for managing MetricsService state prefs, specifically the UMA 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// client id and low entropy source. Code outside the metrics directory should 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// not be instantiating or using this class directly. 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class MetricsStateManager { 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // A callback that can be invoked to store client info to persistent storage. 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Storing an empty client_id will resulted in the backup being voided. 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef base::Callback<void(const ClientInfo& client_info)> 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StoreClientInfoCallback; 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // A callback that can be invoked to load client info stored through the 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // StoreClientInfoCallback. 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef base::Callback<scoped_ptr<ClientInfo>(void)> LoadClientInfoCallback; 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~MetricsStateManager(); 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns true if the user opted in to sending metric reports. 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool IsMetricsReportingEnabled(); 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns the client ID for this client, or the empty string if the user is 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // not opted in to metrics reporting. 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& client_id() const { return client_id_; } 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Forces the client ID to be generated. This is useful in case it's needed 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // before recording. 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void ForceClientIdCreation(); 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Checks if this install was cloned or imaged from another machine. If a 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // clone is detected, resets the client id and low entropy source. This 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // should not be called more than once. 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CheckForClonedInstall( 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> task_runner); 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns the preferred entropy provider used to seed persistent activities 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // based on whether or not metrics reporting is permitted on this client. 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If metrics reporting is enabled, this method returns an entropy provider 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // that has a high source of entropy, partially based on the client ID. 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Otherwise, it returns an entropy provider that is based on a low entropy 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // source. 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<const base::FieldTrial::EntropyProvider> CreateEntropyProvider(); 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Creates the MetricsStateManager, enforcing that only a single instance 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // of the class exists at a time. Returns NULL if an instance exists already. 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static scoped_ptr<MetricsStateManager> Create( 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state, 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Callback<bool(void)>& is_reporting_enabled_callback, 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const StoreClientInfoCallback& store_client_info, 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const LoadClientInfoCallback& load_client_info); 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Registers local state prefs used by this class. 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static void RegisterPrefs(PrefRegistrySimple* registry); 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private: 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, EntropySourceUsed_Low); 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, EntropySourceUsed_High); 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, LowEntropySource0NotReset); 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PermutedEntropyCacheClearedWhenLowEntropyReset); 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ResetMetricsIDs); 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Designates which entropy source was returned from this class. 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // This is used for testing to validate that we return the correct source 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // depending on the state of the service. 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) enum EntropySourceType { 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ENTROPY_SOURCE_NONE, 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ENTROPY_SOURCE_LOW, 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ENTROPY_SOURCE_HIGH, 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Creates the MetricsStateManager with the given |local_state|. Calls 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |is_reporting_enabled_callback| to query whether metrics reporting is 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // enabled. Clients should instead use Create(), which enforces that a single 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // instance of this class be alive at any given time. 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |store_client_info| should back up client info to persistent storage such 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // that it is later retrievable by |load_client_info|. 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsStateManager( 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state, 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Callback<bool(void)>& is_reporting_enabled_callback, 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const StoreClientInfoCallback& store_client_info, 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const LoadClientInfoCallback& load_client_info); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Backs up the current client info via |store_client_info_|. 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void BackUpCurrentClientInfo(); 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Loads the client info via |load_client_info_| and potentially migrates it 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // before returning it if it comes back in its old form. 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ClientInfo> LoadClientInfoAndMaybeMigrate(); 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns the low entropy source for this client. This is a random value 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // that is non-identifying amongst browser clients. This method will 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // generate the entropy source value if it has not been called before. 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int GetLowEntropySource(); 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns the first entropy source that was returned by this service since 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // start up, or NONE if neither was returned yet. This is exposed for testing 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // only. 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EntropySourceType entropy_source_returned() const { 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return entropy_source_returned_; 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Reset the client id and low entropy source if the kMetricsResetMetricIDs 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // pref is true. 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void ResetMetricsIDsIfNecessary(); 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Whether an instance of this class exists. Used to enforce that there aren't 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // multiple instances of this class at a given time. 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static bool instance_exists_; 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Weak pointer to the local state prefs store. 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* const local_state_; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // A callback run by this MetricsStateManager to know whether reporting is 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // enabled. 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::Callback<bool(void)> is_reporting_enabled_callback_; 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // A callback run during client id creation so this MetricsStateManager can 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // store a backup of the newly generated ID. 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const StoreClientInfoCallback store_client_info_; 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // A callback run if this MetricsStateManager can't get the client id from 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // its typical location and wants to attempt loading it from this backup. 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const LoadClientInfoCallback load_client_info_; 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The identifier that's sent to the server with the log reports. 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string client_id_; 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The non-identifying low entropy source value. 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int low_entropy_source_; 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The last entropy source returned by this service, used for testing. 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EntropySourceType entropy_source_returned_; 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<ClonedInstallDetector> cloned_install_detector_; 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MetricsStateManager); 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace metrics 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif // COMPONENTS_METRICS_METRICS_STATE_MANAGER_H_ 166