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