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