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 82 using content::BrowserThread; 83 using content::UserMetricsAction; 84 85 namespace { 86 87 // Profiles that should be deleted on shutdown. 88 std::vector<base::FilePath>& ProfilesToDelete() { 89 CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ()); 90 return profiles_to_delete; 91 } 92 93 int64 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. 104 void 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 157 void QueueProfileDirectoryForDeletion(const base::FilePath& path) { 158 ProfilesToDelete().push_back(path); 159 } 160 161 bool 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) 167 void 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 183 void 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 194 void 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 208 namespace { 209 210 bool s_allow_get_default_profile = false; 211 212 } // namespace 213 214 // static 215 void ProfileManager::AllowGetDefaultProfile() { 216 s_allow_get_default_profile = true; 217 } 218 219 // static 220 bool ProfileManager::IsGetDefaultProfileAllowed() { 221 return s_allow_get_default_profile; 222 } 223 224 // static 225 // TODO(nkostylev): Remove this method once all clients are migrated. 226 Profile* 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. 235 Profile* 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 249 Profile* 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 255 Profile* 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 265 std::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 271 ProfileManager::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 307 ProfileManager::~ProfileManager() { 308 } 309 310 base::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 347 Profile* 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 358 base::FilePath ProfileManager::GetLastUsedProfileDir( 359 const base::FilePath& user_data_dir) { 360 base::FilePath last_used_profile_dir(user_data_dir); 361 PrefService* local_state = g_browser_process->local_state(); 362 DCHECK(local_state); 363 364 if (local_state->HasPrefPath(prefs::kProfileLastUsed)) { 365 return last_used_profile_dir.AppendASCII( 366 local_state->GetString(prefs::kProfileLastUsed)); 367 } 368 369 return last_used_profile_dir.AppendASCII(chrome::kInitialProfile); 370 } 371 372 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles( 373 const base::FilePath& user_data_dir) { 374 PrefService* local_state = g_browser_process->local_state(); 375 DCHECK(local_state); 376 377 std::vector<Profile*> to_return; 378 if (local_state->HasPrefPath(prefs::kProfilesLastActive)) { 379 const ListValue* profile_list = 380 local_state->GetList(prefs::kProfilesLastActive); 381 if (profile_list) { 382 ListValue::const_iterator it; 383 std::string profile; 384 for (it = profile_list->begin(); it != profile_list->end(); ++it) { 385 if (!(*it)->GetAsString(&profile) || profile.empty()) { 386 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive; 387 continue; 388 } 389 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile))); 390 } 391 } 392 } 393 return to_return; 394 } 395 396 Profile* ProfileManager::GetDefaultProfile( 397 const base::FilePath& user_data_dir) { 398 #if defined(OS_CHROMEOS) 399 base::FilePath default_profile_dir(user_data_dir); 400 if (logged_in_) { 401 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); 402 } else { 403 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); 404 } 405 #else 406 base::FilePath default_profile_dir(user_data_dir); 407 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); 408 #endif 409 #if defined(OS_CHROMEOS) 410 if (!logged_in_) { 411 Profile* profile = GetProfile(default_profile_dir); 412 // For cros, return the OTR profile so we never accidentally keep 413 // user data in an unencrypted profile. But doing this makes 414 // many of the browser and ui tests fail. We do return the OTR profile 415 // if the login-profile switch is passed so that we can test this. 416 // TODO(davemoore) Fix the tests so they allow OTR profiles. 417 if (ShouldGoOffTheRecord(profile)) 418 return profile->GetOffTheRecordProfile(); 419 return profile; 420 } 421 422 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir); 423 // Fallback to default off-the-record profile, if user profile has not fully 424 // loaded yet. 425 if (profile_info && !profile_info->created) 426 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); 427 #endif 428 return GetProfile(default_profile_dir); 429 } 430 431 bool ProfileManager::IsValidProfile(Profile* profile) { 432 for (ProfilesInfoMap::iterator iter = profiles_info_.begin(); 433 iter != profiles_info_.end(); ++iter) { 434 if (iter->second->created) { 435 Profile* candidate = iter->second->profile.get(); 436 if (candidate == profile || 437 (candidate->HasOffTheRecordProfile() && 438 candidate->GetOffTheRecordProfile() == profile)) { 439 return true; 440 } 441 } 442 } 443 return false; 444 } 445 446 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const { 447 std::vector<Profile*> profiles; 448 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin(); 449 iter != profiles_info_.end(); ++iter) { 450 if (iter->second->created) 451 profiles.push_back(iter->second->profile.get()); 452 } 453 return profiles; 454 } 455 456 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) { 457 TRACE_EVENT0("browser", "ProfileManager::GetProfile") 458 // If the profile is already loaded (e.g., chrome.exe launched twice), just 459 // return it. 460 Profile* profile = GetProfileByPath(profile_dir); 461 if (NULL != profile) 462 return profile; 463 464 profile = CreateProfileHelper(profile_dir); 465 DCHECK(profile); 466 if (profile) { 467 bool result = AddProfile(profile); 468 DCHECK(result); 469 } 470 return profile; 471 } 472 473 void ProfileManager::CreateProfileAsync( 474 const base::FilePath& profile_path, 475 const CreateCallback& callback, 476 const string16& name, 477 const string16& icon_url, 478 const std::string& managed_user_id) { 479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 480 481 // Make sure that this profile is not pending deletion. 482 if (IsProfileMarkedForDeletion(profile_path)) { 483 if (!callback.is_null()) 484 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); 485 return; 486 } 487 488 // Create the profile if needed and collect its ProfileInfo. 489 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); 490 ProfileInfo* info = NULL; 491 492 if (iter != profiles_info_.end()) { 493 info = iter->second.get(); 494 } else { 495 // Initiate asynchronous creation process. 496 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); 497 ProfileInfoCache& cache = GetProfileInfoCache(); 498 // Get the icon index from the user's icon url 499 size_t icon_index; 500 std::string icon_url_std = UTF16ToASCII(icon_url); 501 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) { 502 // add profile to cache with user selected name and avatar 503 cache.AddProfileToCache(profile_path, name, string16(), icon_index, 504 managed_user_id); 505 } 506 507 if (!managed_user_id.empty()) { 508 content::RecordAction( 509 UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); 510 } 511 } 512 513 // Call or enqueue the callback. 514 if (!callback.is_null()) { 515 if (iter != profiles_info_.end() && info->created) { 516 // Profile has already been created. Run callback immediately. 517 callback.Run(info->profile.get(), Profile::CREATE_STATUS_INITIALIZED); 518 } else { 519 // Profile is either already in the process of being created, or new. 520 // Add callback to the list. 521 info->callbacks.push_back(callback); 522 } 523 } 524 } 525 526 // static 527 void ProfileManager::CreateDefaultProfileAsync(const CreateCallback& callback) { 528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 529 ProfileManager* profile_manager = g_browser_process->profile_manager(); 530 531 base::FilePath default_profile_dir = profile_manager->user_data_dir_; 532 // TODO(mirandac): current directory will not always be default in the future 533 default_profile_dir = default_profile_dir.Append( 534 profile_manager->GetInitialProfileDir()); 535 536 // Chrome OS specific note: since we pass string16() here as the icon_url, 537 // profile cache information will not get updated with the is_managed value 538 // so we're fine with passing all default values here. 539 // On Chrome OS |is_managed| preference will get initialized in 540 // Profile::CREATE_STATUS_CREATED callback. 541 profile_manager->CreateProfileAsync( 542 default_profile_dir, callback, string16(), string16(), std::string()); 543 } 544 545 bool ProfileManager::AddProfile(Profile* profile) { 546 DCHECK(profile); 547 548 // Make sure that we're not loading a profile with the same ID as a profile 549 // that's already loaded. 550 if (GetProfileByPath(profile->GetPath())) { 551 NOTREACHED() << "Attempted to add profile with the same path (" << 552 profile->GetPath().value() << 553 ") as an already-loaded profile."; 554 return false; 555 } 556 557 RegisterProfile(profile, true); 558 DoFinalInit(profile, ShouldGoOffTheRecord(profile)); 559 return true; 560 } 561 562 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile( 563 Profile* profile, 564 bool created) { 565 ProfileInfo* info = new ProfileInfo(profile, created); 566 profiles_info_.insert( 567 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info))); 568 return info; 569 } 570 571 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath( 572 const base::FilePath& path) const { 573 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path); 574 return (iter == profiles_info_.end()) ? NULL : iter->second.get(); 575 } 576 577 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { 578 ProfileInfo* profile_info = GetProfileInfoByPath(path); 579 return profile_info ? profile_info->profile.get() : NULL; 580 } 581 582 void ProfileManager::Observe( 583 int type, 584 const content::NotificationSource& source, 585 const content::NotificationDetails& details) { 586 #if defined(OS_CHROMEOS) 587 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { 588 logged_in_ = true; 589 590 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 591 if (!command_line.HasSwitch(switches::kTestType)) { 592 // If we don't have a mounted profile directory we're in trouble. 593 // TODO(davemoore) Once we have better api this check should ensure that 594 // our profile directory is the one that's mounted, and that it's mounted 595 // as the current user. 596 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted( 597 base::Bind(&CheckCryptohomeIsMounted)); 598 599 // Confirm that we hadn't loaded the new profile previously. 600 base::FilePath default_profile_dir = user_data_dir_.Append( 601 GetInitialProfileDir()); 602 CHECK(!GetProfileByPath(default_profile_dir)) 603 << "The default profile was loaded before we mounted the cryptohome."; 604 } 605 return; 606 } 607 #endif 608 bool save_active_profiles = false; 609 switch (type) { 610 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: { 611 // Ignore any browsers closing from now on. 612 closing_all_browsers_ = true; 613 break; 614 } 615 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: { 616 // This will cancel the shutdown process, so the active profiles are 617 // tracked again. Also, as the active profiles may have changed (i.e. if 618 // some windows were closed) we save the current list of active profiles 619 // again. 620 closing_all_browsers_ = false; 621 save_active_profiles = true; 622 break; 623 } 624 case chrome::NOTIFICATION_BROWSER_OPENED: { 625 Browser* browser = content::Source<Browser>(source).ptr(); 626 DCHECK(browser); 627 Profile* profile = browser->profile(); 628 DCHECK(profile); 629 if (!profile->IsOffTheRecord() && ++browser_counts_[profile] == 1) { 630 active_profiles_.push_back(profile); 631 save_active_profiles = true; 632 } 633 // If browsers are opening, we can't be closing all the browsers. This 634 // can happen if the application was exited, but background mode or 635 // packaged apps prevented the process from shutting down, and then 636 // a new browser window was opened. 637 closing_all_browsers_ = false; 638 break; 639 } 640 case chrome::NOTIFICATION_BROWSER_CLOSED: { 641 Browser* browser = content::Source<Browser>(source).ptr(); 642 DCHECK(browser); 643 Profile* profile = browser->profile(); 644 DCHECK(profile); 645 if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) { 646 active_profiles_.erase(std::find(active_profiles_.begin(), 647 active_profiles_.end(), profile)); 648 save_active_profiles = !closing_all_browsers_; 649 } 650 break; 651 } 652 default: { 653 NOTREACHED(); 654 break; 655 } 656 } 657 658 if (save_active_profiles) { 659 PrefService* local_state = g_browser_process->local_state(); 660 DCHECK(local_state); 661 ListPrefUpdate update(local_state, prefs::kProfilesLastActive); 662 ListValue* profile_list = update.Get(); 663 664 profile_list->Clear(); 665 666 // crbug.com/120112 -> several non-incognito profiles might have the same 667 // GetPath().BaseName(). In that case, we cannot restore both 668 // profiles. Include each base name only once in the last active profile 669 // list. 670 std::set<std::string> profile_paths; 671 std::vector<Profile*>::const_iterator it; 672 for (it = active_profiles_.begin(); it != active_profiles_.end(); ++it) { 673 std::string profile_path = (*it)->GetPath().BaseName().MaybeAsASCII(); 674 if (profile_paths.find(profile_path) == profile_paths.end()) { 675 profile_paths.insert(profile_path); 676 profile_list->Append(new StringValue(profile_path)); 677 } 678 } 679 } 680 } 681 682 #if !defined(OS_ANDROID) && !defined(OS_IOS) 683 ProfileManager::BrowserListObserver::BrowserListObserver( 684 ProfileManager* manager) 685 : profile_manager_(manager) { 686 BrowserList::AddObserver(this); 687 } 688 689 ProfileManager::BrowserListObserver::~BrowserListObserver() { 690 BrowserList::RemoveObserver(this); 691 } 692 693 void ProfileManager::BrowserListObserver::OnBrowserAdded( 694 Browser* browser) {} 695 696 void ProfileManager::BrowserListObserver::OnBrowserRemoved( 697 Browser* browser) {} 698 699 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive( 700 Browser* browser) { 701 // If all browsers are being closed (e.g. the user is in the process of 702 // shutting down), this event will be fired after each browser is 703 // closed. This does not represent a user intention to change the active 704 // browser so is not handled here. 705 if (profile_manager_->closing_all_browsers_) 706 return; 707 708 Profile* last_active = browser->profile(); 709 PrefService* local_state = g_browser_process->local_state(); 710 DCHECK(local_state); 711 // Only keep track of profiles that we are managing; tests may create others. 712 if (profile_manager_->profiles_info_.find( 713 last_active->GetPath()) != profile_manager_->profiles_info_.end()) { 714 local_state->SetString(prefs::kProfileLastUsed, 715 last_active->GetPath().BaseName().MaybeAsASCII()); 716 } 717 } 718 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 719 720 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) { 721 InitProfileUserPrefs(profile); 722 DoFinalInitForServices(profile, go_off_the_record); 723 AddProfileToCache(profile); 724 DoFinalInitLogging(profile); 725 726 ProfileMetrics::LogNumberOfProfiles(this); 727 content::NotificationService::current()->Notify( 728 chrome::NOTIFICATION_PROFILE_ADDED, 729 content::Source<Profile>(profile), 730 content::NotificationService::NoDetails()); 731 } 732 733 void ProfileManager::DoFinalInitForServices(Profile* profile, 734 bool go_off_the_record) { 735 #if defined(ENABLE_EXTENSIONS) 736 extensions::ExtensionSystem::Get(profile)->InitForRegularProfile( 737 !go_off_the_record); 738 // During tests, when |profile| is an instance of TestingProfile, 739 // ExtensionSystem might not create an ExtensionService. 740 if (extensions::ExtensionSystem::Get(profile)->extension_service()) { 741 profile->GetHostContentSettingsMap()->RegisterExtensionService( 742 extensions::ExtensionSystem::Get(profile)->extension_service()); 743 } 744 #endif 745 #if defined(ENABLE_MANAGED_USERS) 746 // Initialization needs to happen after extension system initialization (for 747 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the 748 // initializing the managed flag if necessary). 749 ManagedUserServiceFactory::GetForProfile(profile)->Init(); 750 #endif 751 // Start the deferred task runners once the profile is loaded. 752 StartupTaskRunnerServiceFactory::GetForProfile(profile)-> 753 StartDeferredTaskRunners(); 754 } 755 756 void ProfileManager::DoFinalInitLogging(Profile* profile) { 757 // Count number of extensions in this profile. 758 int extension_count = -1; 759 #if defined(ENABLE_EXTENSIONS) 760 ExtensionService* extension_service = profile->GetExtensionService(); 761 if (extension_service) 762 extension_count = extension_service->GetAppIds().size(); 763 #endif 764 765 // Log the profile size after a reasonable startup delay. 766 BrowserThread::PostDelayedTask( 767 BrowserThread::FILE, FROM_HERE, 768 base::Bind(&ProfileSizeTask, profile->GetPath(), extension_count), 769 base::TimeDelta::FromSeconds(112)); 770 } 771 772 Profile* ProfileManager::CreateProfileHelper(const base::FilePath& path) { 773 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); 774 } 775 776 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path, 777 Delegate* delegate) { 778 return Profile::CreateProfile(path, 779 delegate, 780 Profile::CREATE_MODE_ASYNCHRONOUS); 781 } 782 783 void ProfileManager::OnProfileCreated(Profile* profile, 784 bool success, 785 bool is_new_profile) { 786 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 787 788 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); 789 DCHECK(iter != profiles_info_.end()); 790 ProfileInfo* info = iter->second.get(); 791 792 std::vector<CreateCallback> callbacks; 793 info->callbacks.swap(callbacks); 794 795 // Invoke CREATED callback for normal profiles. 796 bool go_off_the_record = ShouldGoOffTheRecord(profile); 797 if (success && !go_off_the_record) 798 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); 799 800 // Perform initialization. 801 if (success) { 802 DoFinalInit(profile, go_off_the_record); 803 if (go_off_the_record) 804 profile = profile->GetOffTheRecordProfile(); 805 info->created = true; 806 } else { 807 profile = NULL; 808 profiles_info_.erase(iter); 809 } 810 811 // Invoke CREATED callback for incognito profiles. 812 if (profile && go_off_the_record) 813 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); 814 815 // Invoke INITIALIZED or FAIL for all profiles. 816 RunCallbacks(callbacks, profile, 817 profile ? Profile::CREATE_STATUS_INITIALIZED : 818 Profile::CREATE_STATUS_LOCAL_FAIL); 819 } 820 821 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() { 822 PrefService* local_state = g_browser_process->local_state(); 823 DCHECK(local_state); 824 825 DCHECK(profiles::IsMultipleProfilesEnabled()); 826 827 // Create the next profile in the next available directory slot. 828 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); 829 std::string profile_name = chrome::kMultiProfileDirPrefix; 830 profile_name.append(base::IntToString(next_directory)); 831 base::FilePath new_path = user_data_dir_; 832 #if defined(OS_WIN) 833 new_path = new_path.Append(ASCIIToUTF16(profile_name)); 834 #else 835 new_path = new_path.Append(profile_name); 836 #endif 837 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); 838 return new_path; 839 } 840 841 // static 842 base::FilePath ProfileManager::CreateMultiProfileAsync( 843 const string16& name, 844 const string16& icon_url, 845 const CreateCallback& callback, 846 const std::string& managed_user_id) { 847 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 848 849 ProfileManager* profile_manager = g_browser_process->profile_manager(); 850 851 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); 852 853 profile_manager->CreateProfileAsync(new_path, 854 callback, 855 name, 856 icon_url, 857 managed_user_id); 858 return new_path; 859 } 860 861 // static 862 base::FilePath ProfileManager::GetGuestProfilePath() { 863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 864 865 ProfileManager* profile_manager = g_browser_process->profile_manager(); 866 867 base::FilePath guest_path = profile_manager->user_data_dir(); 868 return guest_path.Append(chrome::kGuestProfileDir); 869 } 870 871 size_t ProfileManager::GetNumberOfProfiles() { 872 return GetProfileInfoCache().GetNumberOfProfiles(); 873 } 874 875 bool ProfileManager::CompareProfilePathAndName( 876 const ProfileManager::ProfilePathAndName& pair1, 877 const ProfileManager::ProfilePathAndName& pair2) { 878 int name_compare = pair1.second.compare(pair2.second); 879 if (name_compare < 0) { 880 return true; 881 } else if (name_compare > 0) { 882 return false; 883 } else { 884 return pair1.first < pair2.first; 885 } 886 } 887 888 ProfileInfoCache& ProfileManager::GetProfileInfoCache() { 889 if (!profile_info_cache_) { 890 profile_info_cache_.reset(new ProfileInfoCache( 891 g_browser_process->local_state(), user_data_dir_)); 892 } 893 return *profile_info_cache_.get(); 894 } 895 896 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() { 897 return profile_shortcut_manager_.get(); 898 } 899 900 void ProfileManager::AddProfileToCache(Profile* profile) { 901 if (profile->IsGuestSession()) 902 return; 903 ProfileInfoCache& cache = GetProfileInfoCache(); 904 if (profile->GetPath().DirName() != cache.GetUserDataDir()) 905 return; 906 907 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos) 908 return; 909 910 string16 username = UTF8ToUTF16(profile->GetPrefs()->GetString( 911 prefs::kGoogleServicesUsername)); 912 913 // Profile name and avatar are set by InitProfileUserPrefs and stored in the 914 // profile. Use those values to setup the cache entry. 915 string16 profile_name = UTF8ToUTF16(profile->GetPrefs()->GetString( 916 prefs::kProfileName)); 917 918 size_t icon_index = profile->GetPrefs()->GetInteger( 919 prefs::kProfileAvatarIndex); 920 921 std::string managed_user_id = 922 profile->GetPrefs()->GetString(prefs::kManagedUserId); 923 924 cache.AddProfileToCache(profile->GetPath(), 925 profile_name, 926 username, 927 icon_index, 928 managed_user_id); 929 } 930 931 void 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 std::string managed_user_id; 941 if (profile->IsGuestSession()) { 942 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME); 943 avatar_index = 0; 944 } else { 945 size_t profile_cache_index = 946 cache.GetIndexOfProfileWithPath(profile->GetPath()); 947 // If the cache has an entry for this profile, use the cache data. 948 if (profile_cache_index != std::string::npos) { 949 avatar_index = 950 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index); 951 profile_name = 952 UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index)); 953 is_managed = cache.ProfileIsManagedAtIndex(profile_cache_index); 954 managed_user_id = 955 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index); 956 } else if (profile->GetPath() == 957 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) { 958 avatar_index = 0; 959 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME); 960 } else { 961 avatar_index = cache.ChooseAvatarIconIndexForNewProfile(); 962 profile_name = UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)); 963 } 964 } 965 966 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex)) 967 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index); 968 969 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName)) 970 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name); 971 972 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileIsManaged)) 973 profile->GetPrefs()->SetBoolean(prefs::kProfileIsManaged, is_managed); 974 975 if (!profile->GetPrefs()->HasPrefPath(prefs::kManagedUserId)) 976 profile->GetPrefs()->SetString(prefs::kManagedUserId, managed_user_id); 977 } 978 979 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) { 980 bool go_off_the_record = false; 981 #if defined(OS_CHROMEOS) 982 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 983 if (profile->GetPath().BaseName().value() == chrome::kInitialProfile && 984 (!command_line.HasSwitch(switches::kTestType) || 985 command_line.HasSwitch(chromeos::switches::kLoginProfile))) { 986 go_off_the_record = true; 987 } 988 #endif 989 return go_off_the_record; 990 } 991 992 void ProfileManager::ScheduleProfileForDeletion( 993 const base::FilePath& profile_dir, 994 const CreateCallback& callback) { 995 DCHECK(profiles::IsMultipleProfilesEnabled()); 996 PrefService* local_state = g_browser_process->local_state(); 997 ProfileInfoCache& cache = GetProfileInfoCache(); 998 999 if (profile_dir.BaseName().MaybeAsASCII() == 1000 local_state->GetString(prefs::kProfileLastUsed)) { 1001 // Update the last used profile pref before closing browser windows. This 1002 // way the correct last used profile is set for any notification observers. 1003 base::FilePath last_non_managed_profile_path; 1004 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { 1005 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); 1006 // Make sure that this profile is not pending deletion. 1007 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) && 1008 !IsProfileMarkedForDeletion(cur_path)) { 1009 last_non_managed_profile_path = cur_path; 1010 break; 1011 } 1012 } 1013 1014 // If we're deleting the last (non-managed) profile, then create a new 1015 // profile in its place. 1016 const std::string last_non_managed_profile = 1017 last_non_managed_profile_path.BaseName().MaybeAsASCII(); 1018 if (last_non_managed_profile.empty()) { 1019 base::FilePath new_path = GenerateNextProfileDirectoryPath(); 1020 // Make sure the last used profile path is pointing at it. This way the 1021 // correct last used profile is set for any notification observers. 1022 local_state->SetString(prefs::kProfileLastUsed, 1023 new_path.BaseName().MaybeAsASCII()); 1024 CreateProfileAsync(new_path, 1025 callback, 1026 string16(), 1027 string16(), 1028 std::string()); 1029 } else { 1030 // On the Mac, the browser process is not killed when all browser windows 1031 // are closed, so just in case we are deleting the active profile, and no 1032 // other profile has been loaded, we must pre-load a next one. 1033 #if defined(OS_MACOSX) 1034 CreateProfileAsync(last_non_managed_profile_path, 1035 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, 1036 base::Unretained(this), 1037 profile_dir, 1038 last_non_managed_profile_path, 1039 callback), 1040 string16(), 1041 string16(), 1042 std::string()); 1043 return; 1044 #else 1045 // For OS_MACOSX the pref is updated in the callback to make sure that 1046 // it isn't used before the profile is actually loaded. 1047 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); 1048 #endif 1049 } 1050 } 1051 FinishDeletingProfile(profile_dir); 1052 } 1053 1054 void ProfileManager::OnNewActiveProfileLoaded( 1055 const base::FilePath& profile_to_delete_path, 1056 const base::FilePath& last_non_managed_profile_path, 1057 const CreateCallback& original_callback, 1058 Profile* loaded_profile, 1059 Profile::CreateStatus status) { 1060 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && 1061 status != Profile::CREATE_STATUS_REMOTE_FAIL); 1062 1063 // Only run the code if the profile initialization has finished completely. 1064 if (status == Profile::CREATE_STATUS_INITIALIZED) { 1065 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) { 1066 // If the profile we tried to load as the next active profile has been 1067 // deleted, then retry deleting this profile to redo the logic to load 1068 // the next available profile. 1069 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); 1070 } else { 1071 // Update the local state as promised in the ScheduleProfileForDeletion. 1072 g_browser_process->local_state()->SetString( 1073 prefs::kProfileLastUsed, 1074 last_non_managed_profile_path.BaseName().MaybeAsASCII()); 1075 FinishDeletingProfile(profile_to_delete_path); 1076 } 1077 } 1078 } 1079 1080 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { 1081 ProfileInfoCache& cache = GetProfileInfoCache(); 1082 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we 1083 // start deleting the profile instance we need to close background apps too. 1084 Profile* profile = GetProfileByPath(profile_dir); 1085 1086 if (profile) { 1087 BrowserList::CloseAllBrowsersWithProfile(profile); 1088 1089 // Disable sync for doomed profile. 1090 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( 1091 profile)) { 1092 ProfileSyncServiceFactory::GetInstance()->GetForProfile( 1093 profile)->DisableForUser(); 1094 } 1095 } 1096 1097 QueueProfileDirectoryForDeletion(profile_dir); 1098 cache.DeleteProfileFromCache(profile_dir); 1099 } 1100 1101 void ProfileManager::AutoloadProfiles() { 1102 // If running in the background is disabled for the browser, do not autoload 1103 // any profiles. 1104 PrefService* local_state = g_browser_process->local_state(); 1105 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) || 1106 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) { 1107 return; 1108 } 1109 1110 ProfileInfoCache& cache = GetProfileInfoCache(); 1111 size_t number_of_profiles = cache.GetNumberOfProfiles(); 1112 for (size_t p = 0; p < number_of_profiles; ++p) { 1113 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) { 1114 // If status is true, that profile is running background apps. By calling 1115 // GetProfile, we automatically cause the profile to be loaded which will 1116 // register it with the BackgroundModeManager. 1117 GetProfile(cache.GetPathOfProfileAtIndex(p)); 1118 } 1119 } 1120 } 1121 1122 ProfileManagerWithoutInit::ProfileManagerWithoutInit( 1123 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { 1124 } 1125 1126 void ProfileManager::RegisterTestingProfile(Profile* profile, 1127 bool add_to_cache, 1128 bool start_deferred_task_runners) { 1129 RegisterProfile(profile, true); 1130 if (add_to_cache) { 1131 InitProfileUserPrefs(profile); 1132 AddProfileToCache(profile); 1133 } 1134 if (start_deferred_task_runners) { 1135 StartupTaskRunnerServiceFactory::GetForProfile(profile)-> 1136 StartDeferredTaskRunners(); 1137 } 1138 } 1139 1140 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks, 1141 Profile* profile, 1142 Profile::CreateStatus status) { 1143 for (size_t i = 0; i < callbacks.size(); ++i) 1144 callbacks[i].Run(profile, status); 1145 } 1146 1147 ProfileManager::ProfileInfo::ProfileInfo( 1148 Profile* profile, 1149 bool created) 1150 : profile(profile), 1151 created(created) { 1152 } 1153 1154 ProfileManager::ProfileInfo::~ProfileInfo() { 1155 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); 1156 } 1157