Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: chrome/browser/prefs/hashed_pref_store.cc

Issue 90563003: Fix a race condition in preference metric reporting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove old changes. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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/hashed_pref_store.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/values.h"
10 #include "chrome/browser/prefs/pref_hash_store.h"
11 #include "chrome/common/pref_names.h"
12
13 namespace {
14
15 // These preferences must be kept in sync with the TrackedPreference enum in
16 // tools/metrics/histograms/histograms.xml. To add a new preference, append it
17 // to the array and add a corresponding value to the histogram enum.
18 const char* kTrackedPrefs[] = {
19 prefs::kShowHomeButton,
20 prefs::kHomePageIsNewTabPage,
21 prefs::kHomePage,
22 prefs::kRestoreOnStartup,
23 prefs::kURLsToRestoreOnStartup,
24 prefs::kExtensionsPref,
25 prefs::kGoogleServicesLastUsername,
26 prefs::kSearchProviderOverrides,
27 prefs::kDefaultSearchProviderSearchURL,
28 prefs::kDefaultSearchProviderKeyword,
29 prefs::kDefaultSearchProviderName,
30 #if !defined(OS_ANDROID)
31 prefs::kPinnedTabs,
32 #else
33 kUnregisteredPreference,
34 #endif
35 prefs::kExtensionKnownDisabled,
36 };
37
38 } // namespace
39
40 HashedPrefStore::HashedPrefStore(
41 const scoped_refptr<PersistentPrefStore>& pref_store,
42 scoped_ptr<PrefHashStore> pref_hash_store)
43 : internal_observer_(pref_store, pref_hash_store.Pass()) {}
44
45 bool HashedPrefStore::GetMutableValue(const std::string& key,
46 base::Value** result) {
47 return internal_observer_.wrapped_pref_store()->GetMutableValue(key, result);
48 }
49
50 void HashedPrefStore::ReportValueChanged(const std::string& key) {
51 internal_observer_.wrapped_pref_store()->ReportValueChanged(key);
52 }
53
54 void HashedPrefStore::SetValue(const std::string& key, base::Value* value) {
55 internal_observer_.wrapped_pref_store()->SetValue(key, value);
56 }
57
58 void HashedPrefStore::SetValueSilently(const std::string& key,
59 base::Value* value) {
60 internal_observer_.wrapped_pref_store()->SetValueSilently(key, value);
61 }
62
63 void HashedPrefStore::RemoveValue(const std::string& key) {
64 internal_observer_.wrapped_pref_store()->RemoveValue(key);
65 }
66
67 void HashedPrefStore::MarkNeedsEmptyValue(const std::string& key) {
68 internal_observer_.wrapped_pref_store()->MarkNeedsEmptyValue(key);
69 }
70
71 bool HashedPrefStore::ReadOnly() const {
72 return internal_observer_.wrapped_pref_store()->ReadOnly();
73 }
74
75 PersistentPrefStore::PrefReadError HashedPrefStore::GetReadError() const {
76 return internal_observer_.wrapped_pref_store()->GetReadError();
77 }
78
79 PersistentPrefStore::PrefReadError HashedPrefStore::ReadPrefs() {
80 return internal_observer_.wrapped_pref_store()->ReadPrefs();
81 }
82
83 void HashedPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
84 internal_observer_.wrapped_pref_store()->ReadPrefsAsync(error_delegate);
85 }
86
87 void HashedPrefStore::CommitPendingWrite() {
88 internal_observer_.wrapped_pref_store()->CommitPendingWrite();
89 }
90
91 void HashedPrefStore::AddObserver(Observer* observer) {
92 internal_observer_.observers().AddObserver(observer);
93 }
94
95 void HashedPrefStore::RemoveObserver(Observer* observer) {
96 internal_observer_.observers().RemoveObserver(observer);
97 }
98
99 bool HashedPrefStore::HasObservers() const {
100 return internal_observer_.observers().might_have_observers();
101 }
102
103 bool HashedPrefStore::IsInitializationComplete() const {
104 return internal_observer_.wrapped_pref_store()->IsInitializationComplete();
105 }
106
107 bool HashedPrefStore::GetValue(const std::string& key,
108 const base::Value** result) const {
109 return internal_observer_.wrapped_pref_store()->GetValue(key, result);
110 }
111
112 void HashedPrefStore::PrefStoreObserver::OnPrefValueChanged(
113 const std::string& key) {
114 const base::Value* value = NULL;
115 wrapped_pref_store_->GetValue(key, &value);
116
117 pref_hash_store_->OnPrefValueChanged(key, value);
118
119 if (initialized_)
120 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
121 }
122
123 void HashedPrefStore::PrefStoreObserver::OnInitializationCompleted(
124 bool succeeded) {
125 DCHECK(pref_hash_store_.get());
126 if (!pref_hash_store_.get())
127 return;
128
129 if (succeeded) {
130 for (size_t i = 0; i < arraysize(kTrackedPrefs); ++i) {
131 // TODO(erikwright): If it's important, have a pointer to the pref_service
132 // in order to skip things that aren't registered.
133 const base::Value* value = NULL;
134 wrapped_pref_store_->GetValue(kTrackedPrefs[i], &value);
135 PrefHashStore::InitializationResult initialization_result =
136 pref_hash_store_->InitializeTrackedValue(kTrackedPrefs[i], value);
137
138 switch (initialization_result) {
139 case PrefHashStore::UNCHANGED:
140 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceUnchanged",
141 i, arraysize(kTrackedPrefs));
142 break;
143 case PrefHashStore::CLEARED:
144 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceCleared",
145 i, arraysize(kTrackedPrefs));
146 break;
147 case PrefHashStore::MIGRATED:
148 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceMigrated",
149 i, arraysize(kTrackedPrefs));
150 break;
151 case PrefHashStore::CHANGED:
152 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceChanged",
153 i, arraysize(kTrackedPrefs));
154 break;
155 case PrefHashStore::INITIALIZED:
156 UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceInitialized",
157 i, arraysize(kTrackedPrefs));
158 break;
159 default:
160 NOTREACHED() << "Unexpected PrefHashStore::InitializationResult: "
161 << initialization_result;
162 break;
163 }
164 }
165 }
166
167 initialized_ = true;
168 FOR_EACH_OBSERVER(PrefStore::Observer,
169 observers_,
170 OnInitializationCompleted(succeeded));
171 }
172
173 HashedPrefStore::PrefStoreObserver::PrefStoreObserver(
174 const scoped_refptr<PersistentPrefStore>& wrapped_pref_store,
175 scoped_ptr<PrefHashStore> pref_hash_store)
176 : initialized_(false),
177 wrapped_pref_store_(wrapped_pref_store),
178 pref_hash_store_(pref_hash_store.Pass()) {
179 wrapped_pref_store_->AddObserver(this);
180 }
181
182 HashedPrefStore::PrefStoreObserver::~PrefStoreObserver() {
183 wrapped_pref_store_->RemoveObserver(this);
184 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698