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