Choose right profile to load without switching active user
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager.cc
blobf4f65ded5892807fb7956a219b370b8d82911553
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"
7 #include <set>
9 #include "base/bind.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"
59 #endif
61 #if !defined(OS_IOS)
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)
68 #if defined(OS_WIN)
69 #include "base/win/metro.h"
70 #include "chrome/installer/util/browser_distribution.h"
71 #endif
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"
81 #endif
83 using content::BrowserThread;
84 using content::UserMetricsAction;
86 namespace {
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,
98 pattern);
99 while (!iter.Next().empty())
100 running_size += iter.GetInfo().GetSize();
101 return running_size;
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,
174 bool is_mounted) {
175 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
176 LOG(ERROR) << "IsMounted call failed.";
177 return;
179 if (!is_mounted)
180 LOG(ERROR) << "Cryptohome is not mounted.";
183 #endif
185 } // namespace
187 #if defined(ENABLE_SESSION_SERVICE)
188 // static
189 void ProfileManager::ShutdownSessionServices() {
190 ProfileManager* pm = g_browser_process->profile_manager();
191 if (!pm) // Is NULL when running unit tests.
192 return;
193 std::vector<Profile*> profiles(pm->GetLoadedProfiles());
194 for (size_t i = 0; i < profiles.size(); ++i)
195 SessionServiceFactory::ShutdownForProfile(profiles[i]);
197 #endif
199 // static
200 void ProfileManager::NukeDeletedProfilesFromDisk() {
201 for (std::vector<base::FilePath>::iterator it =
202 ProfilesToDelete().begin();
203 it != ProfilesToDelete().end();
204 ++it) {
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();
214 namespace {
216 bool s_allow_get_default_profile = false;
218 } // namespace
220 // static
221 void ProfileManager::AllowGetDefaultProfile() {
222 s_allow_get_default_profile = true;
225 // static
226 bool ProfileManager::IsGetDefaultProfileAllowed() {
227 return s_allow_get_default_profile;
230 // static
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_);
239 // static
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();
250 #endif
251 return profile;
254 // static
255 Profile* ProfileManager::GetLastUsedProfile() {
256 ProfileManager* profile_manager = g_browser_process->profile_manager();
257 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_);
260 // static
261 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
262 Profile* profile = GetLastUsedProfile();
263 if (IncognitoModePrefs::GetAvailability(profile->GetPrefs()) ==
264 IncognitoModePrefs::FORCED) {
265 return profile->GetOffTheRecordProfile();
267 return profile;
270 // static
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),
279 logged_in_(false),
281 #if !defined(OS_ANDROID) && !defined(OS_IOS)
282 browser_list_observer_(this),
283 #endif
284 closing_all_browsers_(false) {
285 #if defined(OS_CHROMEOS)
286 registrar_.Add(
287 this,
288 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
289 content::NotificationService::AllSources());
290 #endif
291 registrar_.Add(
292 this,
293 chrome::NOTIFICATION_BROWSER_OPENED,
294 content::NotificationService::AllSources());
295 registrar_.Add(
296 this,
297 chrome::NOTIFICATION_BROWSER_CLOSED,
298 content::NotificationService::AllSources());
299 registrar_.Add(
300 this,
301 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
302 content::NotificationService::AllSources());
303 registrar_.Add(
304 this,
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(
310 this));
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();
320 if (logged_in_) {
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.
330 NOTREACHED();
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;
346 #endif
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.
357 if (!logged_in_)
358 return GetDefaultProfile(user_data_dir);
359 #endif
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();
368 DCHECK(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();
381 DCHECK(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);
387 if (profile_list) {
388 ListValue::const_iterator it;
389 std::string profile;
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;
393 continue;
395 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile)));
399 return to_return;
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);
406 if (logged_in_) {
407 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
408 } else {
409 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
411 #else
412 base::FilePath default_profile_dir(user_data_dir);
413 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
414 #endif
415 #if defined(OS_CHROMEOS)
416 if (!logged_in_) {
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();
425 return profile;
428 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
429 // Fallback to default off-the-record profile, if user profile has not fully
430 // loaded yet.
431 if (profile_info && !profile_info->created)
432 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
433 #endif
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)) {
445 return true;
449 return false;
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());
459 return profiles;
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
465 // return it.
466 Profile* profile = GetProfileByPath(profile_dir);
467 if (NULL != profile)
468 return profile;
470 profile = CreateProfileHelper(profile_dir);
471 DCHECK(profile);
472 if (profile) {
473 bool result = AddProfile(profile);
474 DCHECK(result);
476 return 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);
491 return;
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();
500 } else {
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
505 size_t icon_index;
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,
510 managed_user_id);
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);
528 } else {
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) {
537 DCHECK(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.";
545 return false;
548 RegisterProfile(profile, true);
549 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
550 return true;
553 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
554 Profile* profile,
555 bool created) {
556 ProfileInfo* info = new ProfileInfo(profile, created);
557 profiles_info_.insert(
558 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
559 return 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(
574 int type,
575 const content::NotificationSource& source,
576 const content::NotificationDetails& details) {
577 #if defined(OS_CHROMEOS)
578 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
579 logged_in_ = true;
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.";
596 return;
598 #endif
599 bool save_active_profiles = false;
600 switch (type) {
601 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: {
602 // Ignore any browsers closing from now on.
603 closing_all_browsers_ = true;
604 break;
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
610 // again.
611 closing_all_browsers_ = false;
612 save_active_profiles = true;
613 break;
615 case chrome::NOTIFICATION_BROWSER_OPENED: {
616 Browser* browser = content::Source<Browser>(source).ptr();
617 DCHECK(browser);
618 Profile* profile = browser->profile();
619 DCHECK(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;
629 break;
631 case chrome::NOTIFICATION_BROWSER_CLOSED: {
632 Browser* browser = content::Source<Browser>(source).ptr();
633 DCHECK(browser);
634 Profile* profile = browser->profile();
635 DCHECK(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_;
641 break;
643 default: {
644 NOTREACHED();
645 break;
649 if (save_active_profiles) {
650 PrefService* local_state = g_browser_process->local_state();
651 DCHECK(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
660 // list.
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(
685 Browser* browser) {}
687 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
688 Browser* browser) {}
690 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
691 Browser* browser) {
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_)
697 return;
699 Profile* last_active = browser->profile();
700 PrefService* local_state = g_browser_process->local_state();
701 DCHECK(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;
732 if (!trial.get()) {
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",
742 kDivisor,
743 "RateLimited",
744 2014,
747 base::FieldTrial::ONE_TIME_RANDOMIZED,
748 NULL);
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());
764 #endif
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();
770 #endif
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();
783 #endif
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,
799 delegate,
800 Profile::CREATE_MODE_ASYNCHRONOUS);
803 void ProfileManager::OnProfileCreated(Profile* profile,
804 bool success,
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.
821 if (success) {
822 DoFinalInit(profile, go_off_the_record);
823 if (go_off_the_record)
824 profile = profile->GetOffTheRecordProfile();
825 info->created = true;
826 } else {
827 profile = NULL;
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();
847 DCHECK(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_;
856 #if defined(OS_WIN)
857 new_path = new_path.Append(ASCIIToUTF16(profile_name));
858 #else
859 new_path = new_path.Append(profile_name);
860 #endif
861 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory);
862 return new_path;
865 // static
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,
878 callback,
879 name,
880 icon_url,
881 managed_user_id);
882 return new_path;
885 // static
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) {
904 return true;
905 } else if (name_compare > 0) {
906 return false;
907 } else {
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())
926 return;
927 ProfileInfoCache& cache = GetProfileInfoCache();
928 if (profile->GetPath().DirName() != cache.GetUserDataDir())
929 return;
931 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos)
932 return;
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(),
949 profile_name,
950 username,
951 icon_index,
952 managed_user_id);
955 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
956 ProfileInfoCache& cache = GetProfileInfoCache();
958 if (profile->GetPath().DirName() != cache.GetUserDataDir())
959 return;
961 size_t avatar_index;
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);
966 avatar_index = 0;
967 } else {
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) {
972 avatar_index =
973 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
974 profile_name =
975 UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
976 managed_user_id =
977 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index);
978 } else if (profile->GetPath() ==
979 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
980 avatar_index = 0;
981 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
982 } else {
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;
1007 #endif
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;
1029 break;
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,
1044 callback,
1045 string16(),
1046 string16(),
1047 std::string());
1048 } else {
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),
1056 profile_dir,
1057 last_non_managed_profile_path,
1058 callback),
1059 string16(),
1060 string16(),
1061 std::string());
1062 return;
1063 #else
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);
1067 #endif
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);
1089 } else {
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);
1105 if (profile) {
1106 BrowserList::CloseAllBrowsersWithProfile(profile);
1108 // Disable sync for doomed profile.
1109 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1110 profile)) {
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
1122 // any profiles.
1123 PrefService* local_state = g_browser_process->local_state();
1124 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
1125 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
1126 return;
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,
1146 bool add_to_cache,
1147 bool start_deferred_task_runners) {
1148 RegisterProfile(profile, true);
1149 if (add_to_cache) {
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,
1160 Profile* profile,
1161 Profile::CreateStatus status) {
1162 for (size_t i = 0; i < callbacks.size(); ++i)
1163 callbacks[i].Run(profile, status);
1166 ProfileManager::ProfileInfo::ProfileInfo(
1167 Profile* profile,
1168 bool created)
1169 : profile(profile),
1170 created(created) {
1173 ProfileManager::ProfileInfo::~ProfileInfo() {
1174 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());