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