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