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