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