Chromium Code Reviews| 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 void CreateDirectoryAndSignal(const FilePath& path, | |
| 158 base::WaitableEvent* done_creating) { | |
| 159 DVLOG(1) << "Creating directory " << path.value(); | |
| 160 file_util::CreateDirectory(path); | |
| 161 done_creating->Signal(); | |
| 162 } | |
| 163 | |
| 164 // Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on | |
| 165 // blocking I/O pool. | |
| 166 void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { | |
| 167 done_creating->Wait(); | |
| 168 } | |
| 169 | |
| 170 // Initiates creation of profile directory on |sequenced_task_runner| and | |
| 171 // ensures that FILE thread is blocked until that operation finishes. | |
| 172 void CreateProfileDirectory(base::SequencedTaskRunner* sequenced_task_runner, | |
| 173 const FilePath& path) { | |
| 174 base::WaitableEvent* done_creating = new base::WaitableEvent(false, false); | |
|
Nico
2014/01/23 21:14:44
Who owns this? Is this ever deleted anywhere?
zel
2014/01/23 21:18:57
see line 184 below
Nico
2014/01/23 21:24:42
D'oh, thanks!
(Maybe scoped_ptr and base::Passed
| |
| 175 sequenced_task_runner->PostTask(FROM_HERE, | |
| 176 base::Bind(&CreateDirectoryAndSignal, | |
| 177 path, | |
| 178 done_creating)); | |
| 179 // Block the FILE thread until directory is created on I/O pool to make sure | |
| 180 // that we don't attempt any operation until that part completes. | |
| 181 BrowserThread::PostTask( | |
| 182 BrowserThread::FILE, FROM_HERE, | |
| 183 base::Bind(&BlockFileThreadOnDirectoryCreate, | |
| 184 base::Owned(done_creating))); | |
| 185 } | |
| 186 | |
| 152 FilePath GetCachePath(const FilePath& base) { | 187 FilePath GetCachePath(const FilePath& base) { |
| 153 return base.Append(chrome::kCacheDirname); | 188 return base.Append(chrome::kCacheDirname); |
| 154 } | 189 } |
| 155 | 190 |
| 156 FilePath GetMediaCachePath(const FilePath& base) { | 191 FilePath GetMediaCachePath(const FilePath& base) { |
| 157 return base.Append(chrome::kMediaCacheDirname); | 192 return base.Append(chrome::kMediaCacheDirname); |
| 158 } | 193 } |
| 159 | 194 |
| 160 void EnsureReadmeFile(const FilePath& base) { | 195 void EnsureReadmeFile(const FilePath& base) { |
| 161 FilePath readme_path = base.Append(chrome::kReadmeFilename); | 196 FilePath readme_path = base.Append(chrome::kReadmeFilename); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 192 NOTREACHED(); | 227 NOTREACHED(); |
| 193 return std::string(); | 228 return std::string(); |
| 194 } | 229 } |
| 195 | 230 |
| 196 } // namespace | 231 } // namespace |
| 197 | 232 |
| 198 // static | 233 // static |
| 199 Profile* Profile::CreateProfile(const FilePath& path, | 234 Profile* Profile::CreateProfile(const FilePath& path, |
| 200 Delegate* delegate, | 235 Delegate* delegate, |
| 201 CreateMode create_mode) { | 236 CreateMode create_mode) { |
| 237 // Get sequenced task runner for making sure that file operations of | |
| 238 // this profile (defined by |path|) are executed in expected order | |
| 239 // (what was previously assured by the FILE thread). | |
| 240 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = | |
| 241 JsonPrefStore::GetTaskRunnerForFile(path, | |
| 242 BrowserThread::GetBlockingPool()); | |
| 202 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { | 243 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { |
| 203 DCHECK(delegate); | 244 DCHECK(delegate); |
| 204 // This is safe while all file operations are done on the FILE thread. | 245 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) { | 246 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { |
| 209 if (!file_util::PathExists(path)) { | 247 if (!file_util::PathExists(path)) { |
| 210 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the | 248 // 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 | 249 // profile directory. We should eventually be able to run in this |
| 212 // situation. | 250 // situation. |
| 213 if (!file_util::CreateDirectory(path)) | 251 if (!file_util::CreateDirectory(path)) |
| 214 return NULL; | 252 return NULL; |
| 215 } | 253 } |
| 216 } else { | 254 } else { |
| 217 NOTREACHED(); | 255 NOTREACHED(); |
| 218 } | 256 } |
| 219 | 257 |
| 220 return new ProfileImpl(path, delegate, create_mode); | 258 return new ProfileImpl(path, delegate, create_mode, sequenced_task_runner); |
| 221 } | 259 } |
| 222 | 260 |
| 223 // static | 261 // static |
| 224 int ProfileImpl::create_readme_delay_ms = 60000; | 262 int ProfileImpl::create_readme_delay_ms = 60000; |
| 225 | 263 |
| 226 // static | 264 // static |
| 227 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; | 265 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; |
| 228 | 266 |
| 229 // static | 267 // static |
| 230 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { | 268 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 prefs->RegisterIntegerPref(prefs::kMediaCacheSize, | 301 prefs->RegisterIntegerPref(prefs::kMediaCacheSize, |
| 264 0, | 302 0, |
| 265 PrefService::UNSYNCABLE_PREF); | 303 PrefService::UNSYNCABLE_PREF); |
| 266 | 304 |
| 267 // Deprecated. Kept around for migration. | 305 // Deprecated. Kept around for migration. |
| 268 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, | 306 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, |
| 269 false, | 307 false, |
| 270 PrefService::SYNCABLE_PREF); | 308 PrefService::SYNCABLE_PREF); |
| 271 } | 309 } |
| 272 | 310 |
| 273 ProfileImpl::ProfileImpl(const FilePath& path, | 311 ProfileImpl::ProfileImpl( |
| 274 Delegate* delegate, | 312 const FilePath& path, |
| 275 CreateMode create_mode) | 313 Delegate* delegate, |
| 314 CreateMode create_mode, | |
| 315 base::SequencedTaskRunner* sequenced_task_runner) | |
| 276 : path_(path), | 316 : path_(path), |
| 277 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), | 317 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), |
| 278 host_content_settings_map_(NULL), | 318 host_content_settings_map_(NULL), |
| 279 last_session_exit_type_(EXIT_NORMAL), | 319 last_session_exit_type_(EXIT_NORMAL), |
| 280 start_time_(Time::Now()), | 320 start_time_(Time::Now()), |
| 281 delegate_(delegate), | 321 delegate_(delegate), |
| 282 predictor_(NULL) { | 322 predictor_(NULL) { |
| 283 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << | 323 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << |
| 284 "profile files to the root directory!"; | 324 "profile files to the root directory!"; |
| 285 | 325 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 300 // TODO(atwilson): Change these to ProfileKeyedServices once PrefService is | 340 // TODO(atwilson): Change these to ProfileKeyedServices once PrefService is |
| 301 // a ProfileKeyedService (policy must be initialized before PrefService | 341 // a ProfileKeyedService (policy must be initialized before PrefService |
| 302 // because PrefService depends on policy loading to get overridden pref | 342 // because PrefService depends on policy loading to get overridden pref |
| 303 // values). | 343 // values). |
| 304 policy::BrowserPolicyConnector* connector = | 344 policy::BrowserPolicyConnector* connector = |
| 305 g_browser_process->browser_policy_connector(); | 345 g_browser_process->browser_policy_connector(); |
| 306 cloud_policy_manager_ = connector->CreateCloudPolicyManager(this); | 346 cloud_policy_manager_ = connector->CreateCloudPolicyManager(this); |
| 307 if (cloud_policy_manager_) | 347 if (cloud_policy_manager_) |
| 308 cloud_policy_manager_->Init(); | 348 cloud_policy_manager_->Init(); |
| 309 managed_mode_policy_provider_.reset( | 349 managed_mode_policy_provider_.reset( |
| 310 policy::ManagedModePolicyProvider::Create(this)); | 350 policy::ManagedModePolicyProvider::Create(this, sequenced_task_runner)); |
| 311 managed_mode_policy_provider_->Init(); | 351 managed_mode_policy_provider_->Init(); |
| 312 policy_service_ = connector->CreatePolicyService(this); | 352 policy_service_ = connector->CreatePolicyService(this); |
| 313 #else | 353 #else |
| 314 policy_service_.reset(new policy::PolicyServiceStub()); | 354 policy_service_.reset(new policy::PolicyServiceStub()); |
| 315 #endif | 355 #endif |
| 316 | 356 |
| 317 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { | 357 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { |
| 318 prefs_.reset(PrefService::CreatePrefService( | 358 prefs_.reset(PrefService::CreatePrefService( |
| 319 GetPrefFilePath(), | 359 GetPrefFilePath(), |
| 360 sequenced_task_runner, | |
| 320 policy_service_.get(), | 361 policy_service_.get(), |
| 321 new ExtensionPrefStore( | 362 new ExtensionPrefStore( |
| 322 ExtensionPrefValueMapFactory::GetForProfile(this), false), | 363 ExtensionPrefValueMapFactory::GetForProfile(this), false), |
| 323 true)); | 364 true)); |
| 324 // Wait for the notification that prefs has been loaded | 365 // Wait for the notification that prefs has been loaded |
| 325 // (successfully or not). Note that we can use base::Unretained | 366 // (successfully or not). Note that we can use base::Unretained |
| 326 // because the PrefService is owned by this class and lives on | 367 // because the PrefService is owned by this class and lives on |
| 327 // the same thread. | 368 // the same thread. |
| 328 prefs_->AddPrefInitObserver(base::Bind(&ProfileImpl::OnPrefsLoaded, | 369 prefs_->AddPrefInitObserver(base::Bind(&ProfileImpl::OnPrefsLoaded, |
| 329 base::Unretained(this))); | 370 base::Unretained(this))); |
| 330 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { | 371 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { |
| 331 // Load prefs synchronously. | 372 // Load prefs synchronously. |
| 332 prefs_.reset(PrefService::CreatePrefService( | 373 prefs_.reset(PrefService::CreatePrefService( |
| 333 GetPrefFilePath(), | 374 GetPrefFilePath(), |
| 375 sequenced_task_runner, | |
| 334 policy_service_.get(), | 376 policy_service_.get(), |
| 335 new ExtensionPrefStore( | 377 new ExtensionPrefStore( |
| 336 ExtensionPrefValueMapFactory::GetForProfile(this), false), | 378 ExtensionPrefValueMapFactory::GetForProfile(this), false), |
| 337 false)); | 379 false)); |
| 338 OnPrefsLoaded(true); | 380 OnPrefsLoaded(true); |
| 339 } else { | 381 } else { |
| 340 NOTREACHED(); | 382 NOTREACHED(); |
| 341 } | 383 } |
| 342 } | 384 } |
| 343 | 385 |
| 344 void ProfileImpl::DoFinalInit(bool is_new_profile) { | 386 void ProfileImpl::DoFinalInit(bool is_new_profile) { |
| 345 PrefService* prefs = GetPrefs(); | 387 PrefService* prefs = GetPrefs(); |
| 346 pref_change_registrar_.Init(prefs); | 388 pref_change_registrar_.Init(prefs); |
| 347 pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this); | 389 pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this); |
| 348 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, this); | 390 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, this); |
| 349 pref_change_registrar_.Add(prefs::kProfileAvatarIndex, this); | 391 pref_change_registrar_.Add(prefs::kProfileAvatarIndex, this); |
| 350 pref_change_registrar_.Add(prefs::kProfileName, this); | 392 pref_change_registrar_.Add(prefs::kProfileName, this); |
| 351 | 393 |
| 352 // It would be nice to use PathService for fetching this directory, but | 394 // 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 | 395 // the cache directory depends on the profile directory, which isn't available |
| 354 // to PathService. | 396 // to PathService. |
| 355 chrome::GetUserCacheDirectory(path_, &base_cache_path_); | 397 chrome::GetUserCacheDirectory(path_, &base_cache_path_); |
| 356 // Always create the cache directory asynchronously. | 398 // Always create the cache directory asynchronously. |
| 357 BrowserThread::PostTask( | 399 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = |
| 358 BrowserThread::FILE, FROM_HERE, | 400 JsonPrefStore::GetTaskRunnerForFile(base_cache_path_, |
| 359 base::Bind(base::IgnoreResult(&file_util::CreateDirectory), | 401 BrowserThread::GetBlockingPool()); |
| 360 base_cache_path_)); | 402 CreateProfileDirectory(sequenced_task_runner, base_cache_path_); |
| 361 | 403 |
| 362 // Now that the profile is hooked up to receive pref change notifications to | 404 // Now that the profile is hooked up to receive pref change notifications to |
| 363 // kGoogleServicesUsername, initialize components that depend on it to reflect | 405 // kGoogleServicesUsername, initialize components that depend on it to reflect |
| 364 // the current value. | 406 // the current value. |
| 365 UpdateProfileUserNameCache(); | 407 UpdateProfileUserNameCache(); |
| 366 GetGAIAInfoUpdateService(); | 408 GetGAIAInfoUpdateService(); |
| 367 | 409 |
| 368 #if !defined(OS_CHROMEOS) | 410 #if !defined(OS_CHROMEOS) |
| 369 // Listen for bookmark model load, to bootstrap the sync service. | 411 // Listen for bookmark model load, to bootstrap the sync service. |
| 370 // On CrOS sync service will be initialized after sign in. | 412 // On CrOS sync service will be initialized after sign in. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 } | 597 } |
| 556 | 598 |
| 557 std::string ProfileImpl::GetProfileName() { | 599 std::string ProfileImpl::GetProfileName() { |
| 558 return GetPrefs()->GetString(prefs::kGoogleServicesUsername); | 600 return GetPrefs()->GetString(prefs::kGoogleServicesUsername); |
| 559 } | 601 } |
| 560 | 602 |
| 561 FilePath ProfileImpl::GetPath() { | 603 FilePath ProfileImpl::GetPath() { |
| 562 return path_; | 604 return path_; |
| 563 } | 605 } |
| 564 | 606 |
| 607 scoped_refptr<base::SequencedTaskRunner> ProfileImpl::GetIOTaskRunner() { | |
| 608 return JsonPrefStore::GetTaskRunnerForFile( | |
| 609 GetPath(), BrowserThread::GetBlockingPool()); | |
| 610 } | |
| 611 | |
| 565 bool ProfileImpl::IsOffTheRecord() const { | 612 bool ProfileImpl::IsOffTheRecord() const { |
| 566 return false; | 613 return false; |
| 567 } | 614 } |
| 568 | 615 |
| 569 Profile* ProfileImpl::GetOffTheRecordProfile() { | 616 Profile* ProfileImpl::GetOffTheRecordProfile() { |
| 570 if (!off_the_record_profile_.get()) { | 617 if (!off_the_record_profile_.get()) { |
| 571 scoped_ptr<Profile> p(CreateOffTheRecordProfile()); | 618 scoped_ptr<Profile> p(CreateOffTheRecordProfile()); |
| 572 off_the_record_profile_.swap(p); | 619 off_the_record_profile_.swap(p); |
| 573 | 620 |
| 574 content::NotificationService::current()->Notify( | 621 content::NotificationService::current()->Notify( |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1114 if (!path.empty()) | 1161 if (!path.empty()) |
| 1115 *cache_path = path; | 1162 *cache_path = path; |
| 1116 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : | 1163 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : |
| 1117 prefs_->GetInteger(prefs::kDiskCacheSize); | 1164 prefs_->GetInteger(prefs::kDiskCacheSize); |
| 1118 } | 1165 } |
| 1119 | 1166 |
| 1120 base::Callback<ChromeURLDataManagerBackend*(void)> | 1167 base::Callback<ChromeURLDataManagerBackend*(void)> |
| 1121 ProfileImpl::GetChromeURLDataManagerBackendGetter() const { | 1168 ProfileImpl::GetChromeURLDataManagerBackendGetter() const { |
| 1122 return io_data_.GetChromeURLDataManagerBackendGetter(); | 1169 return io_data_.GetChromeURLDataManagerBackendGetter(); |
| 1123 } | 1170 } |
| OLD | NEW |