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