OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/profiles/profile_impl.h" | 5 #include "chrome/browser/profiles/profile_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/environment.h" | 11 #include "base/environment.h" |
12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
16 #include "base/prefs/json_pref_store.h" | |
16 #include "base/string_number_conversions.h" | 17 #include "base/string_number_conversions.h" |
17 #include "base/string_tokenizer.h" | 18 #include "base/string_tokenizer.h" |
18 #include "base/string_util.h" | 19 #include "base/string_util.h" |
19 #include "base/stringprintf.h" | 20 #include "base/stringprintf.h" |
21 #include "base/synchronization/waitable_event.h" | |
22 #include "base/threading/sequenced_worker_pool.h" | |
20 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
21 #include "base/version.h" | 24 #include "base/version.h" |
22 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 25 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |
23 #include "chrome/browser/background/background_contents_service_factory.h" | 26 #include "chrome/browser/background/background_contents_service_factory.h" |
24 #include "chrome/browser/background/background_mode_manager.h" | 27 #include "chrome/browser/background/background_mode_manager.h" |
25 #include "chrome/browser/browser_process.h" | 28 #include "chrome/browser/browser_process.h" |
26 #include "chrome/browser/chrome_plugin_service_filter.h" | 29 #include "chrome/browser/chrome_plugin_service_filter.h" |
27 #include "chrome/browser/content_settings/cookie_settings.h" | 30 #include "chrome/browser/content_settings/cookie_settings.h" |
28 #include "chrome/browser/content_settings/host_content_settings_map.h" | 31 #include "chrome/browser/content_settings/host_content_settings_map.h" |
29 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | 32 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 // not in resources. | 145 // not in resources. |
143 static const char kReadmeText[] = | 146 static const char kReadmeText[] = |
144 "%s settings and storage represent user-selected preferences and " | 147 "%s settings and storage represent user-selected preferences and " |
145 "information and MUST not be extracted, overwritten or modified except " | 148 "information and MUST not be extracted, overwritten or modified except " |
146 "through %s defined APIs."; | 149 "through %s defined APIs."; |
147 | 150 |
148 // Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED. | 151 // Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED. |
149 const char* const kPrefExitTypeCrashed = "Crashed"; | 152 const char* const kPrefExitTypeCrashed = "Crashed"; |
150 const char* const kPrefExitTypeSessionEnded = "SessionEnded"; | 153 const char* const kPrefExitTypeSessionEnded = "SessionEnded"; |
151 | 154 |
155 // Helper method needed because PostTask cannot currently take a Callback | |
156 // function with non-void return type. | |
157 // TODO(jhawkins): Remove once IgnoreResult is fixed. | |
Mattias Nissler (ping if slow)
2012/11/06 09:07:54
Remove this TODO, the signaling no requires a prop
zel
2012/11/06 23:25:54
Done.
| |
158 void CreateDirectoryAndSignal(const FilePath& path, | |
159 base::WaitableEvent* done_creating) { | |
160 DVLOG(1) << "Creating directory " << path.value(); | |
161 file_util::CreateDirectory(path); | |
162 done_creating->Signal(); | |
163 } | |
164 | |
165 // Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on | |
166 // blocking I/O pool. | |
167 void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { | |
168 done_creating->Wait(); | |
169 } | |
170 | |
171 // Initiates creation of profile directory on |sequenced_task_runner| and | |
172 // ensures that FILE thread is blocked until that operation finishes. | |
173 void CreateProfileDirectory(base::SequencedTaskRunner* sequenced_task_runner, | |
174 const FilePath& path) { | |
175 base::WaitableEvent* done_creating = new base::WaitableEvent(false, false); | |
176 sequenced_task_runner->PostTask(FROM_HERE, | |
177 base::Bind(&CreateDirectoryAndSignal, | |
178 path, | |
179 done_creating)); | |
180 // Block the FILE thread until directory is created on I/O pool to make sure | |
181 // that we don't attempt any operation until that part completes. | |
182 BrowserThread::PostTask( | |
183 BrowserThread::FILE, FROM_HERE, | |
184 base::Bind(&BlockFileThreadOnDirectoryCreate, | |
185 base::Owned(done_creating))); | |
186 } | |
187 | |
152 FilePath GetCachePath(const FilePath& base) { | 188 FilePath GetCachePath(const FilePath& base) { |
153 return base.Append(chrome::kCacheDirname); | 189 return base.Append(chrome::kCacheDirname); |
154 } | 190 } |
155 | 191 |
156 FilePath GetMediaCachePath(const FilePath& base) { | 192 FilePath GetMediaCachePath(const FilePath& base) { |
157 return base.Append(chrome::kMediaCacheDirname); | 193 return base.Append(chrome::kMediaCacheDirname); |
158 } | 194 } |
159 | 195 |
160 void EnsureReadmeFile(const FilePath& base) { | 196 void EnsureReadmeFile(const FilePath& base) { |
161 FilePath readme_path = base.Append(chrome::kReadmeFilename); | 197 FilePath readme_path = base.Append(chrome::kReadmeFilename); |
(...skipping 30 matching lines...) Expand all Loading... | |
192 NOTREACHED(); | 228 NOTREACHED(); |
193 return std::string(); | 229 return std::string(); |
194 } | 230 } |
195 | 231 |
196 } // namespace | 232 } // namespace |
197 | 233 |
198 // static | 234 // static |
199 Profile* Profile::CreateProfile(const FilePath& path, | 235 Profile* Profile::CreateProfile(const FilePath& path, |
200 Delegate* delegate, | 236 Delegate* delegate, |
201 CreateMode create_mode) { | 237 CreateMode create_mode) { |
238 // Get sequenced task runner for making sure that file operations of | |
239 // this profile (defined by |path|) are executed in expected order | |
240 // (what was previously assured by the FILE thread). | |
241 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = | |
242 JsonPrefStore::GetTaskRunnerForFile(path, | |
243 BrowserThread::GetBlockingPool()); | |
202 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { | 244 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { |
203 DCHECK(delegate); | 245 DCHECK(delegate); |
204 // This is safe while all file operations are done on the FILE thread. | 246 CreateProfileDirectory(sequenced_task_runner, path); |
205 BrowserThread::PostTask( | |
206 BrowserThread::FILE, FROM_HERE, | |
207 base::Bind(base::IgnoreResult(&file_util::CreateDirectory), path)); | |
208 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { | 247 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { |
209 if (!file_util::PathExists(path)) { | 248 if (!file_util::PathExists(path)) { |
210 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the | 249 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the |
211 // profile directory. We should eventually be able to run in this | 250 // profile directory. We should eventually be able to run in this |
212 // situation. | 251 // situation. |
213 if (!file_util::CreateDirectory(path)) | 252 if (!file_util::CreateDirectory(path)) |
214 return NULL; | 253 return NULL; |
215 } | 254 } |
216 } else { | 255 } else { |
217 NOTREACHED(); | 256 NOTREACHED(); |
218 } | 257 } |
219 | 258 |
220 return new ProfileImpl(path, delegate, create_mode); | 259 return new ProfileImpl(path, delegate, create_mode, sequenced_task_runner); |
221 } | 260 } |
222 | 261 |
223 // static | 262 // static |
224 int ProfileImpl::create_readme_delay_ms = 60000; | 263 int ProfileImpl::create_readme_delay_ms = 60000; |
225 | 264 |
226 // static | 265 // static |
227 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; | 266 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; |
228 | 267 |
229 // static | 268 // static |
230 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { | 269 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 prefs->RegisterIntegerPref(prefs::kMediaCacheSize, | 302 prefs->RegisterIntegerPref(prefs::kMediaCacheSize, |
264 0, | 303 0, |
265 PrefService::UNSYNCABLE_PREF); | 304 PrefService::UNSYNCABLE_PREF); |
266 | 305 |
267 // Deprecated. Kept around for migration. | 306 // Deprecated. Kept around for migration. |
268 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, | 307 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, |
269 false, | 308 false, |
270 PrefService::SYNCABLE_PREF); | 309 PrefService::SYNCABLE_PREF); |
271 } | 310 } |
272 | 311 |
273 ProfileImpl::ProfileImpl(const FilePath& path, | 312 ProfileImpl::ProfileImpl( |
274 Delegate* delegate, | 313 const FilePath& path, |
275 CreateMode create_mode) | 314 Delegate* delegate, |
315 CreateMode create_mode, | |
316 base::SequencedTaskRunner* sequenced_task_runner) | |
276 : path_(path), | 317 : path_(path), |
277 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), | 318 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), |
278 host_content_settings_map_(NULL), | 319 host_content_settings_map_(NULL), |
279 last_session_exit_type_(EXIT_NORMAL), | 320 last_session_exit_type_(EXIT_NORMAL), |
280 start_time_(Time::Now()), | 321 start_time_(Time::Now()), |
281 delegate_(delegate), | 322 delegate_(delegate), |
282 predictor_(NULL) { | 323 predictor_(NULL) { |
283 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << | 324 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << |
284 "profile files to the root directory!"; | 325 "profile files to the root directory!"; |
285 | 326 |
(...skipping 14 matching lines...) Expand all Loading... | |
300 // TODO(atwilson): Change these to ProfileKeyedServices once PrefService is | 341 // TODO(atwilson): Change these to ProfileKeyedServices once PrefService is |
301 // a ProfileKeyedService (policy must be initialized before PrefService | 342 // a ProfileKeyedService (policy must be initialized before PrefService |
302 // because PrefService depends on policy loading to get overridden pref | 343 // because PrefService depends on policy loading to get overridden pref |
303 // values). | 344 // values). |
304 policy::BrowserPolicyConnector* connector = | 345 policy::BrowserPolicyConnector* connector = |
305 g_browser_process->browser_policy_connector(); | 346 g_browser_process->browser_policy_connector(); |
306 cloud_policy_manager_ = connector->CreateCloudPolicyManager(this); | 347 cloud_policy_manager_ = connector->CreateCloudPolicyManager(this); |
307 if (cloud_policy_manager_) | 348 if (cloud_policy_manager_) |
308 cloud_policy_manager_->Init(); | 349 cloud_policy_manager_->Init(); |
309 managed_mode_policy_provider_.reset( | 350 managed_mode_policy_provider_.reset( |
310 policy::ManagedModePolicyProvider::Create(this)); | 351 policy::ManagedModePolicyProvider::Create(this, sequenced_task_runner)); |
311 managed_mode_policy_provider_->Init(); | 352 managed_mode_policy_provider_->Init(); |
312 policy_service_ = connector->CreatePolicyService(this); | 353 policy_service_ = connector->CreatePolicyService(this); |
313 #else | 354 #else |
314 policy_service_.reset(new policy::PolicyServiceStub()); | 355 policy_service_.reset(new policy::PolicyServiceStub()); |
315 #endif | 356 #endif |
316 | 357 |
317 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { | 358 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { |
318 prefs_.reset(PrefService::CreatePrefService( | 359 prefs_.reset(PrefService::CreatePrefService( |
319 GetPrefFilePath(), | 360 GetPrefFilePath(), |
361 sequenced_task_runner, | |
320 policy_service_.get(), | 362 policy_service_.get(), |
321 new ExtensionPrefStore( | 363 new ExtensionPrefStore( |
322 ExtensionPrefValueMapFactory::GetForProfile(this), false), | 364 ExtensionPrefValueMapFactory::GetForProfile(this), false), |
323 true)); | 365 true)); |
324 // Wait for the notification that prefs has been loaded | 366 // Wait for the notification that prefs has been loaded |
325 // (successfully or not). Note that we can use base::Unretained | 367 // (successfully or not). Note that we can use base::Unretained |
326 // because the PrefService is owned by this class and lives on | 368 // because the PrefService is owned by this class and lives on |
327 // the same thread. | 369 // the same thread. |
328 prefs_->AddPrefInitObserver(base::Bind(&ProfileImpl::OnPrefsLoaded, | 370 prefs_->AddPrefInitObserver(base::Bind(&ProfileImpl::OnPrefsLoaded, |
329 base::Unretained(this))); | 371 base::Unretained(this))); |
330 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { | 372 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { |
331 // Load prefs synchronously. | 373 // Load prefs synchronously. |
332 prefs_.reset(PrefService::CreatePrefService( | 374 prefs_.reset(PrefService::CreatePrefService( |
333 GetPrefFilePath(), | 375 GetPrefFilePath(), |
376 sequenced_task_runner, | |
334 policy_service_.get(), | 377 policy_service_.get(), |
335 new ExtensionPrefStore( | 378 new ExtensionPrefStore( |
336 ExtensionPrefValueMapFactory::GetForProfile(this), false), | 379 ExtensionPrefValueMapFactory::GetForProfile(this), false), |
337 false)); | 380 false)); |
338 OnPrefsLoaded(true); | 381 OnPrefsLoaded(true); |
339 } else { | 382 } else { |
340 NOTREACHED(); | 383 NOTREACHED(); |
341 } | 384 } |
342 } | 385 } |
343 | 386 |
344 void ProfileImpl::DoFinalInit(bool is_new_profile) { | 387 void ProfileImpl::DoFinalInit(bool is_new_profile) { |
345 PrefService* prefs = GetPrefs(); | 388 PrefService* prefs = GetPrefs(); |
346 pref_change_registrar_.Init(prefs); | 389 pref_change_registrar_.Init(prefs); |
347 pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this); | 390 pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this); |
348 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, this); | 391 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, this); |
349 pref_change_registrar_.Add(prefs::kProfileAvatarIndex, this); | 392 pref_change_registrar_.Add(prefs::kProfileAvatarIndex, this); |
350 pref_change_registrar_.Add(prefs::kProfileName, this); | 393 pref_change_registrar_.Add(prefs::kProfileName, this); |
351 | 394 |
352 // It would be nice to use PathService for fetching this directory, but | 395 // It would be nice to use PathService for fetching this directory, but |
353 // the cache directory depends on the profile directory, which isn't available | 396 // the cache directory depends on the profile directory, which isn't available |
354 // to PathService. | 397 // to PathService. |
355 chrome::GetUserCacheDirectory(path_, &base_cache_path_); | 398 chrome::GetUserCacheDirectory(path_, &base_cache_path_); |
356 // Always create the cache directory asynchronously. | 399 // Always create the cache directory asynchronously. |
357 BrowserThread::PostTask( | 400 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = |
358 BrowserThread::FILE, FROM_HERE, | 401 JsonPrefStore::GetTaskRunnerForFile(base_cache_path_, |
359 base::Bind(base::IgnoreResult(&file_util::CreateDirectory), | 402 BrowserThread::GetBlockingPool()); |
360 base_cache_path_)); | 403 CreateProfileDirectory(sequenced_task_runner, base_cache_path_); |
361 | 404 |
362 // Now that the profile is hooked up to receive pref change notifications to | 405 // Now that the profile is hooked up to receive pref change notifications to |
363 // kGoogleServicesUsername, initialize components that depend on it to reflect | 406 // kGoogleServicesUsername, initialize components that depend on it to reflect |
364 // the current value. | 407 // the current value. |
365 UpdateProfileUserNameCache(); | 408 UpdateProfileUserNameCache(); |
366 GetGAIAInfoUpdateService(); | 409 GetGAIAInfoUpdateService(); |
367 | 410 |
368 #if !defined(OS_CHROMEOS) | 411 #if !defined(OS_CHROMEOS) |
369 // Listen for bookmark model load, to bootstrap the sync service. | 412 // Listen for bookmark model load, to bootstrap the sync service. |
370 // On CrOS sync service will be initialized after sign in. | 413 // On CrOS sync service will be initialized after sign in. |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1113 if (!path.empty()) | 1156 if (!path.empty()) |
1114 *cache_path = path; | 1157 *cache_path = path; |
1115 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : | 1158 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : |
1116 prefs_->GetInteger(prefs::kDiskCacheSize); | 1159 prefs_->GetInteger(prefs::kDiskCacheSize); |
1117 } | 1160 } |
1118 | 1161 |
1119 base::Callback<ChromeURLDataManagerBackend*(void)> | 1162 base::Callback<ChromeURLDataManagerBackend*(void)> |
1120 ProfileImpl::GetChromeURLDataManagerBackendGetter() const { | 1163 ProfileImpl::GetChromeURLDataManagerBackendGetter() const { |
1121 return io_data_.GetChromeURLDataManagerBackendGetter(); | 1164 return io_data_.GetChromeURLDataManagerBackendGetter(); |
1122 } | 1165 } |
OLD | NEW |