OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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())); | |
Mattias Nissler (ping if slow)
2011/05/10 11:27:50
It seems like this ReadErrorHandler instance gets
altimofeev
2011/05/10 12:01:18
Excuse me, but I didn't get you.
ReadPrefsAsync ow
Mattias Nissler (ping if slow)
2011/05/10 12:16:41
I'm not talking about the ReadErrorDelegate, but t
altimofeev
2011/05/10 14:24:19
ReadErrorDelegate is an interface which is impleme
Mattias Nissler (ping if slow)
2011/05/10 14:43:54
Ah, sorry, I didn't realize ReadPrefAsync takes ow
| |
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 Loading... | |
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 } |
OLD | NEW |