profile_impl.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 3// found in the LICENSE file. 4 5#include "chrome/browser/profiles/profile_impl.h" 6 7#include "base/bind.h" 8#include "base/callback.h" 9#include "base/command_line.h" 10#include "base/compiler_specific.h" 11#include "base/debug/trace_event.h" 12#include "base/environment.h" 13#include "base/file_util.h" 14#include "base/files/file_path.h" 15#include "base/memory/scoped_ptr.h" 16#include "base/path_service.h" 17#include "base/prefs/json_pref_store.h" 18#include "base/prefs/scoped_user_pref_update.h" 19#include "base/strings/string_number_conversions.h" 20#include "base/strings/string_util.h" 21#include "base/strings/stringprintf.h" 22#include "base/strings/utf_string_conversions.h" 23#include "base/synchronization/waitable_event.h" 24#include "base/threading/sequenced_worker_pool.h" 25#include "base/version.h" 26#include "chrome/browser/autocomplete/autocomplete_classifier.h" 27#include "chrome/browser/background/background_contents_service_factory.h" 28#include "chrome/browser/background/background_mode_manager.h" 29#include "chrome/browser/bookmarks/bookmark_model.h" 30#include "chrome/browser/bookmarks/bookmark_model_factory.h" 31#include "chrome/browser/browser_process.h" 32#include "chrome/browser/chrome_notification_types.h" 33#include "chrome/browser/content_settings/cookie_settings.h" 34#include "chrome/browser/content_settings/host_content_settings_map.h" 35#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" 36#include "chrome/browser/dom_distiller/lazy_dom_distiller_service.h" 37#include "chrome/browser/download/chrome_download_manager_delegate.h" 38#include "chrome/browser/download/download_service.h" 39#include "chrome/browser/download/download_service_factory.h" 40#include "chrome/browser/extensions/extension_service.h" 41#include "chrome/browser/extensions/extension_special_storage_policy.h" 42#include "chrome/browser/geolocation/chrome_geolocation_permission_context.h" 43#include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h" 44#include "chrome/browser/history/shortcuts_backend.h" 45#include "chrome/browser/history/top_sites.h" 46#include "chrome/browser/media/chrome_midi_permission_context.h" 47#include "chrome/browser/media/chrome_midi_permission_context_factory.h" 48#include "chrome/browser/metrics/metrics_service.h" 49#include "chrome/browser/net/chrome_url_request_context.h" 50#include "chrome/browser/net/net_pref_observer.h" 51#include "chrome/browser/net/predictor.h" 52#include "chrome/browser/net/pref_proxy_config_tracker.h" 53#include "chrome/browser/net/proxy_service_factory.h" 54#include "chrome/browser/net/ssl_config_service_manager.h" 55#include "chrome/browser/plugins/chrome_plugin_service_filter.h" 56#include "chrome/browser/plugins/plugin_prefs.h" 57#include "chrome/browser/policy/profile_policy_connector.h" 58#include "chrome/browser/policy/profile_policy_connector_factory.h" 59#include "chrome/browser/prefs/browser_prefs.h" 60#include "chrome/browser/prefs/chrome_pref_service_factory.h" 61#include "chrome/browser/prefs/pref_service_syncable.h" 62#include "chrome/browser/prerender/prerender_manager_factory.h" 63#include "chrome/browser/profiles/bookmark_model_loaded_observer.h" 64#include "chrome/browser/profiles/chrome_version_service.h" 65#include "chrome/browser/profiles/gaia_info_update_service_factory.h" 66#include "chrome/browser/profiles/profile_destroyer.h" 67#include "chrome/browser/profiles/profile_info_cache.h" 68#include "chrome/browser/profiles/profile_manager.h" 69#include "chrome/browser/profiles/profile_metrics.h" 70#include "chrome/browser/search_engines/template_url_fetcher.h" 71#include "chrome/browser/sessions/session_service_factory.h" 72#include "chrome/browser/ui/startup/startup_browser_creator.h" 73#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 74#include "chrome/browser/webdata/web_data_service.h" 75#include "chrome/common/chrome_constants.h" 76#include "chrome/common/chrome_paths_internal.h" 77#include "chrome/common/chrome_switches.h" 78#include "chrome/common/chrome_version_info.h" 79#include "chrome/common/net/url_fixer_upper.h" 80#include "chrome/common/pref_names.h" 81#include "chrome/common/url_constants.h" 82#include "components/dom_distiller/content/dom_distiller_viewer_source.h" 83#include "components/keyed_service/content/browser_context_dependency_manager.h" 84#include "components/startup_metric_utils/startup_metric_utils.h" 85#include "components/user_prefs/pref_registry_syncable.h" 86#include "components/user_prefs/user_prefs.h" 87#include "content/public/browser/browser_thread.h" 88#include "content/public/browser/dom_storage_context.h" 89#include "content/public/browser/host_zoom_map.h" 90#include "content/public/browser/notification_service.h" 91#include "content/public/browser/render_process_host.h" 92#include "content/public/browser/storage_partition.h" 93#include "content/public/browser/url_data_source.h" 94#include "content/public/browser/user_metrics.h" 95#include "content/public/common/content_constants.h" 96#include "extensions/browser/extension_pref_store.h" 97#include "extensions/browser/extension_pref_value_map.h" 98#include "extensions/browser/extension_pref_value_map_factory.h" 99#include "extensions/browser/extension_system.h" 100#include "grit/chromium_strings.h" 101#include "grit/generated_resources.h" 102#include "ui/base/l10n/l10n_util.h" 103 104#if defined(OS_ANDROID) 105#include "chrome/browser/media/protected_media_identifier_permission_context.h" 106#include "chrome/browser/media/protected_media_identifier_permission_context_factory.h" 107#endif // defined(OS_ANDROID) 108 109#if defined(ENABLE_CONFIGURATION_POLICY) 110#include "chrome/browser/policy/schema_registry_service.h" 111#include "chrome/browser/policy/schema_registry_service_factory.h" 112#include "components/policy/core/browser/browser_policy_connector.h" 113#if defined(OS_CHROMEOS) 114#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" 115#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" 116#else 117#include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h" 118#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" 119#endif 120#endif 121 122#if defined(ENABLE_MANAGED_USERS) 123#include "chrome/browser/managed_mode/managed_user_settings_service.h" 124#include "chrome/browser/managed_mode/managed_user_settings_service_factory.h" 125#endif 126 127#if defined(OS_CHROMEOS) 128#include "chrome/browser/chromeos/locale_change_guard.h" 129#include "chrome/browser/chromeos/login/user_manager.h" 130#include "chrome/browser/chromeos/preferences.h" 131#include "chrome/browser/chromeos/profiles/profile_helper.h" 132#endif 133 134using base::Time; 135using base::TimeDelta; 136using base::UserMetricsAction; 137using content::BrowserThread; 138using content::DownloadManagerDelegate; 139using content::HostZoomMap; 140 141namespace { 142 143// Constrict us to a very specific platform and architecture to make sure 144// ifdefs don't cause problems with the check. 145#if defined(OS_LINUX) && defined(TOOLKIT_GTK) && defined(ARCH_CPU_X86_64) && \ 146 !defined(_GLIBCXX_DEBUG) 147// Make sure that the ProfileImpl doesn't grow. We're currently trying to drive 148// the number of services that are included in ProfileImpl (instead of using 149// BrowserContextKeyedServiceFactory) to zero. 150// 151// If you don't know about this effort, please read: 152// https://sites.google.com/a/chromium.org/dev/developers/design-documents/profile-architecture 153// 154// REVIEWERS: Do not let anyone increment this. We need to drive the number of 155// raw accessed services down to zero. DO NOT LET PEOPLE REGRESS THIS UNLESS 156// THE PATCH ITSELF IS MAKING PROGRESS ON PKSF REFACTORING. 157COMPILE_ASSERT(sizeof(ProfileImpl) <= 744u, profile_impl_size_unexpected); 158#endif 159 160#if defined(ENABLE_SESSION_SERVICE) 161// Delay, in milliseconds, before we explicitly create the SessionService. 162static const int kCreateSessionServiceDelayMS = 500; 163#endif 164 165// Text content of README file created in each profile directory. Both %s 166// placeholders must contain the product name. This is not localizable and hence 167// not in resources. 168static const char kReadmeText[] = 169 "%s settings and storage represent user-selected preferences and " 170 "information and MUST not be extracted, overwritten or modified except " 171 "through %s defined APIs."; 172 173// Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED. 174const char* const kPrefExitTypeCrashed = "Crashed"; 175const char* const kPrefExitTypeSessionEnded = "SessionEnded"; 176 177// Helper method needed because PostTask cannot currently take a Callback 178// function with non-void return type. 179void CreateDirectoryAndSignal(const base::FilePath& path, 180 base::WaitableEvent* done_creating) { 181 DVLOG(1) << "Creating directory " << path.value(); 182 base::CreateDirectory(path); 183 done_creating->Signal(); 184} 185 186// Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on 187// blocking I/O pool. 188void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { 189 done_creating->Wait(); 190} 191 192// Initiates creation of profile directory on |sequenced_task_runner| and 193// ensures that FILE thread is blocked until that operation finishes. 194void CreateProfileDirectory(base::SequencedTaskRunner* sequenced_task_runner, 195 const base::FilePath& path) { 196 base::WaitableEvent* done_creating = new base::WaitableEvent(false, false); 197 sequenced_task_runner->PostTask(FROM_HERE, 198 base::Bind(&CreateDirectoryAndSignal, 199 path, 200 done_creating)); 201 // Block the FILE thread until directory is created on I/O pool to make sure 202 // that we don't attempt any operation until that part completes. 203 BrowserThread::PostTask( 204 BrowserThread::FILE, FROM_HERE, 205 base::Bind(&BlockFileThreadOnDirectoryCreate, 206 base::Owned(done_creating))); 207} 208 209base::FilePath GetCachePath(const base::FilePath& base) { 210 return base.Append(chrome::kCacheDirname); 211} 212 213base::FilePath GetMediaCachePath(const base::FilePath& base) { 214 return base.Append(chrome::kMediaCacheDirname); 215} 216 217void EnsureReadmeFile(const base::FilePath& base) { 218 base::FilePath readme_path = base.Append(chrome::kReadmeFilename); 219 if (base::PathExists(readme_path)) 220 return; 221 std::string product_name = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME); 222 std::string readme_text = base::StringPrintf( 223 kReadmeText, product_name.c_str(), product_name.c_str()); 224 if (base::WriteFile(readme_path, readme_text.data(), readme_text.size()) == 225 -1) { 226 LOG(ERROR) << "Could not create README file."; 227 } 228} 229 230// Converts the kSessionExitedCleanly pref to the corresponding EXIT_TYPE. 231Profile::ExitType SessionTypePrefValueToExitType(const std::string& value) { 232 if (value == kPrefExitTypeSessionEnded) 233 return Profile::EXIT_SESSION_ENDED; 234 if (value == kPrefExitTypeCrashed) 235 return Profile::EXIT_CRASHED; 236 return Profile::EXIT_NORMAL; 237} 238 239// Converts an ExitType into a string that is written to prefs. 240std::string ExitTypeToSessionTypePrefValue(Profile::ExitType type) { 241 switch (type) { 242 case Profile::EXIT_NORMAL: 243 return ProfileImpl::kPrefExitTypeNormal; 244 case Profile::EXIT_SESSION_ENDED: 245 return kPrefExitTypeSessionEnded; 246 case Profile::EXIT_CRASHED: 247 return kPrefExitTypeCrashed; 248 } 249 NOTREACHED(); 250 return std::string(); 251} 252 253// Setup URLDataSource for the chrome-distiller:// scheme for the given 254// |profile|. 255void RegisterDomDistillerViewerSource(Profile* profile) { 256 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 257 if (command_line.HasSwitch(switches::kEnableDomDistiller)) { 258 dom_distiller::DomDistillerServiceFactory* dom_distiller_service_factory = 259 dom_distiller::DomDistillerServiceFactory::GetInstance(); 260 // The LazyDomDistillerService deletes itself when the profile is destroyed. 261 dom_distiller::LazyDomDistillerService* lazy_service = 262 new dom_distiller::LazyDomDistillerService( 263 profile, dom_distiller_service_factory); 264 content::URLDataSource::Add(profile, 265 new dom_distiller::DomDistillerViewerSource( 266 lazy_service, chrome::kDomDistillerScheme)); 267 } 268} 269 270} // namespace 271 272// static 273Profile* Profile::CreateProfile(const base::FilePath& path, 274 Delegate* delegate, 275 CreateMode create_mode) { 276 TRACE_EVENT0("browser", "Profile::CreateProfile") 277 // Get sequenced task runner for making sure that file operations of 278 // this profile (defined by |path|) are executed in expected order 279 // (what was previously assured by the FILE thread). 280 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = 281 JsonPrefStore::GetTaskRunnerForFile(path, 282 BrowserThread::GetBlockingPool()); 283 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { 284 DCHECK(delegate); 285 CreateProfileDirectory(sequenced_task_runner.get(), path); 286 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { 287 if (!base::PathExists(path)) { 288 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the 289 // profile directory. We should eventually be able to run in this 290 // situation. 291 if (!base::CreateDirectory(path)) 292 return NULL; 293 } 294 } else { 295 NOTREACHED(); 296 } 297 298 return new ProfileImpl( 299 path, delegate, create_mode, sequenced_task_runner.get()); 300} 301 302// static 303int ProfileImpl::create_readme_delay_ms = 60000; 304 305// static 306const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; 307 308// static 309void ProfileImpl::RegisterProfilePrefs( 310 user_prefs::PrefRegistrySyncable* registry) { 311 registry->RegisterBooleanPref( 312 prefs::kSavingBrowserHistoryDisabled, 313 false, 314 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 315 registry->RegisterBooleanPref( 316 prefs::kAllowDeletingBrowserHistory, 317 true, 318 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 319 registry->RegisterBooleanPref( 320 prefs::kSigninAllowed, 321 true, 322 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 323 registry->RegisterBooleanPref( 324 prefs::kForceSafeSearch, 325 false, 326 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 327 registry->RegisterIntegerPref( 328 prefs::kProfileAvatarIndex, 329 -1, 330 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 331 registry->RegisterStringPref(prefs::kManagedUserId, 332 std::string(), 333 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 334 registry->RegisterStringPref(prefs::kProfileName, 335 std::string(), 336 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 337 registry->RegisterBooleanPref( 338 prefs::kProfileIsManaged, 339 false, 340 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 341 registry->RegisterStringPref(prefs::kHomePage, 342 std::string(), 343 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 344#if defined(ENABLE_PRINTING) 345 registry->RegisterBooleanPref( 346 prefs::kPrintingEnabled, 347 true, 348 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 349#endif 350 registry->RegisterBooleanPref( 351 prefs::kPrintPreviewDisabled, 352#if defined(GOOGLE_CHROME_BUILD) 353 false, 354#else 355 true, 356#endif 357 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 358 registry->RegisterBooleanPref( 359 prefs::kForceEphemeralProfiles, 360 false, 361 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 362 363 // Initialize the cache prefs. 364 registry->RegisterFilePathPref( 365 prefs::kDiskCacheDir, 366 base::FilePath(), 367 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 368 registry->RegisterIntegerPref( 369 prefs::kDiskCacheSize, 370 0, 371 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 372 registry->RegisterIntegerPref( 373 prefs::kMediaCacheSize, 374 0, 375 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 376 377 // Deprecated. Kept around for migration. 378 registry->RegisterBooleanPref( 379 prefs::kClearSiteDataOnExit, 380 false, 381 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 382} 383 384ProfileImpl::ProfileImpl( 385 const base::FilePath& path, 386 Delegate* delegate, 387 CreateMode create_mode, 388 base::SequencedTaskRunner* sequenced_task_runner) 389 : path_(path), 390 pref_registry_(new user_prefs::PrefRegistrySyncable), 391 io_data_(this), 392 host_content_settings_map_(NULL), 393 last_session_exit_type_(EXIT_NORMAL), 394 start_time_(Time::Now()), 395 delegate_(delegate), 396 predictor_(NULL) { 397 TRACE_EVENT0("browser", "ProfileImpl::ctor") 398 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << 399 "profile files to the root directory!"; 400 401#if defined(ENABLE_SESSION_SERVICE) 402 create_session_service_timer_.Start(FROM_HERE, 403 TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS), this, 404 &ProfileImpl::EnsureSessionServiceCreated); 405#endif 406 407 // Determine if prefetch is enabled for this profile. 408 // If not profile_manager is present, it means we are in a unittest. 409 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 410 predictor_ = chrome_browser_net::Predictor::CreatePredictor( 411 !command_line->HasSwitch(switches::kDisablePreconnect), 412 g_browser_process->profile_manager() == NULL); 413 414 // If we are creating the profile synchronously, then we should load the 415 // policy data immediately. 416 bool force_immediate_policy_load = (create_mode == CREATE_MODE_SYNCHRONOUS); 417#if defined(ENABLE_CONFIGURATION_POLICY) 418 policy::BrowserPolicyConnector* connector = 419 g_browser_process->browser_policy_connector(); 420 schema_registry_service_ = 421 policy::SchemaRegistryServiceFactory::CreateForContext( 422 this, connector->GetChromeSchema(), connector->GetSchemaRegistry()); 423#if defined(OS_CHROMEOS) 424 cloud_policy_manager_ = 425 policy::UserCloudPolicyManagerFactoryChromeOS::CreateForProfile( 426 this, force_immediate_policy_load, sequenced_task_runner); 427#else 428 cloud_policy_manager_ = 429 policy::UserCloudPolicyManagerFactory::CreateForOriginalBrowserContext( 430 this, 431 force_immediate_policy_load, 432 sequenced_task_runner, 433 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), 434 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); 435#endif 436#endif 437 profile_policy_connector_ = 438 policy::ProfilePolicyConnectorFactory::CreateForProfile( 439 this, force_immediate_policy_load); 440 441 DCHECK(create_mode == CREATE_MODE_ASYNCHRONOUS || 442 create_mode == CREATE_MODE_SYNCHRONOUS); 443 bool async_prefs = create_mode == CREATE_MODE_ASYNCHRONOUS; 444 445#if defined(OS_CHROMEOS) 446 if (chromeos::ProfileHelper::IsSigninProfile(this)) 447 chrome::RegisterLoginProfilePrefs(pref_registry_.get()); 448 else 449#endif 450 chrome::RegisterUserProfilePrefs(pref_registry_.get()); 451 452 BrowserContextDependencyManager::GetInstance()-> 453 RegisterProfilePrefsForServices(this, pref_registry_.get()); 454 455 ManagedUserSettingsService* managed_user_settings = NULL; 456#if defined(ENABLE_MANAGED_USERS) 457 managed_user_settings = 458 ManagedUserSettingsServiceFactory::GetForProfile(this); 459 managed_user_settings->Init( 460 path_, sequenced_task_runner, create_mode == CREATE_MODE_SYNCHRONOUS); 461#endif 462 463 { 464 // On startup, preference loading is always synchronous so a scoped timer 465 // will work here. 466 startup_metric_utils::ScopedSlowStartupUMA 467 scoped_timer("Startup.SlowStartupPreferenceLoading"); 468 prefs_ = chrome_prefs::CreateProfilePrefs( 469 path_, 470 sequenced_task_runner, 471 profile_policy_connector_->policy_service(), 472 managed_user_settings, 473 new ExtensionPrefStore( 474 ExtensionPrefValueMapFactory::GetForBrowserContext(this), false), 475 pref_registry_, 476 async_prefs).Pass(); 477 // Register on BrowserContext. 478 user_prefs::UserPrefs::Set(this, prefs_.get()); 479 } 480 481 startup_metric_utils::ScopedSlowStartupUMA 482 scoped_timer("Startup.SlowStartupFinalProfileInit"); 483 if (async_prefs) { 484 // Wait for the notification that prefs has been loaded 485 // (successfully or not). Note that we can use base::Unretained 486 // because the PrefService is owned by this class and lives on 487 // the same thread. 488 prefs_->AddPrefInitObserver(base::Bind(&ProfileImpl::OnPrefsLoaded, 489 base::Unretained(this))); 490 } else { 491 // Prefs were loaded synchronously so we can continue directly. 492 OnPrefsLoaded(true); 493 } 494} 495 496void ProfileImpl::DoFinalInit() { 497 TRACE_EVENT0("browser", "ProfileImpl::DoFinalInit") 498 PrefService* prefs = GetPrefs(); 499 pref_change_registrar_.Init(prefs); 500 pref_change_registrar_.Add( 501 prefs::kGoogleServicesUsername, 502 base::Bind(&ProfileImpl::UpdateProfileUserNameCache, 503 base::Unretained(this))); 504 pref_change_registrar_.Add( 505 prefs::kDefaultZoomLevel, 506 base::Bind(&ProfileImpl::OnDefaultZoomLevelChanged, 507 base::Unretained(this))); 508 pref_change_registrar_.Add( 509 prefs::kProfileAvatarIndex, 510 base::Bind(&ProfileImpl::UpdateProfileAvatarCache, 511 base::Unretained(this))); 512 pref_change_registrar_.Add( 513 prefs::kProfileName, 514 base::Bind(&ProfileImpl::UpdateProfileNameCache, 515 base::Unretained(this))); 516 pref_change_registrar_.Add( 517 prefs::kForceEphemeralProfiles, 518 base::Bind(&ProfileImpl::UpdateProfileIsEphemeralCache, 519 base::Unretained(this))); 520 521 // It would be nice to use PathService for fetching this directory, but 522 // the cache directory depends on the profile directory, which isn't available 523 // to PathService. 524 chrome::GetUserCacheDirectory(path_, &base_cache_path_); 525 // Always create the cache directory asynchronously. 526 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = 527 JsonPrefStore::GetTaskRunnerForFile(base_cache_path_, 528 BrowserThread::GetBlockingPool()); 529 CreateProfileDirectory(sequenced_task_runner.get(), base_cache_path_); 530 531 // Now that the profile is hooked up to receive pref change notifications to 532 // kGoogleServicesUsername, initialize components that depend on it to reflect 533 // the current value. 534 UpdateProfileUserNameCache(); 535 UpdateProfileIsEphemeralCache(); 536 GAIAInfoUpdateServiceFactory::GetForProfile(this); 537 538 PrefService* local_state = g_browser_process->local_state(); 539 ssl_config_service_manager_.reset( 540 SSLConfigServiceManager::CreateDefaultManager(local_state)); 541 542 // Initialize the BackgroundModeManager - this has to be done here before 543 // InitExtensions() is called because it relies on receiving notifications 544 // when extensions are loaded. BackgroundModeManager is not needed under 545 // ChromeOS because Chrome is always running, no need for special keep-alive 546 // or launch-on-startup support unless kKeepAliveForTest is set. 547 bool init_background_mode_manager = true; 548#if defined(OS_CHROMEOS) 549 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kKeepAliveForTest)) 550 init_background_mode_manager = false; 551#endif 552 if (init_background_mode_manager) { 553 if (g_browser_process->background_mode_manager()) 554 g_browser_process->background_mode_manager()->RegisterProfile(this); 555 } 556 557 base::FilePath cookie_path = GetPath(); 558 cookie_path = cookie_path.Append(chrome::kCookieFilename); 559 base::FilePath server_bound_cert_path = GetPath(); 560 server_bound_cert_path = 561 server_bound_cert_path.Append(chrome::kOBCertFilename); 562 base::FilePath cache_path = base_cache_path_; 563 int cache_max_size; 564 GetCacheParameters(false, &cache_path, &cache_max_size); 565 cache_path = GetCachePath(cache_path); 566 567 base::FilePath media_cache_path = base_cache_path_; 568 int media_cache_max_size; 569 GetCacheParameters(true, &media_cache_path, &media_cache_max_size); 570 media_cache_path = GetMediaCachePath(media_cache_path); 571 572 base::FilePath extensions_cookie_path = GetPath(); 573 extensions_cookie_path = 574 extensions_cookie_path.Append(chrome::kExtensionsCookieFilename); 575 576 base::FilePath infinite_cache_path = GetPath(); 577 infinite_cache_path = 578 infinite_cache_path.Append(FILE_PATH_LITERAL("Infinite Cache")); 579 580#if defined(OS_ANDROID) 581 SessionStartupPref::Type startup_pref_type = 582 SessionStartupPref::GetDefaultStartupType(); 583#else 584 SessionStartupPref::Type startup_pref_type = 585 StartupBrowserCreator::GetSessionStartupPref( 586 *CommandLine::ForCurrentProcess(), this).type; 587#endif 588 content::CookieStoreConfig::SessionCookieMode session_cookie_mode = 589 content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES; 590 if (GetLastSessionExitType() == Profile::EXIT_CRASHED || 591 startup_pref_type == SessionStartupPref::LAST) { 592 session_cookie_mode = content::CookieStoreConfig::RESTORED_SESSION_COOKIES; 593 } 594 595 InitHostZoomMap(); 596 597 // Make sure we initialize the ProfileIOData after everything else has been 598 // initialized that we might be reading from the IO thread. 599 600 io_data_.Init(cookie_path, server_bound_cert_path, cache_path, 601 cache_max_size, media_cache_path, media_cache_max_size, 602 extensions_cookie_path, GetPath(), infinite_cache_path, 603 predictor_, 604 session_cookie_mode, 605 GetSpecialStoragePolicy()); 606 607#if defined(ENABLE_PLUGINS) 608 ChromePluginServiceFilter::GetInstance()->RegisterResourceContext( 609 PluginPrefs::GetForProfile(this).get(), 610 io_data_.GetResourceContextNoInit()); 611#endif 612 613 // Delay README creation to not impact startup performance. 614 BrowserThread::PostDelayedTask( 615 BrowserThread::FILE, FROM_HERE, 616 base::Bind(&EnsureReadmeFile, GetPath()), 617 base::TimeDelta::FromMilliseconds(create_readme_delay_ms)); 618 619 TRACE_EVENT0("browser", "ProfileImpl::SetSaveSessionStorageOnDisk"); 620 content::BrowserContext::GetDefaultStoragePartition(this)-> 621 GetDOMStorageContext()->SetSaveSessionStorageOnDisk(); 622 623 // The DomDistillerViewerSource is not a normal WebUI so it must be registered 624 // as a URLDataSource early. 625 RegisterDomDistillerViewerSource(this); 626 627 // Creation has been finished. 628 if (delegate_) { 629 TRACE_EVENT0("browser", "ProfileImpl::DoFileInit:DelegateOnProfileCreated") 630 delegate_->OnProfileCreated(this, true, IsNewProfile()); 631 } 632 633 content::NotificationService::current()->Notify( 634 chrome::NOTIFICATION_PROFILE_CREATED, 635 content::Source<Profile>(this), 636 content::NotificationService::NoDetails()); 637 638#if !defined(OS_CHROMEOS) 639 // Listen for bookmark model load, to bootstrap the sync service. 640 // On CrOS sync service will be initialized after sign in. 641 BookmarkModel* model = BookmarkModelFactory::GetForProfile(this); 642 model->AddObserver(new BookmarkModelLoadedObserver(this)); 643#endif 644} 645 646void ProfileImpl::InitHostZoomMap() { 647 HostZoomMap* host_zoom_map = HostZoomMap::GetForBrowserContext(this); 648 host_zoom_map->SetDefaultZoomLevel( 649 prefs_->GetDouble(prefs::kDefaultZoomLevel)); 650 651 const base::DictionaryValue* host_zoom_dictionary = 652 prefs_->GetDictionary(prefs::kPerHostZoomLevels); 653 // Careful: The returned value could be NULL if the pref has never been set. 654 if (host_zoom_dictionary != NULL) { 655 for (base::DictionaryValue::Iterator i(*host_zoom_dictionary); !i.IsAtEnd(); 656 i.Advance()) { 657 const std::string& host(i.key()); 658 double zoom_level = 0; 659 660 bool success = i.value().GetAsDouble(&zoom_level); 661 DCHECK(success); 662 host_zoom_map->SetZoomLevelForHost(host, zoom_level); 663 } 664 } 665 666 zoom_subscription_ = host_zoom_map->AddZoomLevelChangedCallback( 667 base::Bind(&ProfileImpl::OnZoomLevelChanged, base::Unretained(this))); 668} 669 670base::FilePath ProfileImpl::last_selected_directory() { 671 return GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory); 672} 673 674void ProfileImpl::set_last_selected_directory(const base::FilePath& path) { 675 GetPrefs()->SetFilePath(prefs::kSelectFileLastDirectory, path); 676} 677 678ProfileImpl::~ProfileImpl() { 679 MaybeSendDestroyedNotification(); 680 681 bool prefs_loaded = prefs_->GetInitializationStatus() != 682 PrefService::INITIALIZATION_STATUS_WAITING; 683 684#if defined(ENABLE_SESSION_SERVICE) 685 StopCreateSessionServiceTimer(); 686#endif 687 688 // Remove pref observers 689 pref_change_registrar_.RemoveAll(); 690 691#if defined(ENABLE_PLUGINS) 692 ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext( 693 io_data_.GetResourceContextNoInit()); 694#endif 695 696 // Destroy OTR profile and its profile services first. 697 if (off_the_record_profile_) { 698 ProfileDestroyer::DestroyOffTheRecordProfileNow( 699 off_the_record_profile_.get()); 700 } else { 701 ExtensionPrefValueMapFactory::GetForBrowserContext(this)-> 702 ClearAllIncognitoSessionOnlyPreferences(); 703 } 704 705 BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( 706 this); 707 708 if (top_sites_.get()) 709 top_sites_->Shutdown(); 710 711 if (pref_proxy_config_tracker_) 712 pref_proxy_config_tracker_->DetachFromPrefService(); 713 714 if (host_content_settings_map_.get()) 715 host_content_settings_map_->ShutdownOnUIThread(); 716 717 // This causes the Preferences file to be written to disk. 718 if (prefs_loaded) 719 SetExitType(EXIT_NORMAL); 720} 721 722std::string ProfileImpl::GetProfileName() { 723 return GetPrefs()->GetString(prefs::kGoogleServicesUsername); 724} 725 726Profile::ProfileType ProfileImpl::GetProfileType() const { 727 return REGULAR_PROFILE; 728} 729 730base::FilePath ProfileImpl::GetPath() const { 731 return path_; 732} 733 734scoped_refptr<base::SequencedTaskRunner> ProfileImpl::GetIOTaskRunner() { 735 return JsonPrefStore::GetTaskRunnerForFile( 736 GetPath(), BrowserThread::GetBlockingPool()); 737} 738 739bool ProfileImpl::IsOffTheRecord() const { 740 return false; 741} 742 743Profile* ProfileImpl::GetOffTheRecordProfile() { 744 if (!off_the_record_profile_) { 745 scoped_ptr<Profile> p(CreateOffTheRecordProfile()); 746 off_the_record_profile_.swap(p); 747 748 content::NotificationService::current()->Notify( 749 chrome::NOTIFICATION_PROFILE_CREATED, 750 content::Source<Profile>(off_the_record_profile_.get()), 751 content::NotificationService::NoDetails()); 752 } 753 return off_the_record_profile_.get(); 754} 755 756void ProfileImpl::DestroyOffTheRecordProfile() { 757 off_the_record_profile_.reset(); 758 ExtensionPrefValueMapFactory::GetForBrowserContext(this)-> 759 ClearAllIncognitoSessionOnlyPreferences(); 760} 761 762bool ProfileImpl::HasOffTheRecordProfile() { 763 return off_the_record_profile_.get() != NULL; 764} 765 766Profile* ProfileImpl::GetOriginalProfile() { 767 return this; 768} 769 770bool ProfileImpl::IsManaged() { 771 return !GetPrefs()->GetString(prefs::kManagedUserId).empty(); 772} 773 774ExtensionService* ProfileImpl::GetExtensionService() { 775 return extensions::ExtensionSystem::Get(this)->extension_service(); 776} 777 778ExtensionSpecialStoragePolicy* 779 ProfileImpl::GetExtensionSpecialStoragePolicy() { 780 if (!extension_special_storage_policy_.get()) { 781 TRACE_EVENT0("browser", "ProfileImpl::GetExtensionSpecialStoragePolicy") 782 extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy( 783 CookieSettings::Factory::GetForProfile(this).get()); 784 } 785 return extension_special_storage_policy_.get(); 786} 787 788void ProfileImpl::OnPrefsLoaded(bool success) { 789 TRACE_EVENT0("browser", "ProfileImpl::OnPrefsLoaded") 790 if (!success) { 791 if (delegate_) 792 delegate_->OnProfileCreated(this, false, false); 793 return; 794 } 795 796 // TODO(mirandac): remove migration code after 6 months (crbug.com/69995). 797 if (g_browser_process->local_state()) 798 chrome::MigrateBrowserPrefs(this, g_browser_process->local_state()); 799 // TODO(ivankr): remove cleanup code eventually (crbug.com/165672). 800 chrome::MigrateUserPrefs(this); 801 802 // |kSessionExitType| was added after |kSessionExitedCleanly|. If the pref 803 // value is empty fallback to checking for |kSessionExitedCleanly|. 804 const std::string exit_type_pref_value( 805 prefs_->GetString(prefs::kSessionExitType)); 806 if (exit_type_pref_value.empty()) { 807 last_session_exit_type_ = 808 prefs_->GetBoolean(prefs::kSessionExitedCleanly) ? 809 EXIT_NORMAL : EXIT_CRASHED; 810 } else { 811 last_session_exit_type_ = 812 SessionTypePrefValueToExitType(exit_type_pref_value); 813 } 814 // Mark the session as open. 815 prefs_->SetString(prefs::kSessionExitType, kPrefExitTypeCrashed); 816 // Force this to true in case we fallback and use it. 817 // TODO(sky): remove this in a couple of releases (m28ish). 818 prefs_->SetBoolean(prefs::kSessionExitedCleanly, true); 819 820 g_browser_process->profile_manager()->InitProfileUserPrefs(this); 821 822 BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices( 823 this); 824 825 DCHECK(!net_pref_observer_); 826 { 827 TRACE_EVENT0("browser", "ProfileImpl::OnPrefsLoaded:NetPrefObserver") 828 net_pref_observer_.reset(new NetPrefObserver( 829 prefs_.get(), 830 prerender::PrerenderManagerFactory::GetForProfile(this), 831 predictor_)); 832 } 833 834 chrome_prefs::SchedulePrefsFilePathVerification(path_); 835 836 ChromeVersionService::OnProfileLoaded(prefs_.get(), IsNewProfile()); 837 DoFinalInit(); 838} 839 840bool ProfileImpl::WasCreatedByVersionOrLater(const std::string& version) { 841 Version profile_version(ChromeVersionService::GetVersion(prefs_.get())); 842 Version arg_version(version); 843 return (profile_version.CompareTo(arg_version) >= 0); 844} 845 846void ProfileImpl::SetExitType(ExitType exit_type) { 847#if defined(OS_CHROMEOS) 848 if (chromeos::ProfileHelper::IsSigninProfile(this)) 849 return; 850#endif 851 if (!prefs_) 852 return; 853 ExitType current_exit_type = SessionTypePrefValueToExitType( 854 prefs_->GetString(prefs::kSessionExitType)); 855 // This may be invoked multiple times during shutdown. Only persist the value 856 // first passed in (unless it's a reset to the crash state, which happens when 857 // foregrounding the app on mobile). 858 if (exit_type == EXIT_CRASHED || current_exit_type == EXIT_CRASHED) { 859 prefs_->SetString(prefs::kSessionExitType, 860 ExitTypeToSessionTypePrefValue(exit_type)); 861 862 // NOTE: If you change what thread this writes on, be sure and update 863 // chrome::SessionEnding(). 864 prefs_->CommitPendingWrite(); 865 } 866} 867 868Profile::ExitType ProfileImpl::GetLastSessionExitType() { 869 // last_session_exited_cleanly_ is set when the preferences are loaded. Force 870 // it to be set by asking for the prefs. 871 GetPrefs(); 872 return last_session_exit_type_; 873} 874 875PrefService* ProfileImpl::GetPrefs() { 876 DCHECK(prefs_); // Should explicitly be initialized. 877 return prefs_.get(); 878} 879 880PrefService* ProfileImpl::GetOffTheRecordPrefs() { 881 DCHECK(prefs_); 882 if (!otr_prefs_) { 883 // The new ExtensionPrefStore is ref_counted and the new PrefService 884 // stores a reference so that we do not leak memory here. 885 otr_prefs_.reset(prefs_->CreateIncognitoPrefService( 886 new ExtensionPrefStore( 887 ExtensionPrefValueMapFactory::GetForBrowserContext(this), true))); 888 } 889 return otr_prefs_.get(); 890} 891 892net::URLRequestContextGetter* ProfileImpl::CreateRequestContext( 893 content::ProtocolHandlerMap* protocol_handlers, 894 content::ProtocolHandlerScopedVector protocol_interceptors) { 895 return io_data_.CreateMainRequestContextGetter( 896 protocol_handlers, 897 protocol_interceptors.Pass(), 898 g_browser_process->local_state(), 899 g_browser_process->io_thread()).get(); 900} 901 902net::URLRequestContextGetter* ProfileImpl::GetRequestContext() { 903 return GetDefaultStoragePartition(this)->GetURLRequestContext(); 904} 905 906net::URLRequestContextGetter* ProfileImpl::GetRequestContextForRenderProcess( 907 int renderer_child_id) { 908 content::RenderProcessHost* rph = content::RenderProcessHost::FromID( 909 renderer_child_id); 910 911 return rph->GetStoragePartition()->GetURLRequestContext(); 912} 913 914net::URLRequestContextGetter* ProfileImpl::GetMediaRequestContext() { 915 // Return the default media context. 916 return io_data_.GetMediaRequestContextGetter().get(); 917} 918 919net::URLRequestContextGetter* 920ProfileImpl::GetMediaRequestContextForRenderProcess( 921 int renderer_child_id) { 922 content::RenderProcessHost* rph = content::RenderProcessHost::FromID( 923 renderer_child_id); 924 content::StoragePartition* storage_partition = rph->GetStoragePartition(); 925 926 return storage_partition->GetMediaURLRequestContext(); 927} 928 929net::URLRequestContextGetter* 930ProfileImpl::GetMediaRequestContextForStoragePartition( 931 const base::FilePath& partition_path, 932 bool in_memory) { 933 return io_data_ 934 .GetIsolatedMediaRequestContextGetter(partition_path, in_memory).get(); 935} 936 937void ProfileImpl::RequestMidiSysExPermission( 938 int render_process_id, 939 int render_view_id, 940 int bridge_id, 941 const GURL& requesting_frame, 942 const MidiSysExPermissionCallback& callback) { 943 ChromeMidiPermissionContext* context = 944 ChromeMidiPermissionContextFactory::GetForProfile(this); 945 context->RequestMidiSysExPermission(render_process_id, 946 render_view_id, 947 bridge_id, 948 requesting_frame, 949 callback); 950} 951 952void ProfileImpl::CancelMidiSysExPermissionRequest( 953 int render_process_id, 954 int render_view_id, 955 int bridge_id, 956 const GURL& requesting_frame) { 957 ChromeMidiPermissionContext* context = 958 ChromeMidiPermissionContextFactory::GetForProfile(this); 959 context->CancelMidiSysExPermissionRequest( 960 render_process_id, render_view_id, bridge_id, requesting_frame); 961} 962 963void ProfileImpl::RequestProtectedMediaIdentifierPermission( 964 int render_process_id, 965 int render_view_id, 966 int bridge_id, 967 int group_id, 968 const GURL& requesting_frame, 969 const ProtectedMediaIdentifierPermissionCallback& callback) { 970#if defined(OS_ANDROID) 971 ProtectedMediaIdentifierPermissionContext* context = 972 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(this); 973 context->RequestProtectedMediaIdentifierPermission(render_process_id, 974 render_view_id, 975 bridge_id, 976 group_id, 977 requesting_frame, 978 callback); 979#else 980 NOTIMPLEMENTED(); 981 callback.Run(false); 982#endif // defined(OS_ANDROID) 983} 984 985void ProfileImpl::CancelProtectedMediaIdentifierPermissionRequests( 986 int group_id) { 987#if defined(OS_ANDROID) 988 ProtectedMediaIdentifierPermissionContext* context = 989 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(this); 990 context->CancelProtectedMediaIdentifierPermissionRequests(group_id); 991#else 992 NOTIMPLEMENTED(); 993#endif // defined(OS_ANDROID) 994} 995 996content::ResourceContext* ProfileImpl::GetResourceContext() { 997 return io_data_.GetResourceContext(); 998} 999 1000net::URLRequestContextGetter* ProfileImpl::GetRequestContextForExtensions() { 1001 return io_data_.GetExtensionsRequestContextGetter().get(); 1002} 1003 1004net::URLRequestContextGetter* 1005ProfileImpl::CreateRequestContextForStoragePartition( 1006 const base::FilePath& partition_path, 1007 bool in_memory, 1008 content::ProtocolHandlerMap* protocol_handlers, 1009 content::ProtocolHandlerScopedVector protocol_interceptors) { 1010 return io_data_.CreateIsolatedAppRequestContextGetter( 1011 partition_path, 1012 in_memory, 1013 protocol_handlers, 1014 protocol_interceptors.Pass()).get(); 1015} 1016 1017net::SSLConfigService* ProfileImpl::GetSSLConfigService() { 1018 // If ssl_config_service_manager_ is null, this typically means that some 1019 // KeyedService is trying to create a RequestContext at startup, 1020 // but SSLConfigServiceManager is not initialized until DoFinalInit() which is 1021 // invoked after all KeyedServices have been initialized (see 1022 // http://crbug.com/171406). 1023 DCHECK(ssl_config_service_manager_) << 1024 "SSLConfigServiceManager is not initialized yet"; 1025 return ssl_config_service_manager_->Get(); 1026} 1027 1028HostContentSettingsMap* ProfileImpl::GetHostContentSettingsMap() { 1029 if (!host_content_settings_map_.get()) { 1030 host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false); 1031 } 1032 return host_content_settings_map_.get(); 1033} 1034 1035content::GeolocationPermissionContext* 1036 ProfileImpl::GetGeolocationPermissionContext() { 1037 return ChromeGeolocationPermissionContextFactory::GetForProfile(this); 1038} 1039 1040DownloadManagerDelegate* ProfileImpl::GetDownloadManagerDelegate() { 1041 return DownloadServiceFactory::GetForBrowserContext(this)-> 1042 GetDownloadManagerDelegate(); 1043} 1044 1045quota::SpecialStoragePolicy* ProfileImpl::GetSpecialStoragePolicy() { 1046 return GetExtensionSpecialStoragePolicy(); 1047} 1048 1049bool ProfileImpl::IsSameProfile(Profile* profile) { 1050 if (profile == static_cast<Profile*>(this)) 1051 return true; 1052 Profile* otr_profile = off_the_record_profile_.get(); 1053 return otr_profile && profile == otr_profile; 1054} 1055 1056Time ProfileImpl::GetStartTime() const { 1057 return start_time_; 1058} 1059 1060history::TopSites* ProfileImpl::GetTopSites() { 1061 if (!top_sites_.get()) { 1062 top_sites_ = history::TopSites::Create( 1063 this, GetPath().Append(chrome::kTopSitesFilename)); 1064 } 1065 return top_sites_.get(); 1066} 1067 1068history::TopSites* ProfileImpl::GetTopSitesWithoutCreating() { 1069 return top_sites_.get(); 1070} 1071 1072void ProfileImpl::OnDefaultZoomLevelChanged() { 1073 HostZoomMap::GetForBrowserContext(this)->SetDefaultZoomLevel( 1074 pref_change_registrar_.prefs()->GetDouble(prefs::kDefaultZoomLevel)); 1075} 1076 1077void ProfileImpl::OnZoomLevelChanged( 1078 const HostZoomMap::ZoomLevelChange& change) { 1079 1080 if (change.mode != HostZoomMap::ZOOM_CHANGED_FOR_HOST) 1081 return; 1082 HostZoomMap* host_zoom_map = HostZoomMap::GetForBrowserContext(this); 1083 double level = change.zoom_level; 1084 DictionaryPrefUpdate update(prefs_.get(), prefs::kPerHostZoomLevels); 1085 base::DictionaryValue* host_zoom_dictionary = update.Get(); 1086 if (level == host_zoom_map->GetDefaultZoomLevel()) { 1087 host_zoom_dictionary->RemoveWithoutPathExpansion(change.host, NULL); 1088 } else { 1089 host_zoom_dictionary->SetWithoutPathExpansion( 1090 change.host, base::Value::CreateDoubleValue(level)); 1091 } 1092} 1093 1094#if defined(ENABLE_SESSION_SERVICE) 1095void ProfileImpl::StopCreateSessionServiceTimer() { 1096 create_session_service_timer_.Stop(); 1097} 1098 1099void ProfileImpl::EnsureSessionServiceCreated() { 1100 SessionServiceFactory::GetForProfile(this); 1101} 1102#endif 1103 1104#if defined(OS_CHROMEOS) 1105void ProfileImpl::ChangeAppLocale( 1106 const std::string& new_locale, AppLocaleChangedVia via) { 1107 if (new_locale.empty()) { 1108 NOTREACHED(); 1109 return; 1110 } 1111 PrefService* local_state = g_browser_process->local_state(); 1112 DCHECK(local_state); 1113 if (local_state->IsManagedPreference(prefs::kApplicationLocale)) 1114 return; 1115 std::string pref_locale = GetPrefs()->GetString(prefs::kApplicationLocale); 1116 bool do_update_pref = true; 1117 switch (via) { 1118 case APP_LOCALE_CHANGED_VIA_SETTINGS: 1119 case APP_LOCALE_CHANGED_VIA_REVERT: { 1120 // We keep kApplicationLocaleBackup value as a reference. In case value 1121 // of kApplicationLocale preference would change due to sync from other 1122 // device then kApplicationLocaleBackup value will trigger and allow us to 1123 // show notification about automatic locale change in LocaleChangeGuard. 1124 GetPrefs()->SetString(prefs::kApplicationLocaleBackup, new_locale); 1125 GetPrefs()->ClearPref(prefs::kApplicationLocaleAccepted); 1126 // We maintain kApplicationLocale property in both a global storage 1127 // and user's profile. Global property determines locale of login screen, 1128 // while user's profile determines his personal locale preference. 1129 break; 1130 } 1131 case APP_LOCALE_CHANGED_VIA_LOGIN: { 1132 if (!pref_locale.empty()) { 1133 DCHECK(pref_locale == new_locale); 1134 std::string accepted_locale = 1135 GetPrefs()->GetString(prefs::kApplicationLocaleAccepted); 1136 if (accepted_locale == new_locale) { 1137 // If locale is accepted then we do not want to show LocaleChange 1138 // notification. This notification is triggered by different values 1139 // of kApplicationLocaleBackup and kApplicationLocale preferences, 1140 // so make them identical. 1141 GetPrefs()->SetString(prefs::kApplicationLocaleBackup, new_locale); 1142 } else { 1143 // Back up locale of login screen. 1144 std::string cur_locale = g_browser_process->GetApplicationLocale(); 1145 GetPrefs()->SetString(prefs::kApplicationLocaleBackup, cur_locale); 1146 if (locale_change_guard_ == NULL) 1147 locale_change_guard_.reset(new chromeos::LocaleChangeGuard(this)); 1148 locale_change_guard_->PrepareChangingLocale(cur_locale, new_locale); 1149 } 1150 } else { 1151 std::string cur_locale = g_browser_process->GetApplicationLocale(); 1152 std::string backup_locale = 1153 GetPrefs()->GetString(prefs::kApplicationLocaleBackup); 1154 // Profile synchronization takes time and is not completed at that 1155 // moment at first login. So we initialize locale preference in steps: 1156 // (1) first save it to temporary backup; 1157 // (2) on next login we assume that synchronization is already completed 1158 // and we may finalize initialization. 1159 GetPrefs()->SetString(prefs::kApplicationLocaleBackup, cur_locale); 1160 if (!new_locale.empty()) 1161 GetPrefs()->SetString(prefs::kApplicationLocale, new_locale); 1162 else if (!backup_locale.empty()) 1163 GetPrefs()->SetString(prefs::kApplicationLocale, backup_locale); 1164 do_update_pref = false; 1165 } 1166 break; 1167 } 1168 case APP_LOCALE_CHANGED_VIA_UNKNOWN: 1169 default: { 1170 NOTREACHED(); 1171 break; 1172 } 1173 } 1174 if (do_update_pref) 1175 GetPrefs()->SetString(prefs::kApplicationLocale, new_locale); 1176 local_state->SetString(prefs::kApplicationLocale, new_locale); 1177 1178 if (chromeos::UserManager::Get()->GetOwnerEmail() == 1179 chromeos::UserManager::Get()->GetUserByProfile(this)->email()) 1180 local_state->SetString(prefs::kOwnerLocale, new_locale); 1181} 1182 1183void ProfileImpl::OnLogin() { 1184 if (locale_change_guard_ == NULL) 1185 locale_change_guard_.reset(new chromeos::LocaleChangeGuard(this)); 1186 locale_change_guard_->OnLogin(); 1187} 1188 1189void ProfileImpl::InitChromeOSPreferences() { 1190 chromeos_preferences_.reset(new chromeos::Preferences()); 1191 chromeos_preferences_->Init( 1192 PrefServiceSyncable::FromProfile(this), 1193 chromeos::UserManager::Get()->GetUserByProfile(this)); 1194} 1195 1196#endif // defined(OS_CHROMEOS) 1197 1198PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() { 1199 if (!pref_proxy_config_tracker_) 1200 pref_proxy_config_tracker_.reset(CreateProxyConfigTracker()); 1201 return pref_proxy_config_tracker_.get(); 1202} 1203 1204chrome_browser_net::Predictor* ProfileImpl::GetNetworkPredictor() { 1205 return predictor_; 1206} 1207 1208void ProfileImpl::ClearNetworkingHistorySince(base::Time time, 1209 const base::Closure& completion) { 1210 io_data_.ClearNetworkingHistorySince(time, completion); 1211} 1212 1213GURL ProfileImpl::GetHomePage() { 1214 // --homepage overrides any preferences. 1215 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1216 if (command_line.HasSwitch(switches::kHomePage)) { 1217 // TODO(evanm): clean up usage of DIR_CURRENT. 1218 // http://code.google.com/p/chromium/issues/detail?id=60630 1219 // For now, allow this code to call getcwd(). 1220 base::ThreadRestrictions::ScopedAllowIO allow_io; 1221 1222 base::FilePath browser_directory; 1223 PathService::Get(base::DIR_CURRENT, &browser_directory); 1224 GURL home_page(URLFixerUpper::FixupRelativeFile(browser_directory, 1225 command_line.GetSwitchValuePath(switches::kHomePage))); 1226 if (home_page.is_valid()) 1227 return home_page; 1228 } 1229 1230 if (GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage)) 1231 return GURL(chrome::kChromeUINewTabURL); 1232 GURL home_page(URLFixerUpper::FixupURL( 1233 GetPrefs()->GetString(prefs::kHomePage), 1234 std::string())); 1235 if (!home_page.is_valid()) 1236 return GURL(chrome::kChromeUINewTabURL); 1237 return home_page; 1238} 1239 1240void ProfileImpl::UpdateProfileUserNameCache() { 1241 ProfileManager* profile_manager = g_browser_process->profile_manager(); 1242 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); 1243 size_t index = cache.GetIndexOfProfileWithPath(GetPath()); 1244 if (index != std::string::npos) { 1245 std::string user_name = 1246 GetPrefs()->GetString(prefs::kGoogleServicesUsername); 1247 cache.SetUserNameOfProfileAtIndex(index, base::UTF8ToUTF16(user_name)); 1248 ProfileMetrics::UpdateReportedProfilesStatistics(profile_manager); 1249 } 1250} 1251 1252void ProfileImpl::UpdateProfileNameCache() { 1253 ProfileManager* profile_manager = g_browser_process->profile_manager(); 1254 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); 1255 size_t index = cache.GetIndexOfProfileWithPath(GetPath()); 1256 if (index != std::string::npos) { 1257 std::string profile_name = 1258 GetPrefs()->GetString(prefs::kProfileName); 1259 cache.SetNameOfProfileAtIndex(index, base::UTF8ToUTF16(profile_name)); 1260 } 1261} 1262 1263void ProfileImpl::UpdateProfileAvatarCache() { 1264 ProfileManager* profile_manager = g_browser_process->profile_manager(); 1265 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); 1266 size_t index = cache.GetIndexOfProfileWithPath(GetPath()); 1267 if (index != std::string::npos) { 1268 size_t avatar_index = 1269 GetPrefs()->GetInteger(prefs::kProfileAvatarIndex); 1270 cache.SetAvatarIconOfProfileAtIndex(index, avatar_index); 1271 } 1272} 1273 1274void ProfileImpl::UpdateProfileIsEphemeralCache() { 1275 ProfileManager* profile_manager = g_browser_process->profile_manager(); 1276 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); 1277 size_t index = cache.GetIndexOfProfileWithPath(GetPath()); 1278 if (index != std::string::npos) { 1279 bool is_ephemeral = GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles); 1280 cache.SetProfileIsEphemeralAtIndex(index, is_ephemeral); 1281 } 1282} 1283 1284// Gets the cache parameters from the command line. If |is_media_context| is 1285// set to true then settings for the media context type is what we need, 1286// |cache_path| will be set to the user provided path, or will not be touched if 1287// there is not an argument. |max_size| will be the user provided value or zero 1288// by default. 1289void ProfileImpl::GetCacheParameters(bool is_media_context, 1290 base::FilePath* cache_path, 1291 int* max_size) { 1292 DCHECK(cache_path); 1293 DCHECK(max_size); 1294 base::FilePath path(prefs_->GetFilePath(prefs::kDiskCacheDir)); 1295 if (!path.empty()) 1296 *cache_path = path; 1297 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : 1298 prefs_->GetInteger(prefs::kDiskCacheSize); 1299} 1300 1301PrefProxyConfigTracker* ProfileImpl::CreateProxyConfigTracker() { 1302#if defined(OS_CHROMEOS) 1303 if (chromeos::ProfileHelper::IsSigninProfile(this)) { 1304 return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( 1305 g_browser_process->local_state()); 1306 } 1307#endif // defined(OS_CHROMEOS) 1308 return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( 1309 GetPrefs(), g_browser_process->local_state()); 1310} 1311