OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/profiles/profile_manager.h" | 5 #include "chrome/browser/profiles/profile_manager.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
555 Profile* ProfileManager::GetProfileByPathInternal( | 555 Profile* ProfileManager::GetProfileByPathInternal( |
556 const base::FilePath& path) const { | 556 const base::FilePath& path) const { |
557 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPathInternal"); | 557 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPathInternal"); |
558 ProfileInfo* profile_info = GetProfileInfoByPath(path); | 558 ProfileInfo* profile_info = GetProfileInfoByPath(path); |
559 return profile_info ? profile_info->profile.get() : nullptr; | 559 return profile_info ? profile_info->profile.get() : nullptr; |
560 } | 560 } |
561 | 561 |
562 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { | 562 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { |
563 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath"); | 563 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath"); |
564 ProfileInfo* profile_info = GetProfileInfoByPath(path); | 564 ProfileInfo* profile_info = GetProfileInfoByPath(path); |
565 return profile_info && profile_info->created ? profile_info->profile.get() | 565 return (profile_info && profile_info->created) ? profile_info->profile.get() |
566 : nullptr; | 566 : nullptr; |
567 } | 567 } |
568 | 568 |
569 // static | 569 // static |
570 base::FilePath ProfileManager::CreateMultiProfileAsync( | 570 base::FilePath ProfileManager::CreateMultiProfileAsync( |
571 const base::string16& name, | 571 const base::string16& name, |
572 const base::string16& icon_url, | 572 const base::string16& icon_url, |
573 const CreateCallback& callback, | 573 const CreateCallback& callback, |
574 const std::string& supervised_user_id) { | 574 const std::string& supervised_user_id) { |
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
576 | 576 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 // Cancel all in-progress downloads before deleting the profile to prevent a | 647 // Cancel all in-progress downloads before deleting the profile to prevent a |
648 // "Do you want to exit Google Chrome and cancel the downloads?" prompt | 648 // "Do you want to exit Google Chrome and cancel the downloads?" prompt |
649 // (crbug.com/336725). | 649 // (crbug.com/336725). |
650 Profile* profile = GetProfileByPath(profile_dir); | 650 Profile* profile = GetProfileByPath(profile_dir); |
651 if (profile) { | 651 if (profile) { |
652 DownloadService* service = | 652 DownloadService* service = |
653 DownloadServiceFactory::GetForBrowserContext(profile); | 653 DownloadServiceFactory::GetForBrowserContext(profile); |
654 service->CancelDownloads(); | 654 service->CancelDownloads(); |
655 } | 655 } |
656 | 656 |
657 PrefService* local_state = g_browser_process->local_state(); | |
658 ProfileInfoCache& cache = GetProfileInfoCache(); | 657 ProfileInfoCache& cache = GetProfileInfoCache(); |
659 | 658 |
660 // If we're deleting the last (non-legacy-supervised) profile, then create a | 659 // If we're deleting the last (non-legacy-supervised) profile, then create a |
661 // new profile in its place. | 660 // new profile in its place. |
662 base::FilePath last_non_supervised_profile_path; | 661 base::FilePath last_non_supervised_profile_path; |
663 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 662 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
664 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); | 663 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); |
665 // Make sure that this profile is not pending deletion, and is not | 664 // Make sure that this profile is not pending deletion, and is not |
666 // legacy-supervised. | 665 // legacy-supervised. |
667 if (cur_path != profile_dir && | 666 if (cur_path != profile_dir && |
(...skipping 11 matching lines...) Expand all Loading... | |
679 bool is_new_avatar_menu = switches::IsNewAvatarMenu(); | 678 bool is_new_avatar_menu = switches::IsNewAvatarMenu(); |
680 int avatar_index = profiles::GetPlaceholderAvatarIndex(); | 679 int avatar_index = profiles::GetPlaceholderAvatarIndex(); |
681 base::string16 new_avatar_url = is_new_avatar_menu ? | 680 base::string16 new_avatar_url = is_new_avatar_menu ? |
682 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(avatar_index)) : | 681 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(avatar_index)) : |
683 base::string16(); | 682 base::string16(); |
684 base::string16 new_profile_name = is_new_avatar_menu ? | 683 base::string16 new_profile_name = is_new_avatar_menu ? |
685 cache.ChooseNameForNewProfile(avatar_index) : base::string16(); | 684 cache.ChooseNameForNewProfile(avatar_index) : base::string16(); |
686 | 685 |
687 new_path = GenerateNextProfileDirectoryPath(); | 686 new_path = GenerateNextProfileDirectoryPath(); |
688 CreateProfileAsync(new_path, | 687 CreateProfileAsync(new_path, |
689 callback, | 688 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, |
689 base::Unretained(this), | |
690 profile_dir, | |
691 new_path, | |
692 callback), | |
690 new_profile_name, | 693 new_profile_name, |
691 new_avatar_url, | 694 new_avatar_url, |
692 std::string()); | 695 std::string()); |
693 | 696 |
694 ProfileMetrics::LogProfileAddNewUser( | 697 ProfileMetrics::LogProfileAddNewUser( |
695 ProfileMetrics::ADD_NEW_USER_LAST_DELETED); | 698 ProfileMetrics::ADD_NEW_USER_LAST_DELETED); |
699 return; | |
696 } | 700 } |
697 | 701 |
698 // Update the last used profile pref before closing browser windows. This | 702 #if defined(OS_MACOSX) |
699 // way the correct last used profile is set for any notification observers. | 703 // On the Mac, the browser process is not killed when all browser windows are |
noms (inactive)
2015/02/23 23:54:49
I think this may be true of windows in background
Bernhard Bauer
2015/02/24 15:13:32
Hm... but then again, if the browser does indeed q
noms (inactive)
2015/02/24 19:37:37
That makes sense.Let's ignore it for now, and if/w
| |
704 // closed, so just in case we are deleting the active profile, and no other | |
705 // profile has been loaded, we must pre-load a next one. | |
700 const std::string last_used_profile = | 706 const std::string last_used_profile = |
701 local_state->GetString(prefs::kProfileLastUsed); | 707 g_browser_process->local_state()->GetString(prefs::kProfileLastUsed); |
702 if (last_used_profile == profile_dir.BaseName().MaybeAsASCII() || | 708 if (last_used_profile == profile_dir.BaseName().MaybeAsASCII() || |
703 last_used_profile == GetGuestProfilePath().BaseName().MaybeAsASCII()) { | 709 last_used_profile == GetGuestProfilePath().BaseName().MaybeAsASCII()) { |
704 const std::string last_non_supervised_profile = | 710 CreateProfileAsync(last_non_supervised_profile_path, |
705 last_non_supervised_profile_path.BaseName().MaybeAsASCII(); | 711 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, |
706 if (last_non_supervised_profile.empty()) { | 712 base::Unretained(this), |
707 DCHECK(!new_path.empty()); | 713 profile_dir, |
708 local_state->SetString(prefs::kProfileLastUsed, | 714 last_non_supervised_profile_path, |
709 new_path.BaseName().MaybeAsASCII()); | 715 callback), |
710 } else { | 716 base::string16(), |
711 // On the Mac, the browser process is not killed when all browser windows | 717 base::string16(), |
712 // are closed, so just in case we are deleting the active profile, and no | 718 std::string()); |
713 // other profile has been loaded, we must pre-load a next one. | 719 return; |
714 #if defined(OS_MACOSX) | |
715 CreateProfileAsync(last_non_supervised_profile_path, | |
716 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, | |
717 base::Unretained(this), | |
718 profile_dir, | |
719 last_non_supervised_profile_path, | |
720 callback), | |
721 base::string16(), | |
722 base::string16(), | |
723 std::string()); | |
724 return; | |
725 #else | |
726 // For OS_MACOSX the pref is updated in the callback to make sure that | |
727 // it isn't used before the profile is actually loaded. | |
728 local_state->SetString(prefs::kProfileLastUsed, | |
729 last_non_supervised_profile); | |
730 #endif | |
731 } | |
732 } | 720 } |
733 FinishDeletingProfile(profile_dir); | 721 #endif // defined(OS_MACOSX) |
722 | |
723 FinishDeletingProfile(profile_dir, last_non_supervised_profile_path); | |
734 } | 724 } |
735 | 725 |
736 // static | 726 // static |
737 void ProfileManager::CleanUpStaleProfiles( | 727 void ProfileManager::CleanUpStaleProfiles( |
738 const std::vector<base::FilePath>& profile_paths) { | 728 const std::vector<base::FilePath>& profile_paths) { |
739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
740 | 730 |
741 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin(); | 731 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin(); |
742 it != profile_paths.end(); ++it) { | 732 it != profile_paths.end(); ++it) { |
743 NukeProfileFromDisk(*it); | 733 NukeProfileFromDisk(*it); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1156 CHECK(!GetProfileByPathInternal(profile_dir)); | 1146 CHECK(!GetProfileByPathInternal(profile_dir)); |
1157 Profile* profile = CreateProfileHelper(profile_dir); | 1147 Profile* profile = CreateProfileHelper(profile_dir); |
1158 DCHECK(profile); | 1148 DCHECK(profile); |
1159 if (profile) { | 1149 if (profile) { |
1160 bool result = AddProfile(profile); | 1150 bool result = AddProfile(profile); |
1161 DCHECK(result); | 1151 DCHECK(result); |
1162 } | 1152 } |
1163 return profile; | 1153 return profile; |
1164 } | 1154 } |
1165 | 1155 |
1166 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { | 1156 void ProfileManager::FinishDeletingProfile( |
1157 const base::FilePath& profile_dir, | |
1158 const base::FilePath& new_active_profile_dir) { | |
1159 // Update the last used profile pref before closing browser windows. This | |
1160 // way the correct last used profile is set for any notification observers. | |
1161 g_browser_process->local_state()->SetString( | |
1162 prefs::kProfileLastUsed, | |
1163 new_active_profile_dir.BaseName().MaybeAsASCII()); | |
1164 | |
1167 ProfileInfoCache& cache = GetProfileInfoCache(); | 1165 ProfileInfoCache& cache = GetProfileInfoCache(); |
1168 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we | 1166 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we |
1169 // start deleting the profile instance we need to close background apps too. | 1167 // start deleting the profile instance we need to close background apps too. |
1170 Profile* profile = GetProfileByPath(profile_dir); | 1168 Profile* profile = GetProfileByPath(profile_dir); |
1171 | 1169 |
1172 if (profile) { | 1170 if (profile) { |
1173 // TODO: Migrate additional code in this block to observe this notification | 1171 // TODO: Migrate additional code in this block to observe this notification |
1174 // instead of being implemented here. | 1172 // instead of being implemented here. |
1175 content::NotificationService::current()->Notify( | 1173 content::NotificationService::current()->Notify( |
1176 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, | 1174 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1368 | 1366 |
1369 // Don't remember ephemeral profiles as last because they are not going to | 1367 // Don't remember ephemeral profiles as last because they are not going to |
1370 // persist after restart. | 1368 // persist after restart. |
1371 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) | 1369 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) |
1372 return; | 1370 return; |
1373 | 1371 |
1374 profile_manager_->UpdateLastUser(last_active); | 1372 profile_manager_->UpdateLastUser(last_active); |
1375 } | 1373 } |
1376 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) | 1374 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) |
1377 | 1375 |
1378 #if defined(OS_MACOSX) | |
1379 void ProfileManager::OnNewActiveProfileLoaded( | 1376 void ProfileManager::OnNewActiveProfileLoaded( |
1380 const base::FilePath& profile_to_delete_path, | 1377 const base::FilePath& profile_to_delete_path, |
1381 const base::FilePath& last_non_supervised_profile_path, | 1378 const base::FilePath& new_active_profile_path, |
1382 const CreateCallback& original_callback, | 1379 const CreateCallback& original_callback, |
1383 Profile* loaded_profile, | 1380 Profile* loaded_profile, |
1384 Profile::CreateStatus status) { | 1381 Profile::CreateStatus status) { |
1385 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && | 1382 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && |
1386 status != Profile::CREATE_STATUS_REMOTE_FAIL); | 1383 status != Profile::CREATE_STATUS_REMOTE_FAIL); |
1387 | 1384 |
1388 // Only run the code if the profile initialization has finished completely. | 1385 // Only run the code if the profile initialization has finished completely. |
1389 if (status == Profile::CREATE_STATUS_INITIALIZED) { | 1386 if (status != Profile::CREATE_STATUS_INITIALIZED) |
1390 if (IsProfileMarkedForDeletion(last_non_supervised_profile_path)) { | 1387 return; |
1391 // If the profile we tried to load as the next active profile has been | 1388 |
1392 // deleted, then retry deleting this profile to redo the logic to load | 1389 if (IsProfileMarkedForDeletion(new_active_profile_path)) { |
1393 // the next available profile. | 1390 // If the profile we tried to load as the next active profile has been |
1394 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); | 1391 // deleted, then retry deleting this profile to redo the logic to load |
1395 } else { | 1392 // the next available profile. |
1396 // Update the local state as promised in the ScheduleProfileForDeletion. | 1393 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); |
1397 g_browser_process->local_state()->SetString( | 1394 return; |
1398 prefs::kProfileLastUsed, | |
1399 last_non_supervised_profile_path.BaseName().MaybeAsASCII()); | |
1400 FinishDeletingProfile(profile_to_delete_path); | |
1401 } | |
1402 } | 1395 } |
1396 | |
1397 FinishDeletingProfile(profile_to_delete_path, new_active_profile_path); | |
1403 } | 1398 } |
1404 #endif | |
1405 | 1399 |
1406 ProfileManagerWithoutInit::ProfileManagerWithoutInit( | 1400 ProfileManagerWithoutInit::ProfileManagerWithoutInit( |
1407 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { | 1401 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { |
1408 } | 1402 } |
OLD | NEW |