Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: chrome/browser/profiles/profile_manager.cc

Issue 14923004: [Mac] AppController needs to update its "last profile" pointer when the active profile is deleted (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: derp. no test on CrOS either. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 154
155 // Count number of extensions in this profile, if we know. 155 // Count number of extensions in this profile, if we know.
156 if (extension_count != -1) 156 if (extension_count != -1)
157 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", extension_count); 157 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", extension_count);
158 } 158 }
159 159
160 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { 160 void QueueProfileDirectoryForDeletion(const base::FilePath& path) {
161 ProfilesToDelete().push_back(path); 161 ProfilesToDelete().push_back(path);
162 } 162 }
163 163
164 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) {
165 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
166 profile_path) != ProfilesToDelete().end();
167 }
168
164 #if defined(OS_CHROMEOS) 169 #if defined(OS_CHROMEOS)
165 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status, 170 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status,
166 bool is_mounted) { 171 bool is_mounted) {
167 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { 172 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
168 LOG(ERROR) << "IsMounted call failed."; 173 LOG(ERROR) << "IsMounted call failed.";
169 return; 174 return;
170 } 175 }
171 if (!is_mounted) 176 if (!is_mounted)
172 LOG(ERROR) << "Cryptohome is not mounted."; 177 LOG(ERROR) << "Cryptohome is not mounted.";
173 } 178 }
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 492
488 void ProfileManager::CreateProfileAsync( 493 void ProfileManager::CreateProfileAsync(
489 const base::FilePath& profile_path, 494 const base::FilePath& profile_path,
490 const CreateCallback& callback, 495 const CreateCallback& callback,
491 const string16& name, 496 const string16& name,
492 const string16& icon_url, 497 const string16& icon_url,
493 bool is_managed) { 498 bool is_managed) {
494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
495 500
496 // Make sure that this profile is not pending deletion. 501 // Make sure that this profile is not pending deletion.
497 if (std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), 502 if (IsProfileMarkedForDeletion(profile_path)) {
498 profile_path) != ProfilesToDelete().end()) {
499 if (!callback.is_null()) 503 if (!callback.is_null())
500 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); 504 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
501 return; 505 return;
502 } 506 }
503 507
504 // Create the profile if needed and collect its ProfileInfo. 508 // Create the profile if needed and collect its ProfileInfo.
505 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); 509 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
506 ProfileInfo* info = NULL; 510 ProfileInfo* info = NULL;
507 511
508 if (iter != profiles_info_.end()) { 512 if (iter != profiles_info_.end()) {
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 go_off_the_record = true; 1039 go_off_the_record = true;
1036 } 1040 }
1037 #endif 1041 #endif
1038 return go_off_the_record; 1042 return go_off_the_record;
1039 } 1043 }
1040 1044
1041 void ProfileManager::ScheduleProfileForDeletion( 1045 void ProfileManager::ScheduleProfileForDeletion(
1042 const base::FilePath& profile_dir, 1046 const base::FilePath& profile_dir,
1043 const CreateCallback& callback) { 1047 const CreateCallback& callback) {
1044 DCHECK(IsMultipleProfilesEnabled()); 1048 DCHECK(IsMultipleProfilesEnabled());
1045
1046 PrefService* local_state = g_browser_process->local_state(); 1049 PrefService* local_state = g_browser_process->local_state();
1047 ProfileInfoCache& cache = GetProfileInfoCache(); 1050 ProfileInfoCache& cache = GetProfileInfoCache();
1051
1048 if (profile_dir.BaseName().MaybeAsASCII() == 1052 if (profile_dir.BaseName().MaybeAsASCII() ==
1049 local_state->GetString(prefs::kProfileLastUsed)) { 1053 local_state->GetString(prefs::kProfileLastUsed)) {
1050 // Update the last used profile pref before closing browser windows. This 1054 // Update the last used profile pref before closing browser windows. This
1051 // way the correct last used profile is set for any notification observers. 1055 // way the correct last used profile is set for any notification observers.
1052 std::string last_non_managed_profile; 1056 base::FilePath last_non_managed_profile_path;
1053 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { 1057 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
1054 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); 1058 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
1055 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i)) { 1059 // Make sure that this profile is not pending deletion.
1056 last_non_managed_profile = cur_path.BaseName().MaybeAsASCII(); 1060 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) &&
1061 !IsProfileMarkedForDeletion(cur_path)) {
1062 last_non_managed_profile_path = cur_path;
1057 break; 1063 break;
1058 } 1064 }
1059 } 1065 }
1066
1060 // If we're deleting the last (non-managed) profile, then create a new 1067 // If we're deleting the last (non-managed) profile, then create a new
1061 // profile in its place. 1068 // profile in its place.
1069 const std::string last_non_managed_profile =
1070 last_non_managed_profile_path.BaseName().MaybeAsASCII();
1062 if (last_non_managed_profile.empty()) { 1071 if (last_non_managed_profile.empty()) {
1063 base::FilePath new_path = GenerateNextProfileDirectoryPath(); 1072 base::FilePath new_path = GenerateNextProfileDirectoryPath();
1064 // Make sure the last used profile path is pointing at it. This way the 1073 // Make sure the last used profile path is pointing at it. This way the
1065 // correct last used profile is set for any notification observers. 1074 // correct last used profile is set for any notification observers.
1066 local_state->SetString(prefs::kProfileLastUsed, 1075 local_state->SetString(prefs::kProfileLastUsed,
1067 new_path.BaseName().MaybeAsASCII()); 1076 new_path.BaseName().MaybeAsASCII());
1068 CreateProfileAsync(new_path, 1077 CreateProfileAsync(new_path,
1069 callback, 1078 callback,
1070 string16(), 1079 string16(),
1071 string16(), 1080 string16(),
1072 false); 1081 false);
1073 } else { 1082 } else {
1083 // On the Mac, the browser process is not killed when all browser windows
1084 // are closed, so just in case we are deleting the active profile, and no
1085 // other profile has been loaded, we must pre-load a next one.
1086 #if defined(OS_MACOSX)
1087 CreateProfileAsync(last_non_managed_profile_path,
1088 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
1089 base::Unretained(this),
1090 profile_dir,
1091 last_non_managed_profile_path,
1092 callback),
1093 string16(),
1094 string16(),
1095 false);
1096 return;
1097 #else
1098 // For OS_MACOSX the pref is updated in the callback to make sure that
1099 // it isn't used before the profile is actually loaded.
1074 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); 1100 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile);
1101 #endif
1075 } 1102 }
1076 } 1103 }
1104 FinishDeletingProfile(profile_dir);
1105 }
1077 1106
1107 void ProfileManager::OnNewActiveProfileLoaded(
1108 const base::FilePath& profile_to_delete_path,
1109 const base::FilePath& last_non_managed_profile_path,
1110 const CreateCallback& original_callback,
1111 Profile* loaded_profile,
1112 Profile::CreateStatus status) {
1113 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
1114 status != Profile::CREATE_STATUS_REMOTE_FAIL);
1115
1116 // Only run the code if the profile initialization has finished completely.
1117 if (status == Profile::CREATE_STATUS_INITIALIZED) {
1118 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) {
1119 // If the profile we tried to load as the next active profile has been
1120 // deleted, then retry deleting this profile to redo the logic to load
1121 // the next available profile.
1122 ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
1123 } else {
1124 // Update the local state as promised in the ScheduleProfileForDeletion.
1125 g_browser_process->local_state()->SetString(
1126 prefs::kProfileLastUsed,
1127 last_non_managed_profile_path.BaseName().MaybeAsASCII());
1128 FinishDeletingProfile(profile_to_delete_path);
1129 }
1130 }
1131 }
1132
1133 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) {
1134 ProfileInfoCache& cache = GetProfileInfoCache();
1078 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we 1135 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1079 // start deleting the profile instance we need to close background apps too. 1136 // start deleting the profile instance we need to close background apps too.
1080 Profile* profile = GetProfileByPath(profile_dir); 1137 Profile* profile = GetProfileByPath(profile_dir);
1138
1081 if (profile) { 1139 if (profile) {
1082 BrowserList::CloseAllBrowsersWithProfile(profile); 1140 BrowserList::CloseAllBrowsersWithProfile(profile);
1083 1141
1084 // Disable sync for doomed profile. 1142 // Disable sync for doomed profile.
1085 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( 1143 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1086 profile)) { 1144 profile)) {
1087 ProfileSyncServiceFactory::GetInstance()->GetForProfile( 1145 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1088 profile)->DisableForUser(); 1146 profile)->DisableForUser();
1089 } 1147 }
1090 } 1148 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 ProfileManager::ProfileInfo::ProfileInfo( 1213 ProfileManager::ProfileInfo::ProfileInfo(
1156 Profile* profile, 1214 Profile* profile,
1157 bool created) 1215 bool created)
1158 : profile(profile), 1216 : profile(profile),
1159 created(created) { 1217 created(created) {
1160 } 1218 }
1161 1219
1162 ProfileManager::ProfileInfo::~ProfileInfo() { 1220 ProfileManager::ProfileInfo::~ProfileInfo() {
1163 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); 1221 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1164 } 1222 }
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_manager.h ('k') | chrome/browser/profiles/profile_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698