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