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

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

Issue 6894020: Adds async interface method to PersistentPrefStore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 2010->2011 Created 9 years, 7 months 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
« no previous file with comments | « chrome/browser/prefs/pref_service.h ('k') | chrome/browser/prefs/pref_service_mock_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prefs/pref_service.h" 5 #include "chrome/browser/prefs/pref_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 NOTREACHED() << 72 NOTREACHED() <<
73 "list and dictionary types cannot have default locale values"; 73 "list and dictionary types cannot have default locale values";
74 } 74 }
75 } 75 }
76 NOTREACHED(); 76 NOTREACHED();
77 return Value::CreateNullValue(); 77 return Value::CreateNullValue();
78 } 78 }
79 79
80 // Forwards a notification after a PostMessage so that we can wait for the 80 // Forwards a notification after a PostMessage so that we can wait for the
81 // MessageLoop to run. 81 // MessageLoop to run.
82 void NotifyReadError(PrefService* pref, int message_id) { 82 void NotifyReadError(int message_id) {
83 ShowProfileErrorDialog(message_id); 83 ShowProfileErrorDialog(message_id);
84 } 84 }
85 85
86 // Shows notifications which correspond to PersistentPrefStore's reading errors.
87 class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
88 public:
89 virtual void OnError(PersistentPrefStore::PrefReadError error) {
90 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
91 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
92 // an example problem that this can cause.
93 // Do some diagnosis and try to avoid losing data.
94 int message_id = 0;
95 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
96 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
97 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
98 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
99 }
100
101 if (message_id) {
102 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
103 NewRunnableFunction(&NotifyReadError, message_id));
104 }
105 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20);
106 }
107 }
108 };
109
86 } // namespace 110 } // namespace
87 111
88 // static 112 // static
89 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, 113 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
90 PrefStore* extension_prefs, 114 PrefStore* extension_prefs,
91 Profile* profile) { 115 Profile* profile,
92 return CreatePrefServiceAsync(pref_filename, extension_prefs, profile, NULL); 116 bool async) {
93 }
94
95 // static
96 PrefService* PrefService::CreatePrefServiceAsync(
97 const FilePath& pref_filename,
98 PrefStore* extension_prefs,
99 Profile* profile,
100 PrefServiceDelegate* delegate) {
101 using policy::ConfigurationPolicyPrefStore; 117 using policy::ConfigurationPolicyPrefStore;
102 118
103 #if defined(OS_LINUX) 119 #if defined(OS_LINUX)
104 // We'd like to see what fraction of our users have the preferences 120 // We'd like to see what fraction of our users have the preferences
105 // stored on a network file system, as we've had no end of troubles 121 // stored on a network file system, as we've had no end of troubles
106 // with NFS/AFS. 122 // with NFS/AFS.
107 // TODO(evanm): remove this once we've collected state. 123 // TODO(evanm): remove this once we've collected state.
108 file_util::FileSystemType fstype; 124 file_util::FileSystemType fstype;
109 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) { 125 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
110 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType", 126 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
(...skipping 11 matching lines...) Expand all
122 JsonPrefStore* user = new JsonPrefStore( 138 JsonPrefStore* user = new JsonPrefStore(
123 pref_filename, 139 pref_filename,
124 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 140 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
125 ConfigurationPolicyPrefStore* recommended_platform = 141 ConfigurationPolicyPrefStore* recommended_platform =
126 ConfigurationPolicyPrefStore::CreateRecommendedPlatformPolicyPrefStore(); 142 ConfigurationPolicyPrefStore::CreateRecommendedPlatformPolicyPrefStore();
127 ConfigurationPolicyPrefStore* recommended_cloud = 143 ConfigurationPolicyPrefStore* recommended_cloud =
128 ConfigurationPolicyPrefStore::CreateRecommendedCloudPolicyPrefStore( 144 ConfigurationPolicyPrefStore::CreateRecommendedCloudPolicyPrefStore(
129 profile); 145 profile);
130 DefaultPrefStore* default_pref_store = new DefaultPrefStore(); 146 DefaultPrefStore* default_pref_store = new DefaultPrefStore();
131 147
132 return new PrefService(managed_platform, managed_cloud, extension_prefs, 148 return new PrefService(
133 command_line, user, recommended_platform, 149 managed_platform, managed_cloud, extension_prefs,
134 recommended_cloud, default_pref_store, delegate); 150 command_line, user, recommended_platform,
151 recommended_cloud, default_pref_store, async);
135 } 152 }
136 153
137 PrefService* PrefService::CreateIncognitoPrefService( 154 PrefService* PrefService::CreateIncognitoPrefService(
138 PrefStore* incognito_extension_prefs) { 155 PrefStore* incognito_extension_prefs) {
139 return new PrefService(*this, incognito_extension_prefs); 156 return new PrefService(*this, incognito_extension_prefs);
140 } 157 }
141 158
142 PrefService::PrefService(PrefStore* managed_platform_prefs, 159 PrefService::PrefService(PrefStore* managed_platform_prefs,
143 PrefStore* managed_cloud_prefs, 160 PrefStore* managed_cloud_prefs,
144 PrefStore* extension_prefs, 161 PrefStore* extension_prefs,
145 PrefStore* command_line_prefs, 162 PrefStore* command_line_prefs,
146 PersistentPrefStore* user_prefs, 163 PersistentPrefStore* user_prefs,
147 PrefStore* recommended_platform_prefs, 164 PrefStore* recommended_platform_prefs,
148 PrefStore* recommended_cloud_prefs, 165 PrefStore* recommended_cloud_prefs,
149 DefaultPrefStore* default_store, 166 DefaultPrefStore* default_store,
150 PrefServiceDelegate* delegate) 167 bool async)
151 : user_pref_store_(user_prefs), 168 : user_pref_store_(user_prefs),
152 default_store_(default_store), 169 default_store_(default_store) {
153 delegate_(delegate) {
154 pref_sync_associator_.reset(new PrefModelAssociator(this)); 170 pref_sync_associator_.reset(new PrefModelAssociator(this));
155 pref_notifier_.reset(new PrefNotifierImpl(this)); 171 pref_notifier_.reset(new PrefNotifierImpl(this));
156 pref_value_store_.reset( 172 pref_value_store_.reset(
157 new PrefValueStore(managed_platform_prefs, 173 new PrefValueStore(managed_platform_prefs,
158 managed_cloud_prefs, 174 managed_cloud_prefs,
159 extension_prefs, 175 extension_prefs,
160 command_line_prefs, 176 command_line_prefs,
161 user_pref_store_, 177 user_pref_store_,
162 recommended_platform_prefs, 178 recommended_platform_prefs,
163 recommended_cloud_prefs, 179 recommended_cloud_prefs,
164 default_store, 180 default_store,
165 pref_sync_associator_.get(), 181 pref_sync_associator_.get(),
166 pref_notifier_.get())); 182 pref_notifier_.get()));
167 InitFromStorage(); 183 InitFromStorage(async);
168 } 184 }
169 185
170 PrefService::PrefService(const PrefService& original, 186 PrefService::PrefService(const PrefService& original,
171 PrefStore* incognito_extension_prefs) 187 PrefStore* incognito_extension_prefs)
172 : user_pref_store_( 188 : user_pref_store_(
173 new OverlayPersistentPrefStore(original.user_pref_store_.get())), 189 new OverlayPersistentPrefStore(original.user_pref_store_.get())),
174 default_store_(original.default_store_.get()), 190 default_store_(original.default_store_.get()) {
175 delegate_(NULL) {
176 // Incognito mode doesn't sync, so no need to create PrefModelAssociator. 191 // Incognito mode doesn't sync, so no need to create PrefModelAssociator.
177 pref_notifier_.reset(new PrefNotifierImpl(this)); 192 pref_notifier_.reset(new PrefNotifierImpl(this));
178 pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize( 193 pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize(
179 NULL, // managed_platform_prefs 194 NULL, // managed_platform_prefs
180 NULL, // managed_cloud_prefs 195 NULL, // managed_cloud_prefs
181 incognito_extension_prefs, 196 incognito_extension_prefs,
182 NULL, // command_line_prefs 197 NULL, // command_line_prefs
183 user_pref_store_.get(), 198 user_pref_store_.get(),
184 NULL, // recommended_platform_prefs 199 NULL, // recommended_platform_prefs
185 NULL, // recommended_cloud_prefs 200 NULL, // recommended_cloud_prefs
186 default_store_.get(), 201 default_store_.get(),
187 NULL, // pref_sync_associator_ 202 NULL, // pref_sync_associator_
188 pref_notifier_.get())); 203 pref_notifier_.get()));
189 InitFromStorage();
190 } 204 }
191 205
192 PrefService::~PrefService() { 206 PrefService::~PrefService() {
193 DCHECK(CalledOnValidThread()); 207 DCHECK(CalledOnValidThread());
194 STLDeleteContainerPointers(prefs_.begin(), prefs_.end()); 208 STLDeleteContainerPointers(prefs_.begin(), prefs_.end());
195 prefs_.clear(); 209 prefs_.clear();
196 210
197 // Reset pointers so accesses after destruction reliably crash. 211 // Reset pointers so accesses after destruction reliably crash.
198 pref_value_store_.reset(); 212 pref_value_store_.reset();
199 user_pref_store_ = NULL; 213 user_pref_store_ = NULL;
200 default_store_ = NULL; 214 default_store_ = NULL;
201 if (pref_sync_associator_.get()) 215 if (pref_sync_associator_.get())
202 pref_sync_associator_->DisassociateModels(); 216 pref_sync_associator_->DisassociateModels();
203 pref_sync_associator_.reset(); 217 pref_sync_associator_.reset();
204 } 218 }
205 219
206 void PrefService::OnPrefsRead(PersistentPrefStore::PrefReadError error, 220 void PrefService::InitFromStorage(bool async) {
207 bool no_dir) { 221 if (!async) {
208 if (no_dir) { 222 ReadErrorHandler error_handler;
209 // Bad news. When profile is created, the process that creates the directory 223 error_handler.OnError(user_pref_store_->ReadPrefs());
210 // is explicitly started. So if directory is missing it probably means that
211 // Chromium hasn't sufficient privileges.
212 CHECK(delegate_);
213 delegate_->OnPrefsLoaded(this, false);
214 return;
215 }
216
217 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
218 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
219 // an example problem that this can cause.
220 // Do some diagnosis and try to avoid losing data.
221 int message_id = 0;
222 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
223 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
224 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
225 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
226 }
227
228 if (message_id) {
229 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
230 NewRunnableFunction(&NotifyReadError, this, message_id));
231 }
232 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20);
233 }
234
235 if (delegate_)
236 delegate_->OnPrefsLoaded(this, true);
237 }
238
239 void PrefService::InitFromStorage() {
240 if (!delegate_) {
241 const PersistentPrefStore::PrefReadError error =
242 user_pref_store_->ReadPrefs();
243 OnPrefsRead(error, false);
244 } else { 224 } else {
245 // todo(altimofeev): move this method to PersistentPrefStore interface. 225 // Guarantee that initialization happens after this function returned.
246 (static_cast<JsonPrefStore*>(user_pref_store_.get()))->ReadPrefs(this); 226 MessageLoop::current()->PostTask(
227 FROM_HERE,
228 NewRunnableMethod(user_pref_store_.get(),
229 &PersistentPrefStore::ReadPrefsAsync,
230 new ReadErrorHandler()));
247 } 231 }
248 } 232 }
249 233
250 bool PrefService::ReloadPersistentPrefs() { 234 bool PrefService::ReloadPersistentPrefs() {
251 return user_pref_store_->ReadPrefs() == 235 return user_pref_store_->ReadPrefs() ==
252 PersistentPrefStore::PREF_READ_ERROR_NONE; 236 PersistentPrefStore::PREF_READ_ERROR_NONE;
253 } 237 }
254 238
255 bool PrefService::SavePersistentPrefs() { 239 bool PrefService::SavePersistentPrefs() {
256 DCHECK(CalledOnValidThread()); 240 DCHECK(CalledOnValidThread());
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str()); 894 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str());
911 } 895 }
912 896
913 bool PrefService::Preference::IsUserModifiable() const { 897 bool PrefService::Preference::IsUserModifiable() const {
914 return pref_value_store()->PrefValueUserModifiable(name_.c_str()); 898 return pref_value_store()->PrefValueUserModifiable(name_.c_str());
915 } 899 }
916 900
917 bool PrefService::Preference::IsExtensionModifiable() const { 901 bool PrefService::Preference::IsExtensionModifiable() const {
918 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str()); 902 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str());
919 } 903 }
OLDNEW
« no previous file with comments | « chrome/browser/prefs/pref_service.h ('k') | chrome/browser/prefs/pref_service_mock_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698