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