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