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