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

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

Powered by Google App Engine
This is Rietveld 408576698