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.
5 #include "chrome/browser/profiles/profile_impl.h"
8 #include "base/callback.h"
9 #include "base/command_line.h"
10 #include "base/compiler_specific.h"
11 #include "base/environment.h"
12 #include "base/file_util.h"
13 #include "base/files/file_path.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/path_service.h"
16 #include "base/prefs/json_pref_store.h"
17 #include "base/string_util.h"
18 #include "base/stringprintf.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/synchronization/waitable_event.h"
21 #include "base/threading/sequenced_worker_pool.h"
22 #include "base/utf_string_conversions.h"
23 #include "base/version.h"
24 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
25 #include "chrome/browser/background/background_contents_service_factory.h"
26 #include "chrome/browser/background/background_mode_manager.h"
27 #include "chrome/browser/bookmarks/bookmark_model.h"
28 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
29 #include "chrome/browser/browser_process.h"
30 #include "chrome/browser/content_settings/cookie_settings.h"
31 #include "chrome/browser/content_settings/host_content_settings_map.h"
32 #include "chrome/browser/download/chrome_download_manager_delegate.h"
33 #include "chrome/browser/download/download_service.h"
34 #include "chrome/browser/download/download_service_factory.h"
35 #include "chrome/browser/extensions/extension_pref_store.h"
36 #include "chrome/browser/extensions/extension_pref_value_map.h"
37 #include "chrome/browser/extensions/extension_pref_value_map_factory.h"
38 #include "chrome/browser/extensions/extension_service.h"
39 #include "chrome/browser/extensions/extension_special_storage_policy.h"
40 #include "chrome/browser/extensions/extension_system.h"
41 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
42 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
43 #include "chrome/browser/history/shortcuts_backend.h"
44 #include "chrome/browser/history/top_sites.h"
45 #include "chrome/browser/metrics/metrics_service.h"
46 #include "chrome/browser/net/chrome_url_request_context.h"
47 #include "chrome/browser/net/net_pref_observer.h"
48 #include "chrome/browser/net/predictor.h"
49 #include "chrome/browser/net/proxy_service_factory.h"
50 #include "chrome/browser/net/ssl_config_service_manager.h"
51 #include "chrome/browser/net/url_fixer_upper.h"
52 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
53 #include "chrome/browser/plugins/plugin_prefs.h"
54 #include "chrome/browser/prefs/browser_prefs.h"
55 #include "chrome/browser/prefs/chrome_pref_service_factory.h"
56 #include "chrome/browser/prefs/pref_service_syncable.h"
57 #include "chrome/browser/prefs/scoped_user_pref_update.h"
58 #include "chrome/browser/prerender/prerender_manager_factory.h"
59 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
60 #include "chrome/browser/profiles/chrome_version_service.h"
61 #include "chrome/browser/profiles/gaia_info_update_service_factory.h"
62 #include "chrome/browser/profiles/profile_dependency_manager.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/search_engines/template_url_fetcher.h"
67 #include "chrome/browser/sessions/session_service_factory.h"
68 #include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
69 #include "chrome/browser/ui/startup/startup_browser_creator.h"
70 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
71 #include "chrome/browser/user_style_sheet_watcher.h"
72 #include "chrome/browser/webdata/web_data_service.h"
73 #include "chrome/common/chrome_constants.h"
74 #include "chrome/common/chrome_notification_types.h"
75 #include "chrome/common/chrome_paths_internal.h"
76 #include "chrome/common/chrome_switches.h"
77 #include "chrome/common/chrome_version_info.h"
78 #include "chrome/common/pref_names.h"
79 #include "chrome/common/startup_metric_utils.h"
80 #include "chrome/common/url_constants.h"
81 #include "components/user_prefs/pref_registry_syncable.h"
82 #include "components/user_prefs/user_prefs.h"
83 #include "content/public/browser/browser_thread.h"
84 #include "content/public/browser/dom_storage_context.h"
85 #include "content/public/browser/host_zoom_map.h"
86 #include "content/public/browser/notification_service.h"
87 #include "content/public/browser/render_process_host.h"
88 #include "content/public/browser/storage_partition.h"
89 #include "content/public/browser/user_metrics.h"
90 #include "content/public/common/content_constants.h"
91 #include "grit/chromium_strings.h"
92 #include "grit/generated_resources.h"
93 #include "ui/base/l10n/l10n_util.h"
95 #if defined(ENABLE_CONFIGURATION_POLICY)
96 #include "chrome/browser/policy/browser_policy_connector.h"
97 #if !defined(OS_CHROMEOS)
98 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
99 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
101 #if defined(ENABLE_MANAGED_USERS)
102 #include "chrome/browser/policy/managed_mode_policy_provider.h"
105 #include "chrome/browser/policy/policy_service_stub.h"
106 #endif // defined(ENABLE_CONFIGURATION_POLICY)
109 #include "chrome/installer/util/install_util.h"
112 #if defined(OS_CHROMEOS)
113 #include "chrome/browser/chromeos/enterprise_extension_observer.h"
114 #include "chrome/browser/chromeos/locale_change_guard.h"
115 #include "chrome/browser/chromeos/login/user_manager.h"
116 #include "chrome/browser/chromeos/preferences.h"
117 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
121 using base::TimeDelta
;
122 using content::BrowserThread
;
123 using content::DownloadManagerDelegate
;
124 using content::HostZoomMap
;
125 using content::UserMetricsAction
;
129 // Constrict us to a very specific platform and architecture to make sure
130 // ifdefs don't cause problems with the check.
131 #if defined(OS_LINUX) && defined(TOOLKIT_GTK) && defined(ARCH_CPU_X86_64) && \
132 !defined(_GLIBCXX_DEBUG)
133 // Make sure that the ProfileImpl doesn't grow. We're currently trying to drive
134 // the number of services that are included in ProfileImpl (instead of using
135 // ProfileKeyedServiceFactory) to zero.
137 // If you don't know about this effort, please read:
138 // https://sites.google.com/a/chromium.org/dev/developers/design-documents/profile-architecture
140 // REVIEWERS: Do not let anyone increment this. We need to drive the number of
141 // raw accessed services down to zero. DO NOT LET PEOPLE REGRESS THIS UNLESS
142 // THE PATCH ITSELF IS MAKING PROGRESS ON PKSF REFACTORING.
143 COMPILE_ASSERT(sizeof(ProfileImpl
) <= 744u, profile_impl_size_unexpected
);
146 #if defined(ENABLE_SESSION_SERVICE)
147 // Delay, in milliseconds, before we explicitly create the SessionService.
148 static const int kCreateSessionServiceDelayMS
= 500;
151 // Text content of README file created in each profile directory. Both %s
152 // placeholders must contain the product name. This is not localizable and hence
154 static const char kReadmeText
[] =
155 "%s settings and storage represent user-selected preferences and "
156 "information and MUST not be extracted, overwritten or modified except "
157 "through %s defined APIs.";
159 // Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED.
160 const char* const kPrefExitTypeCrashed
= "Crashed";
161 const char* const kPrefExitTypeSessionEnded
= "SessionEnded";
163 // Helper method needed because PostTask cannot currently take a Callback
164 // function with non-void return type.
165 void CreateDirectoryAndSignal(const base::FilePath
& path
,
166 base::WaitableEvent
* done_creating
) {
167 DVLOG(1) << "Creating directory " << path
.value();
168 file_util::CreateDirectory(path
);
169 done_creating
->Signal();
172 // Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on
173 // blocking I/O pool.
174 void BlockFileThreadOnDirectoryCreate(base::WaitableEvent
* done_creating
) {
175 done_creating
->Wait();
178 // Initiates creation of profile directory on |sequenced_task_runner| and
179 // ensures that FILE thread is blocked until that operation finishes.
180 void CreateProfileDirectory(base::SequencedTaskRunner
* sequenced_task_runner
,
181 const base::FilePath
& path
) {
182 base::WaitableEvent
* done_creating
= new base::WaitableEvent(false, false);
183 sequenced_task_runner
->PostTask(FROM_HERE
,
184 base::Bind(&CreateDirectoryAndSignal
,
187 // Block the FILE thread until directory is created on I/O pool to make sure
188 // that we don't attempt any operation until that part completes.
189 BrowserThread::PostTask(
190 BrowserThread::FILE, FROM_HERE
,
191 base::Bind(&BlockFileThreadOnDirectoryCreate
,
192 base::Owned(done_creating
)));
195 base::FilePath
GetCachePath(const base::FilePath
& base
) {
196 return base
.Append(chrome::kCacheDirname
);
199 base::FilePath
GetMediaCachePath(const base::FilePath
& base
) {
200 return base
.Append(chrome::kMediaCacheDirname
);
203 void EnsureReadmeFile(const base::FilePath
& base
) {
204 base::FilePath readme_path
= base
.Append(chrome::kReadmeFilename
);
205 if (file_util::PathExists(readme_path
))
207 std::string product_name
= l10n_util::GetStringUTF8(IDS_PRODUCT_NAME
);
208 std::string readme_text
= base::StringPrintf(
209 kReadmeText
, product_name
.c_str(), product_name
.c_str());
210 if (file_util::WriteFile(
211 readme_path
, readme_text
.data(), readme_text
.size()) == -1) {
212 LOG(ERROR
) << "Could not create README file.";
216 // Converts the kSessionExitedCleanly pref to the corresponding EXIT_TYPE.
217 Profile::ExitType
SessionTypePrefValueToExitType(const std::string
& value
) {
218 if (value
== kPrefExitTypeSessionEnded
)
219 return Profile::EXIT_SESSION_ENDED
;
220 if (value
== kPrefExitTypeCrashed
)
221 return Profile::EXIT_CRASHED
;
222 return Profile::EXIT_NORMAL
;
225 // Converts an ExitType into a string that is written to prefs.
226 std::string
ExitTypeToSessionTypePrefValue(Profile::ExitType type
) {
228 case Profile::EXIT_NORMAL
:
229 return ProfileImpl::kPrefExitTypeNormal
;
230 case Profile::EXIT_SESSION_ENDED
:
231 return kPrefExitTypeSessionEnded
;
232 case Profile::EXIT_CRASHED
:
233 return kPrefExitTypeCrashed
;
236 return std::string();
242 Profile
* Profile::CreateProfile(const base::FilePath
& path
,
244 CreateMode create_mode
) {
245 // Get sequenced task runner for making sure that file operations of
246 // this profile (defined by |path|) are executed in expected order
247 // (what was previously assured by the FILE thread).
248 scoped_refptr
<base::SequencedTaskRunner
> sequenced_task_runner
=
249 JsonPrefStore::GetTaskRunnerForFile(path
,
250 BrowserThread::GetBlockingPool());
251 if (create_mode
== CREATE_MODE_ASYNCHRONOUS
) {
253 CreateProfileDirectory(sequenced_task_runner
, path
);
254 } else if (create_mode
== CREATE_MODE_SYNCHRONOUS
) {
255 if (!file_util::PathExists(path
)) {
256 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the
257 // profile directory. We should eventually be able to run in this
259 if (!file_util::CreateDirectory(path
))
266 return new ProfileImpl(path
, delegate
, create_mode
, sequenced_task_runner
);
270 int ProfileImpl::create_readme_delay_ms
= 60000;
273 const char* const ProfileImpl::kPrefExitTypeNormal
= "Normal";
276 void ProfileImpl::RegisterUserPrefs(PrefRegistrySyncable
* registry
) {
277 registry
->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled
,
279 PrefRegistrySyncable::UNSYNCABLE_PREF
);
280 registry
->RegisterBooleanPref(prefs::kAllowDeletingBrowserHistory
,
282 PrefRegistrySyncable::UNSYNCABLE_PREF
);
283 registry
->RegisterBooleanPref(prefs::kSigninAllowed
,
285 PrefRegistrySyncable::UNSYNCABLE_PREF
);
286 registry
->RegisterBooleanPref(prefs::kForceSafeSearch
,
288 PrefRegistrySyncable::UNSYNCABLE_PREF
);
289 registry
->RegisterIntegerPref(prefs::kProfileAvatarIndex
,
291 PrefRegistrySyncable::SYNCABLE_PREF
);
292 registry
->RegisterStringPref(
293 prefs::kProfileName
, std::string(), PrefRegistrySyncable::SYNCABLE_PREF
);
294 registry
->RegisterBooleanPref(prefs::kProfileIsManaged
,
296 PrefRegistrySyncable::SYNCABLE_PREF
);
297 registry
->RegisterStringPref(prefs::kHomePage
,
299 PrefRegistrySyncable::SYNCABLE_PREF
);
300 #if defined(ENABLE_PRINTING)
301 registry
->RegisterBooleanPref(prefs::kPrintingEnabled
,
303 PrefRegistrySyncable::UNSYNCABLE_PREF
);
305 registry
->RegisterBooleanPref(prefs::kPrintPreviewDisabled
,
306 #if defined(GOOGLE_CHROME_BUILD)
311 PrefRegistrySyncable::UNSYNCABLE_PREF
);
313 // Initialize the cache prefs.
314 registry
->RegisterFilePathPref(prefs::kDiskCacheDir
,
316 PrefRegistrySyncable::UNSYNCABLE_PREF
);
317 registry
->RegisterIntegerPref(prefs::kDiskCacheSize
,
319 PrefRegistrySyncable::UNSYNCABLE_PREF
);
320 registry
->RegisterIntegerPref(prefs::kMediaCacheSize
,
322 PrefRegistrySyncable::UNSYNCABLE_PREF
);
324 // Deprecated. Kept around for migration.
325 registry
->RegisterBooleanPref(prefs::kClearSiteDataOnExit
,
327 PrefRegistrySyncable::SYNCABLE_PREF
);
330 ProfileImpl::ProfileImpl(
331 const base::FilePath
& path
,
333 CreateMode create_mode
,
334 base::SequencedTaskRunner
* sequenced_task_runner
)
335 : zoom_callback_(base::Bind(&ProfileImpl::OnZoomLevelChanged
,
336 base::Unretained(this))),
338 pref_registry_(new PrefRegistrySyncable
),
339 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)),
340 host_content_settings_map_(NULL
),
341 last_session_exit_type_(EXIT_NORMAL
),
342 start_time_(Time::Now()),
345 DCHECK(!path
.empty()) << "Using an empty path will attempt to write " <<
346 "profile files to the root directory!";
348 #if defined(ENABLE_SESSION_SERVICE)
349 create_session_service_timer_
.Start(FROM_HERE
,
350 TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS
), this,
351 &ProfileImpl::EnsureSessionServiceCreated
);
354 // Determine if prefetch is enabled for this profile.
355 // If not profile_manager is present, it means we are in a unittest.
356 const CommandLine
* command_line
= CommandLine::ForCurrentProcess();
357 predictor_
= chrome_browser_net::Predictor::CreatePredictor(
358 !command_line
->HasSwitch(switches::kDisablePreconnect
),
359 g_browser_process
->profile_manager() == NULL
);
361 #if defined(ENABLE_CONFIGURATION_POLICY)
362 // If we are creating the profile synchronously, then we should load the
363 // policy data immediately.
364 bool force_immediate_policy_load
= (create_mode
== CREATE_MODE_SYNCHRONOUS
);
366 // TODO(atwilson): Change |cloud_policy_manager_| and
367 // |managed_mode_policy_provider_| to proper ProfileKeyedServices once
368 // PrefServiceSyncable is a ProfileKeyedService (policy must be initialized
369 // before PrefServiceSyncable because PrefServiceSyncable depends on policy
370 // loading to get overridden pref values).
371 #if !defined(OS_CHROMEOS)
372 if (!command_line
->HasSwitch(switches::kDisableCloudPolicyOnSignin
)) {
373 cloud_policy_manager_
=
374 policy::UserCloudPolicyManagerFactory::CreateForProfile(
375 this, force_immediate_policy_load
);
376 cloud_policy_manager_
->Init();
379 #if defined(ENABLE_MANAGED_USERS)
380 managed_mode_policy_provider_
=
381 policy::ManagedModePolicyProvider::Create(this,
382 sequenced_task_runner
,
383 force_immediate_policy_load
);
384 managed_mode_policy_provider_
->Init();
387 g_browser_process
->browser_policy_connector()->CreatePolicyService(this);
389 policy_service_
.reset(new policy::PolicyServiceStub());
392 DCHECK(create_mode
== CREATE_MODE_ASYNCHRONOUS
||
393 create_mode
== CREATE_MODE_SYNCHRONOUS
);
394 bool async_prefs
= create_mode
== CREATE_MODE_ASYNCHRONOUS
;
396 chrome::RegisterUserPrefs(pref_registry_
);
399 // On startup, preference loading is always synchronous so a scoped timer
401 startup_metric_utils::ScopedSlowStartupUMA
402 scoped_timer("Startup.SlowStartupPreferenceLoading");
403 prefs_
.reset(chrome_prefs::CreateProfilePrefs(
405 sequenced_task_runner
,
406 policy_service_
.get(),
407 new ExtensionPrefStore(
408 ExtensionPrefValueMapFactory::GetForProfile(this), false),
411 // Register on BrowserContext.
412 components::UserPrefs::Set(this, prefs_
.get());
415 startup_metric_utils::ScopedSlowStartupUMA
416 scoped_timer("Startup.SlowStartupFinalProfileInit");
418 // Wait for the notification that prefs has been loaded
419 // (successfully or not). Note that we can use base::Unretained
420 // because the PrefService is owned by this class and lives on
422 prefs_
->AddPrefInitObserver(base::Bind(&ProfileImpl::OnPrefsLoaded
,
423 base::Unretained(this)));
425 // Prefs were loaded synchronously so we can continue directly.
430 void ProfileImpl::DoFinalInit() {
431 PrefService
* prefs
= GetPrefs();
432 pref_change_registrar_
.Init(prefs
);
433 pref_change_registrar_
.Add(
434 prefs::kGoogleServicesUsername
,
435 base::Bind(&ProfileImpl::UpdateProfileUserNameCache
,
436 base::Unretained(this)));
437 pref_change_registrar_
.Add(
438 prefs::kDefaultZoomLevel
,
439 base::Bind(&ProfileImpl::OnDefaultZoomLevelChanged
,
440 base::Unretained(this)));
441 pref_change_registrar_
.Add(
442 prefs::kProfileAvatarIndex
,
443 base::Bind(&ProfileImpl::UpdateProfileAvatarCache
,
444 base::Unretained(this)));
445 pref_change_registrar_
.Add(
447 base::Bind(&ProfileImpl::UpdateProfileNameCache
,
448 base::Unretained(this)));
450 // It would be nice to use PathService for fetching this directory, but
451 // the cache directory depends on the profile directory, which isn't available
453 chrome::GetUserCacheDirectory(path_
, &base_cache_path_
);
454 // Always create the cache directory asynchronously.
455 scoped_refptr
<base::SequencedTaskRunner
> sequenced_task_runner
=
456 JsonPrefStore::GetTaskRunnerForFile(base_cache_path_
,
457 BrowserThread::GetBlockingPool());
458 CreateProfileDirectory(sequenced_task_runner
, base_cache_path_
);
460 // Now that the profile is hooked up to receive pref change notifications to
461 // kGoogleServicesUsername, initialize components that depend on it to reflect
462 // the current value.
463 UpdateProfileUserNameCache();
464 GAIAInfoUpdateServiceFactory::GetForProfile(this);
466 PrefService
* local_state
= g_browser_process
->local_state();
467 ssl_config_service_manager_
.reset(
468 SSLConfigServiceManager::CreateDefaultManager(local_state
, prefs
));
470 // Initialize the BackgroundModeManager - this has to be done here before
471 // InitExtensions() is called because it relies on receiving notifications
472 // when extensions are loaded. BackgroundModeManager is not needed under
473 // ChromeOS because Chrome is always running, no need for special keep-alive
474 // or launch-on-startup support unless kKeepAliveForTest is set.
475 bool init_background_mode_manager
= true;
476 #if defined(OS_CHROMEOS)
477 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kKeepAliveForTest
))
478 init_background_mode_manager
= false;
480 if (init_background_mode_manager
) {
481 if (g_browser_process
->background_mode_manager())
482 g_browser_process
->background_mode_manager()->RegisterProfile(this);
485 base::FilePath cookie_path
= GetPath();
486 cookie_path
= cookie_path
.Append(chrome::kCookieFilename
);
487 base::FilePath server_bound_cert_path
= GetPath();
488 server_bound_cert_path
=
489 server_bound_cert_path
.Append(chrome::kOBCertFilename
);
490 base::FilePath cache_path
= base_cache_path_
;
492 GetCacheParameters(false, &cache_path
, &cache_max_size
);
493 cache_path
= GetCachePath(cache_path
);
495 base::FilePath media_cache_path
= base_cache_path_
;
496 int media_cache_max_size
;
497 GetCacheParameters(true, &media_cache_path
, &media_cache_max_size
);
498 media_cache_path
= GetMediaCachePath(media_cache_path
);
500 base::FilePath extensions_cookie_path
= GetPath();
501 extensions_cookie_path
=
502 extensions_cookie_path
.Append(chrome::kExtensionsCookieFilename
);
504 base::FilePath infinite_cache_path
= GetPath();
505 infinite_cache_path
=
506 infinite_cache_path
.Append(FILE_PATH_LITERAL("Infinite Cache"));
508 #if defined(OS_ANDROID)
509 SessionStartupPref::Type startup_pref_type
=
510 SessionStartupPref::GetDefaultStartupType();
512 SessionStartupPref::Type startup_pref_type
=
513 StartupBrowserCreator::GetSessionStartupPref(
514 *CommandLine::ForCurrentProcess(), this).type
;
516 bool restore_old_session_cookies
=
517 (GetLastSessionExitType() == Profile::EXIT_CRASHED
||
518 startup_pref_type
== SessionStartupPref::LAST
);
522 // Make sure we initialize the ProfileIOData after everything else has been
523 // initialized that we might be reading from the IO thread.
525 io_data_
.Init(cookie_path
, server_bound_cert_path
, cache_path
,
526 cache_max_size
, media_cache_path
, media_cache_max_size
,
527 extensions_cookie_path
, GetPath(), infinite_cache_path
,
529 restore_old_session_cookies
,
530 GetSpecialStoragePolicy());
532 #if defined(ENABLE_PLUGINS)
533 ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
534 PluginPrefs::GetForProfile(this),
535 io_data_
.GetResourceContextNoInit());
538 // Delay README creation to not impact startup performance.
539 BrowserThread::PostDelayedTask(
540 BrowserThread::FILE, FROM_HERE
,
541 base::Bind(&EnsureReadmeFile
, GetPath()),
542 base::TimeDelta::FromMilliseconds(create_readme_delay_ms
));
544 if (!CommandLine::ForCurrentProcess()->HasSwitch(
545 switches::kDisableRestoreSessionState
)) {
546 content::BrowserContext::GetDefaultStoragePartition(this)->
547 GetDOMStorageContext()->SetSaveSessionStorageOnDisk();
550 // Creation has been finished.
552 delegate_
->OnProfileCreated(this, true, IsNewProfile());
554 content::NotificationService::current()->Notify(
555 chrome::NOTIFICATION_PROFILE_CREATED
,
556 content::Source
<Profile
>(this),
557 content::NotificationService::NoDetails());
559 #if !defined(OS_CHROMEOS)
560 // Listen for bookmark model load, to bootstrap the sync service.
561 // On CrOS sync service will be initialized after sign in.
562 if (!g_browser_process
->profile_manager()->will_import()) {
563 // If |will_import()| is true we add the observer in
564 // ProfileManager::OnImportFinished().
565 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(this);
566 model
->AddObserver(new BookmarkModelLoadedObserver(this));
571 void ProfileImpl::InitHostZoomMap() {
572 HostZoomMap
* host_zoom_map
= HostZoomMap::GetForBrowserContext(this);
573 host_zoom_map
->SetDefaultZoomLevel(
574 prefs_
->GetDouble(prefs::kDefaultZoomLevel
));
576 const DictionaryValue
* host_zoom_dictionary
=
577 prefs_
->GetDictionary(prefs::kPerHostZoomLevels
);
578 // Careful: The returned value could be NULL if the pref has never been set.
579 if (host_zoom_dictionary
!= NULL
) {
580 for (DictionaryValue::Iterator
i(*host_zoom_dictionary
); !i
.IsAtEnd();
582 const std::string
& host(i
.key());
583 double zoom_level
= 0;
585 bool success
= i
.value().GetAsDouble(&zoom_level
);
587 host_zoom_map
->SetZoomLevelForHost(host
, zoom_level
);
591 host_zoom_map
->AddZoomLevelChangedCallback(zoom_callback_
);
594 base::FilePath
ProfileImpl::last_selected_directory() {
595 return GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory
);
598 void ProfileImpl::set_last_selected_directory(const base::FilePath
& path
) {
599 GetPrefs()->SetFilePath(prefs::kSelectFileLastDirectory
, path
);
602 ProfileImpl::~ProfileImpl() {
603 MaybeSendDestroyedNotification();
605 HostZoomMap::GetForBrowserContext(this)->RemoveZoomLevelChangedCallback(
608 bool prefs_loaded
= prefs_
->GetInitializationStatus() !=
609 PrefService::INITIALIZATION_STATUS_WAITING
;
611 #if defined(ENABLE_SESSION_SERVICE)
612 StopCreateSessionServiceTimer();
615 // Remove pref observers
616 pref_change_registrar_
.RemoveAll();
618 #if defined(ENABLE_PLUGINS)
619 ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext(
620 io_data_
.GetResourceContextNoInit());
623 // Destroy OTR profile and its profile services first.
624 if (off_the_record_profile_
.get()) {
625 ProfileDestroyer::DestroyOffTheRecordProfileNow(
626 off_the_record_profile_
.get());
628 ExtensionPrefValueMapFactory::GetForProfile(this)->
629 ClearAllIncognitoSessionOnlyPreferences();
632 ProfileDependencyManager::GetInstance()->DestroyProfileServices(this);
634 if (top_sites_
.get())
635 top_sites_
->Shutdown();
637 if (pref_proxy_config_tracker_
.get())
638 pref_proxy_config_tracker_
->DetachFromPrefService();
640 if (host_content_settings_map_
)
641 host_content_settings_map_
->ShutdownOnUIThread();
643 #if defined(ENABLE_CONFIGURATION_POLICY) && defined(ENABLE_MANAGED_USERS)
644 if (managed_mode_policy_provider_
)
645 managed_mode_policy_provider_
->Shutdown();
648 // This causes the Preferences file to be written to disk.
650 SetExitType(EXIT_NORMAL
);
653 std::string
ProfileImpl::GetProfileName() {
654 return GetPrefs()->GetString(prefs::kGoogleServicesUsername
);
657 base::FilePath
ProfileImpl::GetPath() {
661 scoped_refptr
<base::SequencedTaskRunner
> ProfileImpl::GetIOTaskRunner() {
662 return JsonPrefStore::GetTaskRunnerForFile(
663 GetPath(), BrowserThread::GetBlockingPool());
666 bool ProfileImpl::IsOffTheRecord() const {
670 Profile
* ProfileImpl::GetOffTheRecordProfile() {
671 if (!off_the_record_profile_
.get()) {
672 scoped_ptr
<Profile
> p(CreateOffTheRecordProfile());
673 off_the_record_profile_
.swap(p
);
675 content::NotificationService::current()->Notify(
676 chrome::NOTIFICATION_PROFILE_CREATED
,
677 content::Source
<Profile
>(off_the_record_profile_
.get()),
678 content::NotificationService::NoDetails());
680 return off_the_record_profile_
.get();
683 void ProfileImpl::DestroyOffTheRecordProfile() {
684 off_the_record_profile_
.reset();
685 ExtensionPrefValueMapFactory::GetForProfile(this)->
686 ClearAllIncognitoSessionOnlyPreferences();
689 bool ProfileImpl::HasOffTheRecordProfile() {
690 return off_the_record_profile_
.get() != NULL
;
693 Profile
* ProfileImpl::GetOriginalProfile() {
697 ExtensionService
* ProfileImpl::GetExtensionService() {
698 return extensions::ExtensionSystem::Get(this)->extension_service();
701 ExtensionSpecialStoragePolicy
*
702 ProfileImpl::GetExtensionSpecialStoragePolicy() {
703 if (!extension_special_storage_policy_
.get()) {
704 extension_special_storage_policy_
= new ExtensionSpecialStoragePolicy(
705 CookieSettings::Factory::GetForProfile(this));
707 return extension_special_storage_policy_
.get();
710 void ProfileImpl::OnPrefsLoaded(bool success
) {
713 delegate_
->OnProfileCreated(this, false, false);
717 // TODO(mirandac): remove migration code after 6 months (crbug.com/69995).
718 if (g_browser_process
->local_state())
719 chrome::MigrateBrowserPrefs(this, g_browser_process
->local_state());
720 // TODO(ivankr): remove cleanup code eventually (crbug.com/165672).
721 chrome::MigrateUserPrefs(this);
723 // |kSessionExitType| was added after |kSessionExitedCleanly|. If the pref
724 // value is empty fallback to checking for |kSessionExitedCleanly|.
725 const std::string
exit_type_pref_value(
726 prefs_
->GetString(prefs::kSessionExitType
));
727 if (exit_type_pref_value
.empty()) {
728 last_session_exit_type_
=
729 prefs_
->GetBoolean(prefs::kSessionExitedCleanly
) ?
730 EXIT_NORMAL
: EXIT_CRASHED
;
732 last_session_exit_type_
=
733 SessionTypePrefValueToExitType(exit_type_pref_value
);
735 // Mark the session as open.
736 prefs_
->SetString(prefs::kSessionExitType
, kPrefExitTypeCrashed
);
737 // Force this to true in case we fallback and use it.
738 // TODO(sky): remove this in a couple of releases (m28ish).
739 prefs_
->SetBoolean(prefs::kSessionExitedCleanly
, true);
741 ProfileDependencyManager::GetInstance()->CreateProfileServices(this, false);
743 DCHECK(!net_pref_observer_
.get());
744 net_pref_observer_
.reset(new NetPrefObserver(
746 prerender::PrerenderManagerFactory::GetForProfile(this),
749 ChromeVersionService::OnProfileLoaded(prefs_
.get(), IsNewProfile());
753 bool ProfileImpl::WasCreatedByVersionOrLater(const std::string
& version
) {
754 Version
profile_version(ChromeVersionService::GetVersion(prefs_
.get()));
755 Version
arg_version(version
);
756 return (profile_version
.CompareTo(arg_version
) >= 0);
759 void ProfileImpl::SetExitType(ExitType exit_type
) {
762 ExitType current_exit_type
= SessionTypePrefValueToExitType(
763 prefs_
->GetString(prefs::kSessionExitType
));
764 // This may be invoked multiple times during shutdown. Only persist the value
765 // first passed in (unless it's a reset to the crash state, which happens when
766 // foregrounding the app on mobile).
767 if (exit_type
== EXIT_CRASHED
|| current_exit_type
== EXIT_CRASHED
) {
768 prefs_
->SetString(prefs::kSessionExitType
,
769 ExitTypeToSessionTypePrefValue(exit_type
));
771 // NOTE: If you change what thread this writes on, be sure and update
772 // ChromeFrame::EndSession().
773 prefs_
->CommitPendingWrite();
777 Profile::ExitType
ProfileImpl::GetLastSessionExitType() {
778 // last_session_exited_cleanly_ is set when the preferences are loaded. Force
779 // it to be set by asking for the prefs.
781 return last_session_exit_type_
;
784 policy::ManagedModePolicyProvider
* ProfileImpl::GetManagedModePolicyProvider() {
785 #if defined(ENABLE_CONFIGURATION_POLICY) && defined(ENABLE_MANAGED_USERS)
786 return managed_mode_policy_provider_
.get();
792 policy::PolicyService
* ProfileImpl::GetPolicyService() {
793 DCHECK(policy_service_
.get()); // Should explicitly be initialized.
794 return policy_service_
.get();
797 PrefService
* ProfileImpl::GetPrefs() {
798 DCHECK(prefs_
.get()); // Should explicitly be initialized.
802 PrefService
* ProfileImpl::GetOffTheRecordPrefs() {
803 DCHECK(prefs_
.get());
804 if (!otr_prefs_
.get()) {
805 // The new ExtensionPrefStore is ref_counted and the new PrefService
806 // stores a reference so that we do not leak memory here.
807 otr_prefs_
.reset(prefs_
->CreateIncognitoPrefService(
808 new ExtensionPrefStore(
809 ExtensionPrefValueMapFactory::GetForProfile(this), true)));
811 return otr_prefs_
.get();
814 base::FilePath
ProfileImpl::GetPrefFilePath() {
815 base::FilePath pref_file_path
= path_
;
816 pref_file_path
= pref_file_path
.Append(chrome::kPreferencesFilename
);
817 return pref_file_path
;
820 net::URLRequestContextGetter
* ProfileImpl::CreateRequestContext(
821 content::ProtocolHandlerMap
* protocol_handlers
) {
822 return io_data_
.CreateMainRequestContextGetter(
824 g_browser_process
->local_state(),
825 g_browser_process
->io_thread());
828 net::URLRequestContextGetter
* ProfileImpl::GetRequestContext() {
829 return GetDefaultStoragePartition(this)->GetURLRequestContext();
832 net::URLRequestContextGetter
* ProfileImpl::GetRequestContextForRenderProcess(
833 int renderer_child_id
) {
834 content::RenderProcessHost
* rph
= content::RenderProcessHost::FromID(
837 return rph
->GetStoragePartition()->GetURLRequestContext();
840 net::URLRequestContextGetter
* ProfileImpl::GetMediaRequestContext() {
841 // Return the default media context.
842 return io_data_
.GetMediaRequestContextGetter();
845 net::URLRequestContextGetter
*
846 ProfileImpl::GetMediaRequestContextForRenderProcess(
847 int renderer_child_id
) {
848 content::RenderProcessHost
* rph
= content::RenderProcessHost::FromID(
850 content::StoragePartition
* storage_partition
= rph
->GetStoragePartition();
852 return storage_partition
->GetMediaURLRequestContext();
855 net::URLRequestContextGetter
*
856 ProfileImpl::GetMediaRequestContextForStoragePartition(
857 const base::FilePath
& partition_path
,
859 return io_data_
.GetIsolatedMediaRequestContextGetter(partition_path
,
863 content::ResourceContext
* ProfileImpl::GetResourceContext() {
864 return io_data_
.GetResourceContext();
867 net::URLRequestContextGetter
* ProfileImpl::GetRequestContextForExtensions() {
868 return io_data_
.GetExtensionsRequestContextGetter();
871 net::URLRequestContextGetter
*
872 ProfileImpl::CreateRequestContextForStoragePartition(
873 const base::FilePath
& partition_path
,
875 content::ProtocolHandlerMap
* protocol_handlers
) {
876 return io_data_
.CreateIsolatedAppRequestContextGetter(
877 partition_path
, in_memory
, protocol_handlers
);
880 net::SSLConfigService
* ProfileImpl::GetSSLConfigService() {
881 // If ssl_config_service_manager_ is null, this typically means that some
882 // ProfileKeyedService is trying to create a RequestContext at startup, but
883 // SSLConfigServiceManager is not initialized until DoFinalInit() which is
884 // invoked after all ProfileKeyedServices have been initialized (see
885 // http://crbug.com/171406).
886 DCHECK(ssl_config_service_manager_
.get()) <<
887 "SSLConfigServiceManager is not initialized yet";
888 return ssl_config_service_manager_
->Get();
891 HostContentSettingsMap
* ProfileImpl::GetHostContentSettingsMap() {
892 if (!host_content_settings_map_
.get()) {
893 host_content_settings_map_
= new HostContentSettingsMap(GetPrefs(), false);
895 return host_content_settings_map_
.get();
898 content::GeolocationPermissionContext
*
899 ProfileImpl::GetGeolocationPermissionContext() {
900 return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
903 content::SpeechRecognitionPreferences
*
904 ProfileImpl::GetSpeechRecognitionPreferences() {
905 #if defined(ENABLE_INPUT_SPEECH)
906 return ChromeSpeechRecognitionPreferences::GetForProfile(this);
912 DownloadManagerDelegate
* ProfileImpl::GetDownloadManagerDelegate() {
913 return DownloadServiceFactory::GetForProfile(this)->
914 GetDownloadManagerDelegate();
917 quota::SpecialStoragePolicy
* ProfileImpl::GetSpecialStoragePolicy() {
918 return GetExtensionSpecialStoragePolicy();
921 bool ProfileImpl::IsSameProfile(Profile
* profile
) {
922 if (profile
== static_cast<Profile
*>(this))
924 Profile
* otr_profile
= off_the_record_profile_
.get();
925 return otr_profile
&& profile
== otr_profile
;
928 Time
ProfileImpl::GetStartTime() const {
932 history::TopSites
* ProfileImpl::GetTopSites() {
933 if (!top_sites_
.get()) {
934 top_sites_
= new history::TopSites(this);
935 top_sites_
->Init(GetPath().Append(chrome::kTopSitesFilename
));
940 history::TopSites
* ProfileImpl::GetTopSitesWithoutCreating() {
944 void ProfileImpl::OnDefaultZoomLevelChanged() {
945 HostZoomMap::GetForBrowserContext(this)->SetDefaultZoomLevel(
946 pref_change_registrar_
.prefs()->GetDouble(prefs::kDefaultZoomLevel
));
949 void ProfileImpl::OnZoomLevelChanged(
950 const HostZoomMap::ZoomLevelChange
& change
) {
952 if (change
.mode
!= HostZoomMap::ZOOM_CHANGED_FOR_HOST
)
954 HostZoomMap
* host_zoom_map
= HostZoomMap::GetForBrowserContext(this);
955 double level
= change
.zoom_level
;
956 DictionaryPrefUpdate
update(prefs_
.get(), prefs::kPerHostZoomLevels
);
957 DictionaryValue
* host_zoom_dictionary
= update
.Get();
958 if (level
== host_zoom_map
->GetDefaultZoomLevel()) {
959 host_zoom_dictionary
->RemoveWithoutPathExpansion(change
.host
, NULL
);
961 host_zoom_dictionary
->SetWithoutPathExpansion(
962 change
.host
, Value::CreateDoubleValue(level
));
966 #if defined(ENABLE_SESSION_SERVICE)
967 void ProfileImpl::StopCreateSessionServiceTimer() {
968 create_session_service_timer_
.Stop();
971 void ProfileImpl::EnsureSessionServiceCreated() {
972 SessionServiceFactory::GetForProfile(this);
976 #if defined(OS_CHROMEOS)
977 void ProfileImpl::ChangeAppLocale(
978 const std::string
& new_locale
, AppLocaleChangedVia via
) {
979 if (new_locale
.empty()) {
983 PrefService
* local_state
= g_browser_process
->local_state();
985 if (local_state
->IsManagedPreference(prefs::kApplicationLocale
))
987 std::string pref_locale
= GetPrefs()->GetString(prefs::kApplicationLocale
);
988 bool do_update_pref
= true;
990 case APP_LOCALE_CHANGED_VIA_SETTINGS
:
991 case APP_LOCALE_CHANGED_VIA_REVERT
: {
992 // We keep kApplicationLocaleBackup value as a reference. In case value
993 // of kApplicationLocale preference would change due to sync from other
994 // device then kApplicationLocaleBackup value will trigger and allow us to
995 // show notification about automatic locale change in LocaleChangeGuard.
996 GetPrefs()->SetString(prefs::kApplicationLocaleBackup
, new_locale
);
997 GetPrefs()->ClearPref(prefs::kApplicationLocaleAccepted
);
998 // We maintain kApplicationLocale property in both a global storage
999 // and user's profile. Global property determines locale of login screen,
1000 // while user's profile determines his personal locale preference.
1003 case APP_LOCALE_CHANGED_VIA_LOGIN
: {
1004 if (!pref_locale
.empty()) {
1005 DCHECK(pref_locale
== new_locale
);
1006 std::string accepted_locale
=
1007 GetPrefs()->GetString(prefs::kApplicationLocaleAccepted
);
1008 if (accepted_locale
== new_locale
) {
1009 // If locale is accepted then we do not want to show LocaleChange
1010 // notification. This notification is triggered by different values
1011 // of kApplicationLocaleBackup and kApplicationLocale preferences,
1012 // so make them identical.
1013 GetPrefs()->SetString(prefs::kApplicationLocaleBackup
, new_locale
);
1015 // Back up locale of login screen.
1016 std::string cur_locale
= g_browser_process
->GetApplicationLocale();
1017 GetPrefs()->SetString(prefs::kApplicationLocaleBackup
, cur_locale
);
1018 if (locale_change_guard_
== NULL
)
1019 locale_change_guard_
.reset(new chromeos::LocaleChangeGuard(this));
1020 locale_change_guard_
->PrepareChangingLocale(cur_locale
, new_locale
);
1023 std::string cur_locale
= g_browser_process
->GetApplicationLocale();
1024 std::string backup_locale
=
1025 GetPrefs()->GetString(prefs::kApplicationLocaleBackup
);
1026 // Profile synchronization takes time and is not completed at that
1027 // moment at first login. So we initialize locale preference in steps:
1028 // (1) first save it to temporary backup;
1029 // (2) on next login we assume that synchronization is already completed
1030 // and we may finalize initialization.
1031 GetPrefs()->SetString(prefs::kApplicationLocaleBackup
, cur_locale
);
1032 if (!backup_locale
.empty())
1033 GetPrefs()->SetString(prefs::kApplicationLocale
, backup_locale
);
1034 do_update_pref
= false;
1038 case APP_LOCALE_CHANGED_VIA_UNKNOWN
:
1045 GetPrefs()->SetString(prefs::kApplicationLocale
, new_locale
);
1046 local_state
->SetString(prefs::kApplicationLocale
, new_locale
);
1048 if (chromeos::UserManager::Get()->IsCurrentUserOwner())
1049 local_state
->SetString(prefs::kOwnerLocale
, new_locale
);
1052 void ProfileImpl::OnLogin() {
1053 if (locale_change_guard_
== NULL
)
1054 locale_change_guard_
.reset(new chromeos::LocaleChangeGuard(this));
1055 locale_change_guard_
->OnLogin();
1058 void ProfileImpl::SetupChromeOSEnterpriseExtensionObserver() {
1059 DCHECK(!chromeos_enterprise_extension_observer_
.get());
1060 chromeos_enterprise_extension_observer_
.reset(
1061 new chromeos::EnterpriseExtensionObserver(this));
1064 void ProfileImpl::InitChromeOSPreferences() {
1065 chromeos_preferences_
.reset(new chromeos::Preferences());
1066 chromeos_preferences_
->Init(PrefServiceSyncable::FromProfile(this));
1068 #endif // defined(OS_CHROMEOS)
1070 PrefProxyConfigTracker
* ProfileImpl::GetProxyConfigTracker() {
1071 if (!pref_proxy_config_tracker_
.get()) {
1072 pref_proxy_config_tracker_
.reset(
1073 ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs()));
1075 return pref_proxy_config_tracker_
.get();
1078 chrome_browser_net::Predictor
* ProfileImpl::GetNetworkPredictor() {
1082 void ProfileImpl::ClearNetworkingHistorySince(base::Time time
,
1083 const base::Closure
& completion
) {
1084 io_data_
.ClearNetworkingHistorySince(time
, completion
);
1087 GURL
ProfileImpl::GetHomePage() {
1088 // --homepage overrides any preferences.
1089 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
1090 if (command_line
.HasSwitch(switches::kHomePage
)) {
1091 // TODO(evanm): clean up usage of DIR_CURRENT.
1092 // http://code.google.com/p/chromium/issues/detail?id=60630
1093 // For now, allow this code to call getcwd().
1094 base::ThreadRestrictions::ScopedAllowIO allow_io
;
1096 base::FilePath browser_directory
;
1097 PathService::Get(base::DIR_CURRENT
, &browser_directory
);
1098 GURL
home_page(URLFixerUpper::FixupRelativeFile(browser_directory
,
1099 command_line
.GetSwitchValuePath(switches::kHomePage
)));
1100 if (home_page
.is_valid())
1104 if (GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage
))
1105 return GURL(chrome::kChromeUINewTabURL
);
1106 GURL
home_page(URLFixerUpper::FixupURL(
1107 GetPrefs()->GetString(prefs::kHomePage
),
1109 if (!home_page
.is_valid())
1110 return GURL(chrome::kChromeUINewTabURL
);
1114 void ProfileImpl::UpdateProfileUserNameCache() {
1115 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
1116 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
1117 size_t index
= cache
.GetIndexOfProfileWithPath(GetPath());
1118 if (index
!= std::string::npos
) {
1119 std::string user_name
=
1120 GetPrefs()->GetString(prefs::kGoogleServicesUsername
);
1121 cache
.SetUserNameOfProfileAtIndex(index
, UTF8ToUTF16(user_name
));
1125 void ProfileImpl::UpdateProfileNameCache() {
1126 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
1127 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
1128 size_t index
= cache
.GetIndexOfProfileWithPath(GetPath());
1129 if (index
!= std::string::npos
) {
1130 std::string profile_name
=
1131 GetPrefs()->GetString(prefs::kProfileName
);
1132 cache
.SetNameOfProfileAtIndex(index
, UTF8ToUTF16(profile_name
));
1136 void ProfileImpl::UpdateProfileAvatarCache() {
1137 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
1138 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
1139 size_t index
= cache
.GetIndexOfProfileWithPath(GetPath());
1140 if (index
!= std::string::npos
) {
1141 size_t avatar_index
=
1142 GetPrefs()->GetInteger(prefs::kProfileAvatarIndex
);
1143 cache
.SetAvatarIconOfProfileAtIndex(index
, avatar_index
);
1147 // Gets the cache parameters from the command line. If |is_media_context| is
1148 // set to true then settings for the media context type is what we need,
1149 // |cache_path| will be set to the user provided path, or will not be touched if
1150 // there is not an argument. |max_size| will be the user provided value or zero
1152 void ProfileImpl::GetCacheParameters(bool is_media_context
,
1153 base::FilePath
* cache_path
,
1157 base::FilePath
path(prefs_
->GetFilePath(prefs::kDiskCacheDir
));
1160 *max_size
= is_media_context
? prefs_
->GetInteger(prefs::kMediaCacheSize
) :
1161 prefs_
->GetInteger(prefs::kDiskCacheSize
);