| Index: chrome/browser/profiles/profile_manager.cc
|
| diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
|
| index 15c174cf574aec5edbeeb7822baeab6702d48dc1..84d0a1bf9615621060a9dc7967d866f4ec5c1ce5 100644
|
| --- a/chrome/browser/profiles/profile_manager.cc
|
| +++ b/chrome/browser/profiles/profile_manager.cc
|
| @@ -161,6 +161,11 @@ void QueueProfileDirectoryForDeletion(const base::FilePath& path) {
|
| ProfilesToDelete().push_back(path);
|
| }
|
|
|
| +bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) {
|
| + return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
|
| + profile_path) != ProfilesToDelete().end();
|
| +}
|
| +
|
| #if defined(OS_CHROMEOS)
|
| void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status,
|
| bool is_mounted) {
|
| @@ -494,8 +499,7 @@ void ProfileManager::CreateProfileAsync(
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| // Make sure that this profile is not pending deletion.
|
| - if (std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
|
| - profile_path) != ProfilesToDelete().end()) {
|
| + if (IsProfileMarkedForDeletion(profile_path)) {
|
| if (!callback.is_null())
|
| callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
|
| return;
|
| @@ -1042,23 +1046,28 @@ void ProfileManager::ScheduleProfileForDeletion(
|
| const base::FilePath& profile_dir,
|
| const CreateCallback& callback) {
|
| DCHECK(IsMultipleProfilesEnabled());
|
| -
|
| PrefService* local_state = g_browser_process->local_state();
|
| ProfileInfoCache& cache = GetProfileInfoCache();
|
| +
|
| if (profile_dir.BaseName().MaybeAsASCII() ==
|
| local_state->GetString(prefs::kProfileLastUsed)) {
|
| // Update the last used profile pref before closing browser windows. This
|
| // way the correct last used profile is set for any notification observers.
|
| - std::string last_non_managed_profile;
|
| + base::FilePath last_non_managed_profile_path;
|
| for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
|
| base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
|
| - if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i)) {
|
| - last_non_managed_profile = cur_path.BaseName().MaybeAsASCII();
|
| + // Make sure that this profile is not pending deletion.
|
| + if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) &&
|
| + !IsProfileMarkedForDeletion(cur_path)) {
|
| + last_non_managed_profile_path = cur_path;
|
| break;
|
| }
|
| }
|
| +
|
| // If we're deleting the last (non-managed) profile, then create a new
|
| // profile in its place.
|
| + const std::string last_non_managed_profile =
|
| + last_non_managed_profile_path.BaseName().MaybeAsASCII();
|
| if (last_non_managed_profile.empty()) {
|
| base::FilePath new_path = GenerateNextProfileDirectoryPath();
|
| // Make sure the last used profile path is pointing at it. This way the
|
| @@ -1071,13 +1080,62 @@ void ProfileManager::ScheduleProfileForDeletion(
|
| string16(),
|
| false);
|
| } else {
|
| + // On the Mac, the browser process is not killed when all browser windows
|
| + // are closed, so just in case we are deleting the active profile, and no
|
| + // other profile has been loaded, we must pre-load a next one.
|
| +#if defined(OS_MACOSX)
|
| + CreateProfileAsync(last_non_managed_profile_path,
|
| + base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
|
| + base::Unretained(this),
|
| + profile_dir,
|
| + last_non_managed_profile_path,
|
| + callback),
|
| + string16(),
|
| + string16(),
|
| + false);
|
| + return;
|
| +#else
|
| + // For OS_MACOSX the pref is updated in the callback to make sure that
|
| + // it isn't used before the profile is actually loaded.
|
| local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile);
|
| +#endif
|
| }
|
| }
|
| + FinishDeletingProfile(profile_dir);
|
| +}
|
|
|
| +void ProfileManager::OnNewActiveProfileLoaded(
|
| + const base::FilePath& profile_to_delete_path,
|
| + const base::FilePath& last_non_managed_profile_path,
|
| + const CreateCallback& original_callback,
|
| + Profile* loaded_profile,
|
| + Profile::CreateStatus status) {
|
| + DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
|
| + status != Profile::CREATE_STATUS_REMOTE_FAIL);
|
| +
|
| + // Only run the code if the profile initialization has finished completely.
|
| + if (status == Profile::CREATE_STATUS_INITIALIZED) {
|
| + if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) {
|
| + // If the profile we tried to load as the next active profile has been
|
| + // deleted, then retry deleting this profile to redo the logic to load
|
| + // the next available profile.
|
| + ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
|
| + } else {
|
| + // Update the local state as promised in the ScheduleProfileForDeletion.
|
| + g_browser_process->local_state()->SetString(
|
| + prefs::kProfileLastUsed,
|
| + last_non_managed_profile_path.BaseName().MaybeAsASCII());
|
| + FinishDeletingProfile(profile_to_delete_path);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) {
|
| + ProfileInfoCache& cache = GetProfileInfoCache();
|
| // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
|
| // start deleting the profile instance we need to close background apps too.
|
| Profile* profile = GetProfileByPath(profile_dir);
|
| +
|
| if (profile) {
|
| BrowserList::CloseAllBrowsersWithProfile(profile);
|
|
|
|
|