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/file_util.h"
14 #include "base/files/file_enumerator.h"
15 #include "base/files/file_path.h"
16 #include "base/metrics/field_trial.h"
17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_service.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.h"
23 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/content_settings/host_content_settings_map.h"
27 #include "chrome/browser/prefs/incognito_mode_prefs.h"
28 #include "chrome/browser/prefs/scoped_user_pref_update.h"
29 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
30 #include "chrome/browser/profiles/profile_destroyer.h"
31 #include "chrome/browser/profiles/profile_info_cache.h"
32 #include "chrome/browser/profiles/profile_metrics.h"
33 #include "chrome/browser/profiles/profiles_state.h"
34 #include "chrome/browser/profiles/startup_task_runner_service.h"
35 #include "chrome/browser/profiles/startup_task_runner_service_factory.h"
36 #include "chrome/browser/sync/profile_sync_service.h"
37 #include "chrome/browser/sync/profile_sync_service_factory.h"
38 #include "chrome/browser/ui/browser.h"
39 #include "chrome/browser/ui/sync/sync_promo_ui.h"
40 #include "chrome/common/chrome_constants.h"
41 #include "chrome/common/chrome_paths_internal.h"
42 #include "chrome/common/chrome_switches.h"
43 #include "chrome/common/logging_chrome.h"
44 #include "chrome/common/pref_names.h"
45 #include "chrome/common/url_constants.h"
46 #include "content/public/browser/browser_thread.h"
47 #include "content/public/browser/notification_service.h"
48 #include "content/public/browser/user_metrics.h"
49 #include "grit/generated_resources.h"
50 #include "net/http/http_transaction_factory.h"
51 #include "net/url_request/url_request_context.h"
52 #include "net/url_request/url_request_context_getter.h"
53 #include "net/url_request/url_request_job.h"
54 #include "ui/base/l10n/l10n_util.h"
56 #if defined(ENABLE_MANAGED_USERS)
57 #include "chrome/browser/managed_mode/managed_user_service.h"
58 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
62 #include "chrome/browser/extensions/extension_service.h"
63 #include "chrome/browser/extensions/extension_system.h"
64 #include "chrome/browser/sessions/session_service_factory.h"
65 #include "chrome/browser/ui/browser_list.h"
66 #endif // !defined (OS_IOS)
69 #include "base/win/metro.h"
70 #include "chrome/installer/util/browser_distribution.h"
73 #if defined(OS_CHROMEOS)
74 #include "chrome/browser/browser_process_platform_part_chromeos.h"
75 #include "chrome/browser/chromeos/login/user.h"
76 #include "chrome/browser/chromeos/login/user_manager.h"
77 #include "chrome/browser/chromeos/profiles/profile_helper.h"
78 #include "chromeos/chromeos_switches.h"
79 #include "chromeos/dbus/cryptohome_client.h"
80 #include "chromeos/dbus/dbus_thread_manager.h"
83 using content::BrowserThread
;
84 using content::UserMetricsAction
;
88 // Profiles that should be deleted on shutdown.
89 std::vector
<base::FilePath
>& ProfilesToDelete() {
90 CR_DEFINE_STATIC_LOCAL(std::vector
<base::FilePath
>, profiles_to_delete
, ());
91 return profiles_to_delete
;
94 int64
ComputeFilesSize(const base::FilePath
& directory
,
95 const base::FilePath::StringType
& pattern
) {
96 int64 running_size
= 0;
97 base::FileEnumerator
iter(directory
, false, base::FileEnumerator::FILES
,
99 while (!iter
.Next().empty())
100 running_size
+= iter
.GetInfo().GetSize();
104 // Simple task to log the size of the current profile.
105 void ProfileSizeTask(const base::FilePath
& path
, int extension_count
) {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
107 const int64 kBytesInOneMB
= 1024 * 1024;
109 int64 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("*"));
110 int size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
111 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB
);
113 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("History"));
114 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
115 UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB
);
117 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("History*"));
118 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
119 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB
);
121 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Cookies"));
122 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
123 UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB
);
125 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Bookmarks"));
126 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
127 UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB
);
129 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Favicons"));
130 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
131 UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB
);
133 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Top Sites"));
134 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
135 UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB
);
137 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Visited Links"));
138 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
139 UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB
);
141 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Web Data"));
142 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
143 UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB
);
145 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Extension*"));
146 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
147 UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB
);
149 size
= ComputeFilesSize(path
, FILE_PATH_LITERAL("Policy"));
150 size_MB
= static_cast<int>(size
/ kBytesInOneMB
);
151 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB
);
153 // Count number of extensions in this profile, if we know.
154 if (extension_count
!= -1)
155 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", extension_count
);
158 void QueueProfileDirectoryForDeletion(const base::FilePath
& path
) {
159 ProfilesToDelete().push_back(path
);
162 bool IsProfileMarkedForDeletion(const base::FilePath
& profile_path
) {
163 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
164 profile_path
) != ProfilesToDelete().end();
167 void ForceIncognitoModeOnProfile(Profile
* profile
) {
168 IncognitoModePrefs::SetAvailability(profile
->GetPrefs(),
169 IncognitoModePrefs::FORCED
);
172 #if defined(OS_CHROMEOS)
173 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status
,
175 if (call_status
!= chromeos::DBUS_METHOD_CALL_SUCCESS
) {
176 LOG(ERROR
) << "IsMounted call failed.";
180 LOG(ERROR
) << "Cryptohome is not mounted.";
187 #if defined(ENABLE_SESSION_SERVICE)
189 void ProfileManager::ShutdownSessionServices() {
190 ProfileManager
* pm
= g_browser_process
->profile_manager();
191 if (!pm
) // Is NULL when running unit tests.
193 std::vector
<Profile
*> profiles(pm
->GetLoadedProfiles());
194 for (size_t i
= 0; i
< profiles
.size(); ++i
)
195 SessionServiceFactory::ShutdownForProfile(profiles
[i
]);
200 void ProfileManager::NukeDeletedProfilesFromDisk() {
201 for (std::vector
<base::FilePath
>::iterator it
=
202 ProfilesToDelete().begin();
203 it
!= ProfilesToDelete().end();
205 // Delete both the profile directory and its corresponding cache.
206 base::FilePath cache_path
;
207 chrome::GetUserCacheDirectory(*it
, &cache_path
);
208 base::DeleteFile(*it
, true);
209 base::DeleteFile(cache_path
, true);
211 ProfilesToDelete().clear();
216 bool s_allow_get_default_profile
= false;
221 void ProfileManager::AllowGetDefaultProfile() {
222 s_allow_get_default_profile
= true;
226 bool ProfileManager::IsGetDefaultProfileAllowed() {
227 return s_allow_get_default_profile
;
231 // TODO(nkostylev): Remove this method once all clients are migrated.
232 Profile
* ProfileManager::GetDefaultProfile() {
233 CHECK(s_allow_get_default_profile
)
234 << "GetDefaultProfile() caled befofre allowed.";
235 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
236 return profile_manager
->GetDefaultProfile(profile_manager
->user_data_dir_
);
240 // TODO(nkostylev): Remove this method once all clients are migrated.
241 Profile
* ProfileManager::GetDefaultProfileOrOffTheRecord() {
242 CHECK(s_allow_get_default_profile
)
243 << "GetDefaultProfileOrOffTheRecord() caled befofre allowed.";
244 // TODO (mukai,nkostylev): In the long term we should fix those cases that
245 // crash on Guest mode and have only one GetDefaultProfile() method.
246 Profile
* profile
= GetDefaultProfile();
247 #if defined(OS_CHROMEOS)
248 if (chromeos::UserManager::Get()->IsLoggedInAsGuest())
249 profile
= profile
->GetOffTheRecordProfile();
255 Profile
* ProfileManager::GetLastUsedProfile() {
256 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
257 return profile_manager
->GetLastUsedProfile(profile_manager
->user_data_dir_
);
261 Profile
* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
262 Profile
* profile
= GetLastUsedProfile();
263 if (IncognitoModePrefs::GetAvailability(profile
->GetPrefs()) ==
264 IncognitoModePrefs::FORCED
) {
265 return profile
->GetOffTheRecordProfile();
271 std::vector
<Profile
*> ProfileManager::GetLastOpenedProfiles() {
272 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
273 return profile_manager
->GetLastOpenedProfiles(
274 profile_manager
->user_data_dir_
);
277 ProfileManager::ProfileManager(const base::FilePath
& user_data_dir
)
278 : user_data_dir_(user_data_dir
),
281 #if !defined(OS_ANDROID) && !defined(OS_IOS)
282 browser_list_observer_(this),
284 closing_all_browsers_(false) {
285 #if defined(OS_CHROMEOS)
288 chrome::NOTIFICATION_LOGIN_USER_CHANGED
,
289 content::NotificationService::AllSources());
293 chrome::NOTIFICATION_BROWSER_OPENED
,
294 content::NotificationService::AllSources());
297 chrome::NOTIFICATION_BROWSER_CLOSED
,
298 content::NotificationService::AllSources());
301 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST
,
302 content::NotificationService::AllSources());
305 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED
,
306 content::NotificationService::AllSources());
308 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_
.empty())
309 profile_shortcut_manager_
.reset(ProfileShortcutManager::Create(
313 ProfileManager::~ProfileManager() {
316 base::FilePath
ProfileManager::GetInitialProfileDir() {
317 base::FilePath relative_profile_dir
;
318 #if defined(OS_CHROMEOS)
319 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
321 base::FilePath profile_dir
;
322 // If the user has logged in, pick up the new profile.
323 if (command_line
.HasSwitch(chromeos::switches::kLoginProfile
)) {
324 profile_dir
= command_line
.GetSwitchValuePath(
325 chromeos::switches::kLoginProfile
);
326 } else if (!command_line
.HasSwitch(switches::kMultiProfiles
)) {
327 // We should never be logged in with no profile dir unless
328 // multi-profiles are enabled.
329 // In that case profile dir will be defined by user_id hash.
331 return base::FilePath("");
333 // In case of multi-profiles ignore --login-profile switch.
334 // TODO(nkostylev): Some cases like Guest mode will have empty username_hash
335 // so default kLoginProfile dir will be used.
336 std::string user_id_hash
= g_browser_process
->platform_part()->
337 profile_helper()->active_user_id_hash();
338 if (command_line
.HasSwitch(switches::kMultiProfiles
) &&
339 !user_id_hash
.empty()) {
340 profile_dir
= g_browser_process
->platform_part()->
341 profile_helper()->GetActiveUserProfileDir();
343 relative_profile_dir
= relative_profile_dir
.Append(profile_dir
);
344 return relative_profile_dir
;
347 // TODO(mirandac): should not automatically be default profile.
348 relative_profile_dir
=
349 relative_profile_dir
.AppendASCII(chrome::kInitialProfile
);
350 return relative_profile_dir
;
353 Profile
* ProfileManager::GetLastUsedProfile(
354 const base::FilePath
& user_data_dir
) {
355 #if defined(OS_CHROMEOS)
356 // Use default login profile if user has not logged in yet.
358 return GetDefaultProfile(user_data_dir
);
361 return GetProfile(GetLastUsedProfileDir(user_data_dir
));
364 base::FilePath
ProfileManager::GetLastUsedProfileDir(
365 const base::FilePath
& user_data_dir
) {
366 base::FilePath
last_used_profile_dir(user_data_dir
);
367 PrefService
* local_state
= g_browser_process
->local_state();
370 if (local_state
->HasPrefPath(prefs::kProfileLastUsed
)) {
371 return last_used_profile_dir
.AppendASCII(
372 local_state
->GetString(prefs::kProfileLastUsed
));
375 return last_used_profile_dir
.AppendASCII(chrome::kInitialProfile
);
378 std::vector
<Profile
*> ProfileManager::GetLastOpenedProfiles(
379 const base::FilePath
& user_data_dir
) {
380 PrefService
* local_state
= g_browser_process
->local_state();
383 std::vector
<Profile
*> to_return
;
384 if (local_state
->HasPrefPath(prefs::kProfilesLastActive
)) {
385 const ListValue
* profile_list
=
386 local_state
->GetList(prefs::kProfilesLastActive
);
388 ListValue::const_iterator it
;
390 for (it
= profile_list
->begin(); it
!= profile_list
->end(); ++it
) {
391 if (!(*it
)->GetAsString(&profile
) || profile
.empty()) {
392 LOG(WARNING
) << "Invalid entry in " << prefs::kProfilesLastActive
;
395 to_return
.push_back(GetProfile(user_data_dir
.AppendASCII(profile
)));
402 Profile
* ProfileManager::GetDefaultProfile(
403 const base::FilePath
& user_data_dir
) {
404 #if defined(OS_CHROMEOS)
405 base::FilePath
default_profile_dir(user_data_dir
);
407 default_profile_dir
= default_profile_dir
.Append(GetInitialProfileDir());
409 default_profile_dir
= profiles::GetDefaultProfileDir(user_data_dir
);
412 base::FilePath
default_profile_dir(user_data_dir
);
413 default_profile_dir
= default_profile_dir
.Append(GetInitialProfileDir());
415 #if defined(OS_CHROMEOS)
417 Profile
* profile
= GetProfile(default_profile_dir
);
418 // For cros, return the OTR profile so we never accidentally keep
419 // user data in an unencrypted profile. But doing this makes
420 // many of the browser and ui tests fail. We do return the OTR profile
421 // if the login-profile switch is passed so that we can test this.
422 // TODO(davemoore) Fix the tests so they allow OTR profiles.
423 if (ShouldGoOffTheRecord(profile
))
424 return profile
->GetOffTheRecordProfile();
428 ProfileInfo
* profile_info
= GetProfileInfoByPath(default_profile_dir
);
429 // Fallback to default off-the-record profile, if user profile has not fully
431 if (profile_info
&& !profile_info
->created
)
432 default_profile_dir
= profiles::GetDefaultProfileDir(user_data_dir
);
434 return GetProfile(default_profile_dir
);
437 bool ProfileManager::IsValidProfile(Profile
* profile
) {
438 for (ProfilesInfoMap::iterator iter
= profiles_info_
.begin();
439 iter
!= profiles_info_
.end(); ++iter
) {
440 if (iter
->second
->created
) {
441 Profile
* candidate
= iter
->second
->profile
.get();
442 if (candidate
== profile
||
443 (candidate
->HasOffTheRecordProfile() &&
444 candidate
->GetOffTheRecordProfile() == profile
)) {
452 std::vector
<Profile
*> ProfileManager::GetLoadedProfiles() const {
453 std::vector
<Profile
*> profiles
;
454 for (ProfilesInfoMap::const_iterator iter
= profiles_info_
.begin();
455 iter
!= profiles_info_
.end(); ++iter
) {
456 if (iter
->second
->created
)
457 profiles
.push_back(iter
->second
->profile
.get());
462 Profile
* ProfileManager::GetProfile(const base::FilePath
& profile_dir
) {
463 TRACE_EVENT0("browser", "ProfileManager::GetProfile")
464 // If the profile is already loaded (e.g., chrome.exe launched twice), just
466 Profile
* profile
= GetProfileByPath(profile_dir
);
470 profile
= CreateProfileHelper(profile_dir
);
473 bool result
= AddProfile(profile
);
479 void ProfileManager::CreateProfileAsync(
480 const base::FilePath
& profile_path
,
481 const CreateCallback
& callback
,
482 const string16
& name
,
483 const string16
& icon_url
,
484 const std::string
& managed_user_id
) {
485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
487 // Make sure that this profile is not pending deletion.
488 if (IsProfileMarkedForDeletion(profile_path
)) {
489 if (!callback
.is_null())
490 callback
.Run(NULL
, Profile::CREATE_STATUS_LOCAL_FAIL
);
494 // Create the profile if needed and collect its ProfileInfo.
495 ProfilesInfoMap::iterator iter
= profiles_info_
.find(profile_path
);
496 ProfileInfo
* info
= NULL
;
498 if (iter
!= profiles_info_
.end()) {
499 info
= iter
->second
.get();
501 // Initiate asynchronous creation process.
502 info
= RegisterProfile(CreateProfileAsyncHelper(profile_path
, this), false);
503 ProfileInfoCache
& cache
= GetProfileInfoCache();
504 // Get the icon index from the user's icon url
506 std::string icon_url_std
= UTF16ToASCII(icon_url
);
507 if (cache
.IsDefaultAvatarIconUrl(icon_url_std
, &icon_index
)) {
508 // add profile to cache with user selected name and avatar
509 cache
.AddProfileToCache(profile_path
, name
, string16(), icon_index
,
513 if (!managed_user_id
.empty()) {
514 content::RecordAction(
515 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
519 // Call or enqueue the callback.
520 if (!callback
.is_null()) {
521 if (iter
!= profiles_info_
.end() && info
->created
) {
522 Profile
* profile
= info
->profile
.get();
523 // If this was the guest profile, finish setting its incognito status.
524 if (profile
->GetPath() == ProfileManager::GetGuestProfilePath())
525 ForceIncognitoModeOnProfile(profile
);
526 // Profile has already been created. Run callback immediately.
527 callback
.Run(profile
, Profile::CREATE_STATUS_INITIALIZED
);
529 // Profile is either already in the process of being created, or new.
530 // Add callback to the list.
531 info
->callbacks
.push_back(callback
);
536 bool ProfileManager::AddProfile(Profile
* profile
) {
539 // Make sure that we're not loading a profile with the same ID as a profile
540 // that's already loaded.
541 if (GetProfileByPath(profile
->GetPath())) {
542 NOTREACHED() << "Attempted to add profile with the same path (" <<
543 profile
->GetPath().value() <<
544 ") as an already-loaded profile.";
548 RegisterProfile(profile
, true);
549 DoFinalInit(profile
, ShouldGoOffTheRecord(profile
));
553 ProfileManager::ProfileInfo
* ProfileManager::RegisterProfile(
556 ProfileInfo
* info
= new ProfileInfo(profile
, created
);
557 profiles_info_
.insert(
558 std::make_pair(profile
->GetPath(), linked_ptr
<ProfileInfo
>(info
)));
562 ProfileManager::ProfileInfo
* ProfileManager::GetProfileInfoByPath(
563 const base::FilePath
& path
) const {
564 ProfilesInfoMap::const_iterator iter
= profiles_info_
.find(path
);
565 return (iter
== profiles_info_
.end()) ? NULL
: iter
->second
.get();
568 Profile
* ProfileManager::GetProfileByPath(const base::FilePath
& path
) const {
569 ProfileInfo
* profile_info
= GetProfileInfoByPath(path
);
570 return profile_info
? profile_info
->profile
.get() : NULL
;
573 void ProfileManager::Observe(
575 const content::NotificationSource
& source
,
576 const content::NotificationDetails
& details
) {
577 #if defined(OS_CHROMEOS)
578 if (type
== chrome::NOTIFICATION_LOGIN_USER_CHANGED
) {
581 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
582 if (!command_line
.HasSwitch(switches::kTestType
)) {
583 // If we don't have a mounted profile directory we're in trouble.
584 // TODO(davemoore) Once we have better api this check should ensure that
585 // our profile directory is the one that's mounted, and that it's mounted
586 // as the current user.
587 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
588 base::Bind(&CheckCryptohomeIsMounted
));
590 // Confirm that we hadn't loaded the new profile previously.
591 base::FilePath default_profile_dir
= user_data_dir_
.Append(
592 GetInitialProfileDir());
593 CHECK(!GetProfileByPath(default_profile_dir
))
594 << "The default profile was loaded before we mounted the cryptohome.";
599 bool save_active_profiles
= false;
601 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST
: {
602 // Ignore any browsers closing from now on.
603 closing_all_browsers_
= true;
606 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED
: {
607 // This will cancel the shutdown process, so the active profiles are
608 // tracked again. Also, as the active profiles may have changed (i.e. if
609 // some windows were closed) we save the current list of active profiles
611 closing_all_browsers_
= false;
612 save_active_profiles
= true;
615 case chrome::NOTIFICATION_BROWSER_OPENED
: {
616 Browser
* browser
= content::Source
<Browser
>(source
).ptr();
618 Profile
* profile
= browser
->profile();
620 if (!profile
->IsOffTheRecord() && ++browser_counts_
[profile
] == 1) {
621 active_profiles_
.push_back(profile
);
622 save_active_profiles
= true;
624 // If browsers are opening, we can't be closing all the browsers. This
625 // can happen if the application was exited, but background mode or
626 // packaged apps prevented the process from shutting down, and then
627 // a new browser window was opened.
628 closing_all_browsers_
= false;
631 case chrome::NOTIFICATION_BROWSER_CLOSED
: {
632 Browser
* browser
= content::Source
<Browser
>(source
).ptr();
634 Profile
* profile
= browser
->profile();
636 if (!profile
->IsOffTheRecord() && --browser_counts_
[profile
] == 0) {
637 active_profiles_
.erase(std::find(active_profiles_
.begin(),
638 active_profiles_
.end(), profile
));
639 save_active_profiles
= !closing_all_browsers_
;
649 if (save_active_profiles
) {
650 PrefService
* local_state
= g_browser_process
->local_state();
652 ListPrefUpdate
update(local_state
, prefs::kProfilesLastActive
);
653 ListValue
* profile_list
= update
.Get();
655 profile_list
->Clear();
657 // crbug.com/120112 -> several non-incognito profiles might have the same
658 // GetPath().BaseName(). In that case, we cannot restore both
659 // profiles. Include each base name only once in the last active profile
661 std::set
<std::string
> profile_paths
;
662 std::vector
<Profile
*>::const_iterator it
;
663 for (it
= active_profiles_
.begin(); it
!= active_profiles_
.end(); ++it
) {
664 std::string profile_path
= (*it
)->GetPath().BaseName().MaybeAsASCII();
665 if (profile_paths
.find(profile_path
) == profile_paths
.end()) {
666 profile_paths
.insert(profile_path
);
667 profile_list
->Append(new StringValue(profile_path
));
673 #if !defined(OS_ANDROID) && !defined(OS_IOS)
674 ProfileManager::BrowserListObserver::BrowserListObserver(
675 ProfileManager
* manager
)
676 : profile_manager_(manager
) {
677 BrowserList::AddObserver(this);
680 ProfileManager::BrowserListObserver::~BrowserListObserver() {
681 BrowserList::RemoveObserver(this);
684 void ProfileManager::BrowserListObserver::OnBrowserAdded(
687 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
690 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
692 // If all browsers are being closed (e.g. the user is in the process of
693 // shutting down), this event will be fired after each browser is
694 // closed. This does not represent a user intention to change the active
695 // browser so is not handled here.
696 if (profile_manager_
->closing_all_browsers_
)
699 Profile
* last_active
= browser
->profile();
700 PrefService
* local_state
= g_browser_process
->local_state();
702 // Only keep track of profiles that we are managing; tests may create others.
703 if (profile_manager_
->profiles_info_
.find(
704 last_active
->GetPath()) != profile_manager_
->profiles_info_
.end()) {
705 local_state
->SetString(prefs::kProfileLastUsed
,
706 last_active
->GetPath().BaseName().MaybeAsASCII());
709 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
711 void ProfileManager::DoFinalInit(Profile
* profile
, bool go_off_the_record
) {
712 InitProfileUserPrefs(profile
);
713 DoFinalInitForServices(profile
, go_off_the_record
);
714 AddProfileToCache(profile
);
715 DoFinalInitLogging(profile
);
717 ProfileMetrics::LogNumberOfProfiles(this);
718 content::NotificationService::current()->Notify(
719 chrome::NOTIFICATION_PROFILE_ADDED
,
720 content::Source
<Profile
>(profile
),
721 content::NotificationService::NoDetails());
724 void ProfileManager::DoFinalInitForServices(Profile
* profile
,
725 bool go_off_the_record
) {
726 #if defined(ENABLE_EXTENSIONS)
727 // Set up a field trial to determine the effectiveness of deferring
728 // creation of background extension RenderViews.
729 CR_DEFINE_STATIC_LOCAL(scoped_refptr
<base::FieldTrial
>, trial
, ());
730 static bool defer_creation
= false;
733 const base::FieldTrial::Probability kDivisor
= 100;
735 // Enable the deferred creation for 50% of the users.
736 base::FieldTrial::Probability probability_per_group
= 50;
738 // After August 31, 2014 builds, it will always be in default group
739 // (defer_creation == false).
740 trial
= base::FieldTrialList::FactoryGetFieldTrial(
741 "DeferBackgroundExtensionCreation",
747 base::FieldTrial::ONE_TIME_RANDOMIZED
,
750 // Add group for deferred creation of background extension RenderViews.
751 int defer_creation_group
=
752 trial
->AppendGroup("Deferred", probability_per_group
);
753 defer_creation
= trial
->group() == defer_creation_group
;
756 extensions::ExtensionSystem::Get(profile
)->InitForRegularProfile(
757 !go_off_the_record
, defer_creation
);
758 // During tests, when |profile| is an instance of TestingProfile,
759 // ExtensionSystem might not create an ExtensionService.
760 if (extensions::ExtensionSystem::Get(profile
)->extension_service()) {
761 profile
->GetHostContentSettingsMap()->RegisterExtensionService(
762 extensions::ExtensionSystem::Get(profile
)->extension_service());
765 #if defined(ENABLE_MANAGED_USERS)
766 // Initialization needs to happen after extension system initialization (for
767 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
768 // initializing the managed flag if necessary).
769 ManagedUserServiceFactory::GetForProfile(profile
)->Init();
771 // Start the deferred task runners once the profile is loaded.
772 StartupTaskRunnerServiceFactory::GetForProfile(profile
)->
773 StartDeferredTaskRunners();
776 void ProfileManager::DoFinalInitLogging(Profile
* profile
) {
777 // Count number of extensions in this profile.
778 int extension_count
= -1;
779 #if defined(ENABLE_EXTENSIONS)
780 ExtensionService
* extension_service
= profile
->GetExtensionService();
781 if (extension_service
)
782 extension_count
= extension_service
->GetAppIds().size();
785 // Log the profile size after a reasonable startup delay.
786 BrowserThread::PostDelayedTask(
787 BrowserThread::FILE, FROM_HERE
,
788 base::Bind(&ProfileSizeTask
, profile
->GetPath(), extension_count
),
789 base::TimeDelta::FromSeconds(112));
792 Profile
* ProfileManager::CreateProfileHelper(const base::FilePath
& path
) {
793 return Profile::CreateProfile(path
, NULL
, Profile::CREATE_MODE_SYNCHRONOUS
);
796 Profile
* ProfileManager::CreateProfileAsyncHelper(const base::FilePath
& path
,
797 Delegate
* delegate
) {
798 return Profile::CreateProfile(path
,
800 Profile::CREATE_MODE_ASYNCHRONOUS
);
803 void ProfileManager::OnProfileCreated(Profile
* profile
,
805 bool is_new_profile
) {
806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
808 ProfilesInfoMap::iterator iter
= profiles_info_
.find(profile
->GetPath());
809 DCHECK(iter
!= profiles_info_
.end());
810 ProfileInfo
* info
= iter
->second
.get();
812 std::vector
<CreateCallback
> callbacks
;
813 info
->callbacks
.swap(callbacks
);
815 // Invoke CREATED callback for normal profiles.
816 bool go_off_the_record
= ShouldGoOffTheRecord(profile
);
817 if (success
&& !go_off_the_record
)
818 RunCallbacks(callbacks
, profile
, Profile::CREATE_STATUS_CREATED
);
820 // Perform initialization.
822 DoFinalInit(profile
, go_off_the_record
);
823 if (go_off_the_record
)
824 profile
= profile
->GetOffTheRecordProfile();
825 info
->created
= true;
828 profiles_info_
.erase(iter
);
831 // If this was the guest profile, finish setting its incognito status.
832 if (profile
->GetPath() == ProfileManager::GetGuestProfilePath())
833 ForceIncognitoModeOnProfile(profile
);
835 // Invoke CREATED callback for incognito profiles.
836 if (profile
&& go_off_the_record
)
837 RunCallbacks(callbacks
, profile
, Profile::CREATE_STATUS_CREATED
);
839 // Invoke INITIALIZED or FAIL for all profiles.
840 RunCallbacks(callbacks
, profile
,
841 profile
? Profile::CREATE_STATUS_INITIALIZED
:
842 Profile::CREATE_STATUS_LOCAL_FAIL
);
845 base::FilePath
ProfileManager::GenerateNextProfileDirectoryPath() {
846 PrefService
* local_state
= g_browser_process
->local_state();
849 DCHECK(profiles::IsMultipleProfilesEnabled());
851 // Create the next profile in the next available directory slot.
852 int next_directory
= local_state
->GetInteger(prefs::kProfilesNumCreated
);
853 std::string profile_name
= chrome::kMultiProfileDirPrefix
;
854 profile_name
.append(base::IntToString(next_directory
));
855 base::FilePath new_path
= user_data_dir_
;
857 new_path
= new_path
.Append(ASCIIToUTF16(profile_name
));
859 new_path
= new_path
.Append(profile_name
);
861 local_state
->SetInteger(prefs::kProfilesNumCreated
, ++next_directory
);
866 base::FilePath
ProfileManager::CreateMultiProfileAsync(
867 const string16
& name
,
868 const string16
& icon_url
,
869 const CreateCallback
& callback
,
870 const std::string
& managed_user_id
) {
871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
873 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
875 base::FilePath new_path
= profile_manager
->GenerateNextProfileDirectoryPath();
877 profile_manager
->CreateProfileAsync(new_path
,
886 base::FilePath
ProfileManager::GetGuestProfilePath() {
887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
889 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
891 base::FilePath guest_path
= profile_manager
->user_data_dir();
892 return guest_path
.Append(chrome::kGuestProfileDir
);
895 size_t ProfileManager::GetNumberOfProfiles() {
896 return GetProfileInfoCache().GetNumberOfProfiles();
899 bool ProfileManager::CompareProfilePathAndName(
900 const ProfileManager::ProfilePathAndName
& pair1
,
901 const ProfileManager::ProfilePathAndName
& pair2
) {
902 int name_compare
= pair1
.second
.compare(pair2
.second
);
903 if (name_compare
< 0) {
905 } else if (name_compare
> 0) {
908 return pair1
.first
< pair2
.first
;
912 ProfileInfoCache
& ProfileManager::GetProfileInfoCache() {
913 if (!profile_info_cache_
) {
914 profile_info_cache_
.reset(new ProfileInfoCache(
915 g_browser_process
->local_state(), user_data_dir_
));
917 return *profile_info_cache_
.get();
920 ProfileShortcutManager
* ProfileManager::profile_shortcut_manager() {
921 return profile_shortcut_manager_
.get();
924 void ProfileManager::AddProfileToCache(Profile
* profile
) {
925 if (profile
->IsGuestSession())
927 ProfileInfoCache
& cache
= GetProfileInfoCache();
928 if (profile
->GetPath().DirName() != cache
.GetUserDataDir())
931 if (cache
.GetIndexOfProfileWithPath(profile
->GetPath()) != std::string::npos
)
934 string16 username
= UTF8ToUTF16(profile
->GetPrefs()->GetString(
935 prefs::kGoogleServicesUsername
));
937 // Profile name and avatar are set by InitProfileUserPrefs and stored in the
938 // profile. Use those values to setup the cache entry.
939 string16 profile_name
= UTF8ToUTF16(profile
->GetPrefs()->GetString(
940 prefs::kProfileName
));
942 size_t icon_index
= profile
->GetPrefs()->GetInteger(
943 prefs::kProfileAvatarIndex
);
945 std::string managed_user_id
=
946 profile
->GetPrefs()->GetString(prefs::kManagedUserId
);
948 cache
.AddProfileToCache(profile
->GetPath(),
955 void ProfileManager::InitProfileUserPrefs(Profile
* profile
) {
956 ProfileInfoCache
& cache
= GetProfileInfoCache();
958 if (profile
->GetPath().DirName() != cache
.GetUserDataDir())
962 std::string profile_name
;
963 std::string managed_user_id
;
964 if (profile
->IsGuestSession()) {
965 profile_name
= l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME
);
968 size_t profile_cache_index
=
969 cache
.GetIndexOfProfileWithPath(profile
->GetPath());
970 // If the cache has an entry for this profile, use the cache data.
971 if (profile_cache_index
!= std::string::npos
) {
973 cache
.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index
);
975 UTF16ToUTF8(cache
.GetNameOfProfileAtIndex(profile_cache_index
));
977 cache
.GetManagedUserIdOfProfileAtIndex(profile_cache_index
);
978 } else if (profile
->GetPath() ==
979 profiles::GetDefaultProfileDir(cache
.GetUserDataDir())) {
981 profile_name
= l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME
);
983 avatar_index
= cache
.ChooseAvatarIconIndexForNewProfile();
984 profile_name
= UTF16ToUTF8(cache
.ChooseNameForNewProfile(avatar_index
));
988 if (!profile
->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex
))
989 profile
->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex
, avatar_index
);
991 if (!profile
->GetPrefs()->HasPrefPath(prefs::kProfileName
))
992 profile
->GetPrefs()->SetString(prefs::kProfileName
, profile_name
);
994 if (!profile
->GetPrefs()->HasPrefPath(prefs::kManagedUserId
))
995 profile
->GetPrefs()->SetString(prefs::kManagedUserId
, managed_user_id
);
998 bool ProfileManager::ShouldGoOffTheRecord(Profile
* profile
) {
999 bool go_off_the_record
= false;
1000 #if defined(OS_CHROMEOS)
1001 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
1002 if (profile
->GetPath().BaseName().value() == chrome::kInitialProfile
&&
1003 (!command_line
.HasSwitch(switches::kTestType
) ||
1004 command_line
.HasSwitch(chromeos::switches::kLoginProfile
))) {
1005 go_off_the_record
= true;
1008 return go_off_the_record
;
1011 void ProfileManager::ScheduleProfileForDeletion(
1012 const base::FilePath
& profile_dir
,
1013 const CreateCallback
& callback
) {
1014 DCHECK(profiles::IsMultipleProfilesEnabled());
1015 PrefService
* local_state
= g_browser_process
->local_state();
1016 ProfileInfoCache
& cache
= GetProfileInfoCache();
1018 if (profile_dir
.BaseName().MaybeAsASCII() ==
1019 local_state
->GetString(prefs::kProfileLastUsed
)) {
1020 // Update the last used profile pref before closing browser windows. This
1021 // way the correct last used profile is set for any notification observers.
1022 base::FilePath last_non_managed_profile_path
;
1023 for (size_t i
= 0; i
< cache
.GetNumberOfProfiles(); ++i
) {
1024 base::FilePath cur_path
= cache
.GetPathOfProfileAtIndex(i
);
1025 // Make sure that this profile is not pending deletion.
1026 if (cur_path
!= profile_dir
&& !cache
.ProfileIsManagedAtIndex(i
) &&
1027 !IsProfileMarkedForDeletion(cur_path
)) {
1028 last_non_managed_profile_path
= cur_path
;
1033 // If we're deleting the last (non-managed) profile, then create a new
1034 // profile in its place.
1035 const std::string last_non_managed_profile
=
1036 last_non_managed_profile_path
.BaseName().MaybeAsASCII();
1037 if (last_non_managed_profile
.empty()) {
1038 base::FilePath new_path
= GenerateNextProfileDirectoryPath();
1039 // Make sure the last used profile path is pointing at it. This way the
1040 // correct last used profile is set for any notification observers.
1041 local_state
->SetString(prefs::kProfileLastUsed
,
1042 new_path
.BaseName().MaybeAsASCII());
1043 CreateProfileAsync(new_path
,
1049 // On the Mac, the browser process is not killed when all browser windows
1050 // are closed, so just in case we are deleting the active profile, and no
1051 // other profile has been loaded, we must pre-load a next one.
1052 #if defined(OS_MACOSX)
1053 CreateProfileAsync(last_non_managed_profile_path
,
1054 base::Bind(&ProfileManager::OnNewActiveProfileLoaded
,
1055 base::Unretained(this),
1057 last_non_managed_profile_path
,
1064 // For OS_MACOSX the pref is updated in the callback to make sure that
1065 // it isn't used before the profile is actually loaded.
1066 local_state
->SetString(prefs::kProfileLastUsed
, last_non_managed_profile
);
1070 FinishDeletingProfile(profile_dir
);
1073 void ProfileManager::OnNewActiveProfileLoaded(
1074 const base::FilePath
& profile_to_delete_path
,
1075 const base::FilePath
& last_non_managed_profile_path
,
1076 const CreateCallback
& original_callback
,
1077 Profile
* loaded_profile
,
1078 Profile::CreateStatus status
) {
1079 DCHECK(status
!= Profile::CREATE_STATUS_LOCAL_FAIL
&&
1080 status
!= Profile::CREATE_STATUS_REMOTE_FAIL
);
1082 // Only run the code if the profile initialization has finished completely.
1083 if (status
== Profile::CREATE_STATUS_INITIALIZED
) {
1084 if (IsProfileMarkedForDeletion(last_non_managed_profile_path
)) {
1085 // If the profile we tried to load as the next active profile has been
1086 // deleted, then retry deleting this profile to redo the logic to load
1087 // the next available profile.
1088 ScheduleProfileForDeletion(profile_to_delete_path
, original_callback
);
1090 // Update the local state as promised in the ScheduleProfileForDeletion.
1091 g_browser_process
->local_state()->SetString(
1092 prefs::kProfileLastUsed
,
1093 last_non_managed_profile_path
.BaseName().MaybeAsASCII());
1094 FinishDeletingProfile(profile_to_delete_path
);
1099 void ProfileManager::FinishDeletingProfile(const base::FilePath
& profile_dir
) {
1100 ProfileInfoCache
& cache
= GetProfileInfoCache();
1101 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1102 // start deleting the profile instance we need to close background apps too.
1103 Profile
* profile
= GetProfileByPath(profile_dir
);
1106 BrowserList::CloseAllBrowsersWithProfile(profile
);
1108 // Disable sync for doomed profile.
1109 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1111 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1112 profile
)->DisableForUser();
1116 QueueProfileDirectoryForDeletion(profile_dir
);
1117 cache
.DeleteProfileFromCache(profile_dir
);
1120 void ProfileManager::AutoloadProfiles() {
1121 // If running in the background is disabled for the browser, do not autoload
1123 PrefService
* local_state
= g_browser_process
->local_state();
1124 if (!local_state
->HasPrefPath(prefs::kBackgroundModeEnabled
) ||
1125 !local_state
->GetBoolean(prefs::kBackgroundModeEnabled
)) {
1129 ProfileInfoCache
& cache
= GetProfileInfoCache();
1130 size_t number_of_profiles
= cache
.GetNumberOfProfiles();
1131 for (size_t p
= 0; p
< number_of_profiles
; ++p
) {
1132 if (cache
.GetBackgroundStatusOfProfileAtIndex(p
)) {
1133 // If status is true, that profile is running background apps. By calling
1134 // GetProfile, we automatically cause the profile to be loaded which will
1135 // register it with the BackgroundModeManager.
1136 GetProfile(cache
.GetPathOfProfileAtIndex(p
));
1141 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1142 const base::FilePath
& user_data_dir
) : ProfileManager(user_data_dir
) {
1145 void ProfileManager::RegisterTestingProfile(Profile
* profile
,
1147 bool start_deferred_task_runners
) {
1148 RegisterProfile(profile
, true);
1150 InitProfileUserPrefs(profile
);
1151 AddProfileToCache(profile
);
1153 if (start_deferred_task_runners
) {
1154 StartupTaskRunnerServiceFactory::GetForProfile(profile
)->
1155 StartDeferredTaskRunners();
1159 void ProfileManager::RunCallbacks(const std::vector
<CreateCallback
>& callbacks
,
1161 Profile::CreateStatus status
) {
1162 for (size_t i
= 0; i
< callbacks
.size(); ++i
)
1163 callbacks
[i
].Run(profile
, status
);
1166 ProfileManager::ProfileInfo::ProfileInfo(
1173 ProfileManager::ProfileInfo::~ProfileInfo() {
1174 ProfileDestroyer::DestroyProfileWhenAppropriate(profile
.release());