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