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