Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager.cc
blobb4d70c8f3507240907543281fd8da21556c319bd
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/profiler/scoped_profile.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 "base/trace_event/trace_event.h"
23 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/download/download_service.h"
27 #include "chrome/browser/download/download_service_factory.h"
28 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
29 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
30 #include "chrome/browser/password_manager/password_store_factory.h"
31 #include "chrome/browser/prefs/incognito_mode_prefs.h"
32 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
33 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
34 #include "chrome/browser/profiles/profile_destroyer.h"
35 #include "chrome/browser/profiles/profile_info_cache.h"
36 #include "chrome/browser/profiles/profile_metrics.h"
37 #include "chrome/browser/profiles/profiles_state.h"
38 #include "chrome/browser/profiles/startup_task_runner_service.h"
39 #include "chrome/browser/profiles/startup_task_runner_service_factory.h"
40 #include "chrome/browser/signin/account_reconcilor_factory.h"
41 #include "chrome/browser/signin/account_tracker_service_factory.h"
42 #include "chrome/browser/signin/cross_device_promo.h"
43 #include "chrome/browser/signin/cross_device_promo_factory.h"
44 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
45 #include "chrome/browser/signin/signin_manager_factory.h"
46 #include "chrome/browser/sync/profile_sync_service.h"
47 #include "chrome/browser/sync/profile_sync_service_factory.h"
48 #include "chrome/browser/ui/browser.h"
49 #include "chrome/browser/ui/browser_iterator.h"
50 #include "chrome/browser/ui/sync/sync_promo_ui.h"
51 #include "chrome/common/chrome_constants.h"
52 #include "chrome/common/chrome_paths_internal.h"
53 #include "chrome/common/chrome_switches.h"
54 #include "chrome/common/logging_chrome.h"
55 #include "chrome/common/pref_names.h"
56 #include "chrome/common/url_constants.h"
57 #include "chrome/grit/generated_resources.h"
58 #include "components/bookmarks/browser/bookmark_model.h"
59 #include "components/content_settings/core/browser/host_content_settings_map.h"
60 #include "components/password_manager/core/browser/password_store.h"
61 #include "components/signin/core/browser/account_tracker_service.h"
62 #include "components/signin/core/browser/gaia_cookie_manager_service.h"
63 #include "components/signin/core/browser/signin_manager.h"
64 #include "components/signin/core/common/profile_management_switches.h"
65 #include "content/public/browser/browser_thread.h"
66 #include "content/public/browser/notification_service.h"
67 #include "content/public/browser/user_metrics.h"
68 #include "net/http/http_transaction_factory.h"
69 #include "net/url_request/url_request_context.h"
70 #include "net/url_request/url_request_context_getter.h"
71 #include "net/url_request/url_request_job.h"
72 #include "ui/base/l10n/l10n_util.h"
74 #if defined(ENABLE_EXTENSIONS)
75 #include "chrome/browser/extensions/extension_service.h"
76 #include "extensions/browser/extension_registry.h"
77 #include "extensions/browser/extension_system.h"
78 #include "extensions/common/extension_set.h"
79 #include "extensions/common/manifest.h"
80 #endif
82 #if defined(ENABLE_SUPERVISED_USERS)
83 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
84 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
85 #include "chrome/browser/supervised_user/supervised_user_service.h"
86 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
87 #endif
89 #if !defined(OS_IOS)
90 #include "chrome/browser/sessions/session_service_factory.h"
91 #include "chrome/browser/ui/browser_list.h"
92 #endif // !defined (OS_IOS)
94 #if defined(OS_WIN)
95 #include "base/win/metro.h"
96 #include "chrome/installer/util/browser_distribution.h"
97 #endif
99 #if defined(OS_CHROMEOS)
100 #include "chrome/browser/browser_process_platform_part_chromeos.h"
101 #include "chrome/browser/chromeos/profiles/profile_helper.h"
102 #include "chromeos/chromeos_switches.h"
103 #include "chromeos/dbus/cryptohome_client.h"
104 #include "chromeos/dbus/dbus_thread_manager.h"
105 #include "components/user_manager/user.h"
106 #include "components/user_manager/user_manager.h"
107 #endif
109 using base::UserMetricsAction;
110 using content::BrowserThread;
112 namespace {
114 // Profiles that should be deleted on shutdown.
115 std::vector<base::FilePath>& ProfilesToDelete() {
116 CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ());
117 return profiles_to_delete;
120 int64 ComputeFilesSize(const base::FilePath& directory,
121 const base::FilePath::StringType& pattern) {
122 int64 running_size = 0;
123 base::FileEnumerator iter(directory, false, base::FileEnumerator::FILES,
124 pattern);
125 while (!iter.Next().empty())
126 running_size += iter.GetInfo().GetSize();
127 return running_size;
130 // Simple task to log the size of the current profile.
131 void ProfileSizeTask(const base::FilePath& path, int enabled_app_count) {
132 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
133 const int64 kBytesInOneMB = 1024 * 1024;
135 int64 size = ComputeFilesSize(path, FILE_PATH_LITERAL("*"));
136 int size_MB = static_cast<int>(size / kBytesInOneMB);
137 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB);
139 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History"));
140 size_MB = static_cast<int>(size / kBytesInOneMB);
141 UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB);
143 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History*"));
144 size_MB = static_cast<int>(size / kBytesInOneMB);
145 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB);
147 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Cookies"));
148 size_MB = static_cast<int>(size / kBytesInOneMB);
149 UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB);
151 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Bookmarks"));
152 size_MB = static_cast<int>(size / kBytesInOneMB);
153 UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB);
155 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Favicons"));
156 size_MB = static_cast<int>(size / kBytesInOneMB);
157 UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB);
159 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Top Sites"));
160 size_MB = static_cast<int>(size / kBytesInOneMB);
161 UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB);
163 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Visited Links"));
164 size_MB = static_cast<int>(size / kBytesInOneMB);
165 UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB);
167 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Web Data"));
168 size_MB = static_cast<int>(size / kBytesInOneMB);
169 UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB);
171 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Extension*"));
172 size_MB = static_cast<int>(size / kBytesInOneMB);
173 UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB);
175 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Policy"));
176 size_MB = static_cast<int>(size / kBytesInOneMB);
177 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB);
179 // Count number of enabled apps in this profile, if we know.
180 if (enabled_app_count != -1)
181 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count);
184 void QueueProfileDirectoryForDeletion(const base::FilePath& path) {
185 ProfilesToDelete().push_back(path);
188 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) {
189 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
190 profile_path) != ProfilesToDelete().end();
193 // Physically remove deleted profile directories from disk.
194 void NukeProfileFromDisk(const base::FilePath& profile_path) {
195 // Delete both the profile directory and its corresponding cache.
196 base::FilePath cache_path;
197 chrome::GetUserCacheDirectory(profile_path, &cache_path);
198 base::DeleteFile(profile_path, true);
199 base::DeleteFile(cache_path, true);
202 #if defined(OS_CHROMEOS)
203 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status,
204 bool is_mounted) {
205 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
206 LOG(ERROR) << "IsMounted call failed.";
207 return;
209 if (!is_mounted)
210 LOG(ERROR) << "Cryptohome is not mounted.";
213 #endif
215 #if defined(ENABLE_EXTENSIONS)
217 // Returns the number of installed (and enabled) apps, excluding any component
218 // apps.
219 size_t GetEnabledAppCount(Profile* profile) {
220 size_t installed_apps = 0u;
221 const extensions::ExtensionSet& extensions =
222 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
223 for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
224 iter != extensions.end();
225 ++iter) {
226 if ((*iter)->is_app() &&
227 (*iter)->location() != extensions::Manifest::COMPONENT) {
228 ++installed_apps;
231 return installed_apps;
234 #endif // ENABLE_EXTENSIONS
236 } // namespace
238 ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
239 : user_data_dir_(user_data_dir),
240 logged_in_(false),
241 #if !defined(OS_ANDROID) && !defined(OS_IOS)
242 browser_list_observer_(this),
243 #endif
244 closing_all_browsers_(false) {
245 #if defined(OS_CHROMEOS)
246 registrar_.Add(
247 this,
248 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
249 content::NotificationService::AllSources());
250 #endif
251 registrar_.Add(
252 this,
253 chrome::NOTIFICATION_BROWSER_OPENED,
254 content::NotificationService::AllSources());
255 registrar_.Add(
256 this,
257 chrome::NOTIFICATION_BROWSER_CLOSED,
258 content::NotificationService::AllSources());
259 registrar_.Add(
260 this,
261 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
262 content::NotificationService::AllSources());
263 registrar_.Add(
264 this,
265 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
266 content::NotificationService::AllSources());
268 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty())
269 profile_shortcut_manager_.reset(ProfileShortcutManager::Create(
270 this));
273 ProfileManager::~ProfileManager() {
276 #if defined(ENABLE_SESSION_SERVICE)
277 // static
278 void ProfileManager::ShutdownSessionServices() {
279 ProfileManager* pm = g_browser_process->profile_manager();
280 if (!pm) // Is NULL when running unit tests.
281 return;
282 std::vector<Profile*> profiles(pm->GetLoadedProfiles());
283 for (size_t i = 0; i < profiles.size(); ++i)
284 SessionServiceFactory::ShutdownForProfile(profiles[i]);
286 #endif
288 // static
289 void ProfileManager::NukeDeletedProfilesFromDisk() {
290 for (std::vector<base::FilePath>::iterator it =
291 ProfilesToDelete().begin();
292 it != ProfilesToDelete().end();
293 ++it) {
294 NukeProfileFromDisk(*it);
296 ProfilesToDelete().clear();
299 // static
300 Profile* ProfileManager::GetLastUsedProfile() {
301 ProfileManager* profile_manager = g_browser_process->profile_manager();
302 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_);
305 // static
306 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
307 Profile* profile = GetLastUsedProfile();
308 if (profile->IsGuestSession() ||
309 profile->IsSystemProfile() ||
310 IncognitoModePrefs::GetAvailability(profile->GetPrefs()) ==
311 IncognitoModePrefs::FORCED) {
312 return profile->GetOffTheRecordProfile();
314 return profile;
317 // static
318 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() {
319 ProfileManager* profile_manager = g_browser_process->profile_manager();
320 return profile_manager->GetLastOpenedProfiles(
321 profile_manager->user_data_dir_);
324 // static
325 Profile* ProfileManager::GetPrimaryUserProfile() {
326 ProfileManager* profile_manager = g_browser_process->profile_manager();
327 #if defined(OS_CHROMEOS)
328 if (!profile_manager->IsLoggedIn() ||
329 !user_manager::UserManager::IsInitialized())
330 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
331 profile_manager->user_data_dir());
332 user_manager::UserManager* manager = user_manager::UserManager::Get();
333 // Note: The ProfileHelper will take care of guest profiles.
334 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
335 manager->GetPrimaryUser());
336 #else
337 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
338 profile_manager->user_data_dir());
339 #endif
342 // static
343 Profile* ProfileManager::GetActiveUserProfile() {
344 ProfileManager* profile_manager = g_browser_process->profile_manager();
345 #if defined(OS_CHROMEOS)
346 if (!profile_manager)
347 return NULL;
349 if (!profile_manager->IsLoggedIn() ||
350 !user_manager::UserManager::IsInitialized()) {
351 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
352 profile_manager->user_data_dir());
355 user_manager::UserManager* manager = user_manager::UserManager::Get();
356 const user_manager::User* user = manager->GetActiveUser();
357 // To avoid an endless loop (crbug.com/334098) we have to additionally check
358 // if the profile of the user was already created. If the profile was not yet
359 // created we load the profile using the profile directly.
360 // TODO: This should be cleaned up with the new profile manager.
361 if (user && user->is_profile_created())
362 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user);
364 #endif
365 Profile* profile =
366 profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
367 profile_manager->user_data_dir());
368 // |profile| could be null if the user doesn't have a profile yet and the path
369 // is on a read-only volume (preventing Chrome from making a new one).
370 // However, most callers of this function immediately dereference the result
371 // which would lead to crashes in a variety of call sites. Assert here to
372 // figure out how common this is. http://crbug.com/383019
373 CHECK(profile) << profile_manager->user_data_dir().AsUTF8Unsafe();
374 return profile;
377 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) {
378 TRACE_EVENT0("browser", "ProfileManager::GetProfile");
380 // If the profile is already loaded (e.g., chrome.exe launched twice), just
381 // return it.
382 Profile* profile = GetProfileByPath(profile_dir);
383 if (profile)
384 return profile;
385 return CreateAndInitializeProfile(profile_dir);
388 size_t ProfileManager::GetNumberOfProfiles() {
389 return GetProfileInfoCache().GetNumberOfProfiles();
392 void ProfileManager::CreateProfileAsync(
393 const base::FilePath& profile_path,
394 const CreateCallback& callback,
395 const base::string16& name,
396 const base::string16& icon_url,
397 const std::string& supervised_user_id) {
398 DCHECK_CURRENTLY_ON(BrowserThread::UI);
399 TRACE_EVENT1("browser,startup",
400 "ProfileManager::CreateProfileAsync",
401 "profile_path",
402 profile_path.AsUTF8Unsafe());
404 // Make sure that this profile is not pending deletion.
405 if (IsProfileMarkedForDeletion(profile_path)) {
406 if (!callback.is_null())
407 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
408 return;
411 // Create the profile if needed and collect its ProfileInfo.
412 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
413 ProfileInfo* info = NULL;
415 if (iter != profiles_info_.end()) {
416 info = iter->second.get();
417 } else {
418 // Initiate asynchronous creation process.
419 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false);
420 ProfileInfoCache& cache = GetProfileInfoCache();
421 // Get the icon index from the user's icon url
422 size_t icon_index;
423 std::string icon_url_std = base::UTF16ToASCII(icon_url);
424 if (profiles::IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) {
425 // add profile to cache with user selected name and avatar
426 cache.AddProfileToCache(profile_path, name, std::string(),
427 base::string16(), icon_index, supervised_user_id);
430 if (!supervised_user_id.empty()) {
431 content::RecordAction(
432 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
435 ProfileMetrics::UpdateReportedProfilesStatistics(this);
438 // Call or enqueue the callback.
439 if (!callback.is_null()) {
440 if (iter != profiles_info_.end() && info->created) {
441 Profile* profile = info->profile.get();
442 // If this was the guest profile, apply settings and go OffTheRecord.
443 // The system profile also needs characteristics of being off the record,
444 // such as having no extensions, not writing to disk, etc.
445 if (profile->IsGuestSession() || profile->IsSystemProfile()) {
446 SetNonPersonalProfilePrefs(profile);
447 profile = profile->GetOffTheRecordProfile();
449 // Profile has already been created. Run callback immediately.
450 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
451 } else {
452 // Profile is either already in the process of being created, or new.
453 // Add callback to the list.
454 info->callbacks.push_back(callback);
459 bool ProfileManager::IsValidProfile(Profile* profile) {
460 for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
461 iter != profiles_info_.end(); ++iter) {
462 if (iter->second->created) {
463 Profile* candidate = iter->second->profile.get();
464 if (candidate == profile ||
465 (candidate->HasOffTheRecordProfile() &&
466 candidate->GetOffTheRecordProfile() == profile)) {
467 return true;
471 return false;
474 base::FilePath ProfileManager::GetInitialProfileDir() {
475 #if defined(OS_CHROMEOS)
476 if (logged_in_) {
477 return chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
479 #endif
480 base::FilePath relative_profile_dir;
481 // TODO(mirandac): should not automatically be default profile.
482 return relative_profile_dir.AppendASCII(chrome::kInitialProfile);
485 Profile* ProfileManager::GetLastUsedProfile(
486 const base::FilePath& user_data_dir) {
487 #if defined(OS_CHROMEOS)
488 // Use default login profile if user has not logged in yet.
489 if (!logged_in_) {
490 return GetActiveUserOrOffTheRecordProfileFromPath(user_data_dir);
491 } else {
492 // CrOS multi-profiles implementation is different so GetLastUsedProfile
493 // has custom implementation too.
494 base::FilePath profile_dir;
495 // In case of multi-profiles we ignore "last used profile" preference
496 // since it may refer to profile that has been in use in previous session.
497 // That profile dir may not be mounted in this session so instead return
498 // active profile from current session.
499 profile_dir = chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
501 base::FilePath profile_path(user_data_dir);
502 Profile* profile = GetProfile(profile_path.Append(profile_dir));
503 return profile->IsGuestSession() ? profile->GetOffTheRecordProfile() :
504 profile;
506 #endif
508 return GetProfile(GetLastUsedProfileDir(user_data_dir));
511 base::FilePath ProfileManager::GetLastUsedProfileDir(
512 const base::FilePath& user_data_dir) {
513 return user_data_dir.AppendASCII(GetLastUsedProfileName());
516 std::string ProfileManager::GetLastUsedProfileName() {
517 PrefService* local_state = g_browser_process->local_state();
518 DCHECK(local_state);
519 const std::string last_used_profile_name =
520 local_state->GetString(prefs::kProfileLastUsed);
521 if (!last_used_profile_name.empty())
522 return last_used_profile_name;
524 return chrome::kInitialProfile;
527 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles(
528 const base::FilePath& user_data_dir) {
529 PrefService* local_state = g_browser_process->local_state();
530 DCHECK(local_state);
532 std::vector<Profile*> to_return;
533 if (local_state->HasPrefPath(prefs::kProfilesLastActive) &&
534 local_state->GetList(prefs::kProfilesLastActive)) {
535 // Make a copy because the list might change in the calls to GetProfile.
536 scoped_ptr<base::ListValue> profile_list(
537 local_state->GetList(prefs::kProfilesLastActive)->DeepCopy());
538 base::ListValue::const_iterator it;
539 std::string profile;
540 for (it = profile_list->begin(); it != profile_list->end(); ++it) {
541 if (!(*it)->GetAsString(&profile) || profile.empty()) {
542 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive;
543 continue;
545 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile)));
548 return to_return;
551 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const {
552 std::vector<Profile*> profiles;
553 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin();
554 iter != profiles_info_.end(); ++iter) {
555 if (iter->second->created)
556 profiles.push_back(iter->second->profile.get());
558 return profiles;
561 Profile* ProfileManager::GetProfileByPathInternal(
562 const base::FilePath& path) const {
563 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPathInternal");
564 ProfileInfo* profile_info = GetProfileInfoByPath(path);
565 return profile_info ? profile_info->profile.get() : nullptr;
568 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const {
569 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath");
570 ProfileInfo* profile_info = GetProfileInfoByPath(path);
571 return (profile_info && profile_info->created) ? profile_info->profile.get()
572 : nullptr;
575 // static
576 base::FilePath ProfileManager::CreateMultiProfileAsync(
577 const base::string16& name,
578 const base::string16& icon_url,
579 const CreateCallback& callback,
580 const std::string& supervised_user_id) {
581 DCHECK_CURRENTLY_ON(BrowserThread::UI);
583 ProfileManager* profile_manager = g_browser_process->profile_manager();
585 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
587 profile_manager->CreateProfileAsync(new_path,
588 callback,
589 name,
590 icon_url,
591 supervised_user_id);
592 return new_path;
595 // static
596 base::FilePath ProfileManager::GetGuestProfilePath() {
597 DCHECK_CURRENTLY_ON(BrowserThread::UI);
599 ProfileManager* profile_manager = g_browser_process->profile_manager();
601 base::FilePath guest_path = profile_manager->user_data_dir();
602 return guest_path.Append(chrome::kGuestProfileDir);
605 // static
606 base::FilePath ProfileManager::GetSystemProfilePath() {
607 DCHECK_CURRENTLY_ON(BrowserThread::UI);
609 ProfileManager* profile_manager = g_browser_process->profile_manager();
611 base::FilePath system_path = profile_manager->user_data_dir();
612 return system_path.Append(chrome::kSystemProfileDir);
615 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() {
616 PrefService* local_state = g_browser_process->local_state();
617 DCHECK(local_state);
619 DCHECK(profiles::IsMultipleProfilesEnabled());
621 // Create the next profile in the next available directory slot.
622 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated);
623 std::string profile_name = chrome::kMultiProfileDirPrefix;
624 profile_name.append(base::IntToString(next_directory));
625 base::FilePath new_path = user_data_dir_;
626 #if defined(OS_WIN)
627 new_path = new_path.Append(base::ASCIIToUTF16(profile_name));
628 #else
629 new_path = new_path.Append(profile_name);
630 #endif
631 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory);
632 return new_path;
635 ProfileInfoCache& ProfileManager::GetProfileInfoCache() {
636 TRACE_EVENT0("browser", "ProfileManager::GetProfileInfoCache");
637 if (!profile_info_cache_) {
638 profile_info_cache_.reset(new ProfileInfoCache(
639 g_browser_process->local_state(), user_data_dir_));
641 return *profile_info_cache_.get();
644 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
645 return profile_shortcut_manager_.get();
648 void ProfileManager::ScheduleProfileForDeletion(
649 const base::FilePath& profile_dir,
650 const CreateCallback& callback) {
651 DCHECK(profiles::IsMultipleProfilesEnabled());
653 // Cancel all in-progress downloads before deleting the profile to prevent a
654 // "Do you want to exit Google Chrome and cancel the downloads?" prompt
655 // (crbug.com/336725).
656 Profile* profile = GetProfileByPath(profile_dir);
657 if (profile) {
658 DownloadService* service =
659 DownloadServiceFactory::GetForBrowserContext(profile);
660 service->CancelDownloads();
663 ProfileInfoCache& cache = GetProfileInfoCache();
665 // If we're deleting the last (non-legacy-supervised) profile, then create a
666 // new profile in its place.
667 base::FilePath last_non_supervised_profile_path;
668 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
669 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
670 // Make sure that this profile is not pending deletion, and is not
671 // legacy-supervised.
672 if (cur_path != profile_dir &&
673 !cache.ProfileIsLegacySupervisedAtIndex(i) &&
674 !IsProfileMarkedForDeletion(cur_path)) {
675 last_non_supervised_profile_path = cur_path;
676 break;
680 base::FilePath new_path;
681 if (last_non_supervised_profile_path.empty()) {
682 // If we are using --new-avatar-menu, then assign the default
683 // placeholder avatar and name. Otherwise, use random ones.
684 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
685 int avatar_index = profiles::GetPlaceholderAvatarIndex();
686 base::string16 new_avatar_url = is_new_avatar_menu ?
687 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(avatar_index)) :
688 base::string16();
689 base::string16 new_profile_name = is_new_avatar_menu ?
690 cache.ChooseNameForNewProfile(avatar_index) : base::string16();
692 new_path = GenerateNextProfileDirectoryPath();
693 CreateProfileAsync(new_path,
694 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
695 base::Unretained(this),
696 profile_dir,
697 new_path,
698 callback),
699 new_profile_name,
700 new_avatar_url,
701 std::string());
703 ProfileMetrics::LogProfileAddNewUser(
704 ProfileMetrics::ADD_NEW_USER_LAST_DELETED);
705 return;
708 #if defined(OS_MACOSX)
709 // On the Mac, the browser process is not killed when all browser windows are
710 // closed, so just in case we are deleting the active profile, and no other
711 // profile has been loaded, we must pre-load a next one.
712 const base::FilePath last_used_profile =
713 GetLastUsedProfileDir(user_data_dir_);
714 if (last_used_profile == profile_dir ||
715 last_used_profile == GetGuestProfilePath()) {
716 CreateProfileAsync(last_non_supervised_profile_path,
717 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
718 base::Unretained(this),
719 profile_dir,
720 last_non_supervised_profile_path,
721 callback),
722 base::string16(),
723 base::string16(),
724 std::string());
725 return;
727 #endif // defined(OS_MACOSX)
729 FinishDeletingProfile(profile_dir, last_non_supervised_profile_path);
732 void ProfileManager::AutoloadProfiles() {
733 // If running in the background is disabled for the browser, do not autoload
734 // any profiles.
735 PrefService* local_state = g_browser_process->local_state();
736 DCHECK(local_state);
737 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
738 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
739 return;
742 ProfileInfoCache& cache = GetProfileInfoCache();
743 size_t number_of_profiles = cache.GetNumberOfProfiles();
744 for (size_t p = 0; p < number_of_profiles; ++p) {
745 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) {
746 // If status is true, that profile is running background apps. By calling
747 // GetProfile, we automatically cause the profile to be loaded which will
748 // register it with the BackgroundModeManager.
749 GetProfile(cache.GetPathOfProfileAtIndex(p));
754 void ProfileManager::CleanUpEphemeralProfiles() {
755 const std::string last_used_profile = GetLastUsedProfileName();
757 bool last_active_profile_deleted = false;
758 base::FilePath new_profile_path;
759 std::vector<base::FilePath> profiles_to_delete;
760 ProfileInfoCache& profile_cache = GetProfileInfoCache();
761 size_t profiles_count = profile_cache.GetNumberOfProfiles();
762 for (size_t i = 0; i < profiles_count; ++i) {
763 base::FilePath profile_path = profile_cache.GetPathOfProfileAtIndex(i);
764 if (profile_cache.ProfileIsEphemeralAtIndex(i)) {
765 profiles_to_delete.push_back(profile_path);
766 if (profile_path.BaseName().MaybeAsASCII() == last_used_profile)
767 last_active_profile_deleted = true;
768 } else if (new_profile_path.empty()) {
769 new_profile_path = profile_path;
773 // If the last active profile was ephemeral, set a new one.
774 if (last_active_profile_deleted) {
775 if (new_profile_path.empty())
776 new_profile_path = GenerateNextProfileDirectoryPath();
778 PrefService* local_state = g_browser_process->local_state();
779 local_state->SetString(prefs::kProfileLastUsed,
780 new_profile_path.BaseName().MaybeAsASCII());
783 // This uses a separate loop, because deleting the profile from the
784 // ProfileInfoCache will modify indices.
785 for (const base::FilePath& profile_path : profiles_to_delete) {
786 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
787 base::Bind(&NukeProfileFromDisk, profile_path));
789 profile_cache.DeleteProfileFromCache(profile_path);
793 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
794 TRACE_EVENT0("browser", "ProfileManager::InitProfileUserPrefs");
795 ProfileInfoCache& cache = GetProfileInfoCache();
797 if (profile->GetPath().DirName() != cache.GetUserDataDir())
798 return;
800 size_t avatar_index;
801 std::string profile_name;
802 std::string supervised_user_id;
803 if (profile->IsGuestSession()) {
804 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
805 avatar_index = 0;
806 } else {
807 size_t profile_cache_index =
808 cache.GetIndexOfProfileWithPath(profile->GetPath());
809 // If the cache has an entry for this profile, use the cache data.
810 if (profile_cache_index != std::string::npos) {
811 avatar_index =
812 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
813 profile_name =
814 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
815 supervised_user_id =
816 cache.GetSupervisedUserIdOfProfileAtIndex(profile_cache_index);
817 } else if (profile->GetPath() ==
818 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
819 // The --new-avatar-menu flag no longer uses the "First User" name.
820 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
821 avatar_index = profiles::GetPlaceholderAvatarIndex();
822 profile_name = is_new_avatar_menu ?
823 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)) :
824 l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
825 } else {
826 avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
827 profile_name =
828 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
832 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
833 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
835 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
836 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
838 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
839 bool force_supervised_user_id =
840 #if defined(OS_CHROMEOS)
841 g_browser_process->platform_part()
842 ->profile_helper()
843 ->GetSigninProfileDir() != profile->GetPath() &&
844 #endif
845 command_line->HasSwitch(switches::kSupervisedUserId);
846 if (force_supervised_user_id) {
847 supervised_user_id =
848 command_line->GetSwitchValueASCII(switches::kSupervisedUserId);
850 if (force_supervised_user_id ||
851 !profile->GetPrefs()->HasPrefPath(prefs::kSupervisedUserId)) {
852 profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
853 supervised_user_id);
857 void ProfileManager::RegisterTestingProfile(Profile* profile,
858 bool add_to_cache,
859 bool start_deferred_task_runners) {
860 RegisterProfile(profile, true);
861 if (add_to_cache) {
862 InitProfileUserPrefs(profile);
863 AddProfileToCache(profile);
865 if (start_deferred_task_runners) {
866 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
867 StartDeferredTaskRunners();
871 void ProfileManager::Observe(
872 int type,
873 const content::NotificationSource& source,
874 const content::NotificationDetails& details) {
875 #if defined(OS_CHROMEOS)
876 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
877 logged_in_ = true;
879 const base::CommandLine& command_line =
880 *base::CommandLine::ForCurrentProcess();
881 if (!command_line.HasSwitch(switches::kTestType)) {
882 // If we don't have a mounted profile directory we're in trouble.
883 // TODO(davemoore) Once we have better api this check should ensure that
884 // our profile directory is the one that's mounted, and that it's mounted
885 // as the current user.
886 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
887 base::Bind(&CheckCryptohomeIsMounted));
889 // Confirm that we hadn't loaded the new profile previously.
890 base::FilePath default_profile_dir = user_data_dir_.Append(
891 GetInitialProfileDir());
892 CHECK(!GetProfileByPathInternal(default_profile_dir))
893 << "The default profile was loaded before we mounted the cryptohome.";
895 return;
897 #endif
898 bool save_active_profiles = false;
899 switch (type) {
900 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: {
901 // Ignore any browsers closing from now on.
902 closing_all_browsers_ = true;
903 save_active_profiles = true;
904 break;
906 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: {
907 // This will cancel the shutdown process, so the active profiles are
908 // tracked again. Also, as the active profiles may have changed (i.e. if
909 // some windows were closed) we save the current list of active profiles
910 // again.
911 closing_all_browsers_ = false;
912 save_active_profiles = true;
913 break;
915 case chrome::NOTIFICATION_BROWSER_OPENED: {
916 Browser* browser = content::Source<Browser>(source).ptr();
917 DCHECK(browser);
918 Profile* profile = browser->profile();
919 DCHECK(profile);
920 bool is_ephemeral =
921 profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles);
922 if (!profile->IsOffTheRecord() && !is_ephemeral &&
923 ++browser_counts_[profile] == 1) {
924 active_profiles_.push_back(profile);
925 save_active_profiles = true;
927 // If browsers are opening, we can't be closing all the browsers. This
928 // can happen if the application was exited, but background mode or
929 // packaged apps prevented the process from shutting down, and then
930 // a new browser window was opened.
931 closing_all_browsers_ = false;
932 break;
934 case chrome::NOTIFICATION_BROWSER_CLOSED: {
935 Browser* browser = content::Source<Browser>(source).ptr();
936 DCHECK(browser);
937 Profile* profile = browser->profile();
938 DCHECK(profile);
939 if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) {
940 active_profiles_.erase(std::find(active_profiles_.begin(),
941 active_profiles_.end(), profile));
942 save_active_profiles = !closing_all_browsers_;
944 break;
946 default: {
947 NOTREACHED();
948 break;
952 if (save_active_profiles) {
953 PrefService* local_state = g_browser_process->local_state();
954 DCHECK(local_state);
955 ListPrefUpdate update(local_state, prefs::kProfilesLastActive);
956 base::ListValue* profile_list = update.Get();
958 profile_list->Clear();
960 // crbug.com/120112 -> several non-incognito profiles might have the same
961 // GetPath().BaseName(). In that case, we cannot restore both
962 // profiles. Include each base name only once in the last active profile
963 // list.
964 std::set<std::string> profile_paths;
965 std::vector<Profile*>::const_iterator it;
966 for (it = active_profiles_.begin(); it != active_profiles_.end(); ++it) {
967 std::string profile_path = (*it)->GetPath().BaseName().MaybeAsASCII();
968 // Some profiles might become ephemeral after they are created.
969 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
970 profile_paths.find(profile_path) == profile_paths.end()) {
971 profile_paths.insert(profile_path);
972 profile_list->Append(new base::StringValue(profile_path));
978 void ProfileManager::OnProfileCreated(Profile* profile,
979 bool success,
980 bool is_new_profile) {
981 DCHECK_CURRENTLY_ON(BrowserThread::UI);
983 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath());
984 DCHECK(iter != profiles_info_.end());
985 ProfileInfo* info = iter->second.get();
987 std::vector<CreateCallback> callbacks;
988 info->callbacks.swap(callbacks);
990 // Invoke CREATED callback for normal profiles.
991 bool go_off_the_record = ShouldGoOffTheRecord(profile);
992 if (success && !go_off_the_record)
993 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
995 // Perform initialization.
996 if (success) {
997 DoFinalInit(profile, go_off_the_record);
998 if (go_off_the_record)
999 profile = profile->GetOffTheRecordProfile();
1000 info->created = true;
1001 } else {
1002 profile = NULL;
1003 profiles_info_.erase(iter);
1004 // TODO(yiyaoliu): This is temporary, remove it after it's not used.
1005 UMA_HISTOGRAM_COUNTS_100("UMA.ProfilesCount.AfterErase",
1006 profiles_info_.size());
1009 if (profile) {
1010 // If this was the guest or system profile, finish setting its special
1011 // status.
1012 if (profile->IsGuestSession() || profile->IsSystemProfile())
1013 SetNonPersonalProfilePrefs(profile);
1015 // Invoke CREATED callback for incognito profiles.
1016 if (go_off_the_record)
1017 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
1020 // Invoke INITIALIZED or FAIL for all profiles.
1021 RunCallbacks(callbacks, profile,
1022 profile ? Profile::CREATE_STATUS_INITIALIZED :
1023 Profile::CREATE_STATUS_LOCAL_FAIL);
1026 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) {
1027 TRACE_EVENT0("browser", "ProfileManager::DoFinalInit");
1028 TRACK_SCOPED_REGION("Startup", "ProfileManager::DoFinalInit");
1030 DoFinalInitForServices(profile, go_off_the_record);
1031 AddProfileToCache(profile);
1032 DoFinalInitLogging(profile);
1034 ProfileMetrics::LogNumberOfProfiles(this);
1035 content::NotificationService::current()->Notify(
1036 chrome::NOTIFICATION_PROFILE_ADDED,
1037 content::Source<Profile>(profile),
1038 content::NotificationService::NoDetails());
1041 void ProfileManager::DoFinalInitForServices(Profile* profile,
1042 bool go_off_the_record) {
1043 TRACE_EVENT0("browser", "ProfileManager::DoFinalInitForServices");
1044 TRACK_SCOPED_REGION("Startup", "ProfileManager::DoFinalInitForServices");
1046 #if defined(ENABLE_EXTENSIONS)
1047 ProfileInfoCache& cache = GetProfileInfoCache();
1048 extensions::ExtensionSystem::Get(profile)->InitForRegularProfile(
1049 !go_off_the_record);
1050 // During tests, when |profile| is an instance of TestingProfile,
1051 // ExtensionSystem might not create an ExtensionService.
1052 if (extensions::ExtensionSystem::Get(profile)->extension_service()) {
1053 extensions::ExtensionSystem::Get(profile)->extension_service()->
1054 RegisterContentSettings(profile->GetHostContentSettingsMap());
1056 // Set the block extensions bit on the ExtensionService. There likely are no
1057 // blockable extensions to block.
1058 size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
1059 if (profile_index != std::string::npos &&
1060 cache.ProfileIsSigninRequiredAtIndex(profile_index)) {
1061 extensions::ExtensionSystem::Get(profile)
1062 ->extension_service()
1063 ->BlockAllExtensions();
1066 #endif
1067 #if defined(ENABLE_SUPERVISED_USERS)
1068 // Initialization needs to happen after extension system initialization (for
1069 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
1070 // initializing the supervised flag if necessary).
1071 ChildAccountServiceFactory::GetForProfile(profile)->Init();
1072 SupervisedUserServiceFactory::GetForProfile(profile)->Init();
1073 #endif
1074 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
1075 // If the lock enabled algorithm changed, update this profile's lock status.
1076 // This depends on services which shouldn't be initialized until
1077 // DoFinalInitForServices.
1078 if (switches::IsNewProfileManagement())
1079 profiles::UpdateIsProfileLockEnabledIfNeeded(profile);
1080 #endif
1081 // Start the deferred task runners once the profile is loaded.
1082 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
1083 StartDeferredTaskRunners();
1085 // Activate data reduction proxy. This creates a request context and makes a
1086 // URL request to check if the data reduction proxy server is reachable.
1087 DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile)->
1088 MaybeActivateDataReductionProxy(true);
1090 GaiaCookieManagerServiceFactory::GetForProfile(profile)->Init();
1091 AccountTrackerServiceFactory::GetForProfile(profile)->EnableNetworkFetches();
1092 AccountReconcilorFactory::GetForProfile(profile);
1095 void ProfileManager::DoFinalInitLogging(Profile* profile) {
1096 TRACE_EVENT0("browser", "ProfileManager::DoFinalInitLogging");
1097 // Count number of extensions in this profile.
1098 int enabled_app_count = -1;
1099 #if defined(ENABLE_EXTENSIONS)
1100 enabled_app_count = GetEnabledAppCount(profile);
1101 #endif
1103 // Log the profile size after a reasonable startup delay.
1104 BrowserThread::PostDelayedTask(
1105 BrowserThread::FILE, FROM_HERE,
1106 base::Bind(&ProfileSizeTask, profile->GetPath(), enabled_app_count),
1107 base::TimeDelta::FromSeconds(112));
1110 Profile* ProfileManager::CreateProfileHelper(const base::FilePath& path) {
1111 TRACE_EVENT0("browser", "ProfileManager::CreateProfileHelper");
1112 SCOPED_UMA_HISTOGRAM_TIMER("Profile.CreateProfileHelperTime");
1113 TRACK_SCOPED_REGION("Startup", "ProfileManager::CreateProfileHelper");
1115 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
1118 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path,
1119 Delegate* delegate) {
1120 return Profile::CreateProfile(path,
1121 delegate,
1122 Profile::CREATE_MODE_ASYNCHRONOUS);
1125 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
1126 const base::FilePath& user_data_dir) {
1127 #if defined(OS_CHROMEOS)
1128 base::FilePath default_profile_dir(user_data_dir);
1129 if (!logged_in_) {
1130 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1131 Profile* profile = GetProfile(default_profile_dir);
1132 // For cros, return the OTR profile so we never accidentally keep
1133 // user data in an unencrypted profile. But doing this makes
1134 // many of the browser and ui tests fail. We do return the OTR profile
1135 // if the login-profile switch is passed so that we can test this.
1136 if (ShouldGoOffTheRecord(profile))
1137 return profile->GetOffTheRecordProfile();
1138 DCHECK(!user_manager::UserManager::Get()->IsLoggedInAsGuest());
1139 return profile;
1142 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1143 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
1144 // Fallback to default off-the-record profile, if user profile has not fully
1145 // loaded yet.
1146 if (profile_info && !profile_info->created)
1147 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1149 Profile* profile = GetProfile(default_profile_dir);
1150 // Some unit tests didn't initialize the UserManager.
1151 if (user_manager::UserManager::IsInitialized() &&
1152 user_manager::UserManager::Get()->IsLoggedInAsGuest())
1153 return profile->GetOffTheRecordProfile();
1154 return profile;
1155 #else
1156 base::FilePath default_profile_dir(user_data_dir);
1157 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1158 return GetProfile(default_profile_dir);
1159 #endif
1162 bool ProfileManager::AddProfile(Profile* profile) {
1163 TRACE_EVENT0("browser", "ProfileManager::AddProfile");
1164 TRACK_SCOPED_REGION("Startup", "ProfileManager::AddProfile");
1166 DCHECK(profile);
1168 // Make sure that we're not loading a profile with the same ID as a profile
1169 // that's already loaded.
1170 if (GetProfileByPathInternal(profile->GetPath())) {
1171 NOTREACHED() << "Attempted to add profile with the same path (" <<
1172 profile->GetPath().value() <<
1173 ") as an already-loaded profile.";
1174 return false;
1177 RegisterProfile(profile, true);
1178 InitProfileUserPrefs(profile);
1179 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
1180 return true;
1183 Profile* ProfileManager::CreateAndInitializeProfile(
1184 const base::FilePath& profile_dir) {
1185 TRACE_EVENT0("browser", "ProfileManager::CreateAndInitializeProfile");
1186 TRACK_SCOPED_REGION(
1187 "Startup", "ProfileManager::CreateAndInitializeProfile");
1188 SCOPED_UMA_HISTOGRAM_LONG_TIMER("Profile.CreateAndInitializeProfile");
1190 // CHECK that we are not trying to load the same profile twice, to prevent
1191 // profile corruption. Note that this check also covers the case when we have
1192 // already started loading the profile but it is not fully initialized yet,
1193 // which would make Bad Things happen if we returned it.
1194 CHECK(!GetProfileByPathInternal(profile_dir));
1195 Profile* profile = CreateProfileHelper(profile_dir);
1196 DCHECK(profile);
1197 if (profile) {
1198 bool result = AddProfile(profile);
1199 DCHECK(result);
1201 return profile;
1204 void ProfileManager::FinishDeletingProfile(
1205 const base::FilePath& profile_dir,
1206 const base::FilePath& new_active_profile_dir) {
1207 // Update the last used profile pref before closing browser windows. This
1208 // way the correct last used profile is set for any notification observers.
1209 PrefService* local_state = g_browser_process->local_state();
1210 DCHECK(local_state);
1211 local_state->SetString(prefs::kProfileLastUsed,
1212 new_active_profile_dir.BaseName().MaybeAsASCII());
1214 ProfileInfoCache& cache = GetProfileInfoCache();
1215 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1216 // start deleting the profile instance we need to close background apps too.
1217 Profile* profile = GetProfileByPath(profile_dir);
1219 if (profile) {
1220 // TODO: Migrate additional code in this block to observe this notification
1221 // instead of being implemented here.
1222 content::NotificationService::current()->Notify(
1223 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
1224 content::Source<Profile>(profile),
1225 content::NotificationService::NoDetails());
1227 // By this point, all in-progress downloads for the profile being deleted
1228 // must have been canceled (crbug.com/336725).
1229 DCHECK(DownloadServiceFactory::GetForBrowserContext(profile)->
1230 NonMaliciousDownloadCount() == 0);
1231 BrowserList::CloseAllBrowsersWithProfile(profile);
1233 // Disable sync for doomed profile.
1234 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1235 profile)) {
1236 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1237 profile)->DisableForUser();
1240 ProfileMetrics::LogProfileDelete(cache.ProfileIsAuthenticatedAtIndex(
1241 cache.GetIndexOfProfileWithPath(profile_dir)));
1242 // Some platforms store passwords in keychains. They should be removed.
1243 scoped_refptr<password_manager::PasswordStore> password_store =
1244 PasswordStoreFactory::GetForProfile(
1245 profile, ServiceAccessType::EXPLICIT_ACCESS).get();
1246 if (password_store.get()) {
1247 password_store->RemoveLoginsCreatedBetween(base::Time(),
1248 base::Time::Max());
1251 // The Profile Data doesn't get wiped until Chrome closes. Since we promised
1252 // that the user's data would be removed, do so immediately.
1253 profiles::RemoveBrowsingDataForProfile(profile_dir);
1254 } else {
1255 // It is safe to delete a not yet loaded Profile from disk.
1256 BrowserThread::PostTask(
1257 BrowserThread::FILE, FROM_HERE,
1258 base::Bind(&NukeProfileFromDisk, profile_dir));
1261 // Queue even a profile that was nuked so it will be MarkedForDeletion and so
1262 // CreateProfileAsync can't create it.
1263 QueueProfileDirectoryForDeletion(profile_dir);
1264 cache.DeleteProfileFromCache(profile_dir);
1265 ProfileMetrics::UpdateReportedProfilesStatistics(this);
1268 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
1269 Profile* profile,
1270 bool created) {
1271 TRACE_EVENT0("browser", "ProfileManager::RegisterProfile");
1272 ProfileInfo* info = new ProfileInfo(profile, created);
1273 profiles_info_.insert(
1274 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
1275 return info;
1278 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath(
1279 const base::FilePath& path) const {
1280 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
1281 return (iter == profiles_info_.end()) ? NULL : iter->second.get();
1284 void ProfileManager::AddProfileToCache(Profile* profile) {
1285 TRACE_EVENT0("browser", "ProfileManager::AddProfileToCache");
1286 if (profile->IsGuestSession() || profile->IsSystemProfile())
1287 return;
1288 ProfileInfoCache& cache = GetProfileInfoCache();
1289 if (profile->GetPath().DirName() != cache.GetUserDataDir())
1290 return;
1292 SigninManagerBase* signin_manager =
1293 SigninManagerFactory::GetForProfile(profile);
1294 AccountTrackerService* account_tracker =
1295 AccountTrackerServiceFactory::GetForProfile(profile);
1296 AccountTrackerService::AccountInfo account_info =
1297 account_tracker->GetAccountInfo(
1298 signin_manager->GetAuthenticatedAccountId());
1299 base::string16 username = base::UTF8ToUTF16(account_info.email);
1301 size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
1302 if (profile_index != std::string::npos) {
1303 // The ProfileInfoCache's info must match the Signin Manager.
1304 cache.SetAuthInfoOfProfileAtIndex(profile_index, account_info.gaia,
1305 username);
1306 return;
1309 // Profile name and avatar are set by InitProfileUserPrefs and stored in the
1310 // profile. Use those values to setup the cache entry.
1311 base::string16 profile_name =
1312 base::UTF8ToUTF16(profile->GetPrefs()->GetString(prefs::kProfileName));
1314 size_t icon_index = profile->GetPrefs()->GetInteger(
1315 prefs::kProfileAvatarIndex);
1317 std::string supervised_user_id =
1318 profile->GetPrefs()->GetString(prefs::kSupervisedUserId);
1320 cache.AddProfileToCache(profile->GetPath(),
1321 profile_name,
1322 account_info.gaia,
1323 username,
1324 icon_index,
1325 supervised_user_id);
1327 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) {
1328 cache.SetProfileIsEphemeralAtIndex(
1329 cache.GetIndexOfProfileWithPath(profile->GetPath()), true);
1333 void ProfileManager::SetNonPersonalProfilePrefs(Profile* profile) {
1334 PrefService* prefs = profile->GetPrefs();
1335 prefs->SetBoolean(prefs::kSigninAllowed, false);
1336 prefs->SetBoolean(bookmarks::prefs::kEditBookmarksEnabled, false);
1337 prefs->SetBoolean(bookmarks::prefs::kShowBookmarkBar, false);
1338 prefs->ClearPref(DefaultSearchManager::kDefaultSearchProviderDataPrefName);
1341 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) {
1342 #if defined(OS_CHROMEOS)
1343 if (profile->GetPath().BaseName().value() == chrome::kInitialProfile) {
1344 return true;
1346 #endif
1347 return profile->IsGuestSession() || profile->IsSystemProfile();
1350 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks,
1351 Profile* profile,
1352 Profile::CreateStatus status) {
1353 for (size_t i = 0; i < callbacks.size(); ++i)
1354 callbacks[i].Run(profile, status);
1357 ProfileManager::ProfileInfo::ProfileInfo(
1358 Profile* profile,
1359 bool created)
1360 : profile(profile),
1361 created(created) {
1364 ProfileManager::ProfileInfo::~ProfileInfo() {
1365 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1368 #if !defined(OS_ANDROID) && !defined(OS_IOS)
1369 void ProfileManager::UpdateLastUser(Profile* last_active) {
1370 PrefService* local_state = g_browser_process->local_state();
1371 DCHECK(local_state);
1372 // Only keep track of profiles that we are managing; tests may create others.
1373 // Also never consider the SystemProfile as "active".
1374 if (profiles_info_.find(last_active->GetPath()) != profiles_info_.end() &&
1375 !last_active->IsSystemProfile()) {
1376 std::string profile_path_base =
1377 last_active->GetPath().BaseName().MaybeAsASCII();
1378 if (profile_path_base != GetLastUsedProfileName())
1379 local_state->SetString(prefs::kProfileLastUsed, profile_path_base);
1381 ProfileInfoCache& cache = GetProfileInfoCache();
1382 size_t profile_index =
1383 cache.GetIndexOfProfileWithPath(last_active->GetPath());
1384 if (profile_index != std::string::npos) {
1385 #if !defined(OS_CHROMEOS)
1386 // Incognito Profiles don't have ProfileKeyedServices.
1387 if (!last_active->IsOffTheRecord()) {
1388 CrossDevicePromoFactory::GetForProfile(last_active)
1389 ->MaybeBrowsingSessionStarted(
1390 cache.GetProfileActiveTimeAtIndex(profile_index));
1392 #endif
1393 cache.SetProfileActiveTimeAtIndex(profile_index);
1398 ProfileManager::BrowserListObserver::BrowserListObserver(
1399 ProfileManager* manager)
1400 : profile_manager_(manager) {
1401 BrowserList::AddObserver(this);
1404 ProfileManager::BrowserListObserver::~BrowserListObserver() {
1405 BrowserList::RemoveObserver(this);
1408 void ProfileManager::BrowserListObserver::OnBrowserAdded(
1409 Browser* browser) {}
1411 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
1412 Browser* browser) {
1413 Profile* profile = browser->profile();
1414 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1415 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1416 // Not the last window for this profile.
1417 return;
1420 // If the last browser of a profile that is scheduled for deletion is closed
1421 // do that now.
1422 base::FilePath path = profile->GetPath();
1423 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
1424 !IsProfileMarkedForDeletion(path)) {
1425 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
1426 path, ProfileManager::CreateCallback());
1430 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
1431 Browser* browser) {
1432 // If all browsers are being closed (e.g. the user is in the process of
1433 // shutting down), this event will be fired after each browser is
1434 // closed. This does not represent a user intention to change the active
1435 // browser so is not handled here.
1436 if (profile_manager_->closing_all_browsers_)
1437 return;
1439 Profile* last_active = browser->profile();
1441 // Don't remember ephemeral profiles as last because they are not going to
1442 // persist after restart.
1443 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
1444 return;
1446 profile_manager_->UpdateLastUser(last_active);
1448 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
1450 void ProfileManager::OnNewActiveProfileLoaded(
1451 const base::FilePath& profile_to_delete_path,
1452 const base::FilePath& new_active_profile_path,
1453 const CreateCallback& original_callback,
1454 Profile* loaded_profile,
1455 Profile::CreateStatus status) {
1456 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
1457 status != Profile::CREATE_STATUS_REMOTE_FAIL);
1459 // Only run the code if the profile initialization has finished completely.
1460 if (status != Profile::CREATE_STATUS_INITIALIZED)
1461 return;
1463 if (IsProfileMarkedForDeletion(new_active_profile_path)) {
1464 // If the profile we tried to load as the next active profile has been
1465 // deleted, then retry deleting this profile to redo the logic to load
1466 // the next available profile.
1467 ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
1468 return;
1471 FinishDeletingProfile(profile_to_delete_path, new_active_profile_path);
1472 if (!original_callback.is_null())
1473 original_callback.Run(loaded_profile, status);
1476 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1477 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) {