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