[Presentation API, Android] Implement basic messaging
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager.cc
blob67acac17bb9292879caed2b9e2b9722271896fc3
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/bookmarks/startup_task_runner_service_factory.h"
25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/download/download_service.h"
28 #include "chrome/browser/download/download_service_factory.h"
29 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
30 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
31 #include "chrome/browser/password_manager/password_store_factory.h"
32 #include "chrome/browser/prefs/incognito_mode_prefs.h"
33 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
34 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
35 #include "chrome/browser/profiles/profile_destroyer.h"
36 #include "chrome/browser/profiles/profile_info_cache.h"
37 #include "chrome/browser/profiles/profile_metrics.h"
38 #include "chrome/browser/profiles/profiles_state.h"
39 #include "chrome/browser/signin/account_fetcher_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/bookmarks/browser/startup_task_runner_service.h"
60 #include "components/content_settings/core/browser/host_content_settings_map.h"
61 #include "components/password_manager/core/browser/password_store.h"
62 #include "components/signin/core/browser/account_fetcher_service.h"
63 #include "components/signin/core/browser/account_tracker_service.h"
64 #include "components/signin/core/browser/gaia_cookie_manager_service.h"
65 #include "components/signin/core/browser/signin_manager.h"
66 #include "components/signin/core/common/profile_management_switches.h"
67 #include "content/public/browser/browser_thread.h"
68 #include "content/public/browser/notification_service.h"
69 #include "content/public/browser/user_metrics.h"
70 #include "net/http/http_transaction_factory.h"
71 #include "net/url_request/url_request_context.h"
72 #include "net/url_request/url_request_context_getter.h"
73 #include "net/url_request/url_request_job.h"
74 #include "ui/base/l10n/l10n_util.h"
76 #if defined(ENABLE_EXTENSIONS)
77 #include "chrome/browser/extensions/extension_service.h"
78 #include "extensions/browser/extension_registry.h"
79 #include "extensions/browser/extension_system.h"
80 #include "extensions/common/extension_set.h"
81 #include "extensions/common/manifest.h"
82 #endif
84 #if defined(ENABLE_SUPERVISED_USERS)
85 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
86 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
87 #include "chrome/browser/supervised_user/supervised_user_service.h"
88 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
89 #endif
91 #if !defined(OS_IOS)
92 #include "chrome/browser/sessions/session_service_factory.h"
93 #include "chrome/browser/ui/browser_list.h"
94 #endif // !defined (OS_IOS)
96 #if defined(OS_WIN)
97 #include "base/win/metro.h"
98 #include "chrome/installer/util/browser_distribution.h"
99 #endif
101 #if defined(OS_CHROMEOS)
102 #include "chrome/browser/browser_process_platform_part_chromeos.h"
103 #include "chrome/browser/chromeos/profiles/profile_helper.h"
104 #include "chromeos/chromeos_switches.h"
105 #include "chromeos/dbus/cryptohome_client.h"
106 #include "chromeos/dbus/dbus_thread_manager.h"
107 #include "components/user_manager/user.h"
108 #include "components/user_manager/user_manager.h"
109 #endif
111 using base::UserMetricsAction;
112 using content::BrowserThread;
114 namespace {
116 // Profiles that should be deleted on shutdown.
117 std::vector<base::FilePath>& ProfilesToDelete() {
118 CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ());
119 return profiles_to_delete;
122 int64 ComputeFilesSize(const base::FilePath& directory,
123 const base::FilePath::StringType& pattern) {
124 int64 running_size = 0;
125 base::FileEnumerator iter(directory, false, base::FileEnumerator::FILES,
126 pattern);
127 while (!iter.Next().empty())
128 running_size += iter.GetInfo().GetSize();
129 return running_size;
132 // Simple task to log the size of the current profile.
133 void ProfileSizeTask(const base::FilePath& path, int enabled_app_count) {
134 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
135 const int64 kBytesInOneMB = 1024 * 1024;
137 int64 size = ComputeFilesSize(path, FILE_PATH_LITERAL("*"));
138 int size_MB = static_cast<int>(size / kBytesInOneMB);
139 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB);
141 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History"));
142 size_MB = static_cast<int>(size / kBytesInOneMB);
143 UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB);
145 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History*"));
146 size_MB = static_cast<int>(size / kBytesInOneMB);
147 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB);
149 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Cookies"));
150 size_MB = static_cast<int>(size / kBytesInOneMB);
151 UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB);
153 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Bookmarks"));
154 size_MB = static_cast<int>(size / kBytesInOneMB);
155 UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB);
157 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Favicons"));
158 size_MB = static_cast<int>(size / kBytesInOneMB);
159 UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB);
161 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Top Sites"));
162 size_MB = static_cast<int>(size / kBytesInOneMB);
163 UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB);
165 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Visited Links"));
166 size_MB = static_cast<int>(size / kBytesInOneMB);
167 UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB);
169 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Web Data"));
170 size_MB = static_cast<int>(size / kBytesInOneMB);
171 UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB);
173 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Extension*"));
174 size_MB = static_cast<int>(size / kBytesInOneMB);
175 UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB);
177 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Policy"));
178 size_MB = static_cast<int>(size / kBytesInOneMB);
179 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB);
181 // Count number of enabled apps in this profile, if we know.
182 if (enabled_app_count != -1)
183 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count);
186 void QueueProfileDirectoryForDeletion(const base::FilePath& path) {
187 ProfilesToDelete().push_back(path);
190 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) {
191 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
192 profile_path) != ProfilesToDelete().end();
195 // Physically remove deleted profile directories from disk.
196 void NukeProfileFromDisk(const base::FilePath& profile_path) {
197 // Delete both the profile directory and its corresponding cache.
198 base::FilePath cache_path;
199 chrome::GetUserCacheDirectory(profile_path, &cache_path);
200 base::DeleteFile(profile_path, true);
201 base::DeleteFile(cache_path, true);
204 #if defined(OS_CHROMEOS)
205 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status,
206 bool is_mounted) {
207 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
208 LOG(ERROR) << "IsMounted call failed.";
209 return;
211 if (!is_mounted)
212 LOG(ERROR) << "Cryptohome is not mounted.";
215 #endif
217 #if defined(ENABLE_EXTENSIONS)
219 // Returns the number of installed (and enabled) apps, excluding any component
220 // apps.
221 size_t GetEnabledAppCount(Profile* profile) {
222 size_t installed_apps = 0u;
223 const extensions::ExtensionSet& extensions =
224 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
225 for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
226 iter != extensions.end();
227 ++iter) {
228 if ((*iter)->is_app() &&
229 (*iter)->location() != extensions::Manifest::COMPONENT) {
230 ++installed_apps;
233 return installed_apps;
236 #endif // ENABLE_EXTENSIONS
238 } // namespace
240 ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
241 : user_data_dir_(user_data_dir),
242 logged_in_(false),
243 #if !defined(OS_ANDROID) && !defined(OS_IOS)
244 browser_list_observer_(this),
245 #endif
246 closing_all_browsers_(false) {
247 #if defined(OS_CHROMEOS)
248 registrar_.Add(
249 this,
250 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
251 content::NotificationService::AllSources());
252 #endif
253 registrar_.Add(
254 this,
255 chrome::NOTIFICATION_BROWSER_OPENED,
256 content::NotificationService::AllSources());
257 registrar_.Add(
258 this,
259 chrome::NOTIFICATION_BROWSER_CLOSED,
260 content::NotificationService::AllSources());
261 registrar_.Add(
262 this,
263 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
264 content::NotificationService::AllSources());
265 registrar_.Add(
266 this,
267 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
268 content::NotificationService::AllSources());
270 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty())
271 profile_shortcut_manager_.reset(ProfileShortcutManager::Create(
272 this));
275 ProfileManager::~ProfileManager() {
278 #if defined(ENABLE_SESSION_SERVICE)
279 // static
280 void ProfileManager::ShutdownSessionServices() {
281 ProfileManager* pm = g_browser_process->profile_manager();
282 if (!pm) // Is NULL when running unit tests.
283 return;
284 std::vector<Profile*> profiles(pm->GetLoadedProfiles());
285 for (size_t i = 0; i < profiles.size(); ++i)
286 SessionServiceFactory::ShutdownForProfile(profiles[i]);
288 #endif
290 // static
291 void ProfileManager::NukeDeletedProfilesFromDisk() {
292 for (std::vector<base::FilePath>::iterator it =
293 ProfilesToDelete().begin();
294 it != ProfilesToDelete().end();
295 ++it) {
296 NukeProfileFromDisk(*it);
298 ProfilesToDelete().clear();
301 // static
302 Profile* ProfileManager::GetLastUsedProfile() {
303 ProfileManager* profile_manager = g_browser_process->profile_manager();
304 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_);
307 // static
308 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
309 Profile* profile = GetLastUsedProfile();
310 if (profile->IsGuestSession() ||
311 profile->IsSystemProfile() ||
312 IncognitoModePrefs::GetAvailability(profile->GetPrefs()) ==
313 IncognitoModePrefs::FORCED) {
314 return profile->GetOffTheRecordProfile();
316 return profile;
319 // static
320 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() {
321 ProfileManager* profile_manager = g_browser_process->profile_manager();
322 return profile_manager->GetLastOpenedProfiles(
323 profile_manager->user_data_dir_);
326 // static
327 Profile* ProfileManager::GetPrimaryUserProfile() {
328 ProfileManager* profile_manager = g_browser_process->profile_manager();
329 #if defined(OS_CHROMEOS)
330 if (!profile_manager->IsLoggedIn() ||
331 !user_manager::UserManager::IsInitialized())
332 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
333 profile_manager->user_data_dir());
334 user_manager::UserManager* manager = user_manager::UserManager::Get();
335 // Note: The ProfileHelper will take care of guest profiles.
336 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
337 manager->GetPrimaryUser());
338 #else
339 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
340 profile_manager->user_data_dir());
341 #endif
344 // static
345 Profile* ProfileManager::GetActiveUserProfile() {
346 ProfileManager* profile_manager = g_browser_process->profile_manager();
347 #if defined(OS_CHROMEOS)
348 if (!profile_manager)
349 return NULL;
351 if (!profile_manager->IsLoggedIn() ||
352 !user_manager::UserManager::IsInitialized()) {
353 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
354 profile_manager->user_data_dir());
357 user_manager::UserManager* manager = user_manager::UserManager::Get();
358 const user_manager::User* user = manager->GetActiveUser();
359 // To avoid an endless loop (crbug.com/334098) we have to additionally check
360 // if the profile of the user was already created. If the profile was not yet
361 // created we load the profile using the profile directly.
362 // TODO: This should be cleaned up with the new profile manager.
363 if (user && user->is_profile_created())
364 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user);
366 #endif
367 Profile* profile =
368 profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
369 profile_manager->user_data_dir());
370 // |profile| could be null if the user doesn't have a profile yet and the path
371 // is on a read-only volume (preventing Chrome from making a new one).
372 // However, most callers of this function immediately dereference the result
373 // which would lead to crashes in a variety of call sites. Assert here to
374 // figure out how common this is. http://crbug.com/383019
375 CHECK(profile) << profile_manager->user_data_dir().AsUTF8Unsafe();
376 return profile;
379 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) {
380 TRACE_EVENT0("browser", "ProfileManager::GetProfile");
382 // If the profile is already loaded (e.g., chrome.exe launched twice), just
383 // return it.
384 Profile* profile = GetProfileByPath(profile_dir);
385 if (profile)
386 return profile;
387 return CreateAndInitializeProfile(profile_dir);
390 size_t ProfileManager::GetNumberOfProfiles() {
391 return GetProfileInfoCache().GetNumberOfProfiles();
394 void ProfileManager::CreateProfileAsync(
395 const base::FilePath& profile_path,
396 const CreateCallback& callback,
397 const base::string16& name,
398 const base::string16& icon_url,
399 const std::string& supervised_user_id) {
400 DCHECK_CURRENTLY_ON(BrowserThread::UI);
401 TRACE_EVENT1("browser,startup",
402 "ProfileManager::CreateProfileAsync",
403 "profile_path",
404 profile_path.AsUTF8Unsafe());
406 // Make sure that this profile is not pending deletion.
407 if (IsProfileMarkedForDeletion(profile_path)) {
408 if (!callback.is_null())
409 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
410 return;
413 // Create the profile if needed and collect its ProfileInfo.
414 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
415 ProfileInfo* info = NULL;
417 if (iter != profiles_info_.end()) {
418 info = iter->second.get();
419 } else {
420 // Initiate asynchronous creation process.
421 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false);
422 ProfileInfoCache& cache = GetProfileInfoCache();
423 // Get the icon index from the user's icon url
424 size_t icon_index;
425 std::string icon_url_std = base::UTF16ToASCII(icon_url);
426 if (profiles::IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) {
427 // add profile to cache with user selected name and avatar
428 cache.AddProfileToCache(profile_path, name, std::string(),
429 base::string16(), icon_index, supervised_user_id);
432 if (!supervised_user_id.empty()) {
433 content::RecordAction(
434 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
437 ProfileMetrics::UpdateReportedProfilesStatistics(this);
440 // Call or enqueue the callback.
441 if (!callback.is_null()) {
442 if (iter != profiles_info_.end() && info->created) {
443 Profile* profile = info->profile.get();
444 // If this was the guest profile, apply settings and go OffTheRecord.
445 // The system profile also needs characteristics of being off the record,
446 // such as having no extensions, not writing to disk, etc.
447 if (profile->IsGuestSession() || profile->IsSystemProfile()) {
448 SetNonPersonalProfilePrefs(profile);
449 profile = profile->GetOffTheRecordProfile();
451 // Profile has already been created. Run callback immediately.
452 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
453 } else {
454 // Profile is either already in the process of being created, or new.
455 // Add callback to the list.
456 info->callbacks.push_back(callback);
461 bool ProfileManager::IsValidProfile(Profile* profile) {
462 for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
463 iter != profiles_info_.end(); ++iter) {
464 if (iter->second->created) {
465 Profile* candidate = iter->second->profile.get();
466 if (candidate == profile ||
467 (candidate->HasOffTheRecordProfile() &&
468 candidate->GetOffTheRecordProfile() == profile)) {
469 return true;
473 return false;
476 base::FilePath ProfileManager::GetInitialProfileDir() {
477 #if defined(OS_CHROMEOS)
478 if (logged_in_) {
479 return chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
481 #endif
482 base::FilePath relative_profile_dir;
483 // TODO(mirandac): should not automatically be default profile.
484 return relative_profile_dir.AppendASCII(chrome::kInitialProfile);
487 Profile* ProfileManager::GetLastUsedProfile(
488 const base::FilePath& user_data_dir) {
489 #if defined(OS_CHROMEOS)
490 // Use default login profile if user has not logged in yet.
491 if (!logged_in_) {
492 return GetActiveUserOrOffTheRecordProfileFromPath(user_data_dir);
493 } else {
494 // CrOS multi-profiles implementation is different so GetLastUsedProfile
495 // has custom implementation too.
496 base::FilePath profile_dir;
497 // In case of multi-profiles we ignore "last used profile" preference
498 // since it may refer to profile that has been in use in previous session.
499 // That profile dir may not be mounted in this session so instead return
500 // active profile from current session.
501 profile_dir = chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
503 base::FilePath profile_path(user_data_dir);
504 Profile* profile = GetProfile(profile_path.Append(profile_dir));
505 return profile->IsGuestSession() ? profile->GetOffTheRecordProfile() :
506 profile;
508 #endif
510 return GetProfile(GetLastUsedProfileDir(user_data_dir));
513 base::FilePath ProfileManager::GetLastUsedProfileDir(
514 const base::FilePath& user_data_dir) {
515 return user_data_dir.AppendASCII(GetLastUsedProfileName());
518 std::string ProfileManager::GetLastUsedProfileName() {
519 PrefService* local_state = g_browser_process->local_state();
520 DCHECK(local_state);
521 const std::string last_used_profile_name =
522 local_state->GetString(prefs::kProfileLastUsed);
523 // Make sure the system profile can't be the one marked as the last one used
524 // since it shouldn't get a browser.
525 if (!last_used_profile_name.empty() &&
526 last_used_profile_name !=
527 base::FilePath(chrome::kSystemProfileDir).AsUTF8Unsafe()) {
528 return last_used_profile_name;
531 return chrome::kInitialProfile;
534 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles(
535 const base::FilePath& user_data_dir) {
536 PrefService* local_state = g_browser_process->local_state();
537 DCHECK(local_state);
539 std::vector<Profile*> to_return;
540 if (local_state->HasPrefPath(prefs::kProfilesLastActive) &&
541 local_state->GetList(prefs::kProfilesLastActive)) {
542 // Make a copy because the list might change in the calls to GetProfile.
543 scoped_ptr<base::ListValue> profile_list(
544 local_state->GetList(prefs::kProfilesLastActive)->DeepCopy());
545 base::ListValue::const_iterator it;
546 std::string profile;
547 for (it = profile_list->begin(); it != profile_list->end(); ++it) {
548 if (!(*it)->GetAsString(&profile) || profile.empty() ||
549 profile == base::FilePath(chrome::kSystemProfileDir).AsUTF8Unsafe()) {
550 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive;
551 continue;
553 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile)));
556 return to_return;
559 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const {
560 std::vector<Profile*> profiles;
561 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin();
562 iter != profiles_info_.end(); ++iter) {
563 if (iter->second->created)
564 profiles.push_back(iter->second->profile.get());
566 return profiles;
569 Profile* ProfileManager::GetProfileByPathInternal(
570 const base::FilePath& path) const {
571 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPathInternal");
572 ProfileInfo* profile_info = GetProfileInfoByPath(path);
573 return profile_info ? profile_info->profile.get() : nullptr;
576 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const {
577 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath");
578 ProfileInfo* profile_info = GetProfileInfoByPath(path);
579 return (profile_info && profile_info->created) ? profile_info->profile.get()
580 : nullptr;
583 // static
584 base::FilePath ProfileManager::CreateMultiProfileAsync(
585 const base::string16& name,
586 const base::string16& icon_url,
587 const CreateCallback& callback,
588 const std::string& supervised_user_id) {
589 DCHECK_CURRENTLY_ON(BrowserThread::UI);
591 ProfileManager* profile_manager = g_browser_process->profile_manager();
593 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
595 profile_manager->CreateProfileAsync(new_path,
596 callback,
597 name,
598 icon_url,
599 supervised_user_id);
600 return new_path;
603 // static
604 base::FilePath ProfileManager::GetGuestProfilePath() {
605 DCHECK_CURRENTLY_ON(BrowserThread::UI);
607 ProfileManager* profile_manager = g_browser_process->profile_manager();
609 base::FilePath guest_path = profile_manager->user_data_dir();
610 return guest_path.Append(chrome::kGuestProfileDir);
613 // static
614 base::FilePath ProfileManager::GetSystemProfilePath() {
615 DCHECK_CURRENTLY_ON(BrowserThread::UI);
617 ProfileManager* profile_manager = g_browser_process->profile_manager();
619 base::FilePath system_path = profile_manager->user_data_dir();
620 return system_path.Append(chrome::kSystemProfileDir);
623 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() {
624 PrefService* local_state = g_browser_process->local_state();
625 DCHECK(local_state);
627 DCHECK(profiles::IsMultipleProfilesEnabled());
629 // Create the next profile in the next available directory slot.
630 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated);
631 std::string profile_name = chrome::kMultiProfileDirPrefix;
632 profile_name.append(base::IntToString(next_directory));
633 base::FilePath new_path = user_data_dir_;
634 #if defined(OS_WIN)
635 new_path = new_path.Append(base::ASCIIToUTF16(profile_name));
636 #else
637 new_path = new_path.Append(profile_name);
638 #endif
639 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory);
640 return new_path;
643 ProfileInfoCache& ProfileManager::GetProfileInfoCache() {
644 TRACE_EVENT0("browser", "ProfileManager::GetProfileInfoCache");
645 if (!profile_info_cache_) {
646 profile_info_cache_.reset(new ProfileInfoCache(
647 g_browser_process->local_state(), user_data_dir_));
649 return *profile_info_cache_.get();
652 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
653 return profile_shortcut_manager_.get();
656 void ProfileManager::ScheduleProfileForDeletion(
657 const base::FilePath& profile_dir,
658 const CreateCallback& callback) {
659 DCHECK(profiles::IsMultipleProfilesEnabled());
661 // Cancel all in-progress downloads before deleting the profile to prevent a
662 // "Do you want to exit Google Chrome and cancel the downloads?" prompt
663 // (crbug.com/336725).
664 Profile* profile = GetProfileByPath(profile_dir);
665 if (profile) {
666 DownloadService* service =
667 DownloadServiceFactory::GetForBrowserContext(profile);
668 service->CancelDownloads();
671 ProfileInfoCache& cache = GetProfileInfoCache();
673 // If we're deleting the last (non-legacy-supervised) profile, then create a
674 // new profile in its place.
675 base::FilePath last_non_supervised_profile_path;
676 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
677 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
678 // Make sure that this profile is not pending deletion, and is not
679 // legacy-supervised.
680 if (cur_path != profile_dir &&
681 !cache.ProfileIsLegacySupervisedAtIndex(i) &&
682 !IsProfileMarkedForDeletion(cur_path)) {
683 last_non_supervised_profile_path = cur_path;
684 break;
688 base::FilePath new_path;
689 if (last_non_supervised_profile_path.empty()) {
690 // If we are using --new-avatar-menu, then assign the default
691 // placeholder avatar and name. Otherwise, use random ones.
692 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
693 int avatar_index = profiles::GetPlaceholderAvatarIndex();
694 base::string16 new_avatar_url = is_new_avatar_menu ?
695 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(avatar_index)) :
696 base::string16();
697 base::string16 new_profile_name = is_new_avatar_menu ?
698 cache.ChooseNameForNewProfile(avatar_index) : base::string16();
700 new_path = GenerateNextProfileDirectoryPath();
701 CreateProfileAsync(new_path,
702 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
703 base::Unretained(this),
704 profile_dir,
705 new_path,
706 callback),
707 new_profile_name,
708 new_avatar_url,
709 std::string());
711 ProfileMetrics::LogProfileAddNewUser(
712 ProfileMetrics::ADD_NEW_USER_LAST_DELETED);
713 return;
716 #if defined(OS_MACOSX)
717 // On the Mac, the browser process is not killed when all browser windows are
718 // closed, so just in case we are deleting the active profile, and no other
719 // profile has been loaded, we must pre-load a next one.
720 const base::FilePath last_used_profile =
721 GetLastUsedProfileDir(user_data_dir_);
722 if (last_used_profile == profile_dir ||
723 last_used_profile == GetGuestProfilePath()) {
724 CreateProfileAsync(last_non_supervised_profile_path,
725 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
726 base::Unretained(this),
727 profile_dir,
728 last_non_supervised_profile_path,
729 callback),
730 base::string16(),
731 base::string16(),
732 std::string());
733 return;
735 #endif // defined(OS_MACOSX)
737 FinishDeletingProfile(profile_dir, last_non_supervised_profile_path);
740 void ProfileManager::AutoloadProfiles() {
741 // If running in the background is disabled for the browser, do not autoload
742 // any profiles.
743 PrefService* local_state = g_browser_process->local_state();
744 DCHECK(local_state);
745 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
746 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
747 return;
750 ProfileInfoCache& cache = GetProfileInfoCache();
751 size_t number_of_profiles = cache.GetNumberOfProfiles();
752 for (size_t p = 0; p < number_of_profiles; ++p) {
753 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) {
754 // If status is true, that profile is running background apps. By calling
755 // GetProfile, we automatically cause the profile to be loaded which will
756 // register it with the BackgroundModeManager.
757 GetProfile(cache.GetPathOfProfileAtIndex(p));
762 void ProfileManager::CleanUpEphemeralProfiles() {
763 const std::string last_used_profile = GetLastUsedProfileName();
765 bool last_active_profile_deleted = false;
766 base::FilePath new_profile_path;
767 std::vector<base::FilePath> profiles_to_delete;
768 ProfileInfoCache& profile_cache = GetProfileInfoCache();
769 size_t profiles_count = profile_cache.GetNumberOfProfiles();
770 for (size_t i = 0; i < profiles_count; ++i) {
771 base::FilePath profile_path = profile_cache.GetPathOfProfileAtIndex(i);
772 if (profile_cache.ProfileIsEphemeralAtIndex(i)) {
773 profiles_to_delete.push_back(profile_path);
774 if (profile_path.BaseName().MaybeAsASCII() == last_used_profile)
775 last_active_profile_deleted = true;
776 } else if (new_profile_path.empty()) {
777 new_profile_path = profile_path;
781 // If the last active profile was ephemeral, set a new one.
782 if (last_active_profile_deleted) {
783 if (new_profile_path.empty())
784 new_profile_path = GenerateNextProfileDirectoryPath();
786 profiles::SetLastUsedProfile(new_profile_path.BaseName().MaybeAsASCII());
789 // This uses a separate loop, because deleting the profile from the
790 // ProfileInfoCache will modify indices.
791 for (const base::FilePath& profile_path : profiles_to_delete) {
792 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
793 base::Bind(&NukeProfileFromDisk, profile_path));
795 profile_cache.DeleteProfileFromCache(profile_path);
799 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
800 TRACE_EVENT0("browser", "ProfileManager::InitProfileUserPrefs");
801 ProfileInfoCache& cache = GetProfileInfoCache();
803 if (profile->GetPath().DirName() != cache.GetUserDataDir())
804 return;
806 size_t avatar_index;
807 std::string profile_name;
808 std::string supervised_user_id;
809 if (profile->IsGuestSession()) {
810 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
811 avatar_index = 0;
812 } else {
813 size_t profile_cache_index =
814 cache.GetIndexOfProfileWithPath(profile->GetPath());
815 // If the cache has an entry for this profile, use the cache data.
816 if (profile_cache_index != std::string::npos) {
817 avatar_index =
818 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
819 profile_name =
820 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
821 supervised_user_id =
822 cache.GetSupervisedUserIdOfProfileAtIndex(profile_cache_index);
823 } else if (profile->GetPath() ==
824 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
825 // The --new-avatar-menu flag no longer uses the "First User" name.
826 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
827 avatar_index = profiles::GetPlaceholderAvatarIndex();
828 profile_name = is_new_avatar_menu ?
829 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)) :
830 l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
831 } else {
832 avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
833 profile_name =
834 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
838 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
839 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
841 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
842 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
844 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
845 bool force_supervised_user_id =
846 #if defined(OS_CHROMEOS)
847 g_browser_process->platform_part()
848 ->profile_helper()
849 ->GetSigninProfileDir() != profile->GetPath() &&
850 #endif
851 command_line->HasSwitch(switches::kSupervisedUserId);
852 if (force_supervised_user_id) {
853 supervised_user_id =
854 command_line->GetSwitchValueASCII(switches::kSupervisedUserId);
856 if (force_supervised_user_id ||
857 !profile->GetPrefs()->HasPrefPath(prefs::kSupervisedUserId)) {
858 profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
859 supervised_user_id);
863 void ProfileManager::RegisterTestingProfile(Profile* profile,
864 bool add_to_cache,
865 bool start_deferred_task_runners) {
866 RegisterProfile(profile, true);
867 if (add_to_cache) {
868 InitProfileUserPrefs(profile);
869 AddProfileToCache(profile);
871 if (start_deferred_task_runners) {
872 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
873 StartDeferredTaskRunners();
877 void ProfileManager::Observe(
878 int type,
879 const content::NotificationSource& source,
880 const content::NotificationDetails& details) {
881 #if defined(OS_CHROMEOS)
882 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
883 logged_in_ = true;
885 const base::CommandLine& command_line =
886 *base::CommandLine::ForCurrentProcess();
887 if (!command_line.HasSwitch(switches::kTestType)) {
888 // If we don't have a mounted profile directory we're in trouble.
889 // TODO(davemoore) Once we have better api this check should ensure that
890 // our profile directory is the one that's mounted, and that it's mounted
891 // as the current user.
892 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
893 base::Bind(&CheckCryptohomeIsMounted));
895 // Confirm that we hadn't loaded the new profile previously.
896 base::FilePath default_profile_dir = user_data_dir_.Append(
897 GetInitialProfileDir());
898 CHECK(!GetProfileByPathInternal(default_profile_dir))
899 << "The default profile was loaded before we mounted the cryptohome.";
901 return;
903 #endif
904 bool save_active_profiles = false;
905 switch (type) {
906 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: {
907 // Ignore any browsers closing from now on.
908 closing_all_browsers_ = true;
909 save_active_profiles = true;
910 break;
912 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: {
913 // This will cancel the shutdown process, so the active profiles are
914 // tracked again. Also, as the active profiles may have changed (i.e. if
915 // some windows were closed) we save the current list of active profiles
916 // again.
917 closing_all_browsers_ = false;
918 save_active_profiles = true;
919 break;
921 case chrome::NOTIFICATION_BROWSER_OPENED: {
922 Browser* browser = content::Source<Browser>(source).ptr();
923 DCHECK(browser);
924 Profile* profile = browser->profile();
925 DCHECK(profile);
926 bool is_ephemeral =
927 profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles);
928 if (!profile->IsOffTheRecord() && !is_ephemeral &&
929 ++browser_counts_[profile] == 1) {
930 active_profiles_.push_back(profile);
931 save_active_profiles = true;
933 // If browsers are opening, we can't be closing all the browsers. This
934 // can happen if the application was exited, but background mode or
935 // packaged apps prevented the process from shutting down, and then
936 // a new browser window was opened.
937 closing_all_browsers_ = false;
938 break;
940 case chrome::NOTIFICATION_BROWSER_CLOSED: {
941 Browser* browser = content::Source<Browser>(source).ptr();
942 DCHECK(browser);
943 Profile* profile = browser->profile();
944 DCHECK(profile);
945 if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) {
946 active_profiles_.erase(std::find(active_profiles_.begin(),
947 active_profiles_.end(), profile));
948 save_active_profiles = !closing_all_browsers_;
950 break;
952 default: {
953 NOTREACHED();
954 break;
958 if (save_active_profiles) {
959 PrefService* local_state = g_browser_process->local_state();
960 DCHECK(local_state);
961 ListPrefUpdate update(local_state, prefs::kProfilesLastActive);
962 base::ListValue* profile_list = update.Get();
964 profile_list->Clear();
966 // crbug.com/120112 -> several non-incognito profiles might have the same
967 // GetPath().BaseName(). In that case, we cannot restore both
968 // profiles. Include each base name only once in the last active profile
969 // list.
970 std::set<std::string> profile_paths;
971 std::vector<Profile*>::const_iterator it;
972 for (it = active_profiles_.begin(); it != active_profiles_.end(); ++it) {
973 std::string profile_path = (*it)->GetPath().BaseName().MaybeAsASCII();
974 // Some profiles might become ephemeral after they are created.
975 // Don't persist the System Profile as one of the last actives, it should
976 // never get a browser.
977 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
978 profile_paths.find(profile_path) == profile_paths.end() &&
979 profile_path !=
980 base::FilePath(chrome::kSystemProfileDir).AsUTF8Unsafe()) {
981 profile_paths.insert(profile_path);
982 profile_list->Append(new base::StringValue(profile_path));
988 void ProfileManager::OnProfileCreated(Profile* profile,
989 bool success,
990 bool is_new_profile) {
991 DCHECK_CURRENTLY_ON(BrowserThread::UI);
993 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath());
994 DCHECK(iter != profiles_info_.end());
995 ProfileInfo* info = iter->second.get();
997 std::vector<CreateCallback> callbacks;
998 info->callbacks.swap(callbacks);
1000 // Invoke CREATED callback for normal profiles.
1001 bool go_off_the_record = ShouldGoOffTheRecord(profile);
1002 if (success && !go_off_the_record)
1003 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
1005 // Perform initialization.
1006 if (success) {
1007 DoFinalInit(profile, go_off_the_record);
1008 if (go_off_the_record)
1009 profile = profile->GetOffTheRecordProfile();
1010 info->created = true;
1011 } else {
1012 profile = NULL;
1013 profiles_info_.erase(iter);
1014 // TODO(yiyaoliu): This is temporary, remove it after it's not used.
1015 UMA_HISTOGRAM_COUNTS_100("UMA.ProfilesCount.AfterErase",
1016 profiles_info_.size());
1019 if (profile) {
1020 // If this was the guest or system profile, finish setting its special
1021 // status.
1022 if (profile->IsGuestSession() || profile->IsSystemProfile())
1023 SetNonPersonalProfilePrefs(profile);
1025 // Invoke CREATED callback for incognito profiles.
1026 if (go_off_the_record)
1027 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
1030 // Invoke INITIALIZED or FAIL for all profiles.
1031 RunCallbacks(callbacks, profile,
1032 profile ? Profile::CREATE_STATUS_INITIALIZED :
1033 Profile::CREATE_STATUS_LOCAL_FAIL);
1036 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) {
1037 TRACE_EVENT0("browser", "ProfileManager::DoFinalInit");
1038 TRACK_SCOPED_REGION("Startup", "ProfileManager::DoFinalInit");
1040 DoFinalInitForServices(profile, go_off_the_record);
1041 AddProfileToCache(profile);
1042 DoFinalInitLogging(profile);
1044 ProfileMetrics::LogNumberOfProfiles(this);
1045 content::NotificationService::current()->Notify(
1046 chrome::NOTIFICATION_PROFILE_ADDED,
1047 content::Source<Profile>(profile),
1048 content::NotificationService::NoDetails());
1051 void ProfileManager::DoFinalInitForServices(Profile* profile,
1052 bool go_off_the_record) {
1053 TRACE_EVENT0("browser", "ProfileManager::DoFinalInitForServices");
1054 TRACK_SCOPED_REGION("Startup", "ProfileManager::DoFinalInitForServices");
1056 #if defined(ENABLE_EXTENSIONS)
1057 ProfileInfoCache& cache = GetProfileInfoCache();
1058 extensions::ExtensionSystem::Get(profile)->InitForRegularProfile(
1059 !go_off_the_record);
1060 // During tests, when |profile| is an instance of TestingProfile,
1061 // ExtensionSystem might not create an ExtensionService.
1062 if (extensions::ExtensionSystem::Get(profile)->extension_service()) {
1063 extensions::ExtensionSystem::Get(profile)->extension_service()->
1064 RegisterContentSettings(profile->GetHostContentSettingsMap());
1066 // Set the block extensions bit on the ExtensionService. There likely are no
1067 // blockable extensions to block.
1068 size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
1069 if (profile_index != std::string::npos &&
1070 cache.ProfileIsSigninRequiredAtIndex(profile_index)) {
1071 extensions::ExtensionSystem::Get(profile)
1072 ->extension_service()
1073 ->BlockAllExtensions();
1076 #endif
1077 #if defined(ENABLE_SUPERVISED_USERS)
1078 // Initialization needs to happen after extension system initialization (for
1079 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
1080 // initializing the supervised flag if necessary).
1081 ChildAccountServiceFactory::GetForProfile(profile)->Init();
1082 SupervisedUserServiceFactory::GetForProfile(profile)->Init();
1083 #endif
1084 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
1085 // If the lock enabled algorithm changed, update this profile's lock status.
1086 // This depends on services which shouldn't be initialized until
1087 // DoFinalInitForServices.
1088 if (switches::IsNewProfileManagement())
1089 profiles::UpdateIsProfileLockEnabledIfNeeded(profile);
1090 #endif
1091 // Start the deferred task runners once the profile is loaded.
1092 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
1093 StartDeferredTaskRunners();
1095 // Activate data reduction proxy. This creates a request context and makes a
1096 // URL request to check if the data reduction proxy server is reachable.
1097 DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile)->
1098 MaybeActivateDataReductionProxy(true);
1100 GaiaCookieManagerServiceFactory::GetForProfile(profile)->Init();
1101 AccountFetcherServiceFactory::GetForProfile(profile)->EnableNetworkFetches();
1102 AccountReconcilorFactory::GetForProfile(profile);
1105 void ProfileManager::DoFinalInitLogging(Profile* profile) {
1106 TRACE_EVENT0("browser", "ProfileManager::DoFinalInitLogging");
1107 // Count number of extensions in this profile.
1108 int enabled_app_count = -1;
1109 #if defined(ENABLE_EXTENSIONS)
1110 enabled_app_count = GetEnabledAppCount(profile);
1111 #endif
1113 // Log the profile size after a reasonable startup delay.
1114 BrowserThread::PostDelayedTask(
1115 BrowserThread::FILE, FROM_HERE,
1116 base::Bind(&ProfileSizeTask, profile->GetPath(), enabled_app_count),
1117 base::TimeDelta::FromSeconds(112));
1120 Profile* ProfileManager::CreateProfileHelper(const base::FilePath& path) {
1121 TRACE_EVENT0("browser", "ProfileManager::CreateProfileHelper");
1122 SCOPED_UMA_HISTOGRAM_TIMER("Profile.CreateProfileHelperTime");
1123 TRACK_SCOPED_REGION("Startup", "ProfileManager::CreateProfileHelper");
1125 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
1128 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path,
1129 Delegate* delegate) {
1130 return Profile::CreateProfile(path,
1131 delegate,
1132 Profile::CREATE_MODE_ASYNCHRONOUS);
1135 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
1136 const base::FilePath& user_data_dir) {
1137 #if defined(OS_CHROMEOS)
1138 base::FilePath default_profile_dir(user_data_dir);
1139 if (!logged_in_) {
1140 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1141 Profile* profile = GetProfile(default_profile_dir);
1142 // For cros, return the OTR profile so we never accidentally keep
1143 // user data in an unencrypted profile. But doing this makes
1144 // many of the browser and ui tests fail. We do return the OTR profile
1145 // if the login-profile switch is passed so that we can test this.
1146 if (ShouldGoOffTheRecord(profile))
1147 return profile->GetOffTheRecordProfile();
1148 DCHECK(!user_manager::UserManager::Get()->IsLoggedInAsGuest());
1149 return profile;
1152 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1153 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
1154 // Fallback to default off-the-record profile, if user profile has not fully
1155 // loaded yet.
1156 if (profile_info && !profile_info->created)
1157 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1159 Profile* profile = GetProfile(default_profile_dir);
1160 // Some unit tests didn't initialize the UserManager.
1161 if (user_manager::UserManager::IsInitialized() &&
1162 user_manager::UserManager::Get()->IsLoggedInAsGuest())
1163 return profile->GetOffTheRecordProfile();
1164 return profile;
1165 #else
1166 base::FilePath default_profile_dir(user_data_dir);
1167 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1168 return GetProfile(default_profile_dir);
1169 #endif
1172 bool ProfileManager::AddProfile(Profile* profile) {
1173 TRACE_EVENT0("browser", "ProfileManager::AddProfile");
1174 TRACK_SCOPED_REGION("Startup", "ProfileManager::AddProfile");
1176 DCHECK(profile);
1178 // Make sure that we're not loading a profile with the same ID as a profile
1179 // that's already loaded.
1180 if (GetProfileByPathInternal(profile->GetPath())) {
1181 NOTREACHED() << "Attempted to add profile with the same path (" <<
1182 profile->GetPath().value() <<
1183 ") as an already-loaded profile.";
1184 return false;
1187 RegisterProfile(profile, true);
1188 InitProfileUserPrefs(profile);
1189 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
1190 return true;
1193 Profile* ProfileManager::CreateAndInitializeProfile(
1194 const base::FilePath& profile_dir) {
1195 TRACE_EVENT0("browser", "ProfileManager::CreateAndInitializeProfile");
1196 TRACK_SCOPED_REGION(
1197 "Startup", "ProfileManager::CreateAndInitializeProfile");
1198 SCOPED_UMA_HISTOGRAM_LONG_TIMER("Profile.CreateAndInitializeProfile");
1200 // CHECK that we are not trying to load the same profile twice, to prevent
1201 // profile corruption. Note that this check also covers the case when we have
1202 // already started loading the profile but it is not fully initialized yet,
1203 // which would make Bad Things happen if we returned it.
1204 CHECK(!GetProfileByPathInternal(profile_dir));
1205 Profile* profile = CreateProfileHelper(profile_dir);
1206 DCHECK(profile);
1207 if (profile) {
1208 bool result = AddProfile(profile);
1209 DCHECK(result);
1211 return profile;
1214 void ProfileManager::FinishDeletingProfile(
1215 const base::FilePath& profile_dir,
1216 const base::FilePath& new_active_profile_dir) {
1217 // Update the last used profile pref before closing browser windows. This
1218 // way the correct last used profile is set for any notification observers.
1219 profiles::SetLastUsedProfile(
1220 new_active_profile_dir.BaseName().MaybeAsASCII());
1222 ProfileInfoCache& cache = GetProfileInfoCache();
1223 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1224 // start deleting the profile instance we need to close background apps too.
1225 Profile* profile = GetProfileByPath(profile_dir);
1227 if (profile) {
1228 // TODO: Migrate additional code in this block to observe this notification
1229 // instead of being implemented here.
1230 content::NotificationService::current()->Notify(
1231 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
1232 content::Source<Profile>(profile),
1233 content::NotificationService::NoDetails());
1235 // By this point, all in-progress downloads for the profile being deleted
1236 // must have been canceled (crbug.com/336725).
1237 DCHECK(DownloadServiceFactory::GetForBrowserContext(profile)->
1238 NonMaliciousDownloadCount() == 0);
1239 BrowserList::CloseAllBrowsersWithProfile(profile);
1241 // Disable sync for doomed profile.
1242 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1243 profile)) {
1244 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1245 profile)->RequestStop(ProfileSyncService::CLEAR_DATA);
1248 ProfileMetrics::LogProfileDelete(cache.ProfileIsAuthenticatedAtIndex(
1249 cache.GetIndexOfProfileWithPath(profile_dir)));
1250 // Some platforms store passwords in keychains. They should be removed.
1251 scoped_refptr<password_manager::PasswordStore> password_store =
1252 PasswordStoreFactory::GetForProfile(
1253 profile, ServiceAccessType::EXPLICIT_ACCESS).get();
1254 if (password_store.get()) {
1255 password_store->RemoveLoginsCreatedBetween(
1256 base::Time(), base::Time::Max(), base::Closure());
1259 // The Profile Data doesn't get wiped until Chrome closes. Since we promised
1260 // that the user's data would be removed, do so immediately.
1261 profiles::RemoveBrowsingDataForProfile(profile_dir);
1262 } else {
1263 // It is safe to delete a not yet loaded Profile from disk.
1264 BrowserThread::PostTask(
1265 BrowserThread::FILE, FROM_HERE,
1266 base::Bind(&NukeProfileFromDisk, profile_dir));
1269 // Queue even a profile that was nuked so it will be MarkedForDeletion and so
1270 // CreateProfileAsync can't create it.
1271 QueueProfileDirectoryForDeletion(profile_dir);
1272 cache.DeleteProfileFromCache(profile_dir);
1273 ProfileMetrics::UpdateReportedProfilesStatistics(this);
1276 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
1277 Profile* profile,
1278 bool created) {
1279 TRACE_EVENT0("browser", "ProfileManager::RegisterProfile");
1280 ProfileInfo* info = new ProfileInfo(profile, created);
1281 profiles_info_.insert(
1282 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
1283 return info;
1286 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath(
1287 const base::FilePath& path) const {
1288 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
1289 return (iter == profiles_info_.end()) ? NULL : iter->second.get();
1292 void ProfileManager::AddProfileToCache(Profile* profile) {
1293 TRACE_EVENT0("browser", "ProfileManager::AddProfileToCache");
1294 if (profile->IsGuestSession() || profile->IsSystemProfile())
1295 return;
1296 ProfileInfoCache& cache = GetProfileInfoCache();
1297 if (profile->GetPath().DirName() != cache.GetUserDataDir())
1298 return;
1300 SigninManagerBase* signin_manager =
1301 SigninManagerFactory::GetForProfile(profile);
1302 AccountTrackerService* account_tracker =
1303 AccountTrackerServiceFactory::GetForProfile(profile);
1304 AccountTrackerService::AccountInfo account_info =
1305 account_tracker->GetAccountInfo(
1306 signin_manager->GetAuthenticatedAccountId());
1307 base::string16 username = base::UTF8ToUTF16(account_info.email);
1309 size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
1310 if (profile_index != std::string::npos) {
1311 // The ProfileInfoCache's info must match the Signin Manager.
1312 cache.SetAuthInfoOfProfileAtIndex(profile_index, account_info.gaia,
1313 username);
1314 return;
1317 // Profile name and avatar are set by InitProfileUserPrefs and stored in the
1318 // profile. Use those values to setup the cache entry.
1319 base::string16 profile_name =
1320 base::UTF8ToUTF16(profile->GetPrefs()->GetString(prefs::kProfileName));
1322 size_t icon_index = profile->GetPrefs()->GetInteger(
1323 prefs::kProfileAvatarIndex);
1325 std::string supervised_user_id =
1326 profile->GetPrefs()->GetString(prefs::kSupervisedUserId);
1328 cache.AddProfileToCache(profile->GetPath(),
1329 profile_name,
1330 account_info.gaia,
1331 username,
1332 icon_index,
1333 supervised_user_id);
1335 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) {
1336 cache.SetProfileIsEphemeralAtIndex(
1337 cache.GetIndexOfProfileWithPath(profile->GetPath()), true);
1341 void ProfileManager::SetNonPersonalProfilePrefs(Profile* profile) {
1342 PrefService* prefs = profile->GetPrefs();
1343 prefs->SetBoolean(prefs::kSigninAllowed, false);
1344 prefs->SetBoolean(bookmarks::prefs::kEditBookmarksEnabled, false);
1345 prefs->SetBoolean(bookmarks::prefs::kShowBookmarkBar, false);
1346 prefs->ClearPref(DefaultSearchManager::kDefaultSearchProviderDataPrefName);
1349 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) {
1350 #if defined(OS_CHROMEOS)
1351 if (profile->GetPath().BaseName().value() == chrome::kInitialProfile) {
1352 return true;
1354 #endif
1355 return profile->IsGuestSession() || profile->IsSystemProfile();
1358 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks,
1359 Profile* profile,
1360 Profile::CreateStatus status) {
1361 for (size_t i = 0; i < callbacks.size(); ++i)
1362 callbacks[i].Run(profile, status);
1365 ProfileManager::ProfileInfo::ProfileInfo(
1366 Profile* profile,
1367 bool created)
1368 : profile(profile),
1369 created(created) {
1372 ProfileManager::ProfileInfo::~ProfileInfo() {
1373 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1376 #if !defined(OS_ANDROID) && !defined(OS_IOS)
1377 void ProfileManager::UpdateLastUser(Profile* last_active) {
1378 PrefService* local_state = g_browser_process->local_state();
1379 DCHECK(local_state);
1380 // Only keep track of profiles that we are managing; tests may create others.
1381 // Also never consider the SystemProfile as "active".
1382 if (profiles_info_.find(last_active->GetPath()) != profiles_info_.end() &&
1383 !last_active->IsSystemProfile()) {
1384 std::string profile_path_base =
1385 last_active->GetPath().BaseName().MaybeAsASCII();
1386 if (profile_path_base != GetLastUsedProfileName())
1387 profiles::SetLastUsedProfile(profile_path_base);
1389 ProfileInfoCache& cache = GetProfileInfoCache();
1390 size_t profile_index =
1391 cache.GetIndexOfProfileWithPath(last_active->GetPath());
1392 if (profile_index != std::string::npos) {
1393 #if !defined(OS_CHROMEOS)
1394 // Incognito Profiles don't have ProfileKeyedServices.
1395 if (!last_active->IsOffTheRecord()) {
1396 CrossDevicePromoFactory::GetForProfile(last_active)
1397 ->MaybeBrowsingSessionStarted(
1398 cache.GetProfileActiveTimeAtIndex(profile_index));
1400 #endif
1401 cache.SetProfileActiveTimeAtIndex(profile_index);
1406 ProfileManager::BrowserListObserver::BrowserListObserver(
1407 ProfileManager* manager)
1408 : profile_manager_(manager) {
1409 BrowserList::AddObserver(this);
1412 ProfileManager::BrowserListObserver::~BrowserListObserver() {
1413 BrowserList::RemoveObserver(this);
1416 void ProfileManager::BrowserListObserver::OnBrowserAdded(
1417 Browser* browser) {}
1419 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
1420 Browser* browser) {
1421 Profile* profile = browser->profile();
1422 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1423 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1424 // Not the last window for this profile.
1425 return;
1428 // If the last browser of a profile that is scheduled for deletion is closed
1429 // do that now.
1430 base::FilePath path = profile->GetPath();
1431 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
1432 !IsProfileMarkedForDeletion(path)) {
1433 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
1434 path, ProfileManager::CreateCallback());
1438 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
1439 Browser* browser) {
1440 // If all browsers are being closed (e.g. the user is in the process of
1441 // shutting down), this event will be fired after each browser is
1442 // closed. This does not represent a user intention to change the active
1443 // browser so is not handled here.
1444 if (profile_manager_->closing_all_browsers_)
1445 return;
1447 Profile* last_active = browser->profile();
1449 // Don't remember ephemeral profiles as last because they are not going to
1450 // persist after restart.
1451 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
1452 return;
1454 profile_manager_->UpdateLastUser(last_active);
1456 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
1458 void ProfileManager::OnNewActiveProfileLoaded(
1459 const base::FilePath& profile_to_delete_path,
1460 const base::FilePath& new_active_profile_path,
1461 const CreateCallback& original_callback,
1462 Profile* loaded_profile,
1463 Profile::CreateStatus status) {
1464 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
1465 status != Profile::CREATE_STATUS_REMOTE_FAIL);
1467 // Only run the code if the profile initialization has finished completely.
1468 if (status != Profile::CREATE_STATUS_INITIALIZED)
1469 return;
1471 if (IsProfileMarkedForDeletion(new_active_profile_path)) {
1472 // If the profile we tried to load as the next active profile has been
1473 // deleted, then retry deleting this profile to redo the logic to load
1474 // the next available profile.
1475 ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
1476 return;
1479 FinishDeletingProfile(profile_to_delete_path, new_active_profile_path);
1480 if (!original_callback.is_null())
1481 original_callback.Run(loaded_profile, status);
1484 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1485 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) {