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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 | 488 |
489 void ProfileManager::CreateProfileAsync( | 489 void ProfileManager::CreateProfileAsync( |
490 const base::FilePath& profile_path, | 490 const base::FilePath& profile_path, |
491 const CreateCallback& callback, | 491 const CreateCallback& callback, |
492 const string16& name, | 492 const string16& name, |
493 const string16& icon_url, | 493 const string16& icon_url, |
494 bool is_managed) { | 494 bool is_managed) { |
495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
496 | 496 |
497 // Make sure that this profile is not pending deletion. | 497 // Make sure that this profile is not pending deletion. |
498 if (std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), | 498 if (IsProfileMarkedForDeletion(profile_path)) { |
499 profile_path) != ProfilesToDelete().end()) { | |
500 if (!callback.is_null()) | 499 if (!callback.is_null()) |
501 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); | 500 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); |
502 return; | 501 return; |
503 } | 502 } |
504 | 503 |
505 // Create the profile if needed and collect its ProfileInfo. | 504 // Create the profile if needed and collect its ProfileInfo. |
506 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); | 505 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); |
507 ProfileInfo* info = NULL; | 506 ProfileInfo* info = NULL; |
508 | 507 |
509 if (iter != profiles_info_.end()) { | 508 if (iter != profiles_info_.end()) { |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1036 go_off_the_record = true; | 1035 go_off_the_record = true; |
1037 } | 1036 } |
1038 #endif | 1037 #endif |
1039 return go_off_the_record; | 1038 return go_off_the_record; |
1040 } | 1039 } |
1041 | 1040 |
1042 void ProfileManager::ScheduleProfileForDeletion( | 1041 void ProfileManager::ScheduleProfileForDeletion( |
1043 const base::FilePath& profile_dir, | 1042 const base::FilePath& profile_dir, |
1044 const CreateCallback& callback) { | 1043 const CreateCallback& callback) { |
1045 DCHECK(IsMultipleProfilesEnabled()); | 1044 DCHECK(IsMultipleProfilesEnabled()); |
1046 | |
1047 PrefService* local_state = g_browser_process->local_state(); | 1045 PrefService* local_state = g_browser_process->local_state(); |
1048 ProfileInfoCache& cache = GetProfileInfoCache(); | 1046 ProfileInfoCache& cache = GetProfileInfoCache(); |
1047 | |
1049 if (profile_dir.BaseName().MaybeAsASCII() == | 1048 if (profile_dir.BaseName().MaybeAsASCII() == |
1050 local_state->GetString(prefs::kProfileLastUsed)) { | 1049 local_state->GetString(prefs::kProfileLastUsed)) { |
1051 // Update the last used profile pref before closing browser windows. This | 1050 // Update the last used profile pref before closing browser windows. This |
1052 // way the correct last used profile is set for any notification observers. | 1051 // way the correct last used profile is set for any notification observers. |
1053 std::string last_non_managed_profile; | 1052 base::FilePath last_non_managed_profile_path; |
1054 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 1053 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
1055 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); | 1054 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); |
1056 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i)) { | 1055 // Make sure that this profile is not pending deletion. |
1057 last_non_managed_profile = cur_path.BaseName().MaybeAsASCII(); | 1056 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) && |
1057 !IsProfileMarkedForDeletion(cur_path)) { | |
1058 last_non_managed_profile_path = cur_path; | |
1058 break; | 1059 break; |
1059 } | 1060 } |
1060 } | 1061 } |
1062 | |
1061 // If we're deleting the last (non-managed) profile, then create a new | 1063 // If we're deleting the last (non-managed) profile, then create a new |
1062 // profile in its place. | 1064 // profile in its place. |
1065 const std::string last_non_managed_profile = | |
1066 last_non_managed_profile_path.BaseName().MaybeAsASCII(); | |
1063 if (last_non_managed_profile.empty()) { | 1067 if (last_non_managed_profile.empty()) { |
1064 base::FilePath new_path = GenerateNextProfileDirectoryPath(); | 1068 base::FilePath new_path = GenerateNextProfileDirectoryPath(); |
1065 // Make sure the last used profile path is pointing at it. This way the | 1069 // Make sure the last used profile path is pointing at it. This way the |
1066 // correct last used profile is set for any notification observers. | 1070 // correct last used profile is set for any notification observers. |
1067 local_state->SetString(prefs::kProfileLastUsed, | 1071 local_state->SetString(prefs::kProfileLastUsed, |
1068 new_path.BaseName().MaybeAsASCII()); | 1072 new_path.BaseName().MaybeAsASCII()); |
1069 CreateProfileAsync(new_path, | 1073 CreateProfileAsync(new_path, |
1070 callback, | 1074 callback, |
1071 string16(), | 1075 string16(), |
1072 string16(), | 1076 string16(), |
1073 false); | 1077 false); |
1074 } else { | 1078 } else { |
1079 // On the Mac, the browser process is not killed when all browser windows | |
1080 // are closed, so just in case we are deleting the active profile, and no | |
1081 // other profile has been loaded, we must pre-load a next one. | |
1082 #if defined(OS_MACOSX) | |
1083 CreateProfileAsync(last_non_managed_profile_path, | |
1084 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, | |
1085 base::Unretained(this), | |
1086 profile_dir, | |
1087 last_non_managed_profile_path, | |
1088 callback), | |
1089 string16(), | |
1090 string16(), | |
1091 false); | |
1092 return; | |
1093 #else | |
1094 // For OS_MACOSX the pref is updated in the callback to make sure that | |
1095 // it isn't used before the profile is actually loaded. | |
1075 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); | 1096 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); |
1097 #endif | |
1076 } | 1098 } |
1077 } | 1099 } |
1100 FinishDeletingProfile(profile_dir); | |
1101 } | |
1078 | 1102 |
1103 void ProfileManager::OnNewActiveProfileLoaded( | |
1104 const base::FilePath& profile_to_delete_dir, | |
1105 const base::FilePath& last_non_managed_profile_path, | |
1106 const CreateCallback& original_callback, | |
1107 Profile* loaded_profile, | |
1108 Profile::CreateStatus status) { | |
1109 // Only run the code if the profile initialization has finished completely | |
1110 // (either completed successfully, or has failed). | |
1111 if (status == Profile::CREATE_STATUS_INITIALIZED || | |
1112 status == Profile::CREATE_STATUS_LOCAL_FAIL || | |
Alexei Svitkine (slow)
2013/06/19 14:58:31
Should we actually be doing the recursion in the f
noms (inactive)
2013/06/21 23:11:47
I've added a DCHECK.
On 2013/06/19 14:58:31, Alex
| |
1113 status == Profile::CREATE_STATUS_REMOTE_FAIL) { | |
1114 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) { | |
1115 // If the profile we tried to load as the next active profile has been | |
1116 // deleted, then retry deleting this profile to redo the logic and load | |
Alexei Svitkine (slow)
2013/06/19 14:58:31
nit: "and load" -> "to load"
noms (inactive)
2013/06/21 23:11:47
Done.
| |
1117 // the next available profile. | |
1118 ScheduleProfileForDeletion(profile_to_delete_dir, original_callback); | |
1119 } else { | |
1120 // Update the local state as promised in the ScheduleProfileForDeletion. | |
1121 g_browser_process->local_state()->SetString( | |
1122 prefs::kProfileLastUsed, | |
1123 last_non_managed_profile_path.BaseName().MaybeAsASCII()); | |
1124 FinishDeletingProfile(profile_to_delete_dir); | |
1125 } | |
1126 } | |
1127 } | |
1128 | |
1129 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { | |
1130 ProfileInfoCache& cache = GetProfileInfoCache(); | |
1079 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we | 1131 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we |
1080 // start deleting the profile instance we need to close background apps too. | 1132 // start deleting the profile instance we need to close background apps too. |
1081 Profile* profile = GetProfileByPath(profile_dir); | 1133 Profile* profile = GetProfileByPath(profile_dir); |
1134 | |
1082 if (profile) { | 1135 if (profile) { |
1083 BrowserList::CloseAllBrowsersWithProfile(profile); | 1136 BrowserList::CloseAllBrowsersWithProfile(profile); |
1084 | 1137 |
1085 // Disable sync for doomed profile. | 1138 // Disable sync for doomed profile. |
1086 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( | 1139 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( |
1087 profile)) { | 1140 profile)) { |
1088 ProfileSyncServiceFactory::GetInstance()->GetForProfile( | 1141 ProfileSyncServiceFactory::GetInstance()->GetForProfile( |
1089 profile)->DisableForUser(); | 1142 profile)->DisableForUser(); |
1090 } | 1143 } |
1091 } | 1144 } |
1092 | 1145 |
1093 QueueProfileDirectoryForDeletion(profile_dir); | 1146 QueueProfileDirectoryForDeletion(profile_dir); |
1094 cache.DeleteProfileFromCache(profile_dir); | 1147 cache.DeleteProfileFromCache(profile_dir); |
1095 } | 1148 } |
1096 | 1149 |
1150 bool ProfileManager::IsProfileMarkedForDeletion( | |
Alexei Svitkine (slow)
2013/06/19 14:58:31
Move this to the anon namespace at the top of the
noms (inactive)
2013/06/21 23:11:47
Done.
| |
1151 const base::FilePath& profile_dir) { | |
1152 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), | |
1153 profile_dir) != ProfilesToDelete().end(); | |
1154 } | |
1155 | |
1097 // static | 1156 // static |
1098 bool ProfileManager::IsMultipleProfilesEnabled() { | 1157 bool ProfileManager::IsMultipleProfilesEnabled() { |
1099 #if defined(OS_ANDROID) | 1158 #if defined(OS_ANDROID) |
1100 return false; | 1159 return false; |
1101 #endif | 1160 #endif |
1102 #if defined(OS_CHROMEOS) | 1161 #if defined(OS_CHROMEOS) |
1103 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)) | 1162 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)) |
1104 return false; | 1163 return false; |
1105 #endif | 1164 #endif |
1106 | 1165 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1156 ProfileManager::ProfileInfo::ProfileInfo( | 1215 ProfileManager::ProfileInfo::ProfileInfo( |
1157 Profile* profile, | 1216 Profile* profile, |
1158 bool created) | 1217 bool created) |
1159 : profile(profile), | 1218 : profile(profile), |
1160 created(created) { | 1219 created(created) { |
1161 } | 1220 } |
1162 | 1221 |
1163 ProfileManager::ProfileInfo::~ProfileInfo() { | 1222 ProfileManager::ProfileInfo::~ProfileInfo() { |
1164 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); | 1223 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); |
1165 } | 1224 } |
OLD | NEW |