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