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