Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / profile_impl.cc
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       local_state,
1439       prefs::kMetricsReportingEnabled);
1440 }