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