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