Revert of Create a new AccountTrackerService (patchset #8 of https://codereview.chrom...
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager.cc
blob9d410c58537b09c5310b916547e2c29ab790fdf5
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.
5 #include "chrome/browser/profiles/profile_manager.h"
7 #include <set>
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"
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
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)
78 #if defined(OS_WIN)
79 #include "base/win/metro.h"
80 #include "chrome/installer/util/browser_distribution.h"
81 #endif
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
94 using base::UserMetricsAction;
95 using content::BrowserThread;
97 namespace {
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;
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;
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;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
169 void QueueProfileDirectoryForDeletion(const base::FilePath& path) {
170 ProfilesToDelete().push_back(path);
173 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) {
174 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
175 profile_path) != ProfilesToDelete().end();
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);
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;
194 if (!is_mounted)
195 LOG(ERROR) << "Cryptohome is not mounted.";
198 #endif
200 #if defined(ENABLE_EXTENSIONS)
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;
216 return installed_apps;
219 #endif // ENABLE_EXTENSIONS
221 } // namespace
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());
257 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty())
258 profile_shortcut_manager_.reset(ProfileShortcutManager::Create(
259 this));
262 ProfileManager::~ProfileManager() {
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]);
275 #endif
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);
285 ProfilesToDelete().clear();
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_);
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();
302 return profile;
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_);
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
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());
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);
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;
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;
370 profile = CreateProfileHelper(profile_dir);
371 DCHECK(profile);
372 if (profile) {
373 bool result = AddProfile(profile);
374 DCHECK(result);
376 return profile;
379 size_t ProfileManager::GetNumberOfProfiles() {
380 return GetProfileInfoCache().GetNumberOfProfiles();
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());
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;
402 // Create the profile if needed and collect its ProfileInfo.
403 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
404 ProfileInfo* info = NULL;
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);
421 if (!supervised_user_id.empty()) {
422 content::RecordAction(
423 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
426 ProfileMetrics::UpdateReportedProfilesStatistics(this);
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();
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);
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;
460 return false;
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();
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();
485 relative_profile_dir = relative_profile_dir.Append(profile_dir);
486 return relative_profile_dir;
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;
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();
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;
516 #endif
518 return GetProfile(GetLastUsedProfileDir(user_data_dir));
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);
527 if (local_state->HasPrefPath(prefs::kProfileLastUsed)) {
528 return last_used_profile_dir.AppendASCII(
529 local_state->GetString(prefs::kProfileLastUsed));
532 return last_used_profile_dir.AppendASCII(chrome::kInitialProfile);
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);
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;
553 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile)));
556 return to_return;
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());
566 return profiles;
569 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const {
570 ProfileInfo* profile_info = GetProfileInfoByPath(path);
571 return profile_info ? profile_info->profile.get() : NULL;
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));
582 ProfileManager* profile_manager = g_browser_process->profile_manager();
584 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
586 profile_manager->CreateProfileAsync(new_path,
587 callback,
588 name,
589 icon_url,
590 supervised_user_id);
591 return new_path;
594 // static
595 base::FilePath ProfileManager::GetGuestProfilePath() {
596 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
598 ProfileManager* profile_manager = g_browser_process->profile_manager();
600 base::FilePath guest_path = profile_manager->user_data_dir();
601 return guest_path.Append(chrome::kGuestProfileDir);
604 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() {
605 PrefService* local_state = g_browser_process->local_state();
606 DCHECK(local_state);
608 DCHECK(profiles::IsMultipleProfilesEnabled());
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;
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_));
629 return *profile_info_cache_.get();
632 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
633 return profile_shortcut_manager_.get();
636 void ProfileManager::ScheduleProfileForDeletion(
637 const base::FilePath& profile_dir,
638 const CreateCallback& callback) {
639 DCHECK(profiles::IsMultipleProfilesEnabled());
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();
651 PrefService* local_state = g_browser_process->local_state();
652 ProfileInfoCache& cache = GetProfileInfoCache();
654 const std::string last_used_profile =
655 local_state->GetString(prefs::kProfileLastUsed);
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;
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());
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();
693 CreateProfileAsync(new_path,
694 callback,
695 new_profile_name,
696 new_avatar_url,
697 std::string());
698 } else {
699 // On the Mac, the browser process is not killed when all browser windows
700 // are closed, so just in case we are deleting the active profile, and no
701 // other profile has been loaded, we must pre-load a next one.
702 #if defined(OS_MACOSX)
703 CreateProfileAsync(last_non_supervised_profile_path,
704 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
705 base::Unretained(this),
706 profile_dir,
707 last_non_supervised_profile_path,
708 callback),
709 base::string16(),
710 base::string16(),
711 std::string());
712 return;
713 #else
714 // For OS_MACOSX the pref is updated in the callback to make sure that
715 // it isn't used before the profile is actually loaded.
716 local_state->SetString(prefs::kProfileLastUsed,
717 last_non_supervised_profile);
718 #endif
721 FinishDeletingProfile(profile_dir);
724 // static
725 void ProfileManager::CleanUpStaleProfiles(
726 const std::vector<base::FilePath>& profile_paths) {
727 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
729 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin();
730 it != profile_paths.end(); ++it) {
731 NukeProfileFromDisk(*it);
735 void ProfileManager::AutoloadProfiles() {
736 // If running in the background is disabled for the browser, do not autoload
737 // any profiles.
738 PrefService* local_state = g_browser_process->local_state();
739 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
740 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
741 return;
744 ProfileInfoCache& cache = GetProfileInfoCache();
745 size_t number_of_profiles = cache.GetNumberOfProfiles();
746 for (size_t p = 0; p < number_of_profiles; ++p) {
747 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) {
748 // If status is true, that profile is running background apps. By calling
749 // GetProfile, we automatically cause the profile to be loaded which will
750 // register it with the BackgroundModeManager.
751 GetProfile(cache.GetPathOfProfileAtIndex(p));
756 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
757 ProfileInfoCache& cache = GetProfileInfoCache();
759 if (profile->GetPath().DirName() != cache.GetUserDataDir())
760 return;
762 size_t avatar_index;
763 std::string profile_name;
764 std::string supervised_user_id;
765 if (profile->IsGuestSession()) {
766 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
767 avatar_index = 0;
768 } else {
769 size_t profile_cache_index =
770 cache.GetIndexOfProfileWithPath(profile->GetPath());
771 // If the cache has an entry for this profile, use the cache data.
772 if (profile_cache_index != std::string::npos) {
773 avatar_index =
774 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
775 profile_name =
776 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
777 supervised_user_id =
778 cache.GetSupervisedUserIdOfProfileAtIndex(profile_cache_index);
779 } else if (profile->GetPath() ==
780 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
781 // The --new-avatar-menu flag no longer uses the "First User" name.
782 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
783 avatar_index = profiles::GetPlaceholderAvatarIndex();
784 profile_name = is_new_avatar_menu ?
785 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)) :
786 l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
787 } else {
788 avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
789 profile_name =
790 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
794 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
795 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
797 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
798 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
800 CommandLine* command_line = CommandLine::ForCurrentProcess();
801 bool force_supervised_user_id =
802 command_line->HasSwitch(switches::kSupervisedUserId);
803 if (force_supervised_user_id) {
804 supervised_user_id =
805 command_line->GetSwitchValueASCII(switches::kSupervisedUserId);
807 if (force_supervised_user_id ||
808 !profile->GetPrefs()->HasPrefPath(prefs::kSupervisedUserId)) {
809 profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
810 supervised_user_id);
814 void ProfileManager::RegisterTestingProfile(Profile* profile,
815 bool add_to_cache,
816 bool start_deferred_task_runners) {
817 RegisterProfile(profile, true);
818 if (add_to_cache) {
819 InitProfileUserPrefs(profile);
820 AddProfileToCache(profile);
822 if (start_deferred_task_runners) {
823 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
824 StartDeferredTaskRunners();
828 void ProfileManager::Observe(
829 int type,
830 const content::NotificationSource& source,
831 const content::NotificationDetails& details) {
832 #if defined(OS_CHROMEOS)
833 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
834 logged_in_ = true;
836 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
837 if (!command_line.HasSwitch(switches::kTestType)) {
838 // If we don't have a mounted profile directory we're in trouble.
839 // TODO(davemoore) Once we have better api this check should ensure that
840 // our profile directory is the one that's mounted, and that it's mounted
841 // as the current user.
842 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
843 base::Bind(&CheckCryptohomeIsMounted));
845 // Confirm that we hadn't loaded the new profile previously.
846 base::FilePath default_profile_dir = user_data_dir_.Append(
847 GetInitialProfileDir());
848 CHECK(!GetProfileByPath(default_profile_dir))
849 << "The default profile was loaded before we mounted the cryptohome.";
851 return;
853 #endif
854 bool save_active_profiles = false;
855 switch (type) {
856 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: {
857 // Ignore any browsers closing from now on.
858 closing_all_browsers_ = true;
859 save_active_profiles = true;
860 break;
862 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: {
863 // This will cancel the shutdown process, so the active profiles are
864 // tracked again. Also, as the active profiles may have changed (i.e. if
865 // some windows were closed) we save the current list of active profiles
866 // again.
867 closing_all_browsers_ = false;
868 save_active_profiles = true;
869 break;
871 case chrome::NOTIFICATION_BROWSER_OPENED: {
872 Browser* browser = content::Source<Browser>(source).ptr();
873 DCHECK(browser);
874 Profile* profile = browser->profile();
875 DCHECK(profile);
876 bool is_ephemeral =
877 profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles);
878 if (!profile->IsOffTheRecord() && !is_ephemeral &&
879 ++browser_counts_[profile] == 1) {
880 active_profiles_.push_back(profile);
881 save_active_profiles = true;
883 // If browsers are opening, we can't be closing all the browsers. This
884 // can happen if the application was exited, but background mode or
885 // packaged apps prevented the process from shutting down, and then
886 // a new browser window was opened.
887 closing_all_browsers_ = false;
888 break;
890 case chrome::NOTIFICATION_BROWSER_CLOSED: {
891 Browser* browser = content::Source<Browser>(source).ptr();
892 DCHECK(browser);
893 Profile* profile = browser->profile();
894 DCHECK(profile);
895 if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) {
896 active_profiles_.erase(std::find(active_profiles_.begin(),
897 active_profiles_.end(), profile));
898 save_active_profiles = !closing_all_browsers_;
900 break;
902 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: {
903 save_active_profiles = !closing_all_browsers_;
904 break;
906 default: {
907 NOTREACHED();
908 break;
912 if (save_active_profiles) {
913 PrefService* local_state = g_browser_process->local_state();
914 DCHECK(local_state);
915 ListPrefUpdate update(local_state, prefs::kProfilesLastActive);
916 base::ListValue* profile_list = update.Get();
918 profile_list->Clear();
920 // crbug.com/120112 -> several non-incognito profiles might have the same
921 // GetPath().BaseName(). In that case, we cannot restore both
922 // profiles. Include each base name only once in the last active profile
923 // list.
924 std::set<std::string> profile_paths;
925 std::vector<Profile*>::const_iterator it;
926 for (it = active_profiles_.begin(); it != active_profiles_.end(); ++it) {
927 std::string profile_path = (*it)->GetPath().BaseName().MaybeAsASCII();
928 // Some profiles might become ephemeral after they are created.
929 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
930 profile_paths.find(profile_path) == profile_paths.end()) {
931 profile_paths.insert(profile_path);
932 profile_list->Append(new base::StringValue(profile_path));
938 void ProfileManager::OnProfileCreated(Profile* profile,
939 bool success,
940 bool is_new_profile) {
941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
943 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath());
944 DCHECK(iter != profiles_info_.end());
945 ProfileInfo* info = iter->second.get();
947 std::vector<CreateCallback> callbacks;
948 info->callbacks.swap(callbacks);
950 // Invoke CREATED callback for normal profiles.
951 bool go_off_the_record = ShouldGoOffTheRecord(profile);
952 if (success && !go_off_the_record)
953 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
955 // Perform initialization.
956 if (success) {
957 DoFinalInit(profile, go_off_the_record);
958 if (go_off_the_record)
959 profile = profile->GetOffTheRecordProfile();
960 info->created = true;
961 } else {
962 profile = NULL;
963 profiles_info_.erase(iter);
966 if (profile) {
967 // If this was the guest profile, finish setting its special status.
968 if (profile->GetPath() == ProfileManager::GetGuestProfilePath())
969 SetGuestProfilePrefs(profile);
971 // Invoke CREATED callback for incognito profiles.
972 if (go_off_the_record)
973 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
976 // Invoke INITIALIZED or FAIL for all profiles.
977 RunCallbacks(callbacks, profile,
978 profile ? Profile::CREATE_STATUS_INITIALIZED :
979 Profile::CREATE_STATUS_LOCAL_FAIL);
982 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) {
983 DoFinalInitForServices(profile, go_off_the_record);
984 AddProfileToCache(profile);
985 DoFinalInitLogging(profile);
987 ProfileMetrics::LogNumberOfProfiles(this);
988 content::NotificationService::current()->Notify(
989 chrome::NOTIFICATION_PROFILE_ADDED,
990 content::Source<Profile>(profile),
991 content::NotificationService::NoDetails());
994 void ProfileManager::DoFinalInitForServices(Profile* profile,
995 bool go_off_the_record) {
996 #if defined(ENABLE_EXTENSIONS)
997 extensions::ExtensionSystem::Get(profile)->InitForRegularProfile(
998 !go_off_the_record);
999 // During tests, when |profile| is an instance of TestingProfile,
1000 // ExtensionSystem might not create an ExtensionService.
1001 if (extensions::ExtensionSystem::Get(profile)->extension_service()) {
1002 profile->GetHostContentSettingsMap()->RegisterExtensionService(
1003 extensions::ExtensionSystem::Get(profile)->extension_service());
1005 #endif
1006 #if defined(ENABLE_MANAGED_USERS) && !defined(OS_ANDROID)
1007 // Initialization needs to happen after extension system initialization (for
1008 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
1009 // initializing the supervised flag if necessary).
1010 SupervisedUserServiceFactory::GetForProfile(profile)->Init();
1011 #endif
1012 // Start the deferred task runners once the profile is loaded.
1013 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
1014 StartDeferredTaskRunners();
1016 AccountReconcilorFactory::GetForProfile(profile);
1019 void ProfileManager::DoFinalInitLogging(Profile* profile) {
1020 // Count number of extensions in this profile.
1021 int enabled_app_count = -1;
1022 #if defined(ENABLE_EXTENSIONS)
1023 enabled_app_count = GetEnabledAppCount(profile);
1024 #endif
1026 // Log the profile size after a reasonable startup delay.
1027 BrowserThread::PostDelayedTask(
1028 BrowserThread::FILE, FROM_HERE,
1029 base::Bind(&ProfileSizeTask, profile->GetPath(), enabled_app_count),
1030 base::TimeDelta::FromSeconds(112));
1033 Profile* ProfileManager::CreateProfileHelper(const base::FilePath& path) {
1034 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
1037 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path,
1038 Delegate* delegate) {
1039 return Profile::CreateProfile(path,
1040 delegate,
1041 Profile::CREATE_MODE_ASYNCHRONOUS);
1044 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
1045 const base::FilePath& user_data_dir) {
1046 #if defined(OS_CHROMEOS)
1047 base::FilePath default_profile_dir(user_data_dir);
1048 if (!logged_in_) {
1049 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1050 Profile* profile = GetProfile(default_profile_dir);
1051 // For cros, return the OTR profile so we never accidentally keep
1052 // user data in an unencrypted profile. But doing this makes
1053 // many of the browser and ui tests fail. We do return the OTR profile
1054 // if the login-profile switch is passed so that we can test this.
1055 if (ShouldGoOffTheRecord(profile))
1056 return profile->GetOffTheRecordProfile();
1057 DCHECK(!user_manager::UserManager::Get()->IsLoggedInAsGuest());
1058 return profile;
1061 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1062 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
1063 // Fallback to default off-the-record profile, if user profile has not fully
1064 // loaded yet.
1065 if (profile_info && !profile_info->created)
1066 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1068 Profile* profile = GetProfile(default_profile_dir);
1069 // Some unit tests didn't initialize the UserManager.
1070 if (user_manager::UserManager::IsInitialized() &&
1071 user_manager::UserManager::Get()->IsLoggedInAsGuest())
1072 return profile->GetOffTheRecordProfile();
1073 return profile;
1074 #else
1075 base::FilePath default_profile_dir(user_data_dir);
1076 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1077 return GetProfile(default_profile_dir);
1078 #endif
1081 bool ProfileManager::AddProfile(Profile* profile) {
1082 DCHECK(profile);
1084 // Make sure that we're not loading a profile with the same ID as a profile
1085 // that's already loaded.
1086 if (GetProfileByPath(profile->GetPath())) {
1087 NOTREACHED() << "Attempted to add profile with the same path (" <<
1088 profile->GetPath().value() <<
1089 ") as an already-loaded profile.";
1090 return false;
1093 RegisterProfile(profile, true);
1094 InitProfileUserPrefs(profile);
1095 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
1096 return true;
1099 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) {
1100 ProfileInfoCache& cache = GetProfileInfoCache();
1101 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1102 // start deleting the profile instance we need to close background apps too.
1103 Profile* profile = GetProfileByPath(profile_dir);
1105 if (profile) {
1106 // TODO: Migrate additional code in this block to observe this notification
1107 // instead of being implemented here.
1108 content::NotificationService::current()->Notify(
1109 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
1110 content::Source<Profile>(profile),
1111 content::NotificationService::NoDetails());
1113 // By this point, all in-progress downloads for the profile being deleted
1114 // must have been canceled (crbug.com/336725).
1115 DCHECK(DownloadServiceFactory::GetForBrowserContext(profile)->
1116 NonMaliciousDownloadCount() == 0);
1117 BrowserList::CloseAllBrowsersWithProfile(profile);
1119 // Disable sync for doomed profile.
1120 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1121 profile)) {
1122 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1123 profile)->DisableForUser();
1126 bool profile_is_signed_in = !cache.GetUserNameOfProfileAtIndex(
1127 cache.GetIndexOfProfileWithPath(profile_dir)).empty();
1128 ProfileMetrics::LogProfileDelete(profile_is_signed_in);
1129 // Some platforms store passwords in keychains. They should be removed.
1130 scoped_refptr<password_manager::PasswordStore> password_store =
1131 PasswordStoreFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS)
1132 .get();
1133 if (password_store) {
1134 password_store->RemoveLoginsCreatedBetween(base::Time(),
1135 base::Time::Max());
1139 QueueProfileDirectoryForDeletion(profile_dir);
1140 cache.DeleteProfileFromCache(profile_dir);
1141 ProfileMetrics::UpdateReportedProfilesStatistics(this);
1144 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
1145 Profile* profile,
1146 bool created) {
1147 ProfileInfo* info = new ProfileInfo(profile, created);
1148 profiles_info_.insert(
1149 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
1150 return info;
1153 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath(
1154 const base::FilePath& path) const {
1155 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
1156 return (iter == profiles_info_.end()) ? NULL : iter->second.get();
1159 void ProfileManager::AddProfileToCache(Profile* profile) {
1160 if (profile->IsGuestSession())
1161 return;
1162 ProfileInfoCache& cache = GetProfileInfoCache();
1163 if (profile->GetPath().DirName() != cache.GetUserDataDir())
1164 return;
1166 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos)
1167 return;
1169 base::string16 username = base::UTF8ToUTF16(profile->GetPrefs()->GetString(
1170 prefs::kGoogleServicesUsername));
1172 // Profile name and avatar are set by InitProfileUserPrefs and stored in the
1173 // profile. Use those values to setup the cache entry.
1174 base::string16 profile_name =
1175 base::UTF8ToUTF16(profile->GetPrefs()->GetString(prefs::kProfileName));
1177 size_t icon_index = profile->GetPrefs()->GetInteger(
1178 prefs::kProfileAvatarIndex);
1180 std::string supervised_user_id =
1181 profile->GetPrefs()->GetString(prefs::kSupervisedUserId);
1183 cache.AddProfileToCache(profile->GetPath(),
1184 profile_name,
1185 username,
1186 icon_index,
1187 supervised_user_id);
1189 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) {
1190 cache.SetProfileIsEphemeralAtIndex(
1191 cache.GetIndexOfProfileWithPath(profile->GetPath()), true);
1195 void ProfileManager::SetGuestProfilePrefs(Profile* profile) {
1196 PrefService* prefs = profile->GetPrefs();
1197 prefs->SetBoolean(prefs::kSigninAllowed, false);
1198 prefs->SetBoolean(prefs::kEditBookmarksEnabled, false);
1199 prefs->SetBoolean(prefs::kShowBookmarkBar, false);
1200 // This can be removed in the future but needs to be present through
1201 // a release (or two) so that any existing installs get switched to
1202 // the new state and away from the previous "forced" state.
1203 IncognitoModePrefs::SetAvailability(prefs, IncognitoModePrefs::ENABLED);
1206 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) {
1207 #if defined(OS_CHROMEOS)
1208 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1209 if (profile->GetPath().BaseName().value() == chrome::kInitialProfile &&
1210 (!command_line.HasSwitch(switches::kTestType) ||
1211 command_line.HasSwitch(chromeos::switches::kLoginProfile))) {
1212 return true;
1214 #endif
1215 return profile->IsGuestSession();
1218 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks,
1219 Profile* profile,
1220 Profile::CreateStatus status) {
1221 for (size_t i = 0; i < callbacks.size(); ++i)
1222 callbacks[i].Run(profile, status);
1225 ProfileManager::ProfileInfo::ProfileInfo(
1226 Profile* profile,
1227 bool created)
1228 : profile(profile),
1229 created(created) {
1232 ProfileManager::ProfileInfo::~ProfileInfo() {
1233 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1236 #if !defined(OS_ANDROID) && !defined(OS_IOS)
1237 ProfileManager::BrowserListObserver::BrowserListObserver(
1238 ProfileManager* manager)
1239 : profile_manager_(manager) {
1240 BrowserList::AddObserver(this);
1243 ProfileManager::BrowserListObserver::~BrowserListObserver() {
1244 BrowserList::RemoveObserver(this);
1247 void ProfileManager::BrowserListObserver::OnBrowserAdded(
1248 Browser* browser) {}
1250 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
1251 Browser* browser) {
1252 Profile* profile = browser->profile();
1253 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1254 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1255 // Not the last window for this profile.
1256 return;
1259 // If the last browser of a profile that is scheduled for deletion is closed
1260 // do that now.
1261 base::FilePath path = profile->GetPath();
1262 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
1263 !IsProfileMarkedForDeletion(path)) {
1264 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
1265 path, ProfileManager::CreateCallback());
1269 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
1270 Browser* browser) {
1271 // If all browsers are being closed (e.g. the user is in the process of
1272 // shutting down), this event will be fired after each browser is
1273 // closed. This does not represent a user intention to change the active
1274 // browser so is not handled here.
1275 if (profile_manager_->closing_all_browsers_)
1276 return;
1278 Profile* last_active = browser->profile();
1280 // Don't remember ephemeral profiles as last because they are not going to
1281 // persist after restart.
1282 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
1283 return;
1285 PrefService* local_state = g_browser_process->local_state();
1286 DCHECK(local_state);
1287 // Only keep track of profiles that we are managing; tests may create others.
1288 if (profile_manager_->profiles_info_.find(
1289 last_active->GetPath()) != profile_manager_->profiles_info_.end()) {
1290 local_state->SetString(prefs::kProfileLastUsed,
1291 last_active->GetPath().BaseName().MaybeAsASCII());
1293 ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache();
1294 size_t profile_index =
1295 cache.GetIndexOfProfileWithPath(last_active->GetPath());
1296 if (profile_index != std::string::npos)
1297 cache.SetProfileActiveTimeAtIndex(profile_index);
1300 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
1302 #if defined(OS_MACOSX)
1303 void ProfileManager::OnNewActiveProfileLoaded(
1304 const base::FilePath& profile_to_delete_path,
1305 const base::FilePath& last_non_supervised_profile_path,
1306 const CreateCallback& original_callback,
1307 Profile* loaded_profile,
1308 Profile::CreateStatus status) {
1309 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
1310 status != Profile::CREATE_STATUS_REMOTE_FAIL);
1312 // Only run the code if the profile initialization has finished completely.
1313 if (status == Profile::CREATE_STATUS_INITIALIZED) {
1314 if (IsProfileMarkedForDeletion(last_non_supervised_profile_path)) {
1315 // If the profile we tried to load as the next active profile has been
1316 // deleted, then retry deleting this profile to redo the logic to load
1317 // the next available profile.
1318 ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
1319 } else {
1320 // Update the local state as promised in the ScheduleProfileForDeletion.
1321 g_browser_process->local_state()->SetString(
1322 prefs::kProfileLastUsed,
1323 last_non_supervised_profile_path.BaseName().MaybeAsASCII());
1324 FinishDeletingProfile(profile_to_delete_path);
1328 #endif
1330 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1331 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) {