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