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_manager.h"
10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h"
12 #include "base/deferred_sequenced_task_runner.h"
13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_service.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/utf_string_conversions.h"
22 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/download/download_service.h"
26 #include "chrome/browser/download/download_service_factory.h"
27 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
28 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
29 #include "chrome/browser/password_manager/password_store_factory.h"
30 #include "chrome/browser/prefs/incognito_mode_prefs.h"
31 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
32 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
33 #include "chrome/browser/profiles/profile_destroyer.h"
34 #include "chrome/browser/profiles/profile_info_cache.h"
35 #include "chrome/browser/profiles/profile_metrics.h"
36 #include "chrome/browser/profiles/profiles_state.h"
37 #include "chrome/browser/profiles/startup_task_runner_service.h"
38 #include "chrome/browser/profiles/startup_task_runner_service_factory.h"
39 #include "chrome/browser/signin/account_reconcilor_factory.h"
40 #include "chrome/browser/signin/account_tracker_service_factory.h"
41 #include "chrome/browser/signin/signin_manager_factory.h"
42 #include "chrome/browser/sync/profile_sync_service.h"
43 #include "chrome/browser/sync/profile_sync_service_factory.h"
44 #include "chrome/browser/ui/browser.h"
45 #include "chrome/browser/ui/browser_iterator.h"
46 #include "chrome/browser/ui/sync/sync_promo_ui.h"
47 #include "chrome/common/chrome_constants.h"
48 #include "chrome/common/chrome_paths_internal.h"
49 #include "chrome/common/chrome_switches.h"
50 #include "chrome/common/logging_chrome.h"
51 #include "chrome/common/pref_names.h"
52 #include "chrome/common/url_constants.h"
53 #include "chrome/grit/generated_resources.h"
54 #include "components/bookmarks/browser/bookmark_model.h"
55 #include "components/content_settings/core/browser/host_content_settings_map.h"
56 #include "components/password_manager/core/browser/password_store.h"
57 #include "components/signin/core/browser/account_tracker_service.h"
58 #include "components/signin/core/browser/signin_manager.h"
59 #include "components/signin/core/common/profile_management_switches.h"
60 #include "content/public/browser/browser_thread.h"
61 #include "content/public/browser/notification_service.h"
62 #include "content/public/browser/user_metrics.h"
63 #include "net/http/http_transaction_factory.h"
64 #include "net/url_request/url_request_context.h"
65 #include "net/url_request/url_request_context_getter.h"
66 #include "net/url_request/url_request_job.h"
67 #include "ui/base/l10n/l10n_util.h"
69 #if defined(ENABLE_EXTENSIONS)
70 #include "chrome/browser/extensions/extension_service.h"
71 #include "extensions/browser/extension_registry.h"
72 #include "extensions/browser/extension_system.h"
73 #include "extensions/common/extension_set.h"
74 #include "extensions/common/manifest.h"
77 #if defined(ENABLE_SUPERVISED_USERS)
78 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
79 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
80 #include "chrome/browser/supervised_user/supervised_user_service.h"
81 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
85 #include "chrome/browser/sessions/session_service_factory.h"
86 #include "chrome/browser/ui/browser_list.h"
87 #endif // !defined (OS_IOS)
90 #include "base/win/metro.h"
91 #include "chrome/installer/util/browser_distribution.h"
94 #if defined(OS_CHROMEOS)
95 #include "chrome/browser/browser_process_platform_part_chromeos.h"
96 #include "chrome/browser/chromeos/profiles/profile_helper.h"
97 #include "chromeos/chromeos_switches.h"
98 #include "chromeos/dbus/cryptohome_client.h"
99 #include "chromeos/dbus/dbus_thread_manager.h"
100 #include "components/user_manager/user.h"
101 #include "components/user_manager/user_manager.h"
104 using base::UserMetricsAction
;
105 using content::BrowserThread
;
109 // Profiles that should be deleted on shutdown.
110 std::vector
<base::FilePath
>& ProfilesToDelete() {
111 CR_DEFINE_STATIC_LOCAL(std::vector
<base::FilePath
>, profiles_to_delete
, ());
112 return profiles_to_delete
;
115 int64
ComputeFilesSize(const base::FilePath
& directory
,
116 const base::FilePath::StringType
& pattern
) {
117 int64 running_size
= 0;
118 base::FileEnumerator
iter(directory
, false, base::FileEnumerator::FILES
,
120 while (!iter
.Next().empty())
121 running_size
+= iter
.GetInfo().GetSize();
125 // Simple task to log the size of the current profile.
126 void ProfileSizeTask(const base::FilePath
& path
, int enabled_app_count
) {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
128 const int64 kBytesInOneMB
= 1024 * 1024;
130 int64 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("*"));
131 int size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
132 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB
);
134 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("History"));
135 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
136 UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB
);
138 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("History*"));
139 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
140 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB
);
142 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Cookies"));
143 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
144 UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB
);
146 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Bookmarks"));
147 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
148 UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB
);
150 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Favicons"));
151 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
152 UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB
);
154 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Top Sites"));
155 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
156 UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB
);
158 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Visited Links"));
159 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
160 UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB
);
162 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Web Data"));
163 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
164 UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB
);
166 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Extension*"));
167 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
168 UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB
);
170 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Policy"));
171 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
172 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB
);
174 // Count number of enabled apps in this profile, if we know.
175 if (enabled_app_count
!= -1)
176 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count
);
179 void QueueProfileDirectoryForDeletion(const base::FilePath
& path
) {
180 ProfilesToDelete().push_back(path
);
183 bool IsProfileMarkedForDeletion(const base::FilePath
& profile_path
) {
184 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
185 profile_path
) != ProfilesToDelete().end();
188 // Physically remove deleted profile directories from disk.
189 void NukeProfileFromDisk(const base::FilePath
& profile_path
) {
190 // Delete both the profile directory and its corresponding cache.
191 base::FilePath cache_path
;
192 chrome::GetUserCacheDirectory(profile_path
, &cache_path
);
193 base::DeleteFile(profile_path
, true);
194 base::DeleteFile(cache_path
, true);
197 #if defined(OS_CHROMEOS)
198 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status
,
200 if (call_status
!= chromeos::DBUS_METHOD_CALL_SUCCESS
) {
201 LOG(ERROR
) << "IsMounted call failed.";
205 LOG(ERROR
) << "Cryptohome is not mounted.";
210 #if defined(ENABLE_EXTENSIONS)
212 // Returns the number of installed (and enabled) apps, excluding any component
214 size_t GetEnabledAppCount(Profile
* profile
) {
215 size_t installed_apps
= 0u;
216 const extensions::ExtensionSet
& extensions
=
217 extensions::ExtensionRegistry::Get(profile
)->enabled_extensions();
218 for (extensions::ExtensionSet::const_iterator iter
= extensions
.begin();
219 iter
!= extensions
.end();
221 if ((*iter
)->is_app() &&
222 (*iter
)->location() != extensions::Manifest::COMPONENT
) {
226 return installed_apps
;
229 #endif // ENABLE_EXTENSIONS
233 ProfileManager::ProfileManager(const base::FilePath
& user_data_dir
)
234 : user_data_dir_(user_data_dir
),
236 #if !defined(OS_ANDROID) && !defined(OS_IOS)
237 browser_list_observer_(this),
239 closing_all_browsers_(false) {
240 #if defined(OS_CHROMEOS)
243 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
244 content::NotificationService::AllSources());
248 chrome::NOTIFICATION_BROWSER_OPENED
,
249 content::NotificationService::AllSources());
252 chrome::NOTIFICATION_BROWSER_CLOSED
,
253 content::NotificationService::AllSources());
256 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST
,
257 content::NotificationService::AllSources());
260 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED
,
261 content::NotificationService::AllSources());
264 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED
,
265 content::NotificationService::AllSources());
267 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_
.empty())
268 profile_shortcut_manager_
.reset(ProfileShortcutManager::Create(
272 ProfileManager::~ProfileManager() {
275 #if defined(ENABLE_SESSION_SERVICE)
277 void ProfileManager::ShutdownSessionServices() {
278 ProfileManager
* pm
= g_browser_process
->profile_manager();
279 if (!pm
) // Is NULL when running unit tests.
281 std::vector
<Profile
*> profiles(pm
->GetLoadedProfiles());
282 for (size_t i
= 0; i
< profiles
.size(); ++i
)
283 SessionServiceFactory::ShutdownForProfile(profiles
[i
]);
288 void ProfileManager::NukeDeletedProfilesFromDisk() {
289 for (std::vector
<base::FilePath
>::iterator it
=
290 ProfilesToDelete().begin();
291 it
!= ProfilesToDelete().end();
293 NukeProfileFromDisk(*it
);
295 ProfilesToDelete().clear();
299 Profile
* ProfileManager::GetLastUsedProfile() {
300 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
301 return profile_manager
->GetLastUsedProfile(profile_manager
->user_data_dir_
);
305 Profile
* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
306 Profile
* profile
= GetLastUsedProfile();
307 if (profile
->IsGuestSession() ||
308 IncognitoModePrefs::GetAvailability(profile
->GetPrefs()) ==
309 IncognitoModePrefs::FORCED
) {
310 return profile
->GetOffTheRecordProfile();
316 std::vector
<Profile
*> ProfileManager::GetLastOpenedProfiles() {
317 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
318 return profile_manager
->GetLastOpenedProfiles(
319 profile_manager
->user_data_dir_
);
323 Profile
* ProfileManager::GetPrimaryUserProfile() {
324 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
325 #if defined(OS_CHROMEOS)
326 if (!profile_manager
->IsLoggedIn() ||
327 !user_manager::UserManager::IsInitialized())
328 return profile_manager
->GetActiveUserOrOffTheRecordProfileFromPath(
329 profile_manager
->user_data_dir());
330 user_manager::UserManager
* manager
= user_manager::UserManager::Get();
331 // Note: The ProfileHelper will take care of guest profiles.
332 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
333 manager
->GetPrimaryUser());
335 return profile_manager
->GetActiveUserOrOffTheRecordProfileFromPath(
336 profile_manager
->user_data_dir());
341 Profile
* ProfileManager::GetActiveUserProfile() {
342 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
343 #if defined(OS_CHROMEOS)
344 if (!profile_manager
)
347 if (!profile_manager
->IsLoggedIn() ||
348 !user_manager::UserManager::IsInitialized()) {
349 return profile_manager
->GetActiveUserOrOffTheRecordProfileFromPath(
350 profile_manager
->user_data_dir());
353 user_manager::UserManager
* manager
= user_manager::UserManager::Get();
354 const user_manager::User
* user
= manager
->GetActiveUser();
355 // To avoid an endless loop (crbug.com/334098) we have to additionally check
356 // if the profile of the user was already created. If the profile was not yet
357 // created we load the profile using the profile directly.
358 // TODO: This should be cleaned up with the new profile manager.
359 if (user
&& user
->is_profile_created())
360 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user
);
364 profile_manager
->GetActiveUserOrOffTheRecordProfileFromPath(
365 profile_manager
->user_data_dir());
366 // |profile| could be null if the user doesn't have a profile yet and the path
367 // is on a read-only volume (preventing Chrome from making a new one).
368 // However, most callers of this function immediately dereference the result
369 // which would lead to crashes in a variety of call sites. Assert here to
370 // figure out how common this is. http://crbug.com/383019
371 CHECK(profile
) << profile_manager
->user_data_dir().AsUTF8Unsafe();
375 Profile
* ProfileManager::GetProfile(const base::FilePath
& profile_dir
) {
376 TRACE_EVENT0("browser", "ProfileManager::GetProfile")
377 // If the profile is already loaded (e.g., chrome.exe launched twice), just
379 Profile
* profile
= GetProfileByPath(profile_dir
);
383 profile
= CreateProfileHelper(profile_dir
);
386 bool result
= AddProfile(profile
);
392 size_t ProfileManager::GetNumberOfProfiles() {
393 return GetProfileInfoCache().GetNumberOfProfiles();
396 void ProfileManager::CreateProfileAsync(
397 const base::FilePath
& profile_path
,
398 const CreateCallback
& callback
,
399 const base::string16
& name
,
400 const base::string16
& icon_url
,
401 const std::string
& supervised_user_id
) {
402 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
403 TRACE_EVENT1("startup",
404 "ProfileManager::CreateProfileAsync",
406 profile_path
.value().c_str());
408 // Make sure that this profile is not pending deletion.
409 if (IsProfileMarkedForDeletion(profile_path
)) {
410 if (!callback
.is_null())
411 callback
.Run(NULL
, Profile::CREATE_STATUS_LOCAL_FAIL
);
415 // Create the profile if needed and collect its ProfileInfo.
416 ProfilesInfoMap::iterator iter
= profiles_info_
.find(profile_path
);
417 ProfileInfo
* info
= NULL
;
419 if (iter
!= profiles_info_
.end()) {
420 info
= iter
->second
.get();
422 // Initiate asynchronous creation process.
423 info
= RegisterProfile(CreateProfileAsyncHelper(profile_path
, this), false);
424 ProfileInfoCache
& cache
= GetProfileInfoCache();
425 // Get the icon index from the user's icon url
427 std::string icon_url_std
= base::UTF16ToASCII(icon_url
);
428 if (profiles::IsDefaultAvatarIconUrl(icon_url_std
, &icon_index
)) {
429 // add profile to cache with user selected name and avatar
430 cache
.AddProfileToCache(profile_path
, name
, base::string16(), icon_index
,
434 if (!supervised_user_id
.empty()) {
435 content::RecordAction(
436 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
439 ProfileMetrics::UpdateReportedProfilesStatistics(this);
442 // Call or enqueue the callback.
443 if (!callback
.is_null()) {
444 if (iter
!= profiles_info_
.end() && info
->created
) {
445 Profile
* profile
= info
->profile
.get();
446 // If this was the guest profile, apply settings and go OffTheRecord.
447 if (profile
->GetPath() == ProfileManager::GetGuestProfilePath()) {
448 SetGuestProfilePrefs(profile
);
449 profile
= profile
->GetOffTheRecordProfile();
451 // Profile has already been created. Run callback immediately.
452 callback
.Run(profile
, Profile::CREATE_STATUS_INITIALIZED
);
454 // Profile is either already in the process of being created, or new.
455 // Add callback to the list.
456 info
->callbacks
.push_back(callback
);
461 bool ProfileManager::IsValidProfile(Profile
* profile
) {
462 for (ProfilesInfoMap::iterator iter
= profiles_info_
.begin();
463 iter
!= profiles_info_
.end(); ++iter
) {
464 if (iter
->second
->created
) {
465 Profile
* candidate
= iter
->second
->profile
.get();
466 if (candidate
== profile
||
467 (candidate
->HasOffTheRecordProfile() &&
468 candidate
->GetOffTheRecordProfile() == profile
)) {
476 base::FilePath
ProfileManager::GetInitialProfileDir() {
477 #if defined(OS_CHROMEOS)
479 return chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
482 base::FilePath relative_profile_dir
;
483 // TODO(mirandac): should not automatically be default profile.
484 return relative_profile_dir
.AppendASCII(chrome::kInitialProfile
);
487 Profile
* ProfileManager::GetLastUsedProfile(
488 const base::FilePath
& user_data_dir
) {
489 #if defined(OS_CHROMEOS)
490 // Use default login profile if user has not logged in yet.
492 return GetActiveUserOrOffTheRecordProfileFromPath(user_data_dir
);
494 // CrOS multi-profiles implementation is different so GetLastUsedProfile
495 // has custom implementation too.
496 base::FilePath profile_dir
;
497 // In case of multi-profiles we ignore "last used profile" preference
498 // since it may refer to profile that has been in use in previous session.
499 // That profile dir may not be mounted in this session so instead return
500 // active profile from current session.
501 profile_dir
= chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
503 base::FilePath
profile_path(user_data_dir
);
504 Profile
* profile
= GetProfile(profile_path
.Append(profile_dir
));
505 return profile
->IsGuestSession() ? profile
->GetOffTheRecordProfile() :
510 return GetProfile(GetLastUsedProfileDir(user_data_dir
));
513 base::FilePath
ProfileManager::GetLastUsedProfileDir(
514 const base::FilePath
& user_data_dir
) {
515 base::FilePath
last_used_profile_dir(user_data_dir
);
516 PrefService
* local_state
= g_browser_process
->local_state();
519 if (local_state
->HasPrefPath(prefs::kProfileLastUsed
)) {
520 return last_used_profile_dir
.AppendASCII(
521 local_state
->GetString(prefs::kProfileLastUsed
));
524 return last_used_profile_dir
.AppendASCII(chrome::kInitialProfile
);
527 std::vector
<Profile
*> ProfileManager::GetLastOpenedProfiles(
528 const base::FilePath
& user_data_dir
) {
529 PrefService
* local_state
= g_browser_process
->local_state();
532 std::vector
<Profile
*> to_return
;
533 if (local_state
->HasPrefPath(prefs::kProfilesLastActive
) &&
534 local_state
->GetList(prefs::kProfilesLastActive
)) {
535 // Make a copy because the list might change in the calls to GetProfile.
536 scoped_ptr
<base::ListValue
> profile_list(
537 local_state
->GetList(prefs::kProfilesLastActive
)->DeepCopy());
538 base::ListValue::const_iterator it
;
540 for (it
= profile_list
->begin(); it
!= profile_list
->end(); ++it
) {
541 if (!(*it
)->GetAsString(&profile
) || profile
.empty()) {
542 LOG(WARNING
) << "Invalid entry in " << prefs::kProfilesLastActive
;
545 to_return
.push_back(GetProfile(user_data_dir
.AppendASCII(profile
)));
551 std::vector
<Profile
*> ProfileManager::GetLoadedProfiles() const {
552 std::vector
<Profile
*> profiles
;
553 for (ProfilesInfoMap::const_iterator iter
= profiles_info_
.begin();
554 iter
!= profiles_info_
.end(); ++iter
) {
555 if (iter
->second
->created
)
556 profiles
.push_back(iter
->second
->profile
.get());
561 Profile
* ProfileManager::GetProfileByPath(const base::FilePath
& path
) const {
562 ProfileInfo
* profile_info
= GetProfileInfoByPath(path
);
563 return profile_info
? profile_info
->profile
.get() : NULL
;
567 base::FilePath
ProfileManager::CreateMultiProfileAsync(
568 const base::string16
& name
,
569 const base::string16
& icon_url
,
570 const CreateCallback
& callback
,
571 const std::string
& supervised_user_id
) {
572 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
574 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
576 base::FilePath new_path
= profile_manager
->GenerateNextProfileDirectoryPath();
578 profile_manager
->CreateProfileAsync(new_path
,
587 base::FilePath
ProfileManager::GetGuestProfilePath() {
588 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
590 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
592 base::FilePath guest_path
= profile_manager
->user_data_dir();
593 return guest_path
.Append(chrome::kGuestProfileDir
);
596 base::FilePath
ProfileManager::GenerateNextProfileDirectoryPath() {
597 PrefService
* local_state
= g_browser_process
->local_state();
600 DCHECK(profiles::IsMultipleProfilesEnabled());
602 // Create the next profile in the next available directory slot.
603 int next_directory
= local_state
->GetInteger(prefs::kProfilesNumCreated
);
604 std::string profile_name
= chrome::kMultiProfileDirPrefix
;
605 profile_name
.append(base::IntToString(next_directory
));
606 base::FilePath new_path
= user_data_dir_
;
608 new_path
= new_path
.Append(base::ASCIIToUTF16(profile_name
));
610 new_path
= new_path
.Append(profile_name
);
612 local_state
->SetInteger(prefs::kProfilesNumCreated
, ++next_directory
);
616 ProfileInfoCache
& ProfileManager::GetProfileInfoCache() {
617 if (!profile_info_cache_
) {
618 profile_info_cache_
.reset(new ProfileInfoCache(
619 g_browser_process
->local_state(), user_data_dir_
));
621 return *profile_info_cache_
.get();
624 ProfileShortcutManager
* ProfileManager::profile_shortcut_manager() {
625 return profile_shortcut_manager_
.get();
628 void ProfileManager::ScheduleProfileForDeletion(
629 const base::FilePath
& profile_dir
,
630 const CreateCallback
& callback
) {
631 DCHECK(profiles::IsMultipleProfilesEnabled());
633 // Cancel all in-progress downloads before deleting the profile to prevent a
634 // "Do you want to exit Google Chrome and cancel the downloads?" prompt
635 // (crbug.com/336725).
636 Profile
* profile
= GetProfileByPath(profile_dir
);
638 DownloadService
* service
=
639 DownloadServiceFactory::GetForBrowserContext(profile
);
640 service
->CancelDownloads();
643 PrefService
* local_state
= g_browser_process
->local_state();
644 ProfileInfoCache
& cache
= GetProfileInfoCache();
646 const std::string last_used_profile
=
647 local_state
->GetString(prefs::kProfileLastUsed
);
649 if (last_used_profile
== profile_dir
.BaseName().MaybeAsASCII() ||
650 last_used_profile
== GetGuestProfilePath().BaseName().MaybeAsASCII()) {
651 // Update the last used profile pref before closing browser windows. This
652 // way the correct last used profile is set for any notification observers.
653 base::FilePath last_non_supervised_profile_path
;
654 for (size_t i
= 0; i
< cache
.GetNumberOfProfiles(); ++i
) {
655 base::FilePath cur_path
= cache
.GetPathOfProfileAtIndex(i
);
656 // Make sure that this profile is not pending deletion.
657 if (cur_path
!= profile_dir
&&
658 !cache
.ProfileIsLegacySupervisedAtIndex(i
) &&
659 !IsProfileMarkedForDeletion(cur_path
)) {
660 last_non_supervised_profile_path
= cur_path
;
665 // If we're deleting the last (non-supervised) profile, then create a new
666 // profile in its place.
667 const std::string last_non_supervised_profile
=
668 last_non_supervised_profile_path
.BaseName().MaybeAsASCII();
669 if (last_non_supervised_profile
.empty()) {
670 base::FilePath new_path
= GenerateNextProfileDirectoryPath();
671 // Make sure the last used profile path is pointing at it. This way the
672 // correct last used profile is set for any notification observers.
673 local_state
->SetString(prefs::kProfileLastUsed
,
674 new_path
.BaseName().MaybeAsASCII());
676 // If we are using --new-avatar-menu, then assign the default
677 // placeholder avatar and name. Otherwise, use random ones.
678 bool is_new_avatar_menu
= switches::IsNewAvatarMenu();
679 int avatar_index
= profiles::GetPlaceholderAvatarIndex();
680 base::string16 new_avatar_url
= is_new_avatar_menu
?
681 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(avatar_index
)) :
683 base::string16 new_profile_name
= is_new_avatar_menu
?
684 cache
.ChooseNameForNewProfile(avatar_index
) : base::string16();
686 CreateProfileAsync(new_path
,
692 ProfileMetrics::LogProfileAddNewUser(
693 ProfileMetrics::ADD_NEW_USER_LAST_DELETED
);
695 // On the Mac, the browser process is not killed when all browser windows
696 // are closed, so just in case we are deleting the active profile, and no
697 // other profile has been loaded, we must pre-load a next one.
698 #if defined(OS_MACOSX)
699 CreateProfileAsync(last_non_supervised_profile_path
,
700 base::Bind(&ProfileManager::OnNewActiveProfileLoaded
,
701 base::Unretained(this),
703 last_non_supervised_profile_path
,
710 // For OS_MACOSX the pref is updated in the callback to make sure that
711 // it isn't used before the profile is actually loaded.
712 local_state
->SetString(prefs::kProfileLastUsed
,
713 last_non_supervised_profile
);
717 FinishDeletingProfile(profile_dir
);
721 void ProfileManager::CleanUpStaleProfiles(
722 const std::vector
<base::FilePath
>& profile_paths
) {
723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
725 for (std::vector
<base::FilePath
>::const_iterator it
= profile_paths
.begin();
726 it
!= profile_paths
.end(); ++it
) {
727 NukeProfileFromDisk(*it
);
731 void ProfileManager::AutoloadProfiles() {
732 // If running in the background is disabled for the browser, do not autoload
734 PrefService
* local_state
= g_browser_process
->local_state();
735 if (!local_state
->HasPrefPath(prefs::kBackgroundModeEnabled
) ||
736 !local_state
->GetBoolean(prefs::kBackgroundModeEnabled
)) {
740 ProfileInfoCache
& cache
= GetProfileInfoCache();
741 size_t number_of_profiles
= cache
.GetNumberOfProfiles();
742 for (size_t p
= 0; p
< number_of_profiles
; ++p
) {
743 if (cache
.GetBackgroundStatusOfProfileAtIndex(p
)) {
744 // If status is true, that profile is running background apps. By calling
745 // GetProfile, we automatically cause the profile to be loaded which will
746 // register it with the BackgroundModeManager.
747 GetProfile(cache
.GetPathOfProfileAtIndex(p
));
752 void ProfileManager::InitProfileUserPrefs(Profile
* profile
) {
753 ProfileInfoCache
& cache
= GetProfileInfoCache();
755 if (profile
->GetPath().DirName() != cache
.GetUserDataDir())
759 std::string profile_name
;
760 std::string supervised_user_id
;
761 if (profile
->IsGuestSession()) {
762 profile_name
= l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME
);
765 size_t profile_cache_index
=
766 cache
.GetIndexOfProfileWithPath(profile
->GetPath());
767 // If the cache has an entry for this profile, use the cache data.
768 if (profile_cache_index
!= std::string::npos
) {
770 cache
.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index
);
772 base::UTF16ToUTF8(cache
.GetNameOfProfileAtIndex(profile_cache_index
));
774 cache
.GetSupervisedUserIdOfProfileAtIndex(profile_cache_index
);
775 } else if (profile
->GetPath() ==
776 profiles::GetDefaultProfileDir(cache
.GetUserDataDir())) {
777 // The --new-avatar-menu flag no longer uses the "First User" name.
778 bool is_new_avatar_menu
= switches::IsNewAvatarMenu();
779 avatar_index
= profiles::GetPlaceholderAvatarIndex();
780 profile_name
= is_new_avatar_menu
?
781 base::UTF16ToUTF8(cache
.ChooseNameForNewProfile(avatar_index
)) :
782 l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME
);
784 avatar_index
= cache
.ChooseAvatarIconIndexForNewProfile();
786 base::UTF16ToUTF8(cache
.ChooseNameForNewProfile(avatar_index
));
790 if (!profile
->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex
))
791 profile
->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex
, avatar_index
);
793 if (!profile
->GetPrefs()->HasPrefPath(prefs::kProfileName
))
794 profile
->GetPrefs()->SetString(prefs::kProfileName
, profile_name
);
796 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
797 bool force_supervised_user_id
=
798 command_line
->HasSwitch(switches::kSupervisedUserId
);
799 if (force_supervised_user_id
) {
801 command_line
->GetSwitchValueASCII(switches::kSupervisedUserId
);
803 if (force_supervised_user_id
||
804 !profile
->GetPrefs()->HasPrefPath(prefs::kSupervisedUserId
)) {
805 profile
->GetPrefs()->SetString(prefs::kSupervisedUserId
,
809 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
810 // If the lock enabled algorithm changed, update this profile's lock status.
811 if (switches::IsNewProfileManagement())
812 profiles::UpdateIsProfileLockEnabledIfNeeded(profile
);
816 void ProfileManager::RegisterTestingProfile(Profile
* profile
,
818 bool start_deferred_task_runners
) {
819 RegisterProfile(profile
, true);
821 InitProfileUserPrefs(profile
);
822 AddProfileToCache(profile
);
824 if (start_deferred_task_runners
) {
825 StartupTaskRunnerServiceFactory::GetForProfile(profile
)->
826 StartDeferredTaskRunners();
830 void ProfileManager::Observe(
832 const content::NotificationSource
& source
,
833 const content::NotificationDetails
& details
) {
834 #if defined(OS_CHROMEOS)
835 if (type
== chrome::NOTIFICATION_LOGIN_USER_CHANGED
) {
838 const base::CommandLine
& command_line
=
839 *base::CommandLine::ForCurrentProcess();
840 if (!command_line
.HasSwitch(switches::kTestType
)) {
841 // If we don't have a mounted profile directory we're in trouble.
842 // TODO(davemoore) Once we have better api this check should ensure that
843 // our profile directory is the one that's mounted, and that it's mounted
844 // as the current user.
845 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
846 base::Bind(&CheckCryptohomeIsMounted
));
848 // Confirm that we hadn't loaded the new profile previously.
849 base::FilePath default_profile_dir
= user_data_dir_
.Append(
850 GetInitialProfileDir());
851 CHECK(!GetProfileByPath(default_profile_dir
))
852 << "The default profile was loaded before we mounted the cryptohome.";
857 bool save_active_profiles
= false;
859 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST
: {
860 // Ignore any browsers closing from now on.
861 closing_all_browsers_
= true;
862 save_active_profiles
= true;
865 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED
: {
866 // This will cancel the shutdown process, so the active profiles are
867 // tracked again. Also, as the active profiles may have changed (i.e. if
868 // some windows were closed) we save the current list of active profiles
870 closing_all_browsers_
= false;
871 save_active_profiles
= true;
874 case chrome::NOTIFICATION_BROWSER_OPENED
: {
875 Browser
* browser
= content::Source
<Browser
>(source
).ptr();
877 Profile
* profile
= browser
->profile();
880 profile
->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles
);
881 if (!profile
->IsOffTheRecord() && !is_ephemeral
&&
882 ++browser_counts_
[profile
] == 1) {
883 active_profiles_
.push_back(profile
);
884 save_active_profiles
= true;
886 // If browsers are opening, we can't be closing all the browsers. This
887 // can happen if the application was exited, but background mode or
888 // packaged apps prevented the process from shutting down, and then
889 // a new browser window was opened.
890 closing_all_browsers_
= false;
893 case chrome::NOTIFICATION_BROWSER_CLOSED
: {
894 Browser
* browser
= content::Source
<Browser
>(source
).ptr();
896 Profile
* profile
= browser
->profile();
898 if (!profile
->IsOffTheRecord() && --browser_counts_
[profile
] == 0) {
899 active_profiles_
.erase(std::find(active_profiles_
.begin(),
900 active_profiles_
.end(), profile
));
901 save_active_profiles
= !closing_all_browsers_
;
905 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED
: {
906 save_active_profiles
= !closing_all_browsers_
;
915 if (save_active_profiles
) {
916 PrefService
* local_state
= g_browser_process
->local_state();
918 ListPrefUpdate
update(local_state
, prefs::kProfilesLastActive
);
919 base::ListValue
* profile_list
= update
.Get();
921 profile_list
->Clear();
923 // crbug.com/120112 -> several non-incognito profiles might have the same
924 // GetPath().BaseName(). In that case, we cannot restore both
925 // profiles. Include each base name only once in the last active profile
927 std::set
<std::string
> profile_paths
;
928 std::vector
<Profile
*>::const_iterator it
;
929 for (it
= active_profiles_
.begin(); it
!= active_profiles_
.end(); ++it
) {
930 std::string profile_path
= (*it
)->GetPath().BaseName().MaybeAsASCII();
931 // Some profiles might become ephemeral after they are created.
932 if (!(*it
)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles
) &&
933 profile_paths
.find(profile_path
) == profile_paths
.end()) {
934 profile_paths
.insert(profile_path
);
935 profile_list
->Append(new base::StringValue(profile_path
));
941 void ProfileManager::OnProfileCreated(Profile
* profile
,
943 bool is_new_profile
) {
944 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
946 ProfilesInfoMap::iterator iter
= profiles_info_
.find(profile
->GetPath());
947 DCHECK(iter
!= profiles_info_
.end());
948 ProfileInfo
* info
= iter
->second
.get();
950 std::vector
<CreateCallback
> callbacks
;
951 info
->callbacks
.swap(callbacks
);
953 // Invoke CREATED callback for normal profiles.
954 bool go_off_the_record
= ShouldGoOffTheRecord(profile
);
955 if (success
&& !go_off_the_record
)
956 RunCallbacks(callbacks
, profile
, Profile::CREATE_STATUS_CREATED
);
958 // Perform initialization.
960 DoFinalInit(profile
, go_off_the_record
);
961 if (go_off_the_record
)
962 profile
= profile
->GetOffTheRecordProfile();
963 info
->created
= true;
966 profiles_info_
.erase(iter
);
967 // TODO(yiyaoliu): This is temporary, remove it after it's not used.
968 UMA_HISTOGRAM_COUNTS_100("UMA.ProfilesCount.AfterErase",
969 profiles_info_
.size());
973 // If this was the guest profile, finish setting its special status.
974 if (profile
->GetPath() == ProfileManager::GetGuestProfilePath())
975 SetGuestProfilePrefs(profile
);
977 // Invoke CREATED callback for incognito profiles.
978 if (go_off_the_record
)
979 RunCallbacks(callbacks
, profile
, Profile::CREATE_STATUS_CREATED
);
982 // Invoke INITIALIZED or FAIL for all profiles.
983 RunCallbacks(callbacks
, profile
,
984 profile
? Profile::CREATE_STATUS_INITIALIZED
:
985 Profile::CREATE_STATUS_LOCAL_FAIL
);
988 void ProfileManager::DoFinalInit(Profile
* profile
, bool go_off_the_record
) {
989 DoFinalInitForServices(profile
, go_off_the_record
);
990 AddProfileToCache(profile
);
991 DoFinalInitLogging(profile
);
993 ProfileMetrics::LogNumberOfProfiles(this);
994 content::NotificationService::current()->Notify(
995 chrome::NOTIFICATION_PROFILE_ADDED
,
996 content::Source
<Profile
>(profile
),
997 content::NotificationService::NoDetails());
1000 void ProfileManager::DoFinalInitForServices(Profile
* profile
,
1001 bool go_off_the_record
) {
1002 #if defined(ENABLE_EXTENSIONS)
1003 ProfileInfoCache
& cache
= GetProfileInfoCache();
1004 extensions::ExtensionSystem::Get(profile
)->InitForRegularProfile(
1005 !go_off_the_record
);
1006 // During tests, when |profile| is an instance of TestingProfile,
1007 // ExtensionSystem might not create an ExtensionService.
1008 if (extensions::ExtensionSystem::Get(profile
)->extension_service()) {
1009 extensions::ExtensionSystem::Get(profile
)->extension_service()->
1010 RegisterContentSettings(profile
->GetHostContentSettingsMap());
1012 // Set the block extensions bit on the ExtensionService. There likely are no
1013 // blockable extensions to block.
1014 size_t profile_index
= cache
.GetIndexOfProfileWithPath(profile
->GetPath());
1015 if (profile_index
!= std::string::npos
&&
1016 cache
.ProfileIsSigninRequiredAtIndex(profile_index
)) {
1017 extensions::ExtensionSystem::Get(profile
)
1018 ->extension_service()
1019 ->BlockAllExtensions();
1023 #if defined(ENABLE_SUPERVISED_USERS)
1024 // Initialization needs to happen after extension system initialization (for
1025 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
1026 // initializing the supervised flag if necessary).
1027 ChildAccountServiceFactory::GetForProfile(profile
)->Init();
1028 SupervisedUserServiceFactory::GetForProfile(profile
)->Init();
1030 // Start the deferred task runners once the profile is loaded.
1031 StartupTaskRunnerServiceFactory::GetForProfile(profile
)->
1032 StartDeferredTaskRunners();
1034 // Activate data reduction proxy. This creates a request context and makes a
1035 // URL request to check if the data reduction proxy server is reachable.
1036 DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile
)->
1037 MaybeActivateDataReductionProxy(true);
1039 AccountTrackerServiceFactory::GetForProfile(profile
)->EnableNetworkFetches();
1040 AccountReconcilorFactory::GetForProfile(profile
);
1043 void ProfileManager::DoFinalInitLogging(Profile
* profile
) {
1044 // Count number of extensions in this profile.
1045 int enabled_app_count
= -1;
1046 #if defined(ENABLE_EXTENSIONS)
1047 enabled_app_count
= GetEnabledAppCount(profile
);
1050 // Log the profile size after a reasonable startup delay.
1051 BrowserThread::PostDelayedTask(
1052 BrowserThread::FILE, FROM_HERE
,
1053 base::Bind(&ProfileSizeTask
, profile
->GetPath(), enabled_app_count
),
1054 base::TimeDelta::FromSeconds(112));
1057 Profile
* ProfileManager::CreateProfileHelper(const base::FilePath
& path
) {
1058 return Profile::CreateProfile(path
, NULL
, Profile::CREATE_MODE_SYNCHRONOUS
);
1061 Profile
* ProfileManager::CreateProfileAsyncHelper(const base::FilePath
& path
,
1062 Delegate
* delegate
) {
1063 return Profile::CreateProfile(path
,
1065 Profile::CREATE_MODE_ASYNCHRONOUS
);
1068 Profile
* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
1069 const base::FilePath
& user_data_dir
) {
1070 #if defined(OS_CHROMEOS)
1071 base::FilePath
default_profile_dir(user_data_dir
);
1073 default_profile_dir
= profiles::GetDefaultProfileDir(user_data_dir
);
1074 Profile
* profile
= GetProfile(default_profile_dir
);
1075 // For cros, return the OTR profile so we never accidentally keep
1076 // user data in an unencrypted profile. But doing this makes
1077 // many of the browser and ui tests fail. We do return the OTR profile
1078 // if the login-profile switch is passed so that we can test this.
1079 if (ShouldGoOffTheRecord(profile
))
1080 return profile
->GetOffTheRecordProfile();
1081 DCHECK(!user_manager::UserManager::Get()->IsLoggedInAsGuest());
1085 default_profile_dir
= default_profile_dir
.Append(GetInitialProfileDir());
1086 ProfileInfo
* profile_info
= GetProfileInfoByPath(default_profile_dir
);
1087 // Fallback to default off-the-record profile, if user profile has not fully
1089 if (profile_info
&& !profile_info
->created
)
1090 default_profile_dir
= profiles::GetDefaultProfileDir(user_data_dir
);
1092 Profile
* profile
= GetProfile(default_profile_dir
);
1093 // Some unit tests didn't initialize the UserManager.
1094 if (user_manager::UserManager::IsInitialized() &&
1095 user_manager::UserManager::Get()->IsLoggedInAsGuest())
1096 return profile
->GetOffTheRecordProfile();
1099 base::FilePath
default_profile_dir(user_data_dir
);
1100 default_profile_dir
= default_profile_dir
.Append(GetInitialProfileDir());
1101 return GetProfile(default_profile_dir
);
1105 bool ProfileManager::AddProfile(Profile
* profile
) {
1108 // Make sure that we're not loading a profile with the same ID as a profile
1109 // that's already loaded.
1110 if (GetProfileByPath(profile
->GetPath())) {
1111 NOTREACHED() << "Attempted to add profile with the same path (" <<
1112 profile
->GetPath().value() <<
1113 ") as an already-loaded profile.";
1117 RegisterProfile(profile
, true);
1118 InitProfileUserPrefs(profile
);
1119 DoFinalInit(profile
, ShouldGoOffTheRecord(profile
));
1123 void ProfileManager::FinishDeletingProfile(const base::FilePath
& profile_dir
) {
1124 ProfileInfoCache
& cache
= GetProfileInfoCache();
1125 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1126 // start deleting the profile instance we need to close background apps too.
1127 Profile
* profile
= GetProfileByPath(profile_dir
);
1130 // TODO: Migrate additional code in this block to observe this notification
1131 // instead of being implemented here.
1132 content::NotificationService::current()->Notify(
1133 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED
,
1134 content::Source
<Profile
>(profile
),
1135 content::NotificationService::NoDetails());
1137 // By this point, all in-progress downloads for the profile being deleted
1138 // must have been canceled (crbug.com/336725).
1139 DCHECK(DownloadServiceFactory::GetForBrowserContext(profile
)->
1140 NonMaliciousDownloadCount() == 0);
1141 BrowserList::CloseAllBrowsersWithProfile(profile
);
1143 // Disable sync for doomed profile.
1144 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1146 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1147 profile
)->DisableForUser();
1150 bool profile_is_signed_in
= !cache
.GetUserNameOfProfileAtIndex(
1151 cache
.GetIndexOfProfileWithPath(profile_dir
)).empty();
1152 ProfileMetrics::LogProfileDelete(profile_is_signed_in
);
1153 // Some platforms store passwords in keychains. They should be removed.
1154 scoped_refptr
<password_manager::PasswordStore
> password_store
=
1155 PasswordStoreFactory::GetForProfile(profile
, Profile::EXPLICIT_ACCESS
)
1157 if (password_store
.get()) {
1158 password_store
->RemoveLoginsCreatedBetween(base::Time(),
1163 QueueProfileDirectoryForDeletion(profile_dir
);
1164 cache
.DeleteProfileFromCache(profile_dir
);
1165 ProfileMetrics::UpdateReportedProfilesStatistics(this);
1168 ProfileManager::ProfileInfo
* ProfileManager::RegisterProfile(
1171 ProfileInfo
* info
= new ProfileInfo(profile
, created
);
1172 profiles_info_
.insert(
1173 std::make_pair(profile
->GetPath(), linked_ptr
<ProfileInfo
>(info
)));
1177 ProfileManager::ProfileInfo
* ProfileManager::GetProfileInfoByPath(
1178 const base::FilePath
& path
) const {
1179 ProfilesInfoMap::const_iterator iter
= profiles_info_
.find(path
);
1180 return (iter
== profiles_info_
.end()) ? NULL
: iter
->second
.get();
1183 void ProfileManager::AddProfileToCache(Profile
* profile
) {
1184 if (profile
->IsGuestSession())
1186 ProfileInfoCache
& cache
= GetProfileInfoCache();
1187 if (profile
->GetPath().DirName() != cache
.GetUserDataDir())
1190 SigninManagerBase
* signin_manager
=
1191 SigninManagerFactory::GetForProfile(profile
);
1192 base::string16 username
= base::UTF8ToUTF16(
1193 signin_manager
->GetAuthenticatedUsername());
1195 size_t profile_index
= cache
.GetIndexOfProfileWithPath(profile
->GetPath());
1196 if (profile_index
!= std::string::npos
) {
1197 // The ProfileInfoCache's username must match the Signin Manager's username.
1198 cache
.SetUserNameOfProfileAtIndex(profile_index
, username
);
1202 // Profile name and avatar are set by InitProfileUserPrefs and stored in the
1203 // profile. Use those values to setup the cache entry.
1204 base::string16 profile_name
=
1205 base::UTF8ToUTF16(profile
->GetPrefs()->GetString(prefs::kProfileName
));
1207 size_t icon_index
= profile
->GetPrefs()->GetInteger(
1208 prefs::kProfileAvatarIndex
);
1210 std::string supervised_user_id
=
1211 profile
->GetPrefs()->GetString(prefs::kSupervisedUserId
);
1213 cache
.AddProfileToCache(profile
->GetPath(),
1217 supervised_user_id
);
1219 if (profile
->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles
)) {
1220 cache
.SetProfileIsEphemeralAtIndex(
1221 cache
.GetIndexOfProfileWithPath(profile
->GetPath()), true);
1225 void ProfileManager::SetGuestProfilePrefs(Profile
* profile
) {
1226 PrefService
* prefs
= profile
->GetPrefs();
1227 prefs
->SetBoolean(prefs::kSigninAllowed
, false);
1228 prefs
->SetBoolean(bookmarks::prefs::kEditBookmarksEnabled
, false);
1229 prefs
->SetBoolean(bookmarks::prefs::kShowBookmarkBar
, false);
1230 prefs
->ClearPref(DefaultSearchManager::kDefaultSearchProviderDataPrefName
);
1231 // This can be removed in the future but needs to be present through
1232 // a release (or two) so that any existing installs get switched to
1233 // the new state and away from the previous "forced" state.
1234 IncognitoModePrefs::SetAvailability(prefs
, IncognitoModePrefs::ENABLED
);
1237 bool ProfileManager::ShouldGoOffTheRecord(Profile
* profile
) {
1238 #if defined(OS_CHROMEOS)
1239 if (profile
->GetPath().BaseName().value() == chrome::kInitialProfile
) {
1243 return profile
->IsGuestSession();
1246 void ProfileManager::RunCallbacks(const std::vector
<CreateCallback
>& callbacks
,
1248 Profile::CreateStatus status
) {
1249 for (size_t i
= 0; i
< callbacks
.size(); ++i
)
1250 callbacks
[i
].Run(profile
, status
);
1253 ProfileManager::ProfileInfo::ProfileInfo(
1260 ProfileManager::ProfileInfo::~ProfileInfo() {
1261 ProfileDestroyer::DestroyProfileWhenAppropriate(profile
.release());
1264 #if !defined(OS_ANDROID) && !defined(OS_IOS)
1265 void ProfileManager::UpdateLastUser(Profile
* last_active
) {
1266 PrefService
* local_state
= g_browser_process
->local_state();
1267 DCHECK(local_state
);
1268 // Only keep track of profiles that we are managing; tests may create others.
1269 if (profiles_info_
.find(last_active
->GetPath()) != profiles_info_
.end()) {
1270 local_state
->SetString(prefs::kProfileLastUsed
,
1271 last_active
->GetPath().BaseName().MaybeAsASCII());
1273 ProfileInfoCache
& cache
= GetProfileInfoCache();
1274 size_t profile_index
=
1275 cache
.GetIndexOfProfileWithPath(last_active
->GetPath());
1276 if (profile_index
!= std::string::npos
)
1277 cache
.SetProfileActiveTimeAtIndex(profile_index
);
1281 ProfileManager::BrowserListObserver::BrowserListObserver(
1282 ProfileManager
* manager
)
1283 : profile_manager_(manager
) {
1284 BrowserList::AddObserver(this);
1287 ProfileManager::BrowserListObserver::~BrowserListObserver() {
1288 BrowserList::RemoveObserver(this);
1291 void ProfileManager::BrowserListObserver::OnBrowserAdded(
1292 Browser
* browser
) {}
1294 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
1296 Profile
* profile
= browser
->profile();
1297 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1298 if (it
->profile()->GetOriginalProfile() == profile
->GetOriginalProfile())
1299 // Not the last window for this profile.
1303 // If the last browser of a profile that is scheduled for deletion is closed
1305 base::FilePath path
= profile
->GetPath();
1306 if (profile
->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles
) &&
1307 !IsProfileMarkedForDeletion(path
)) {
1308 g_browser_process
->profile_manager()->ScheduleProfileForDeletion(
1309 path
, ProfileManager::CreateCallback());
1313 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
1315 // If all browsers are being closed (e.g. the user is in the process of
1316 // shutting down), this event will be fired after each browser is
1317 // closed. This does not represent a user intention to change the active
1318 // browser so is not handled here.
1319 if (profile_manager_
->closing_all_browsers_
)
1322 Profile
* last_active
= browser
->profile();
1324 // Don't remember ephemeral profiles as last because they are not going to
1325 // persist after restart.
1326 if (last_active
->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles
))
1329 profile_manager_
->UpdateLastUser(last_active
);
1331 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
1333 #if defined(OS_MACOSX)
1334 void ProfileManager::OnNewActiveProfileLoaded(
1335 const base::FilePath
& profile_to_delete_path
,
1336 const base::FilePath
& last_non_supervised_profile_path
,
1337 const CreateCallback
& original_callback
,
1338 Profile
* loaded_profile
,
1339 Profile::CreateStatus status
) {
1340 DCHECK(status
!= Profile::CREATE_STATUS_LOCAL_FAIL
&&
1341 status
!= Profile::CREATE_STATUS_REMOTE_FAIL
);
1343 // Only run the code if the profile initialization has finished completely.
1344 if (status
== Profile::CREATE_STATUS_INITIALIZED
) {
1345 if (IsProfileMarkedForDeletion(last_non_supervised_profile_path
)) {
1346 // If the profile we tried to load as the next active profile has been
1347 // deleted, then retry deleting this profile to redo the logic to load
1348 // the next available profile.
1349 ScheduleProfileForDeletion(profile_to_delete_path
, original_callback
);
1351 // Update the local state as promised in the ScheduleProfileForDeletion.
1352 g_browser_process
->local_state()->SetString(
1353 prefs::kProfileLastUsed
,
1354 last_non_supervised_profile_path
.BaseName().MaybeAsASCII());
1355 FinishDeletingProfile(profile_to_delete_path
);
1361 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1362 const base::FilePath
& user_data_dir
) : ProfileManager(user_data_dir
) {