| 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 | 156 |
| 157 // Count number of extensions in this profile, if we know. | 157 // Count number of extensions in this profile, if we know. |
| 158 if (extension_count != -1) | 158 if (extension_count != -1) |
| 159 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", extension_count); | 159 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", extension_count); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { | 162 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { |
| 163 ProfilesToDelete().push_back(path); | 163 ProfilesToDelete().push_back(path); |
| 164 } | 164 } |
| 165 | 165 |
| 166 // Called upon completion of profile creation. This function takes care of | |
| 167 // launching a new browser window and signing the user in to their Google | |
| 168 // account. | |
| 169 void OnOpenWindowForNewProfile( | |
| 170 chrome::HostDesktopType desktop_type, | |
| 171 const ProfileManager::CreateCallback& callback, | |
| 172 Profile* profile, | |
| 173 Profile::CreateStatus status) { | |
| 174 // Invoke the callback before we open a window for this new profile, so the | |
| 175 // callback has a chance to update the profile state first (to do things like | |
| 176 // sign in the profile). | |
| 177 if (!callback.is_null()) | |
| 178 callback.Run(profile, status); | |
| 179 | |
| 180 if (status == Profile::CREATE_STATUS_INITIALIZED) { | |
| 181 | |
| 182 ProfileManager::FindOrCreateNewWindowForProfile( | |
| 183 profile, | |
| 184 chrome::startup::IS_PROCESS_STARTUP, | |
| 185 chrome::startup::IS_FIRST_RUN, | |
| 186 desktop_type, | |
| 187 false); | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 #if defined(OS_CHROMEOS) | 166 #if defined(OS_CHROMEOS) |
| 192 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status, | 167 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status, |
| 193 bool is_mounted) { | 168 bool is_mounted) { |
| 194 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { | 169 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { |
| 195 LOG(ERROR) << "IsMounted call failed."; | 170 LOG(ERROR) << "IsMounted call failed."; |
| 196 return; | 171 return; |
| 197 } | 172 } |
| 198 if (!is_mounted) | 173 if (!is_mounted) |
| 199 LOG(ERROR) << "Cryptohome is not mounted."; | 174 LOG(ERROR) << "Cryptohome is not mounted."; |
| 200 } | 175 } |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 const base::FilePath& profile_path, | 460 const base::FilePath& profile_path, |
| 486 const CreateCallback& callback, | 461 const CreateCallback& callback, |
| 487 const string16& name, | 462 const string16& name, |
| 488 const string16& icon_url, | 463 const string16& icon_url, |
| 489 bool is_managed) { | 464 bool is_managed) { |
| 490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 491 | 466 |
| 492 // Make sure that this profile is not pending deletion. | 467 // Make sure that this profile is not pending deletion. |
| 493 if (std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), | 468 if (std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), |
| 494 profile_path) != ProfilesToDelete().end()) { | 469 profile_path) != ProfilesToDelete().end()) { |
| 495 callback.Run(NULL, Profile::CREATE_STATUS_FAIL); | 470 if (!callback.is_null()) |
| 471 callback.Run(NULL, Profile::CREATE_STATUS_FAIL); |
| 496 return; | 472 return; |
| 497 } | 473 } |
| 498 | 474 |
| 475 // Create the profile if needed and collect its ProfileInfo. |
| 499 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); | 476 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); |
| 477 ProfileInfo* info = NULL; |
| 478 |
| 500 if (iter != profiles_info_.end()) { | 479 if (iter != profiles_info_.end()) { |
| 501 ProfileInfo* info = iter->second.get(); | 480 info = iter->second.get(); |
| 502 if (info->created) { | |
| 503 // Profile has already been created. Run callback immediately. | |
| 504 callback.Run(info->profile.get(), Profile::CREATE_STATUS_INITIALIZED); | |
| 505 } else { | |
| 506 // Profile is being created. Add callback to list. | |
| 507 info->callbacks.push_back(callback); | |
| 508 } | |
| 509 } else { | 481 } else { |
| 510 // Initiate asynchronous creation process. | 482 // Initiate asynchronous creation process. |
| 511 ProfileInfo* info = | 483 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); |
| 512 RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); | |
| 513 ProfileInfoCache& cache = GetProfileInfoCache(); | 484 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 514 // Get the icon index from the user's icon url | 485 // Get the icon index from the user's icon url |
| 515 size_t icon_index; | 486 size_t icon_index; |
| 516 std::string icon_url_std = UTF16ToASCII(icon_url); | 487 std::string icon_url_std = UTF16ToASCII(icon_url); |
| 517 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) { | 488 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) { |
| 518 // add profile to cache with user selected name and avatar | 489 // add profile to cache with user selected name and avatar |
| 519 cache.AddProfileToCache(profile_path, name, string16(), icon_index, | 490 cache.AddProfileToCache(profile_path, name, string16(), icon_index, |
| 520 is_managed); | 491 is_managed); |
| 521 } | 492 } |
| 522 info->callbacks.push_back(callback); | |
| 523 | 493 |
| 524 if (is_managed) { | 494 if (is_managed) { |
| 525 content::RecordAction( | 495 content::RecordAction( |
| 526 UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); | 496 UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); |
| 527 } | 497 } |
| 528 } | 498 } |
| 499 |
| 500 // Call or enqueue the callback. |
| 501 if (!callback.is_null()) { |
| 502 if (iter != profiles_info_.end() && info->created) { |
| 503 // Profile has already been created. Run callback immediately. |
| 504 callback.Run(info->profile.get(), Profile::CREATE_STATUS_INITIALIZED); |
| 505 } else { |
| 506 // Profile is either already in the process of being created, or new. |
| 507 // Add callback to the list. |
| 508 info->callbacks.push_back(callback); |
| 509 } |
| 510 } |
| 529 } | 511 } |
| 530 | 512 |
| 531 // static | 513 // static |
| 532 void ProfileManager::CreateDefaultProfileAsync(const CreateCallback& callback) { | 514 void ProfileManager::CreateDefaultProfileAsync(const CreateCallback& callback) { |
| 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 534 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 516 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 535 | 517 |
| 536 base::FilePath default_profile_dir = profile_manager->user_data_dir_; | 518 base::FilePath default_profile_dir = profile_manager->user_data_dir_; |
| 537 // TODO(mirandac): current directory will not always be default in the future | 519 // TODO(mirandac): current directory will not always be default in the future |
| 538 default_profile_dir = default_profile_dir.Append( | 520 default_profile_dir = default_profile_dir.Append( |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 base::FilePath new_path = user_data_dir_; | 868 base::FilePath new_path = user_data_dir_; |
| 887 #if defined(OS_WIN) | 869 #if defined(OS_WIN) |
| 888 new_path = new_path.Append(ASCIIToUTF16(profile_name)); | 870 new_path = new_path.Append(ASCIIToUTF16(profile_name)); |
| 889 #else | 871 #else |
| 890 new_path = new_path.Append(profile_name); | 872 new_path = new_path.Append(profile_name); |
| 891 #endif | 873 #endif |
| 892 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); | 874 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); |
| 893 return new_path; | 875 return new_path; |
| 894 } | 876 } |
| 895 | 877 |
| 896 // TODO(robertshield): ProfileManager should not be opening windows and should | |
| 897 // not have to care about HostDesktopType. See http://crbug.com/153864 | |
| 898 // static | 878 // static |
| 899 void ProfileManager::CreateMultiProfileAsync( | 879 void ProfileManager::CreateMultiProfileAsync( |
| 900 const string16& name, | 880 const string16& name, |
| 901 const string16& icon_url, | 881 const string16& icon_url, |
| 902 const CreateCallback& callback, | 882 const CreateCallback& callback, |
| 903 chrome::HostDesktopType desktop_type, | |
| 904 bool is_managed) { | 883 bool is_managed) { |
| 905 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 884 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 906 | 885 |
| 907 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 886 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 908 | 887 |
| 909 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | 888 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
| 910 | 889 |
| 911 profile_manager->CreateProfileAsync(new_path, | 890 profile_manager->CreateProfileAsync(new_path, |
| 912 base::Bind(&OnOpenWindowForNewProfile, | 891 callback, |
| 913 desktop_type, | |
| 914 callback), | |
| 915 name, | 892 name, |
| 916 icon_url, | 893 icon_url, |
| 917 is_managed); | 894 is_managed); |
| 918 } | 895 } |
| 919 | 896 |
| 920 // static | 897 // static |
| 921 void ProfileManager::RegisterPrefs(PrefRegistrySimple* registry) { | 898 void ProfileManager::RegisterPrefs(PrefRegistrySimple* registry) { |
| 922 registry->RegisterStringPref(prefs::kProfileLastUsed, std::string()); | 899 registry->RegisterStringPref(prefs::kProfileLastUsed, std::string()); |
| 923 registry->RegisterIntegerPref(prefs::kProfilesNumCreated, 1); | 900 registry->RegisterIntegerPref(prefs::kProfilesNumCreated, 1); |
| 924 registry->RegisterListPref(prefs::kProfilesLastActive); | 901 registry->RegisterListPref(prefs::kProfilesLastActive); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 1001 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 1025 if (!logged_in_ && | 1002 if (!logged_in_ && |
| 1026 (!command_line.HasSwitch(switches::kTestType) || | 1003 (!command_line.HasSwitch(switches::kTestType) || |
| 1027 command_line.HasSwitch(chromeos::switches::kLoginProfile))) { | 1004 command_line.HasSwitch(chromeos::switches::kLoginProfile))) { |
| 1028 go_off_the_record = true; | 1005 go_off_the_record = true; |
| 1029 } | 1006 } |
| 1030 #endif | 1007 #endif |
| 1031 return go_off_the_record; | 1008 return go_off_the_record; |
| 1032 } | 1009 } |
| 1033 | 1010 |
| 1034 // TODO(robertshield): ProfileManager should not be opening windows and should | |
| 1035 // not have to care about HostDesktopType. See http://crbug.com/153864 | |
| 1036 void ProfileManager::ScheduleProfileForDeletion( | 1011 void ProfileManager::ScheduleProfileForDeletion( |
| 1037 const base::FilePath& profile_dir, | 1012 const base::FilePath& profile_dir, |
| 1038 chrome::HostDesktopType desktop_type) { | 1013 const CreateCallback& callback) { |
| 1039 DCHECK(IsMultipleProfilesEnabled()); | 1014 DCHECK(IsMultipleProfilesEnabled()); |
| 1040 | 1015 |
| 1041 PrefService* local_state = g_browser_process->local_state(); | 1016 PrefService* local_state = g_browser_process->local_state(); |
| 1042 ProfileInfoCache& cache = GetProfileInfoCache(); | 1017 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 1043 if (profile_dir.BaseName().MaybeAsASCII() == | 1018 if (profile_dir.BaseName().MaybeAsASCII() == |
| 1044 local_state->GetString(prefs::kProfileLastUsed)) { | 1019 local_state->GetString(prefs::kProfileLastUsed)) { |
| 1045 // Update the last used profile pref before closing browser windows. This | 1020 // Update the last used profile pref before closing browser windows. This |
| 1046 // way the correct last used profile is set for any notification observers. | 1021 // way the correct last used profile is set for any notification observers. |
| 1047 std::string last_non_managed_profile; | 1022 std::string last_non_managed_profile; |
| 1048 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 1023 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
| 1049 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); | 1024 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); |
| 1050 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i)) { | 1025 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i)) { |
| 1051 last_non_managed_profile = cur_path.BaseName().MaybeAsASCII(); | 1026 last_non_managed_profile = cur_path.BaseName().MaybeAsASCII(); |
| 1052 break; | 1027 break; |
| 1053 } | 1028 } |
| 1054 } | 1029 } |
| 1055 // If we're deleting the last (non-managed) profile, then create a new | 1030 // If we're deleting the last (non-managed) profile, then create a new |
| 1056 // profile in its place. | 1031 // profile in its place. |
| 1057 if (last_non_managed_profile.empty()) { | 1032 if (last_non_managed_profile.empty()) { |
| 1058 base::FilePath new_path = GenerateNextProfileDirectoryPath(); | 1033 base::FilePath new_path = GenerateNextProfileDirectoryPath(); |
| 1059 // Make sure the last used profile path is pointing at it. This way the | 1034 // Make sure the last used profile path is pointing at it. This way the |
| 1060 // correct last used profile is set for any notification observers. | 1035 // correct last used profile is set for any notification observers. |
| 1061 local_state->SetString(prefs::kProfileLastUsed, | 1036 local_state->SetString(prefs::kProfileLastUsed, |
| 1062 new_path.BaseName().MaybeAsASCII()); | 1037 new_path.BaseName().MaybeAsASCII()); |
| 1063 // TODO(robertshield): This desktop type needs to come from the invoker, | |
| 1064 // currently that involves plumbing this through web UI. | |
| 1065 chrome::HostDesktopType desktop_type = chrome::HOST_DESKTOP_TYPE_NATIVE; | |
| 1066 CreateProfileAsync(new_path, | 1038 CreateProfileAsync(new_path, |
| 1067 base::Bind(&OnOpenWindowForNewProfile, | 1039 callback, |
| 1068 desktop_type, | |
| 1069 CreateCallback()), | |
| 1070 string16(), | 1040 string16(), |
| 1071 string16(), | 1041 string16(), |
| 1072 false); | 1042 false); |
| 1073 } else { | 1043 } else { |
| 1074 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); | 1044 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); |
| 1075 } | 1045 } |
| 1076 } | 1046 } |
| 1077 | 1047 |
| 1078 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we | 1048 // 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. | 1049 // start deleting the profile instance we need to close background apps too. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 ProfileManager::ProfileInfo::ProfileInfo( | 1125 ProfileManager::ProfileInfo::ProfileInfo( |
| 1156 Profile* profile, | 1126 Profile* profile, |
| 1157 bool created) | 1127 bool created) |
| 1158 : profile(profile), | 1128 : profile(profile), |
| 1159 created(created) { | 1129 created(created) { |
| 1160 } | 1130 } |
| 1161 | 1131 |
| 1162 ProfileManager::ProfileInfo::~ProfileInfo() { | 1132 ProfileManager::ProfileInfo::~ProfileInfo() { |
| 1163 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); | 1133 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); |
| 1164 } | 1134 } |
| OLD | NEW |