OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/prefs/pref_change_reporter.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/compiler_specific.h" | |
11 #include "base/logging.h" | |
12 #include "base/metrics/histogram.h" | |
13 #include "base/prefs/json_pref_store.h" | |
14 #include "base/values.h" | |
15 #include "chrome/browser/prefs/pref_hash_store.h" | |
16 #include "chrome/browser/prefs/pref_hash_tracker.h" | |
17 #include "chrome/common/pref_names.h" | |
18 | |
19 namespace { | |
20 | |
21 // These preferences must be kept in sync with the TrackedPreference enum in | |
22 // tools/metrics/histograms/histograms.xml. To add a new preference, append it | |
23 // to the array and add a corresponding value to the histogram enum. | |
24 const char* kTrackedPrefs[] = { | |
25 prefs::kShowHomeButton, | |
26 prefs::kHomePageIsNewTabPage, | |
27 prefs::kHomePage, | |
28 prefs::kRestoreOnStartup, | |
29 prefs::kURLsToRestoreOnStartup, | |
30 prefs::kExtensionsPref, | |
31 prefs::kGoogleServicesLastUsername, | |
32 prefs::kSearchProviderOverrides, | |
33 prefs::kDefaultSearchProviderSearchURL, | |
34 prefs::kDefaultSearchProviderKeyword, | |
35 prefs::kDefaultSearchProviderName, | |
36 #if !defined(OS_ANDROID) | |
37 prefs::kPinnedTabs, | |
38 #else | |
39 kUnregisteredPreference, | |
gab
2013/11/27 23:43:27
Looks like you forgot to bring over the definition
| |
40 #endif | |
41 prefs::kExtensionKnownDisabled, | |
42 }; | |
43 | |
44 // Observes initialization of and changes to a JsonPrefStore. During | |
45 // initialization, compares loaded values to stored hashes and reports changes | |
46 // using UMA. In response to preference changes, updates stored hashes. | |
47 class PrefStoreObserver : public PrefStore::Observer { | |
48 public: | |
49 virtual ~PrefStoreObserver(); | |
50 | |
51 // Creates a PrefStoreObserver for |pref_store| using |pref_hash_store|. | |
52 static void Observe(JsonPrefStore* pref_store, | |
53 scoped_ptr<PrefHashStore> pref_hash_store); | |
54 | |
55 // PrefStore::Observer implementation. | |
56 virtual void OnPrefValueChanged(const std::string& key) OVERRIDE; | |
57 virtual void OnInitializationCompleted(bool succeeded) OVERRIDE; | |
58 | |
59 private: | |
60 PrefStoreObserver(PrefStore* pref_store, | |
61 scoped_ptr<PrefHashStore> pref_hash_store); | |
62 | |
63 PrefStore* pref_store_; | |
64 // Used during initialization, for detecting changes. | |
65 scoped_ptr<PrefHashStore> pref_hash_store_; | |
66 // Used after initialization, for updating stored hashes. | |
67 scoped_ptr<PrefHashTracker> pref_hash_tracker_; | |
68 | |
69 DISALLOW_COPY_AND_ASSIGN(PrefStoreObserver); | |
70 }; | |
71 | |
72 PrefStoreObserver::~PrefStoreObserver() {} | |
73 | |
74 // static | |
75 void PrefStoreObserver::Observe(JsonPrefStore* pref_store, | |
76 scoped_ptr<PrefHashStore> pref_hash_store) { | |
77 pref_store->AddOwnedObserver( | |
78 scoped_ptr<PrefStore::Observer>( | |
79 new PrefStoreObserver(pref_store, pref_hash_store.Pass()))); | |
80 } | |
81 | |
82 void PrefStoreObserver::OnPrefValueChanged(const std::string& key) { | |
83 const base::Value* value = NULL; | |
84 pref_store_->GetValue(key, &value); | |
85 | |
86 DCHECK(pref_hash_tracker_.get()); | |
87 if (pref_hash_tracker_.get()) | |
88 pref_hash_tracker_->OnPrefValueChanged(key, value); | |
89 } | |
90 | |
91 void PrefStoreObserver::OnInitializationCompleted(bool succeeded) { | |
gab
2013/11/27 23:43:27
I'm not convinced that doing this OnInitialization
erikwright (departed)
2013/11/28 17:48:07
In this case, chrome_pref_service_factory explicit
| |
92 DCHECK(pref_hash_store_.get()); | |
93 if (!pref_hash_store_.get()) | |
94 return; | |
95 | |
96 for (size_t i = 0; i < arraysize(kTrackedPrefs); ++i) { | |
97 // TODO(erikwright): If it's important, have a pointer to the pref_service | |
98 // in order to skip things that aren't registered. | |
gab
2013/11/27 23:43:27
This matters, in particular to handle kUnregistere
| |
99 const base::Value* value = NULL; | |
100 pref_store_->GetValue(kTrackedPrefs[i], &value); | |
101 PrefHashStore::InitializationResult initialization_result = | |
102 pref_hash_store_->InitializeTrackedValue(kTrackedPrefs[i], value); | |
103 | |
104 switch(initialization_result) { | |
105 case PrefHashStore::UNCHANGED: | |
106 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceUnchanged", | |
107 i, arraysize(kTrackedPrefs)); | |
108 break; | |
109 case PrefHashStore::CLEARED: | |
110 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceCleared", | |
111 i, arraysize(kTrackedPrefs)); | |
112 break; | |
113 case PrefHashStore::MIGRATED: | |
114 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceMigrated", | |
115 i, arraysize(kTrackedPrefs)); | |
116 break; | |
117 case PrefHashStore::CHANGED: | |
118 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceChanged", | |
119 i, arraysize(kTrackedPrefs)); | |
120 break; | |
121 case PrefHashStore::INITIALIZED: | |
122 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceInitialized", | |
123 i, arraysize(kTrackedPrefs)); | |
124 break; | |
125 default: | |
126 NOTREACHED() << "Unexpected PrefHashStore::InitializationResult: " | |
127 << initialization_result; | |
128 break; | |
129 } | |
130 } | |
131 | |
132 pref_hash_tracker_ = | |
133 PrefHashStore::CreateTracker(pref_hash_store_.Pass()); | |
134 } | |
135 | |
136 PrefStoreObserver::PrefStoreObserver( | |
137 PrefStore* pref_store, | |
138 scoped_ptr<PrefHashStore> pref_hash_store) | |
139 : pref_store_(pref_store), pref_hash_store_(pref_hash_store.Pass()) {} | |
140 | |
141 } // namespace | |
142 | |
143 void ReportPrefStoreChangesToUMA(JsonPrefStore* pref_store, | |
144 scoped_ptr<PrefHashStore> pref_hash_store) { | |
145 if (pref_hash_store.get()) | |
146 PrefStoreObserver::Observe(pref_store, pref_hash_store.Pass()); | |
147 } | |
OLD | NEW |