1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_METRICS_CLONED_INSTALL_DETECTOR_H_
6 #define COMPONENTS_METRICS_CLONED_INSTALL_DETECTOR_H_
8 #include "base/callback_list.h"
9 #include "base/functional/callback_forward.h"
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/weak_ptr.h"
13 class PrefRegistrySimple;
18 // A struct that holds cloned install related fields in prefs that need to be
19 // reported in the system_profile.
20 struct ClonedInstallInfo {
21 int64_t last_reset_timestamp;
22 int64_t first_reset_timestamp;
26 // A class for detecting if an install is cloned. It does this by detecting
27 // when the hardware running Chrome changes.
28 class ClonedInstallDetector {
30 ClonedInstallDetector();
32 ClonedInstallDetector(const ClonedInstallDetector&) = delete;
33 ClonedInstallDetector& operator=(const ClonedInstallDetector&) = delete;
35 virtual ~ClonedInstallDetector();
37 // Posts a task to |task_runner| to generate a machine ID and store it to a
38 // local state pref. If the newly generated ID is different than the
39 // previously stored one, then the install is considered cloned. The ID is a
40 // 24-bit value based off of machine characteristics. This value should never
41 // be sent over the network.
42 void CheckForClonedInstall(PrefService* local_state);
44 static void RegisterPrefs(PrefRegistrySimple* registry);
46 // Reads cloned install info fields from |local_state| and returns them in
47 // a ClonedInstallInfo.
48 static ClonedInstallInfo ReadClonedInstallInfo(PrefService* local_state);
50 // Clears cloned install info fields from |local_state|.
51 static void ClearClonedInstallInfo(PrefService* local_state);
53 // Updates cloned install info fields in |local_state| on reset.
54 static void RecordClonedInstallInfo(PrefService* local_state);
56 // Returns true for the whole session if we detected a cloned install during
57 // the construction of a client id.
58 bool ShouldResetClientIds(PrefService* local_state);
60 // Returns true for the whole session if we detect a cloned install this
62 bool ClonedInstallDetectedInCurrentSession() const;
64 // Adds a callback that is run if this install is detected as cloned during
65 // this session. If this is called after the detection had already occurred,
66 // the callback is run immediately.
67 base::CallbackListSubscription AddOnClonedInstallDetectedCallback(
68 base::OnceClosure callback);
70 // Wrapper around SaveMachineId(). Used for testing in UKM (the tests cannot
71 // be declared as friends since they live in a different namespace).
72 void SaveMachineIdForTesting(PrefService* local_state,
73 const std::string& raw_id);
76 FRIEND_TEST_ALL_PREFIXES(ClonedInstallDetectorTest, SaveId);
77 FRIEND_TEST_ALL_PREFIXES(ClonedInstallDetectorTest, DetectClone);
78 FRIEND_TEST_ALL_PREFIXES(ClonedInstallDetectorTest, ShouldResetClientIds);
79 FRIEND_TEST_ALL_PREFIXES(ClonedInstallDetectorTest,
80 ClonedInstallDetectedInCurrentSession);
81 FRIEND_TEST_ALL_PREFIXES(ClonedInstallDetectorTest,
82 ClonedInstallDetectedCallback);
83 FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, CheckProviderResetIds);
84 FRIEND_TEST_ALL_PREFIXES(MetricsServiceTestWithFeatures,
85 PurgeLogsOnClonedInstallDetected);
87 // Converts raw_id into a 24-bit hash and stores the hash in |local_state|.
88 // |raw_id| is not a const ref because it's passed from a cross-thread post
90 void SaveMachineId(PrefService* local_state, const std::string& raw_id);
92 // Indicates that we detected a cloned install during the current session.
93 bool detected_this_session_ = false;
95 // Indicates that we detected a cloned install during the construction of a
96 // client id and should reset client ids as a result.
97 bool should_reset_client_ids_ = false;
99 base::OnceClosureList callback_list_;
101 base::WeakPtrFactory<ClonedInstallDetector> weak_ptr_factory_{this};
104 } // namespace metrics
106 #endif // COMPONENTS_METRICS_CLONED_INSTALL_DETECTOR_H_