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 |