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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/profiles/profile_manager.h" 6 7 #include <set> 8 9 #include "base/bind.h" 10 #include "base/command_line.h" 11 #include "base/debug/trace_event.h" 12 #include "base/deferred_sequenced_task_runner.h" 13 #include "base/file_util.h" 14 #include "base/files/file_enumerator.h" 15 #include "base/files/file_path.h" 16 #include "base/metrics/histogram.h" 17 #include "base/prefs/pref_service.h" 18 #include "base/prefs/scoped_user_pref_update.h" 19 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_util.h" 21 #include "base/strings/utf_string_conversions.h" 22 #include "chrome/browser/bookmarks/bookmark_model.h" 23 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 24 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/chrome_notification_types.h" 26 #include "chrome/browser/content_settings/host_content_settings_map.h" 27 #include "chrome/browser/prefs/incognito_mode_prefs.h" 28 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h" 29 #include "chrome/browser/profiles/profile_destroyer.h" 30 #include "chrome/browser/profiles/profile_info_cache.h" 31 #include "chrome/browser/profiles/profile_metrics.h" 32 #include "chrome/browser/profiles/profiles_state.h" 33 #include "chrome/browser/profiles/startup_task_runner_service.h" 34 #include "chrome/browser/profiles/startup_task_runner_service_factory.h" 35 #include "chrome/browser/signin/account_reconcilor_factory.h" 36 #include "chrome/browser/sync/profile_sync_service.h" 37 #include "chrome/browser/sync/profile_sync_service_factory.h" 38 #include "chrome/browser/ui/browser.h" 39 #include "chrome/browser/ui/browser_iterator.h" 40 #include "chrome/browser/ui/sync/sync_promo_ui.h" 41 #include "chrome/common/chrome_constants.h" 42 #include "chrome/common/chrome_paths_internal.h" 43 #include "chrome/common/chrome_switches.h" 44 #include "chrome/common/logging_chrome.h" 45 #include "chrome/common/pref_names.h" 46 #include "chrome/common/url_constants.h" 47 #include "content/public/browser/browser_thread.h" 48 #include "content/public/browser/notification_service.h" 49 #include "content/public/browser/user_metrics.h" 50 #include "grit/generated_resources.h" 51 #include "net/http/http_transaction_factory.h" 52 #include "net/url_request/url_request_context.h" 53 #include "net/url_request/url_request_context_getter.h" 54 #include "net/url_request/url_request_job.h" 55 #include "ui/base/l10n/l10n_util.h" 56 57 #if defined(ENABLE_MANAGED_USERS) 58 #include "chrome/browser/managed_mode/managed_user_service.h" 59 #include "chrome/browser/managed_mode/managed_user_service_factory.h" 60 #endif 61 62 #if !defined(OS_IOS) 63 #include "chrome/browser/extensions/extension_service.h" 64 #include "chrome/browser/extensions/extension_system.h" 65 #include "chrome/browser/sessions/session_service_factory.h" 66 #include "chrome/browser/ui/browser_list.h" 67 #endif // !defined (OS_IOS) 68 69 #if defined(OS_WIN) 70 #include "base/win/metro.h" 71 #include "chrome/installer/util/browser_distribution.h" 72 #endif 73 74 #if defined(OS_CHROMEOS) 75 #include "chrome/browser/browser_process_platform_part_chromeos.h" 76 #include "chrome/browser/chromeos/login/user.h" 77 #include "chrome/browser/chromeos/login/user_manager.h" 78 #include "chrome/browser/chromeos/profiles/profile_helper.h" 79 #include "chromeos/chromeos_switches.h" 80 #include "chromeos/dbus/cryptohome_client.h" 81 #include "chromeos/dbus/dbus_thread_manager.h" 82 #endif 83 84 using content::BrowserThread; 85 using content::UserMetricsAction; 86 87 namespace { 88 89 // Profiles that should be deleted on shutdown. 90 std::vector<base::FilePath>& ProfilesToDelete() { 91 CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ()); 92 return profiles_to_delete; 93 } 94 95 int64 ComputeFilesSize(const base::FilePath& directory, 96 const base::FilePath::StringType& pattern) { 97 int64 running_size = 0; 98 base::FileEnumerator iter(directory, false, base::FileEnumerator::FILES, 99 pattern); 100 while (!iter.Next().empty()) 101 running_size += iter.GetInfo().GetSize(); 102 return running_size; 103 } 104 105 // Simple task to log the size of the current profile. 106 void ProfileSizeTask(const base::FilePath& path, int extension_count) { 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 108 const int64 kBytesInOneMB = 1024 * 1024; 109 110 int64 size = ComputeFilesSize(path, FILE_PATH_LITERAL("*")); 111 int size_MB = static_cast<int>(size / kBytesInOneMB); 112 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB); 113 114 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History")); 115 size_MB = static_cast<int>(size / kBytesInOneMB); 116 UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB); 117 118 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History*")); 119 size_MB = static_cast<int>(size / kBytesInOneMB); 120 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB); 121 122 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Cookies")); 123 size_MB = static_cast<int>(size / kBytesInOneMB); 124 UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB); 125 126 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Bookmarks")); 127 size_MB = static_cast<int>(size / kBytesInOneMB); 128 UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB); 129 130 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Favicons")); 131 size_MB = static_cast<int>(size / kBytesInOneMB); 132 UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB); 133 134 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Top Sites")); 135 size_MB = static_cast<int>(size / kBytesInOneMB); 136 UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB); 137 138 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Visited Links")); 139 size_MB = static_cast<int>(size / kBytesInOneMB); 140 UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB); 141 142 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Web Data")); 143 size_MB = static_cast<int>(size / kBytesInOneMB); 144 UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB); 145 146 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Extension*")); 147 size_MB = static_cast<int>(size / kBytesInOneMB); 148 UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB); 149 150 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Policy")); 151 size_MB = static_cast<int>(size / kBytesInOneMB); 152 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB); 153 154 // Count number of extensions in this profile, if we know. 155 if (extension_count != -1) 156 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", extension_count); 157 } 158 159 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { 160 ProfilesToDelete().push_back(path); 161 } 162 163 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) { 164 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(), 165 profile_path) != ProfilesToDelete().end(); 166 } 167 168 // Physically remove deleted profile directories from disk. 169 void NukeProfileFromDisk(const base::FilePath& profile_path) { 170 // Delete both the profile directory and its corresponding cache. 171 base::FilePath cache_path; 172 chrome::GetUserCacheDirectory(profile_path, &cache_path); 173 base::DeleteFile(profile_path, true); 174 base::DeleteFile(cache_path, true); 175 } 176 177 #if defined(OS_CHROMEOS) 178 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status, 179 bool is_mounted) { 180 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { 181 LOG(ERROR) << "IsMounted call failed."; 182 return; 183 } 184 if (!is_mounted) 185 LOG(ERROR) << "Cryptohome is not mounted."; 186 } 187 188 #endif 189 190 } // namespace 191 192 #if defined(ENABLE_SESSION_SERVICE) 193 // static 194 void ProfileManager::ShutdownSessionServices() { 195 ProfileManager* pm = g_browser_process->profile_manager(); 196 if (!pm) // Is NULL when running unit tests. 197 return; 198 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); 199 for (size_t i = 0; i < profiles.size(); ++i) 200 SessionServiceFactory::ShutdownForProfile(profiles[i]); 201 } 202 #endif 203 204 // static 205 void ProfileManager::NukeDeletedProfilesFromDisk() { 206 for (std::vector<base::FilePath>::iterator it = 207 ProfilesToDelete().begin(); 208 it != ProfilesToDelete().end(); 209 ++it) { 210 NukeProfileFromDisk(*it); 211 } 212 ProfilesToDelete().clear(); 213 } 214 215 namespace { 216 217 bool s_allow_get_default_profile = false; 218 219 } // namespace 220 221 // static 222 void ProfileManager::AllowGetDefaultProfile() { 223 s_allow_get_default_profile = true; 224 } 225 226 // static 227 bool ProfileManager::IsGetDefaultProfileAllowed() { 228 return s_allow_get_default_profile; 229 } 230 231 // static 232 // TODO(skuhne): Remove this method once all clients are migrated. 233 Profile* ProfileManager::GetDefaultProfile() { 234 CHECK(s_allow_get_default_profile) 235 << "GetDefaultProfile() called before allowed."; 236 ProfileManager* profile_manager = g_browser_process->profile_manager(); 237 return profile_manager->GetDefaultProfile(profile_manager->user_data_dir_); 238 } 239 240 // static 241 // TODO(skuhne): Remove this method once all clients are migrated. 242 Profile* ProfileManager::GetDefaultProfileOrOffTheRecord() { 243 return GetDefaultProfile(); 244 } 245 246 // static 247 Profile* ProfileManager::GetLastUsedProfile() { 248 ProfileManager* profile_manager = g_browser_process->profile_manager(); 249 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_); 250 } 251 252 // static 253 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() { 254 Profile* profile = GetLastUsedProfile(); 255 if (IncognitoModePrefs::GetAvailability(profile->GetPrefs()) == 256 IncognitoModePrefs::FORCED) { 257 return profile->GetOffTheRecordProfile(); 258 } 259 return profile; 260 } 261 262 // static 263 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() { 264 ProfileManager* profile_manager = g_browser_process->profile_manager(); 265 return profile_manager->GetLastOpenedProfiles( 266 profile_manager->user_data_dir_); 267 } 268 269 ProfileManager::ProfileManager(const base::FilePath& user_data_dir) 270 : user_data_dir_(user_data_dir), 271 logged_in_(false), 272 273 #if !defined(OS_ANDROID) && !defined(OS_IOS) 274 browser_list_observer_(this), 275 #endif 276 closing_all_browsers_(false) { 277 #if defined(OS_CHROMEOS) 278 registrar_.Add( 279 this, 280 chrome::NOTIFICATION_LOGIN_USER_CHANGED, 281 content::NotificationService::AllSources()); 282 #endif 283 registrar_.Add( 284 this, 285 chrome::NOTIFICATION_BROWSER_OPENED, 286 content::NotificationService::AllSources()); 287 registrar_.Add( 288 this, 289 chrome::NOTIFICATION_BROWSER_CLOSED, 290 content::NotificationService::AllSources()); 291 registrar_.Add( 292 this, 293 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, 294 content::NotificationService::AllSources()); 295 registrar_.Add( 296 this, 297 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 298 content::NotificationService::AllSources()); 299 registrar_.Add( 300 this, 301 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, 302 content::NotificationService::AllSources()); 303 304 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty()) 305 profile_shortcut_manager_.reset(ProfileShortcutManager::Create( 306 this)); 307 } 308 309 ProfileManager::~ProfileManager() { 310 } 311 312 base::FilePath ProfileManager::GetInitialProfileDir() { 313 base::FilePath relative_profile_dir; 314 #if defined(OS_CHROMEOS) 315 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 316 if (logged_in_) { 317 base::FilePath profile_dir; 318 // If the user has logged in, pick up the new profile. 319 if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) { 320 // TODO(nkostylev): Remove this code completely once we eliminate 321 // legacy --login-profile=user switch and enable multi-profiles on CrOS 322 // by default. http://crbug.com/294628 323 profile_dir = chromeos::ProfileHelper:: 324 GetProfileDirByLegacyLoginProfileSwitch(); 325 } else if (!command_line.HasSwitch(switches::kMultiProfiles)) { 326 // We should never be logged in with no profile dir unless 327 // multi-profiles are enabled. 328 // In that case profile dir will be defined by user_id hash. 329 NOTREACHED(); 330 return base::FilePath(""); 331 } 332 // In case of multi-profiles ignore --login-profile switch. 333 // TODO(nkostylev): Some cases like Guest mode will have empty username_hash 334 // so default kLoginProfile dir will be used. 335 std::string user_id_hash = g_browser_process->platform_part()-> 336 profile_helper()->active_user_id_hash(); 337 if (command_line.HasSwitch(switches::kMultiProfiles) && 338 !user_id_hash.empty()) { 339 profile_dir = g_browser_process->platform_part()-> 340 profile_helper()->GetActiveUserProfileDir(); 341 } 342 relative_profile_dir = relative_profile_dir.Append(profile_dir); 343 return relative_profile_dir; 344 } 345 #endif 346 // TODO(mirandac): should not automatically be default profile. 347 relative_profile_dir = 348 relative_profile_dir.AppendASCII(chrome::kInitialProfile); 349 return relative_profile_dir; 350 } 351 352 Profile* ProfileManager::GetLastUsedProfile( 353 const base::FilePath& user_data_dir) { 354 #if defined(OS_CHROMEOS) 355 // Use default login profile if user has not logged in yet. 356 if (!logged_in_) { 357 return GetDefaultProfile(user_data_dir); 358 } else { 359 // CrOS multi-profiles implementation is different so GetLastUsedProfile 360 // has custom implementation too. 361 base::FilePath profile_dir; 362 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 363 if (command_line.HasSwitch(switches::kMultiProfiles)) { 364 // In case of multi-profiles we ignore "last used profile" preference 365 // since it may refer to profile that has been in use in previous session. 366 // That profile dir may not be mounted in this session so instead return 367 // active profile from current session. 368 profile_dir = g_browser_process->platform_part()-> 369 profile_helper()->GetActiveUserProfileDir(); 370 } else { 371 // For legacy (not multi-profiles) implementation always default to 372 // --login-profile value. 373 profile_dir = 374 chromeos::ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch(); 375 } 376 377 base::FilePath profile_path(user_data_dir); 378 Profile* profile = GetProfile(profile_path.Append(profile_dir)); 379 return (profile && profile->IsGuestSession()) ? 380 profile->GetOffTheRecordProfile() : profile; 381 } 382 #endif 383 384 return GetProfile(GetLastUsedProfileDir(user_data_dir)); 385 } 386 387 base::FilePath ProfileManager::GetLastUsedProfileDir( 388 const base::FilePath& user_data_dir) { 389 base::FilePath last_used_profile_dir(user_data_dir); 390 PrefService* local_state = g_browser_process->local_state(); 391 DCHECK(local_state); 392 393 if (local_state->HasPrefPath(prefs::kProfileLastUsed)) { 394 return last_used_profile_dir.AppendASCII( 395 local_state->GetString(prefs::kProfileLastUsed)); 396 } 397 398 return last_used_profile_dir.AppendASCII(chrome::kInitialProfile); 399 } 400 401 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles( 402 const base::FilePath& user_data_dir) { 403 PrefService* local_state = g_browser_process->local_state(); 404 DCHECK(local_state); 405 406 std::vector<Profile*> to_return; 407 if (local_state->HasPrefPath(prefs::kProfilesLastActive) && 408 local_state->GetList(prefs::kProfilesLastActive)) { 409 // Make a copy because the list might change in the calls to GetProfile. 410 scoped_ptr<base::ListValue> profile_list( 411 local_state->GetList(prefs::kProfilesLastActive)->DeepCopy()); 412 base::ListValue::const_iterator it; 413 std::string profile; 414 for (it = profile_list->begin(); it != profile_list->end(); ++it) { 415 if (!(*it)->GetAsString(&profile) || profile.empty()) { 416 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive; 417 continue; 418 } 419 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile))); 420 } 421 } 422 return to_return; 423 } 424 425 Profile* ProfileManager::GetPrimaryUserProfile() { 426 #if defined(OS_CHROMEOS) 427 // TODO(skuhne): Remove once GetDefaultProfile is removed. 428 CHECK(s_allow_get_default_profile) 429 << "GetPrimaryUserProfile() called before allowed."; 430 ProfileManager* profile_manager = g_browser_process->profile_manager(); 431 if (!profile_manager->IsLoggedIn() || !chromeos::UserManager::IsInitialized()) 432 return GetDefaultProfile(); 433 chromeos::UserManager* manager = chromeos::UserManager::Get(); 434 // Note: The user manager will take care of guest profiles. 435 return manager->GetProfileByUser(manager->GetPrimaryUser()); 436 #else 437 return GetDefaultProfile(); 438 #endif 439 } 440 441 Profile* ProfileManager::GetActiveUserProfile() { 442 #if defined(OS_CHROMEOS) 443 // TODO(skuhne): Remove once GetDefaultProfile is removed. 444 CHECK(s_allow_get_default_profile) 445 << "GetActiveUserProfile() called before allowed."; 446 ProfileManager* profile_manager = g_browser_process->profile_manager(); 447 if (!profile_manager->IsLoggedIn() || !chromeos::UserManager::IsInitialized()) 448 return GetDefaultProfile(); 449 chromeos::UserManager* manager = chromeos::UserManager::Get(); 450 // Note: The user manager will take care of guest profiles. 451 return manager->GetProfileByUser(manager->GetActiveUser()); 452 #else 453 return GetDefaultProfile(); 454 #endif 455 } 456 457 // TODO(skuhne): Remove this method once all clients are migrated. 458 Profile* ProfileManager::GetPrimaryUserProfileOrOffTheRecord() { 459 return GetPrimaryUserProfile(); 460 } 461 462 // TODO(skuhne): Remove this method once all clients are migrated. 463 Profile* ProfileManager::GetActiveUserProfileOrOffTheRecord() { 464 return GetActiveUserProfile(); 465 } 466 467 Profile* ProfileManager::GetDefaultProfile( 468 const base::FilePath& user_data_dir) { 469 #if defined(OS_CHROMEOS) 470 base::FilePath default_profile_dir(user_data_dir); 471 if (logged_in_) { 472 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); 473 } else { 474 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); 475 } 476 #else 477 base::FilePath default_profile_dir(user_data_dir); 478 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); 479 #endif 480 #if defined(OS_CHROMEOS) 481 if (!logged_in_) { 482 Profile* profile = GetProfile(default_profile_dir); 483 // For cros, return the OTR profile so we never accidentally keep 484 // user data in an unencrypted profile. But doing this makes 485 // many of the browser and ui tests fail. We do return the OTR profile 486 // if the login-profile switch is passed so that we can test this. 487 if (ShouldGoOffTheRecord(profile)) 488 return profile->GetOffTheRecordProfile(); 489 DCHECK(!chromeos::UserManager::Get()->IsLoggedInAsGuest()); 490 return profile; 491 } 492 493 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir); 494 // Fallback to default off-the-record profile, if user profile has not fully 495 // loaded yet. 496 if (profile_info && !profile_info->created) 497 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); 498 499 Profile* profile = GetProfile(default_profile_dir); 500 // Some unit tests didn't initialize the UserManager. 501 if (chromeos::UserManager::IsInitialized() && 502 chromeos::UserManager::Get()->IsLoggedInAsGuest()) 503 return profile->GetOffTheRecordProfile(); 504 return profile; 505 #else 506 return GetProfile(default_profile_dir); 507 #endif 508 } 509 510 bool ProfileManager::IsValidProfile(Profile* profile) { 511 for (ProfilesInfoMap::iterator iter = profiles_info_.begin(); 512 iter != profiles_info_.end(); ++iter) { 513 if (iter->second->created) { 514 Profile* candidate = iter->second->profile.get(); 515 if (candidate == profile || 516 (candidate->HasOffTheRecordProfile() && 517 candidate->GetOffTheRecordProfile() == profile)) { 518 return true; 519 } 520 } 521 } 522 return false; 523 } 524 525 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const { 526 std::vector<Profile*> profiles; 527 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin(); 528 iter != profiles_info_.end(); ++iter) { 529 if (iter->second->created) 530 profiles.push_back(iter->second->profile.get()); 531 } 532 return profiles; 533 } 534 535 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) { 536 TRACE_EVENT0("browser", "ProfileManager::GetProfile") 537 // If the profile is already loaded (e.g., chrome.exe launched twice), just 538 // return it. 539 Profile* profile = GetProfileByPath(profile_dir); 540 if (NULL != profile) 541 return profile; 542 543 profile = CreateProfileHelper(profile_dir); 544 DCHECK(profile); 545 if (profile) { 546 bool result = AddProfile(profile); 547 DCHECK(result); 548 } 549 return profile; 550 } 551 552 void ProfileManager::CreateProfileAsync( 553 const base::FilePath& profile_path, 554 const CreateCallback& callback, 555 const base::string16& name, 556 const base::string16& icon_url, 557 const std::string& managed_user_id) { 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 559 560 // Make sure that this profile is not pending deletion. 561 if (IsProfileMarkedForDeletion(profile_path)) { 562 if (!callback.is_null()) 563 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); 564 return; 565 } 566 567 // Create the profile if needed and collect its ProfileInfo. 568 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); 569 ProfileInfo* info = NULL; 570 571 if (iter != profiles_info_.end()) { 572 info = iter->second.get(); 573 } else { 574 // Initiate asynchronous creation process. 575 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); 576 ProfileInfoCache& cache = GetProfileInfoCache(); 577 // Get the icon index from the user's icon url 578 size_t icon_index; 579 std::string icon_url_std = UTF16ToASCII(icon_url); 580 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) { 581 // add profile to cache with user selected name and avatar 582 cache.AddProfileToCache(profile_path, name, base::string16(), icon_index, 583 managed_user_id); 584 } 585 586 if (!managed_user_id.empty()) { 587 content::RecordAction( 588 UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); 589 } 590 591 ProfileMetrics::UpdateReportedProfilesStatistics(this); 592 } 593 594 // Call or enqueue the callback. 595 if (!callback.is_null()) { 596 if (iter != profiles_info_.end() && info->created) { 597 Profile* profile = info->profile.get(); 598 // If this was the guest profile, apply settings. 599 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) 600 SetGuestProfilePrefs(profile); 601 // Profile has already been created. Run callback immediately. 602 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED); 603 } else { 604 // Profile is either already in the process of being created, or new. 605 // Add callback to the list. 606 info->callbacks.push_back(callback); 607 } 608 } 609 } 610 611 bool ProfileManager::AddProfile(Profile* profile) { 612 DCHECK(profile); 613 614 // Make sure that we're not loading a profile with the same ID as a profile 615 // that's already loaded. 616 if (GetProfileByPath(profile->GetPath())) { 617 NOTREACHED() << "Attempted to add profile with the same path (" << 618 profile->GetPath().value() << 619 ") as an already-loaded profile."; 620 return false; 621 } 622 623 RegisterProfile(profile, true); 624 InitProfileUserPrefs(profile); 625 DoFinalInit(profile, ShouldGoOffTheRecord(profile)); 626 return true; 627 } 628 629 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile( 630 Profile* profile, 631 bool created) { 632 ProfileInfo* info = new ProfileInfo(profile, created); 633 profiles_info_.insert( 634 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info))); 635 return info; 636 } 637 638 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath( 639 const base::FilePath& path) const { 640 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path); 641 return (iter == profiles_info_.end()) ? NULL : iter->second.get(); 642 } 643 644 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { 645 ProfileInfo* profile_info = GetProfileInfoByPath(path); 646 return profile_info ? profile_info->profile.get() : NULL; 647 } 648 649 void ProfileManager::Observe( 650 int type, 651 const content::NotificationSource& source, 652 const content::NotificationDetails& details) { 653 #if defined(OS_CHROMEOS) 654 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { 655 logged_in_ = true; 656 657 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 658 if (!command_line.HasSwitch(switches::kTestType)) { 659 // If we don't have a mounted profile directory we're in trouble. 660 // TODO(davemoore) Once we have better api this check should ensure that 661 // our profile directory is the one that's mounted, and that it's mounted 662 // as the current user. 663 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted( 664 base::Bind(&CheckCryptohomeIsMounted)); 665 666 // Confirm that we hadn't loaded the new profile previously. 667 base::FilePath default_profile_dir = user_data_dir_.Append( 668 GetInitialProfileDir()); 669 CHECK(!GetProfileByPath(default_profile_dir)) 670 << "The default profile was loaded before we mounted the cryptohome."; 671 } 672 return; 673 } 674 #endif 675 bool save_active_profiles = false; 676 switch (type) { 677 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: { 678 // Ignore any browsers closing from now on. 679 closing_all_browsers_ = true; 680 save_active_profiles = true; 681 break; 682 } 683 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: { 684 // This will cancel the shutdown process, so the active profiles are 685 // tracked again. Also, as the active profiles may have changed (i.e. if 686 // some windows were closed) we save the current list of active profiles 687 // again. 688 closing_all_browsers_ = false; 689 save_active_profiles = true; 690 break; 691 } 692 case chrome::NOTIFICATION_BROWSER_OPENED: { 693 Browser* browser = content::Source<Browser>(source).ptr(); 694 DCHECK(browser); 695 Profile* profile = browser->profile(); 696 DCHECK(profile); 697 bool is_ephemeral = 698 profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles); 699 if (!profile->IsOffTheRecord() && !is_ephemeral && 700 ++browser_counts_[profile] == 1) { 701 active_profiles_.push_back(profile); 702 save_active_profiles = true; 703 } 704 // If browsers are opening, we can't be closing all the browsers. This 705 // can happen if the application was exited, but background mode or 706 // packaged apps prevented the process from shutting down, and then 707 // a new browser window was opened. 708 closing_all_browsers_ = false; 709 break; 710 } 711 case chrome::NOTIFICATION_BROWSER_CLOSED: { 712 Browser* browser = content::Source<Browser>(source).ptr(); 713 DCHECK(browser); 714 Profile* profile = browser->profile(); 715 DCHECK(profile); 716 if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) { 717 active_profiles_.erase(std::find(active_profiles_.begin(), 718 active_profiles_.end(), profile)); 719 save_active_profiles = !closing_all_browsers_; 720 } 721 break; 722 } 723 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: { 724 save_active_profiles = !closing_all_browsers_; 725 break; 726 } 727 default: { 728 NOTREACHED(); 729 break; 730 } 731 } 732 733 if (save_active_profiles) { 734 PrefService* local_state = g_browser_process->local_state(); 735 DCHECK(local_state); 736 ListPrefUpdate update(local_state, prefs::kProfilesLastActive); 737 ListValue* profile_list = update.Get(); 738 739 profile_list->Clear(); 740 741 // crbug.com/120112 -> several non-incognito profiles might have the same 742 // GetPath().BaseName(). In that case, we cannot restore both 743 // profiles. Include each base name only once in the last active profile 744 // list. 745 std::set<std::string> profile_paths; 746 std::vector<Profile*>::const_iterator it; 747 for (it = active_profiles_.begin(); it != active_profiles_.end(); ++it) { 748 std::string profile_path = (*it)->GetPath().BaseName().MaybeAsASCII(); 749 // Some profiles might become ephemeral after they are created. 750 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && 751 profile_paths.find(profile_path) == profile_paths.end()) { 752 profile_paths.insert(profile_path); 753 profile_list->Append(new StringValue(profile_path)); 754 } 755 } 756 } 757 } 758 759 #if !defined(OS_ANDROID) && !defined(OS_IOS) 760 ProfileManager::BrowserListObserver::BrowserListObserver( 761 ProfileManager* manager) 762 : profile_manager_(manager) { 763 BrowserList::AddObserver(this); 764 } 765 766 ProfileManager::BrowserListObserver::~BrowserListObserver() { 767 BrowserList::RemoveObserver(this); 768 } 769 770 void ProfileManager::BrowserListObserver::OnBrowserAdded( 771 Browser* browser) {} 772 773 void ProfileManager::BrowserListObserver::OnBrowserRemoved( 774 Browser* browser) { 775 Profile* profile = browser->profile(); 776 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 777 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) 778 // Not the last window for this profile. 779 return; 780 } 781 782 // If the last browser of a profile that is scheduled for deletion is closed 783 // do that now. 784 base::FilePath path = profile->GetPath(); 785 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && 786 !IsProfileMarkedForDeletion(path)) { 787 g_browser_process->profile_manager()->ScheduleProfileForDeletion( 788 path, ProfileManager::CreateCallback()); 789 } 790 } 791 792 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive( 793 Browser* browser) { 794 // If all browsers are being closed (e.g. the user is in the process of 795 // shutting down), this event will be fired after each browser is 796 // closed. This does not represent a user intention to change the active 797 // browser so is not handled here. 798 if (profile_manager_->closing_all_browsers_) 799 return; 800 801 Profile* last_active = browser->profile(); 802 803 // Don't remember ephemeral profiles as last because they are not going to 804 // persist after restart. 805 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) 806 return; 807 808 PrefService* local_state = g_browser_process->local_state(); 809 DCHECK(local_state); 810 // Only keep track of profiles that we are managing; tests may create others. 811 if (profile_manager_->profiles_info_.find( 812 last_active->GetPath()) != profile_manager_->profiles_info_.end()) { 813 local_state->SetString(prefs::kProfileLastUsed, 814 last_active->GetPath().BaseName().MaybeAsASCII()); 815 } 816 } 817 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 818 819 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) { 820 DoFinalInitForServices(profile, go_off_the_record); 821 AddProfileToCache(profile); 822 DoFinalInitLogging(profile); 823 824 ProfileMetrics::LogNumberOfProfiles(this); 825 content::NotificationService::current()->Notify( 826 chrome::NOTIFICATION_PROFILE_ADDED, 827 content::Source<Profile>(profile), 828 content::NotificationService::NoDetails()); 829 } 830 831 void ProfileManager::DoFinalInitForServices(Profile* profile, 832 bool go_off_the_record) { 833 #if defined(ENABLE_EXTENSIONS) 834 extensions::ExtensionSystem::Get(profile)->InitForRegularProfile( 835 !go_off_the_record); 836 // During tests, when |profile| is an instance of TestingProfile, 837 // ExtensionSystem might not create an ExtensionService. 838 if (extensions::ExtensionSystem::Get(profile)->extension_service()) { 839 profile->GetHostContentSettingsMap()->RegisterExtensionService( 840 extensions::ExtensionSystem::Get(profile)->extension_service()); 841 } 842 #endif 843 #if defined(ENABLE_MANAGED_USERS) 844 // Initialization needs to happen after extension system initialization (for 845 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the 846 // initializing the managed flag if necessary). 847 ManagedUserServiceFactory::GetForProfile(profile)->Init(); 848 #endif 849 // Start the deferred task runners once the profile is loaded. 850 StartupTaskRunnerServiceFactory::GetForProfile(profile)-> 851 StartDeferredTaskRunners(); 852 853 if (profiles::IsNewProfileManagementEnabled()) 854 AccountReconcilorFactory::GetForProfile(profile); 855 } 856 857 void ProfileManager::DoFinalInitLogging(Profile* profile) { 858 // Count number of extensions in this profile. 859 int extension_count = -1; 860 #if defined(ENABLE_EXTENSIONS) 861 ExtensionService* extension_service = profile->GetExtensionService(); 862 if (extension_service) 863 extension_count = extension_service->GetAppIds().size(); 864 #endif 865 866 // Log the profile size after a reasonable startup delay. 867 BrowserThread::PostDelayedTask( 868 BrowserThread::FILE, FROM_HERE, 869 base::Bind(&ProfileSizeTask, profile->GetPath(), extension_count), 870 base::TimeDelta::FromSeconds(112)); 871 } 872 873 Profile* ProfileManager::CreateProfileHelper(const base::FilePath& path) { 874 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); 875 } 876 877 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path, 878 Delegate* delegate) { 879 return Profile::CreateProfile(path, 880 delegate, 881 Profile::CREATE_MODE_ASYNCHRONOUS); 882 } 883 884 void ProfileManager::OnProfileCreated(Profile* profile, 885 bool success, 886 bool is_new_profile) { 887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 888 889 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); 890 DCHECK(iter != profiles_info_.end()); 891 ProfileInfo* info = iter->second.get(); 892 893 std::vector<CreateCallback> callbacks; 894 info->callbacks.swap(callbacks); 895 896 // Invoke CREATED callback for normal profiles. 897 bool go_off_the_record = ShouldGoOffTheRecord(profile); 898 if (success && !go_off_the_record) 899 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); 900 901 // Perform initialization. 902 if (success) { 903 DoFinalInit(profile, go_off_the_record); 904 if (go_off_the_record) 905 profile = profile->GetOffTheRecordProfile(); 906 info->created = true; 907 } else { 908 profile = NULL; 909 profiles_info_.erase(iter); 910 } 911 912 if (profile) { 913 // If this was the guest profile, finish setting its incognito status. 914 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) 915 SetGuestProfilePrefs(profile); 916 917 // Invoke CREATED callback for incognito profiles. 918 if (go_off_the_record) 919 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); 920 } 921 922 // Invoke INITIALIZED or FAIL for all profiles. 923 RunCallbacks(callbacks, profile, 924 profile ? Profile::CREATE_STATUS_INITIALIZED : 925 Profile::CREATE_STATUS_LOCAL_FAIL); 926 } 927 928 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() { 929 PrefService* local_state = g_browser_process->local_state(); 930 DCHECK(local_state); 931 932 DCHECK(profiles::IsMultipleProfilesEnabled()); 933 934 // Create the next profile in the next available directory slot. 935 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); 936 std::string profile_name = chrome::kMultiProfileDirPrefix; 937 profile_name.append(base::IntToString(next_directory)); 938 base::FilePath new_path = user_data_dir_; 939 #if defined(OS_WIN) 940 new_path = new_path.Append(ASCIIToUTF16(profile_name)); 941 #else 942 new_path = new_path.Append(profile_name); 943 #endif 944 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); 945 return new_path; 946 } 947 948 // static 949 base::FilePath ProfileManager::CreateMultiProfileAsync( 950 const base::string16& name, 951 const base::string16& icon_url, 952 const CreateCallback& callback, 953 const std::string& managed_user_id) { 954 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 955 956 ProfileManager* profile_manager = g_browser_process->profile_manager(); 957 958 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); 959 960 profile_manager->CreateProfileAsync(new_path, 961 callback, 962 name, 963 icon_url, 964 managed_user_id); 965 return new_path; 966 } 967 968 // static 969 base::FilePath ProfileManager::GetGuestProfilePath() { 970 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 971 972 ProfileManager* profile_manager = g_browser_process->profile_manager(); 973 974 base::FilePath guest_path = profile_manager->user_data_dir(); 975 return guest_path.Append(chrome::kGuestProfileDir); 976 } 977 978 size_t ProfileManager::GetNumberOfProfiles() { 979 return GetProfileInfoCache().GetNumberOfProfiles(); 980 } 981 982 bool ProfileManager::CompareProfilePathAndName( 983 const ProfileManager::ProfilePathAndName& pair1, 984 const ProfileManager::ProfilePathAndName& pair2) { 985 int name_compare = pair1.second.compare(pair2.second); 986 if (name_compare < 0) { 987 return true; 988 } else if (name_compare > 0) { 989 return false; 990 } else { 991 return pair1.first < pair2.first; 992 } 993 } 994 995 ProfileInfoCache& ProfileManager::GetProfileInfoCache() { 996 if (!profile_info_cache_) { 997 profile_info_cache_.reset(new ProfileInfoCache( 998 g_browser_process->local_state(), user_data_dir_)); 999 } 1000 return *profile_info_cache_.get(); 1001 } 1002 1003 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() { 1004 return profile_shortcut_manager_.get(); 1005 } 1006 1007 void ProfileManager::AddProfileToCache(Profile* profile) { 1008 if (profile->IsGuestSession()) 1009 return; 1010 ProfileInfoCache& cache = GetProfileInfoCache(); 1011 if (profile->GetPath().DirName() != cache.GetUserDataDir()) 1012 return; 1013 1014 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos) 1015 return; 1016 1017 base::string16 username = UTF8ToUTF16(profile->GetPrefs()->GetString( 1018 prefs::kGoogleServicesUsername)); 1019 1020 // Profile name and avatar are set by InitProfileUserPrefs and stored in the 1021 // profile. Use those values to setup the cache entry. 1022 base::string16 profile_name = UTF8ToUTF16(profile->GetPrefs()->GetString( 1023 prefs::kProfileName)); 1024 1025 size_t icon_index = profile->GetPrefs()->GetInteger( 1026 prefs::kProfileAvatarIndex); 1027 1028 std::string managed_user_id = 1029 profile->GetPrefs()->GetString(prefs::kManagedUserId); 1030 1031 cache.AddProfileToCache(profile->GetPath(), 1032 profile_name, 1033 username, 1034 icon_index, 1035 managed_user_id); 1036 1037 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) { 1038 cache.SetProfileIsEphemeralAtIndex( 1039 cache.GetIndexOfProfileWithPath(profile->GetPath()), true); 1040 } 1041 } 1042 1043 void ProfileManager::InitProfileUserPrefs(Profile* profile) { 1044 ProfileInfoCache& cache = GetProfileInfoCache(); 1045 1046 if (profile->GetPath().DirName() != cache.GetUserDataDir()) 1047 return; 1048 1049 size_t avatar_index; 1050 std::string profile_name; 1051 std::string managed_user_id; 1052 if (profile->IsGuestSession()) { 1053 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME); 1054 avatar_index = 0; 1055 } else { 1056 size_t profile_cache_index = 1057 cache.GetIndexOfProfileWithPath(profile->GetPath()); 1058 // If the cache has an entry for this profile, use the cache data. 1059 if (profile_cache_index != std::string::npos) { 1060 avatar_index = 1061 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index); 1062 profile_name = 1063 UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index)); 1064 managed_user_id = 1065 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index); 1066 } else if (profile->GetPath() == 1067 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) { 1068 avatar_index = 0; 1069 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME); 1070 } else { 1071 avatar_index = cache.ChooseAvatarIconIndexForNewProfile(); 1072 profile_name = UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)); 1073 } 1074 } 1075 1076 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex)) 1077 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index); 1078 1079 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName)) 1080 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name); 1081 1082 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1083 bool force_managed_user_id = 1084 command_line->HasSwitch(switches::kManagedUserId); 1085 if (force_managed_user_id) { 1086 managed_user_id = 1087 command_line->GetSwitchValueASCII(switches::kManagedUserId); 1088 } 1089 if (force_managed_user_id || 1090 !profile->GetPrefs()->HasPrefPath(prefs::kManagedUserId)) { 1091 profile->GetPrefs()->SetString(prefs::kManagedUserId, managed_user_id); 1092 } 1093 } 1094 1095 void ProfileManager::SetGuestProfilePrefs(Profile* profile) { 1096 IncognitoModePrefs::SetAvailability(profile->GetPrefs(), 1097 IncognitoModePrefs::FORCED); 1098 profile->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false); 1099 } 1100 1101 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) { 1102 bool go_off_the_record = false; 1103 #if defined(OS_CHROMEOS) 1104 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1105 if (command_line.HasSwitch(chromeos::switches::kGuestSession) || 1106 (profile->GetPath().BaseName().value() == chrome::kInitialProfile && 1107 (!command_line.HasSwitch(switches::kTestType) || 1108 command_line.HasSwitch(chromeos::switches::kLoginProfile)))) { 1109 go_off_the_record = true; 1110 } 1111 #endif 1112 return go_off_the_record; 1113 } 1114 1115 void ProfileManager::ScheduleProfileForDeletion( 1116 const base::FilePath& profile_dir, 1117 const CreateCallback& callback) { 1118 DCHECK(profiles::IsMultipleProfilesEnabled()); 1119 PrefService* local_state = g_browser_process->local_state(); 1120 ProfileInfoCache& cache = GetProfileInfoCache(); 1121 1122 if (profile_dir.BaseName().MaybeAsASCII() == 1123 local_state->GetString(prefs::kProfileLastUsed)) { 1124 // Update the last used profile pref before closing browser windows. This 1125 // way the correct last used profile is set for any notification observers. 1126 base::FilePath last_non_managed_profile_path; 1127 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { 1128 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); 1129 // Make sure that this profile is not pending deletion. 1130 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) && 1131 !IsProfileMarkedForDeletion(cur_path)) { 1132 last_non_managed_profile_path = cur_path; 1133 break; 1134 } 1135 } 1136 1137 // If we're deleting the last (non-managed) profile, then create a new 1138 // profile in its place. 1139 const std::string last_non_managed_profile = 1140 last_non_managed_profile_path.BaseName().MaybeAsASCII(); 1141 if (last_non_managed_profile.empty()) { 1142 base::FilePath new_path = GenerateNextProfileDirectoryPath(); 1143 // Make sure the last used profile path is pointing at it. This way the 1144 // correct last used profile is set for any notification observers. 1145 local_state->SetString(prefs::kProfileLastUsed, 1146 new_path.BaseName().MaybeAsASCII()); 1147 CreateProfileAsync(new_path, 1148 callback, 1149 base::string16(), 1150 base::string16(), 1151 std::string()); 1152 } else { 1153 // On the Mac, the browser process is not killed when all browser windows 1154 // are closed, so just in case we are deleting the active profile, and no 1155 // other profile has been loaded, we must pre-load a next one. 1156 #if defined(OS_MACOSX) 1157 CreateProfileAsync(last_non_managed_profile_path, 1158 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, 1159 base::Unretained(this), 1160 profile_dir, 1161 last_non_managed_profile_path, 1162 callback), 1163 base::string16(), 1164 base::string16(), 1165 std::string()); 1166 return; 1167 #else 1168 // For OS_MACOSX the pref is updated in the callback to make sure that 1169 // it isn't used before the profile is actually loaded. 1170 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); 1171 #endif 1172 } 1173 } 1174 FinishDeletingProfile(profile_dir); 1175 } 1176 1177 // static 1178 void ProfileManager::CleanUpStaleProfiles( 1179 const std::vector<base::FilePath>& profile_paths) { 1180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1181 1182 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin(); 1183 it != profile_paths.end(); ++it) { 1184 NukeProfileFromDisk(*it); 1185 } 1186 } 1187 1188 void ProfileManager::OnNewActiveProfileLoaded( 1189 const base::FilePath& profile_to_delete_path, 1190 const base::FilePath& last_non_managed_profile_path, 1191 const CreateCallback& original_callback, 1192 Profile* loaded_profile, 1193 Profile::CreateStatus status) { 1194 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && 1195 status != Profile::CREATE_STATUS_REMOTE_FAIL); 1196 1197 // Only run the code if the profile initialization has finished completely. 1198 if (status == Profile::CREATE_STATUS_INITIALIZED) { 1199 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) { 1200 // If the profile we tried to load as the next active profile has been 1201 // deleted, then retry deleting this profile to redo the logic to load 1202 // the next available profile. 1203 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); 1204 } else { 1205 // Update the local state as promised in the ScheduleProfileForDeletion. 1206 g_browser_process->local_state()->SetString( 1207 prefs::kProfileLastUsed, 1208 last_non_managed_profile_path.BaseName().MaybeAsASCII()); 1209 FinishDeletingProfile(profile_to_delete_path); 1210 } 1211 } 1212 } 1213 1214 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { 1215 ProfileInfoCache& cache = GetProfileInfoCache(); 1216 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we 1217 // start deleting the profile instance we need to close background apps too. 1218 Profile* profile = GetProfileByPath(profile_dir); 1219 1220 if (profile) { 1221 BrowserList::CloseAllBrowsersWithProfile(profile); 1222 1223 // Disable sync for doomed profile. 1224 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( 1225 profile)) { 1226 ProfileSyncServiceFactory::GetInstance()->GetForProfile( 1227 profile)->DisableForUser(); 1228 } 1229 } 1230 1231 QueueProfileDirectoryForDeletion(profile_dir); 1232 cache.DeleteProfileFromCache(profile_dir); 1233 ProfileMetrics::UpdateReportedProfilesStatistics(this); 1234 } 1235 1236 void ProfileManager::AutoloadProfiles() { 1237 // If running in the background is disabled for the browser, do not autoload 1238 // any profiles. 1239 PrefService* local_state = g_browser_process->local_state(); 1240 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) || 1241 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) { 1242 return; 1243 } 1244 1245 ProfileInfoCache& cache = GetProfileInfoCache(); 1246 size_t number_of_profiles = cache.GetNumberOfProfiles(); 1247 for (size_t p = 0; p < number_of_profiles; ++p) { 1248 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) { 1249 // If status is true, that profile is running background apps. By calling 1250 // GetProfile, we automatically cause the profile to be loaded which will 1251 // register it with the BackgroundModeManager. 1252 GetProfile(cache.GetPathOfProfileAtIndex(p)); 1253 } 1254 } 1255 } 1256 1257 ProfileManagerWithoutInit::ProfileManagerWithoutInit( 1258 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { 1259 } 1260 1261 void ProfileManager::RegisterTestingProfile(Profile* profile, 1262 bool add_to_cache, 1263 bool start_deferred_task_runners) { 1264 RegisterProfile(profile, true); 1265 if (add_to_cache) { 1266 InitProfileUserPrefs(profile); 1267 AddProfileToCache(profile); 1268 } 1269 if (start_deferred_task_runners) { 1270 StartupTaskRunnerServiceFactory::GetForProfile(profile)-> 1271 StartDeferredTaskRunners(); 1272 } 1273 } 1274 1275 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks, 1276 Profile* profile, 1277 Profile::CreateStatus status) { 1278 for (size_t i = 0; i < callbacks.size(); ++i) 1279 callbacks[i].Run(profile, status); 1280 } 1281 1282 ProfileManager::ProfileInfo::ProfileInfo( 1283 Profile* profile, 1284 bool created) 1285 : profile(profile), 1286 created(created) { 1287 } 1288 1289 ProfileManager::ProfileInfo::~ProfileInfo() { 1290 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); 1291 } 1292