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