Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / profiles / profile_manager.cc
blob40f9bd789f533c911622fe454d0eac0e393d42d6
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/content_settings/host_content_settings_map_factory.h"
28 #include "chrome/browser/download/download_service.h"
29 #include "chrome/browser/download/download_service_factory.h"
30 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
31 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
32 #include "chrome/browser/password_manager/password_store_factory.h"
33 #include "chrome/browser/prefs/incognito_mode_prefs.h"
34 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
35 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
36 #include "chrome/browser/profiles/profile_destroyer.h"
37 #include "chrome/browser/profiles/profile_info_cache.h"
38 #include "chrome/browser/profiles/profile_metrics.h"
39 #include "chrome/browser/profiles/profiles_state.h"
40 #include "chrome/browser/signin/account_fetcher_service_factory.h"
41 #include "chrome/browser/signin/account_reconcilor_factory.h"
42 #include "chrome/browser/signin/account_tracker_service_factory.h"
43 #include "chrome/browser/signin/cross_device_promo.h"
44 #include "chrome/browser/signin/cross_device_promo_factory.h"
45 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
46 #include "chrome/browser/signin/signin_manager_factory.h"
47 #include "chrome/browser/sync/profile_sync_service.h"
48 #include "chrome/browser/sync/profile_sync_service_factory.h"
49 #include "chrome/browser/ui/browser.h"
50 #include "chrome/browser/ui/browser_iterator.h"
51 #include "chrome/browser/ui/sync/sync_promo_ui.h"
52 #include "chrome/common/chrome_constants.h"
53 #include "chrome/common/chrome_paths_internal.h"
54 #include "chrome/common/chrome_switches.h"
55 #include "chrome/common/logging_chrome.h"
56 #include "chrome/common/pref_names.h"
57 #include "chrome/common/url_constants.h"
58 #include "chrome/grit/generated_resources.h"
59 #include "components/bookmarks/browser/bookmark_model.h"
60 #include "components/bookmarks/browser/startup_task_runner_service.h"
61 #include "components/content_settings/core/browser/host_content_settings_map.h"
62 #include "components/password_manager/core/browser/password_store.h"
63 #include "components/signin/core/browser/account_fetcher_service.h"
64 #include "components/signin/core/browser/account_tracker_service.h"
65 #include "components/signin/core/browser/gaia_cookie_manager_service.h"
66 #include "components/signin/core/browser/signin_manager.h"
67 #include "components/signin/core/common/profile_management_switches.h"
68 #include "content/public/browser/browser_thread.h"
69 #include "content/public/browser/notification_service.h"
70 #include "content/public/browser/user_metrics.h"
71 #include "net/http/http_transaction_factory.h"
72 #include "net/url_request/url_request_context.h"
73 #include "net/url_request/url_request_context_getter.h"
74 #include "net/url_request/url_request_job.h"
75 #include "ui/base/l10n/l10n_util.h"
77 #if defined(ENABLE_EXTENSIONS)
78 #include "chrome/browser/extensions/extension_service.h"
79 #include "extensions/browser/extension_registry.h"
80 #include "extensions/browser/extension_system.h"
81 #include "extensions/common/extension_set.h"
82 #include "extensions/common/manifest.h"
83 #endif
85 #if defined(ENABLE_SUPERVISED_USERS)
86 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
87 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
88 #include "chrome/browser/supervised_user/supervised_user_service.h"
89 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
90 #endif
92 #if !defined(OS_IOS)
93 #include "chrome/browser/sessions/session_service_factory.h"
94 #include "chrome/browser/ui/browser_list.h"
95 #endif // !defined (OS_IOS)
97 #if defined(OS_WIN)
98 #include "base/win/metro.h"
99 #include "chrome/installer/util/browser_distribution.h"
100 #endif
102 #if defined(OS_CHROMEOS)
103 #include "chrome/browser/browser_process_platform_part_chromeos.h"
104 #include "chrome/browser/chromeos/profiles/profile_helper.h"
105 #include "chromeos/chromeos_switches.h"
106 #include "chromeos/dbus/cryptohome_client.h"
107 #include "chromeos/dbus/dbus_thread_manager.h"
108 #include "components/user_manager/user.h"
109 #include "components/user_manager/user_manager.h"
110 #endif
112 using base::UserMetricsAction;
113 using content::BrowserThread;
115 namespace {
117 // Profiles that should be deleted on shutdown.
118 std::vector<base::FilePath>& ProfilesToDelete() {
119 CR_DEFINE_STATIC_LOCAL(std::vector<base::FilePath>, profiles_to_delete, ());
120 return profiles_to_delete;
123 int64 ComputeFilesSize(const base::FilePath& directory,
124 const base::FilePath::StringType& pattern) {
125 int64 running_size = 0;
126 base::FileEnumerator iter(directory, false, base::FileEnumerator::FILES,
127 pattern);
128 while (!iter.Next().empty())
129 running_size += iter.GetInfo().GetSize();
130 return running_size;
133 // Simple task to log the size of the current profile.
134 void ProfileSizeTask(const base::FilePath& path, int enabled_app_count) {
135 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
136 const int64 kBytesInOneMB = 1024 * 1024;
138 int64 size = ComputeFilesSize(path, FILE_PATH_LITERAL("*"));
139 int size_MB = static_cast<int>(size / kBytesInOneMB);
140 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB);
142 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History"));
143 size_MB = static_cast<int>(size / kBytesInOneMB);
144 UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB);
146 size = ComputeFilesSize(path, FILE_PATH_LITERAL("History*"));
147 size_MB = static_cast<int>(size / kBytesInOneMB);
148 UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB);
150 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Cookies"));
151 size_MB = static_cast<int>(size / kBytesInOneMB);
152 UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB);
154 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Bookmarks"));
155 size_MB = static_cast<int>(size / kBytesInOneMB);
156 UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB);
158 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Favicons"));
159 size_MB = static_cast<int>(size / kBytesInOneMB);
160 UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB);
162 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Top Sites"));
163 size_MB = static_cast<int>(size / kBytesInOneMB);
164 UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB);
166 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Visited Links"));
167 size_MB = static_cast<int>(size / kBytesInOneMB);
168 UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB);
170 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Web Data"));
171 size_MB = static_cast<int>(size / kBytesInOneMB);
172 UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB);
174 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Extension*"));
175 size_MB = static_cast<int>(size / kBytesInOneMB);
176 UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB);
178 size = ComputeFilesSize(path, FILE_PATH_LITERAL("Policy"));
179 size_MB = static_cast<int>(size / kBytesInOneMB);
180 UMA_HISTOGRAM_COUNTS_10000("Profile.PolicySize", size_MB);
182 // Count number of enabled apps in this profile, if we know.
183 if (enabled_app_count != -1)
184 UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count);
187 void QueueProfileDirectoryForDeletion(const base::FilePath& path) {
188 ProfilesToDelete().push_back(path);
191 bool IsProfileMarkedForDeletion(const base::FilePath& profile_path) {
192 return std::find(ProfilesToDelete().begin(), ProfilesToDelete().end(),
193 profile_path) != ProfilesToDelete().end();
196 // Physically remove deleted profile directories from disk.
197 void NukeProfileFromDisk(const base::FilePath& profile_path) {
198 // Delete both the profile directory and its corresponding cache.
199 base::FilePath cache_path;
200 chrome::GetUserCacheDirectory(profile_path, &cache_path);
201 base::DeleteFile(profile_path, true);
202 base::DeleteFile(cache_path, true);
205 #if defined(OS_CHROMEOS)
206 void CheckCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status,
207 bool is_mounted) {
208 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
209 LOG(ERROR) << "IsMounted call failed.";
210 return;
212 if (!is_mounted)
213 LOG(ERROR) << "Cryptohome is not mounted.";
216 #endif
218 #if defined(ENABLE_EXTENSIONS)
220 // Returns the number of installed (and enabled) apps, excluding any component
221 // apps.
222 size_t GetEnabledAppCount(Profile* profile) {
223 size_t installed_apps = 0u;
224 const extensions::ExtensionSet& extensions =
225 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
226 for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
227 iter != extensions.end();
228 ++iter) {
229 if ((*iter)->is_app() &&
230 (*iter)->location() != extensions::Manifest::COMPONENT) {
231 ++installed_apps;
234 return installed_apps;
237 #endif // ENABLE_EXTENSIONS
239 } // namespace
241 ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
242 : user_data_dir_(user_data_dir),
243 logged_in_(false),
244 #if !defined(OS_ANDROID) && !defined(OS_IOS)
245 browser_list_observer_(this),
246 #endif
247 closing_all_browsers_(false) {
248 #if defined(OS_CHROMEOS)
249 registrar_.Add(
250 this,
251 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
252 content::NotificationService::AllSources());
253 #endif
254 registrar_.Add(
255 this,
256 chrome::NOTIFICATION_BROWSER_OPENED,
257 content::NotificationService::AllSources());
258 registrar_.Add(
259 this,
260 chrome::NOTIFICATION_BROWSER_CLOSED,
261 content::NotificationService::AllSources());
262 registrar_.Add(
263 this,
264 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
265 content::NotificationService::AllSources());
266 registrar_.Add(
267 this,
268 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
269 content::NotificationService::AllSources());
271 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty())
272 profile_shortcut_manager_.reset(ProfileShortcutManager::Create(
273 this));
276 ProfileManager::~ProfileManager() {
279 #if defined(ENABLE_SESSION_SERVICE)
280 // static
281 void ProfileManager::ShutdownSessionServices() {
282 ProfileManager* pm = g_browser_process->profile_manager();
283 if (!pm) // Is NULL when running unit tests.
284 return;
285 std::vector<Profile*> profiles(pm->GetLoadedProfiles());
286 for (size_t i = 0; i < profiles.size(); ++i)
287 SessionServiceFactory::ShutdownForProfile(profiles[i]);
289 #endif
291 // static
292 void ProfileManager::NukeDeletedProfilesFromDisk() {
293 for (std::vector<base::FilePath>::iterator it =
294 ProfilesToDelete().begin();
295 it != ProfilesToDelete().end();
296 ++it) {
297 NukeProfileFromDisk(*it);
299 ProfilesToDelete().clear();
302 // static
303 Profile* ProfileManager::GetLastUsedProfile() {
304 ProfileManager* profile_manager = g_browser_process->profile_manager();
305 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_);
308 // static
309 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
310 Profile* profile = GetLastUsedProfile();
311 if (profile->IsGuestSession() ||
312 profile->IsSystemProfile() ||
313 IncognitoModePrefs::GetAvailability(profile->GetPrefs()) ==
314 IncognitoModePrefs::FORCED) {
315 return profile->GetOffTheRecordProfile();
317 return profile;
320 // static
321 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() {
322 ProfileManager* profile_manager = g_browser_process->profile_manager();
323 return profile_manager->GetLastOpenedProfiles(
324 profile_manager->user_data_dir_);
327 // static
328 Profile* ProfileManager::GetPrimaryUserProfile() {
329 ProfileManager* profile_manager = g_browser_process->profile_manager();
330 #if defined(OS_CHROMEOS)
331 if (!profile_manager->IsLoggedIn() ||
332 !user_manager::UserManager::IsInitialized())
333 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
334 profile_manager->user_data_dir());
335 user_manager::UserManager* manager = user_manager::UserManager::Get();
336 // Note: The ProfileHelper will take care of guest profiles.
337 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
338 manager->GetPrimaryUser());
339 #else
340 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
341 profile_manager->user_data_dir());
342 #endif
345 // static
346 Profile* ProfileManager::GetActiveUserProfile() {
347 ProfileManager* profile_manager = g_browser_process->profile_manager();
348 #if defined(OS_CHROMEOS)
349 if (!profile_manager)
350 return NULL;
352 if (!profile_manager->IsLoggedIn() ||
353 !user_manager::UserManager::IsInitialized()) {
354 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
355 profile_manager->user_data_dir());
358 user_manager::UserManager* manager = user_manager::UserManager::Get();
359 const user_manager::User* user = manager->GetActiveUser();
360 // To avoid an endless loop (crbug.com/334098) we have to additionally check
361 // if the profile of the user was already created. If the profile was not yet
362 // created we load the profile using the profile directly.
363 // TODO: This should be cleaned up with the new profile manager.
364 if (user && user->is_profile_created())
365 return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user);
367 #endif
368 Profile* profile =
369 profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
370 profile_manager->user_data_dir());
371 // |profile| could be null if the user doesn't have a profile yet and the path
372 // is on a read-only volume (preventing Chrome from making a new one).
373 // However, most callers of this function immediately dereference the result
374 // which would lead to crashes in a variety of call sites. Assert here to
375 // figure out how common this is. http://crbug.com/383019
376 CHECK(profile) << profile_manager->user_data_dir().AsUTF8Unsafe();
377 return profile;
380 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) {
381 TRACE_EVENT0("browser", "ProfileManager::GetProfile");
383 // If the profile is already loaded (e.g., chrome.exe launched twice), just
384 // return it.
385 Profile* profile = GetProfileByPath(profile_dir);
386 if (profile)
387 return profile;
388 return CreateAndInitializeProfile(profile_dir);
391 size_t ProfileManager::GetNumberOfProfiles() {
392 return GetProfileInfoCache().GetNumberOfProfiles();
395 void ProfileManager::CreateProfileAsync(
396 const base::FilePath& profile_path,
397 const CreateCallback& callback,
398 const base::string16& name,
399 const base::string16& icon_url,
400 const std::string& supervised_user_id) {
401 DCHECK_CURRENTLY_ON(BrowserThread::UI);
402 TRACE_EVENT1("browser,startup",
403 "ProfileManager::CreateProfileAsync",
404 "profile_path",
405 profile_path.AsUTF8Unsafe());
407 // Make sure that this profile is not pending deletion.
408 if (IsProfileMarkedForDeletion(profile_path)) {
409 if (!callback.is_null())
410 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
411 return;
414 // Create the profile if needed and collect its ProfileInfo.
415 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
416 ProfileInfo* info = NULL;
418 if (iter != profiles_info_.end()) {
419 info = iter->second.get();
420 } else {
421 // Initiate asynchronous creation process.
422 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false);
423 ProfileInfoCache& cache = GetProfileInfoCache();
424 // Get the icon index from the user's icon url
425 size_t icon_index;
426 std::string icon_url_std = base::UTF16ToASCII(icon_url);
427 if (profiles::IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) {
428 // add profile to cache with user selected name and avatar
429 cache.AddProfileToCache(profile_path, name, std::string(),
430 base::string16(), icon_index, supervised_user_id);
433 if (!supervised_user_id.empty()) {
434 content::RecordAction(
435 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
438 ProfileMetrics::UpdateReportedProfilesStatistics(this);
441 // Call or enqueue the callback.
442 if (!callback.is_null()) {
443 if (iter != profiles_info_.end() && info->created) {
444 Profile* profile = info->profile.get();
445 // If this was the guest profile, apply settings and go OffTheRecord.
446 // The system profile also needs characteristics of being off the record,
447 // such as having no extensions, not writing to disk, etc.
448 if (profile->IsGuestSession() || profile->IsSystemProfile()) {
449 SetNonPersonalProfilePrefs(profile);
450 profile = profile->GetOffTheRecordProfile();
452 // Profile has already been created. Run callback immediately.
453 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
454 } else {
455 // Profile is either already in the process of being created, or new.
456 // Add callback to the list.
457 info->callbacks.push_back(callback);
462 bool ProfileManager::IsValidProfile(Profile* profile) {
463 for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
464 iter != profiles_info_.end(); ++iter) {
465 if (iter->second->created) {
466 Profile* candidate = iter->second->profile.get();
467 if (candidate == profile ||
468 (candidate->HasOffTheRecordProfile() &&
469 candidate->GetOffTheRecordProfile() == profile)) {
470 return true;
474 return false;
477 base::FilePath ProfileManager::GetInitialProfileDir() {
478 #if defined(OS_CHROMEOS)
479 if (logged_in_) {
480 return chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
482 #endif
483 base::FilePath relative_profile_dir;
484 // TODO(mirandac): should not automatically be default profile.
485 return relative_profile_dir.AppendASCII(chrome::kInitialProfile);
488 Profile* ProfileManager::GetLastUsedProfile(
489 const base::FilePath& user_data_dir) {
490 #if defined(OS_CHROMEOS)
491 // Use default login profile if user has not logged in yet.
492 if (!logged_in_) {
493 return GetActiveUserOrOffTheRecordProfileFromPath(user_data_dir);
494 } else {
495 // CrOS multi-profiles implementation is different so GetLastUsedProfile
496 // has custom implementation too.
497 base::FilePath profile_dir;
498 // In case of multi-profiles we ignore "last used profile" preference
499 // since it may refer to profile that has been in use in previous session.
500 // That profile dir may not be mounted in this session so instead return
501 // active profile from current session.
502 profile_dir = chromeos::ProfileHelper::Get()->GetActiveUserProfileDir();
504 base::FilePath profile_path(user_data_dir);
505 Profile* profile = GetProfile(profile_path.Append(profile_dir));
506 return profile->IsGuestSession() ? profile->GetOffTheRecordProfile() :
507 profile;
509 #endif
511 return GetProfile(GetLastUsedProfileDir(user_data_dir));
514 base::FilePath ProfileManager::GetLastUsedProfileDir(
515 const base::FilePath& user_data_dir) {
516 return user_data_dir.AppendASCII(GetLastUsedProfileName());
519 std::string ProfileManager::GetLastUsedProfileName() {
520 PrefService* local_state = g_browser_process->local_state();
521 DCHECK(local_state);
522 const std::string last_used_profile_name =
523 local_state->GetString(prefs::kProfileLastUsed);
524 // Make sure the system profile can't be the one marked as the last one used
525 // since it shouldn't get a browser.
526 if (!last_used_profile_name.empty() &&
527 last_used_profile_name !=
528 base::FilePath(chrome::kSystemProfileDir).AsUTF8Unsafe()) {
529 return last_used_profile_name;
532 return chrome::kInitialProfile;
535 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles(
536 const base::FilePath& user_data_dir) {
537 PrefService* local_state = g_browser_process->local_state();
538 DCHECK(local_state);
540 std::vector<Profile*> to_return;
541 if (local_state->HasPrefPath(prefs::kProfilesLastActive) &&
542 local_state->GetList(prefs::kProfilesLastActive)) {
543 // Make a copy because the list might change in the calls to GetProfile.
544 scoped_ptr<base::ListValue> profile_list(
545 local_state->GetList(prefs::kProfilesLastActive)->DeepCopy());
546 base::ListValue::const_iterator it;
547 std::string profile;
548 for (it = profile_list->begin(); it != profile_list->end(); ++it) {
549 if (!(*it)->GetAsString(&profile) || profile.empty() ||
550 profile == base::FilePath(chrome::kSystemProfileDir).AsUTF8Unsafe()) {
551 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive;
552 continue;
554 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile)));
557 return to_return;
560 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const {
561 std::vector<Profile*> profiles;
562 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin();
563 iter != profiles_info_.end(); ++iter) {
564 if (iter->second->created)
565 profiles.push_back(iter->second->profile.get());
567 return profiles;
570 Profile* ProfileManager::GetProfileByPathInternal(
571 const base::FilePath& path) const {
572 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPathInternal");
573 ProfileInfo* profile_info = GetProfileInfoByPath(path);
574 return profile_info ? profile_info->profile.get() : nullptr;
577 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const {
578 TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath");
579 ProfileInfo* profile_info = GetProfileInfoByPath(path);
580 return (profile_info && profile_info->created) ? profile_info->profile.get()
581 : nullptr;
584 // static
585 base::FilePath ProfileManager::CreateMultiProfileAsync(
586 const base::string16& name,
587 const base::string16& icon_url,
588 const CreateCallback& callback,
589 const std::string& supervised_user_id) {
590 DCHECK_CURRENTLY_ON(BrowserThread::UI);
592 ProfileManager* profile_manager = g_browser_process->profile_manager();
594 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
596 profile_manager->CreateProfileAsync(new_path,
597 callback,
598 name,
599 icon_url,
600 supervised_user_id);
601 return new_path;
604 // static
605 base::FilePath ProfileManager::GetGuestProfilePath() {
606 DCHECK_CURRENTLY_ON(BrowserThread::UI);
608 ProfileManager* profile_manager = g_browser_process->profile_manager();
610 base::FilePath guest_path = profile_manager->user_data_dir();
611 return guest_path.Append(chrome::kGuestProfileDir);
614 // static
615 base::FilePath ProfileManager::GetSystemProfilePath() {
616 DCHECK_CURRENTLY_ON(BrowserThread::UI);
618 ProfileManager* profile_manager = g_browser_process->profile_manager();
620 base::FilePath system_path = profile_manager->user_data_dir();
621 return system_path.Append(chrome::kSystemProfileDir);
624 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() {
625 PrefService* local_state = g_browser_process->local_state();
626 DCHECK(local_state);
628 DCHECK(profiles::IsMultipleProfilesEnabled());
630 // Create the next profile in the next available directory slot.
631 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated);
632 std::string profile_name = chrome::kMultiProfileDirPrefix;
633 profile_name.append(base::IntToString(next_directory));
634 base::FilePath new_path = user_data_dir_;
635 #if defined(OS_WIN)
636 new_path = new_path.Append(base::ASCIIToUTF16(profile_name));
637 #else
638 new_path = new_path.Append(profile_name);
639 #endif
640 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory);
641 return new_path;
644 ProfileInfoCache& ProfileManager::GetProfileInfoCache() {
645 TRACE_EVENT0("browser", "ProfileManager::GetProfileInfoCache");
646 if (!profile_info_cache_) {
647 profile_info_cache_.reset(new ProfileInfoCache(
648 g_browser_process->local_state(), user_data_dir_));
650 return *profile_info_cache_.get();
653 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
654 return profile_shortcut_manager_.get();
657 void ProfileManager::ScheduleProfileForDeletion(
658 const base::FilePath& profile_dir,
659 const CreateCallback& callback) {
660 DCHECK(profiles::IsMultipleProfilesEnabled());
662 // Cancel all in-progress downloads before deleting the profile to prevent a
663 // "Do you want to exit Google Chrome and cancel the downloads?" prompt
664 // (crbug.com/336725).
665 Profile* profile = GetProfileByPath(profile_dir);
666 if (profile) {
667 DownloadService* service =
668 DownloadServiceFactory::GetForBrowserContext(profile);
669 service->CancelDownloads();
672 ProfileInfoCache& cache = GetProfileInfoCache();
674 // If we're deleting the last (non-legacy-supervised) profile, then create a
675 // new profile in its place.
676 base::FilePath last_non_supervised_profile_path;
677 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
678 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
679 // Make sure that this profile is not pending deletion, and is not
680 // legacy-supervised.
681 if (cur_path != profile_dir &&
682 !cache.ProfileIsLegacySupervisedAtIndex(i) &&
683 !IsProfileMarkedForDeletion(cur_path)) {
684 last_non_supervised_profile_path = cur_path;
685 break;
689 base::FilePath new_path;
690 if (last_non_supervised_profile_path.empty()) {
691 // If we are using --new-avatar-menu, then assign the default
692 // placeholder avatar and name. Otherwise, use random ones.
693 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
694 int avatar_index = profiles::GetPlaceholderAvatarIndex();
695 base::string16 new_avatar_url = is_new_avatar_menu ?
696 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(avatar_index)) :
697 base::string16();
698 base::string16 new_profile_name = is_new_avatar_menu ?
699 cache.ChooseNameForNewProfile(avatar_index) : base::string16();
701 new_path = GenerateNextProfileDirectoryPath();
702 CreateProfileAsync(new_path,
703 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
704 base::Unretained(this),
705 profile_dir,
706 new_path,
707 callback),
708 new_profile_name,
709 new_avatar_url,
710 std::string());
712 ProfileMetrics::LogProfileAddNewUser(
713 ProfileMetrics::ADD_NEW_USER_LAST_DELETED);
714 return;
717 #if defined(OS_MACOSX)
718 // On the Mac, the browser process is not killed when all browser windows are
719 // closed, so just in case we are deleting the active profile, and no other
720 // profile has been loaded, we must pre-load a next one.
721 const base::FilePath last_used_profile =
722 GetLastUsedProfileDir(user_data_dir_);
723 if (last_used_profile == profile_dir ||
724 last_used_profile == GetGuestProfilePath()) {
725 CreateProfileAsync(last_non_supervised_profile_path,
726 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
727 base::Unretained(this),
728 profile_dir,
729 last_non_supervised_profile_path,
730 callback),
731 base::string16(),
732 base::string16(),
733 std::string());
734 return;
736 #endif // defined(OS_MACOSX)
738 FinishDeletingProfile(profile_dir, last_non_supervised_profile_path);
741 void ProfileManager::AutoloadProfiles() {
742 // If running in the background is disabled for the browser, do not autoload
743 // any profiles.
744 PrefService* local_state = g_browser_process->local_state();
745 DCHECK(local_state);
746 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
747 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
748 return;
751 ProfileInfoCache& cache = GetProfileInfoCache();
752 size_t number_of_profiles = cache.GetNumberOfProfiles();
753 for (size_t p = 0; p < number_of_profiles; ++p) {
754 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) {
755 // If status is true, that profile is running background apps. By calling
756 // GetProfile, we automatically cause the profile to be loaded which will
757 // register it with the BackgroundModeManager.
758 GetProfile(cache.GetPathOfProfileAtIndex(p));
763 void ProfileManager::CleanUpEphemeralProfiles() {
764 const std::string last_used_profile = GetLastUsedProfileName();
766 bool last_active_profile_deleted = false;
767 base::FilePath new_profile_path;
768 std::vector<base::FilePath> profiles_to_delete;
769 ProfileInfoCache& profile_cache = GetProfileInfoCache();
770 size_t profiles_count = profile_cache.GetNumberOfProfiles();
771 for (size_t i = 0; i < profiles_count; ++i) {
772 base::FilePath profile_path = profile_cache.GetPathOfProfileAtIndex(i);
773 if (profile_cache.ProfileIsEphemeralAtIndex(i)) {
774 profiles_to_delete.push_back(profile_path);
775 if (profile_path.BaseName().MaybeAsASCII() == last_used_profile)
776 last_active_profile_deleted = true;
777 } else if (new_profile_path.empty()) {
778 new_profile_path = profile_path;
782 // If the last active profile was ephemeral, set a new one.
783 if (last_active_profile_deleted) {
784 if (new_profile_path.empty())
785 new_profile_path = GenerateNextProfileDirectoryPath();
787 profiles::SetLastUsedProfile(new_profile_path.BaseName().MaybeAsASCII());
790 // This uses a separate loop, because deleting the profile from the
791 // ProfileInfoCache will modify indices.
792 for (const base::FilePath& profile_path : profiles_to_delete) {
793 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
794 base::Bind(&NukeProfileFromDisk, profile_path));
796 profile_cache.DeleteProfileFromCache(profile_path);
800 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
801 TRACE_EVENT0("browser", "ProfileManager::InitProfileUserPrefs");
802 ProfileInfoCache& cache = GetProfileInfoCache();
804 if (profile->GetPath().DirName() != cache.GetUserDataDir())
805 return;
807 size_t avatar_index;
808 std::string profile_name;
809 std::string supervised_user_id;
810 if (profile->IsGuestSession()) {
811 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
812 avatar_index = 0;
813 } else {
814 size_t profile_cache_index =
815 cache.GetIndexOfProfileWithPath(profile->GetPath());
816 // If the cache has an entry for this profile, use the cache data.
817 if (profile_cache_index != std::string::npos) {
818 avatar_index =
819 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
820 profile_name =
821 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
822 supervised_user_id =
823 cache.GetSupervisedUserIdOfProfileAtIndex(profile_cache_index);
824 } else if (profile->GetPath() ==
825 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
826 // The --new-avatar-menu flag no longer uses the "First User" name.
827 bool is_new_avatar_menu = switches::IsNewAvatarMenu();
828 avatar_index = profiles::GetPlaceholderAvatarIndex();
829 profile_name = is_new_avatar_menu ?
830 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)) :
831 l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
832 } else {
833 avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
834 profile_name =
835 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
839 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
840 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
842 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
843 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
845 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
846 bool force_supervised_user_id =
847 #if defined(OS_CHROMEOS)
848 g_browser_process->platform_part()
849 ->profile_helper()
850 ->GetSigninProfileDir() != profile->GetPath() &&
851 #endif
852 command_line->HasSwitch(switches::kSupervisedUserId);
853 if (force_supervised_user_id) {
854 supervised_user_id =
855 command_line->GetSwitchValueASCII(switches::kSupervisedUserId);
857 if (force_supervised_user_id ||
858 !profile->GetPrefs()->HasPrefPath(prefs::kSupervisedUserId)) {
859 profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
860 supervised_user_id);
864 void ProfileManager::RegisterTestingProfile(Profile* profile,
865 bool add_to_cache,
866 bool start_deferred_task_runners) {
867 RegisterProfile(profile, true);
868 if (add_to_cache) {
869 InitProfileUserPrefs(profile);
870 AddProfileToCache(profile);
872 if (start_deferred_task_runners) {
873 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
874 StartDeferredTaskRunners();
878 void ProfileManager::Observe(
879 int type,
880 const content::NotificationSource& source,
881 const content::NotificationDetails& details) {
882 #if defined(OS_CHROMEOS)
883 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
884 logged_in_ = true;
886 const base::CommandLine& command_line =
887 *base::CommandLine::ForCurrentProcess();
888 if (!command_line.HasSwitch(switches::kTestType)) {
889 // If we don't have a mounted profile directory we're in trouble.
890 // TODO(davemoore) Once we have better api this check should ensure that
891 // our profile directory is the one that's mounted, and that it's mounted
892 // as the current user.
893 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
894 base::Bind(&CheckCryptohomeIsMounted));
896 // Confirm that we hadn't loaded the new profile previously.
897 base::FilePath default_profile_dir = user_data_dir_.Append(
898 GetInitialProfileDir());
899 CHECK(!GetProfileByPathInternal(default_profile_dir))
900 << "The default profile was loaded before we mounted the cryptohome.";
902 return;
904 #endif
905 bool save_active_profiles = false;
906 switch (type) {
907 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: {
908 // Ignore any browsers closing from now on.
909 closing_all_browsers_ = true;
910 save_active_profiles = true;
911 break;
913 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: {
914 // This will cancel the shutdown process, so the active profiles are
915 // tracked again. Also, as the active profiles may have changed (i.e. if
916 // some windows were closed) we save the current list of active profiles
917 // again.
918 closing_all_browsers_ = false;
919 save_active_profiles = true;
920 break;
922 case chrome::NOTIFICATION_BROWSER_OPENED: {
923 Browser* browser = content::Source<Browser>(source).ptr();
924 DCHECK(browser);
925 Profile* profile = browser->profile();
926 DCHECK(profile);
927 bool is_ephemeral =
928 profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles);
929 if (!profile->IsOffTheRecord() && !is_ephemeral &&
930 ++browser_counts_[profile] == 1) {
931 active_profiles_.push_back(profile);
932 save_active_profiles = true;
934 // If browsers are opening, we can't be closing all the browsers. This
935 // can happen if the application was exited, but background mode or
936 // packaged apps prevented the process from shutting down, and then
937 // a new browser window was opened.
938 closing_all_browsers_ = false;
939 break;
941 case chrome::NOTIFICATION_BROWSER_CLOSED: {
942 Browser* browser = content::Source<Browser>(source).ptr();
943 DCHECK(browser);
944 Profile* profile = browser->profile();
945 DCHECK(profile);
946 if (!profile->IsOffTheRecord() && --browser_counts_[profile] == 0) {
947 active_profiles_.erase(std::find(active_profiles_.begin(),
948 active_profiles_.end(), profile));
949 save_active_profiles = !closing_all_browsers_;
951 break;
953 default: {
954 NOTREACHED();
955 break;
959 if (save_active_profiles) {
960 PrefService* local_state = g_browser_process->local_state();
961 DCHECK(local_state);
962 ListPrefUpdate update(local_state, prefs::kProfilesLastActive);
963 base::ListValue* profile_list = update.Get();
965 profile_list->Clear();
967 // crbug.com/120112 -> several non-incognito profiles might have the same
968 // GetPath().BaseName(). In that case, we cannot restore both
969 // profiles. Include each base name only once in the last active profile
970 // list.
971 std::set<std::string> profile_paths;
972 std::vector<Profile*>::const_iterator it;
973 for (it = active_profiles_.begin(); it != active_profiles_.end(); ++it) {
974 std::string profile_path = (*it)->GetPath().BaseName().MaybeAsASCII();
975 // Some profiles might become ephemeral after they are created.
976 // Don't persist the System Profile as one of the last actives, it should
977 // never get a browser.
978 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
979 profile_paths.find(profile_path) == profile_paths.end() &&
980 profile_path !=
981 base::FilePath(chrome::kSystemProfileDir).AsUTF8Unsafe()) {
982 profile_paths.insert(profile_path);
983 profile_list->Append(new base::StringValue(profile_path));
989 void ProfileManager::OnProfileCreated(Profile* profile,
990 bool success,
991 bool is_new_profile) {
992 DCHECK_CURRENTLY_ON(BrowserThread::UI);
994 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath());
995 DCHECK(iter != profiles_info_.end());
996 ProfileInfo* info = iter->second.get();
998 std::vector<CreateCallback> callbacks;
999 info->callbacks.swap(callbacks);
1001 // Invoke CREATED callback for normal profiles.
1002 bool go_off_the_record = ShouldGoOffTheRecord(profile);
1003 if (success && !go_off_the_record)
1004 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
1006 // Perform initialization.
1007 if (success) {
1008 DoFinalInit(profile, go_off_the_record);
1009 if (go_off_the_record)
1010 profile = profile->GetOffTheRecordProfile();
1011 info->created = true;
1012 } else {
1013 profile = NULL;
1014 profiles_info_.erase(iter);
1015 // TODO(yiyaoliu): This is temporary, remove it after it's not used.
1016 UMA_HISTOGRAM_COUNTS_100("UMA.ProfilesCount.AfterErase",
1017 profiles_info_.size());
1020 if (profile) {
1021 // If this was the guest or system profile, finish setting its special
1022 // status.
1023 if (profile->IsGuestSession() || profile->IsSystemProfile())
1024 SetNonPersonalProfilePrefs(profile);
1026 // Invoke CREATED callback for incognito profiles.
1027 if (go_off_the_record)
1028 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
1031 // Invoke INITIALIZED or FAIL for all profiles.
1032 RunCallbacks(callbacks, profile,
1033 profile ? Profile::CREATE_STATUS_INITIALIZED :
1034 Profile::CREATE_STATUS_LOCAL_FAIL);
1037 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) {
1038 TRACE_EVENT0("browser", "ProfileManager::DoFinalInit");
1039 TRACK_SCOPED_REGION("Startup", "ProfileManager::DoFinalInit");
1041 DoFinalInitForServices(profile, go_off_the_record);
1042 AddProfileToCache(profile);
1043 DoFinalInitLogging(profile);
1045 ProfileMetrics::LogNumberOfProfiles(this);
1046 content::NotificationService::current()->Notify(
1047 chrome::NOTIFICATION_PROFILE_ADDED,
1048 content::Source<Profile>(profile),
1049 content::NotificationService::NoDetails());
1052 void ProfileManager::DoFinalInitForServices(Profile* profile,
1053 bool go_off_the_record) {
1054 TRACE_EVENT0("browser", "ProfileManager::DoFinalInitForServices");
1055 TRACK_SCOPED_REGION("Startup", "ProfileManager::DoFinalInitForServices");
1057 #if defined(ENABLE_EXTENSIONS)
1058 ProfileInfoCache& cache = GetProfileInfoCache();
1060 // Ensure that the HostContentSettingsMap has been created before the
1061 // ExtensionSystem is initialized otherwise the ExtensionSystem will be
1062 // registered twice
1063 HostContentSettingsMap* content_settings_map =
1064 HostContentSettingsMapFactory::GetForProfile(profile);
1066 extensions::ExtensionSystem::Get(profile)->InitForRegularProfile(
1067 !go_off_the_record);
1068 // During tests, when |profile| is an instance of TestingProfile,
1069 // ExtensionSystem might not create an ExtensionService.
1070 // This block is duplicated in the HostContentSettingsMapFactory
1071 // ::BuildServiceInstanceFor method, it should be called once when both the
1072 // HostContentSettingsMap and the extension_service are set up.
1073 if (extensions::ExtensionSystem::Get(profile)->extension_service()) {
1074 extensions::ExtensionSystem::Get(profile)->extension_service()->
1075 RegisterContentSettings(content_settings_map);
1077 // Set the block extensions bit on the ExtensionService. There likely are no
1078 // blockable extensions to block.
1079 size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
1080 if (profile_index != std::string::npos &&
1081 cache.ProfileIsSigninRequiredAtIndex(profile_index)) {
1082 extensions::ExtensionSystem::Get(profile)
1083 ->extension_service()
1084 ->BlockAllExtensions();
1087 #endif
1088 #if defined(ENABLE_SUPERVISED_USERS)
1089 // Initialization needs to happen after extension system initialization (for
1090 // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
1091 // initializing the supervised flag if necessary).
1092 ChildAccountServiceFactory::GetForProfile(profile)->Init();
1093 SupervisedUserServiceFactory::GetForProfile(profile)->Init();
1094 #endif
1095 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
1096 // If the lock enabled algorithm changed, update this profile's lock status.
1097 // This depends on services which shouldn't be initialized until
1098 // DoFinalInitForServices.
1099 if (switches::IsNewProfileManagement())
1100 profiles::UpdateIsProfileLockEnabledIfNeeded(profile);
1101 #endif
1102 // Start the deferred task runners once the profile is loaded.
1103 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
1104 StartDeferredTaskRunners();
1106 // Activate data reduction proxy. This creates a request context and makes a
1107 // URL request to check if the data reduction proxy server is reachable.
1108 DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile)->
1109 MaybeActivateDataReductionProxy(true);
1111 GaiaCookieManagerServiceFactory::GetForProfile(profile)->Init();
1112 AccountFetcherServiceFactory::GetForProfile(profile)->EnableNetworkFetches();
1113 AccountReconcilorFactory::GetForProfile(profile);
1116 void ProfileManager::DoFinalInitLogging(Profile* profile) {
1117 TRACE_EVENT0("browser", "ProfileManager::DoFinalInitLogging");
1118 // Count number of extensions in this profile.
1119 int enabled_app_count = -1;
1120 #if defined(ENABLE_EXTENSIONS)
1121 enabled_app_count = GetEnabledAppCount(profile);
1122 #endif
1124 // Log the profile size after a reasonable startup delay.
1125 BrowserThread::PostDelayedTask(
1126 BrowserThread::FILE, FROM_HERE,
1127 base::Bind(&ProfileSizeTask, profile->GetPath(), enabled_app_count),
1128 base::TimeDelta::FromSeconds(112));
1131 Profile* ProfileManager::CreateProfileHelper(const base::FilePath& path) {
1132 TRACE_EVENT0("browser", "ProfileManager::CreateProfileHelper");
1133 SCOPED_UMA_HISTOGRAM_TIMER("Profile.CreateProfileHelperTime");
1134 TRACK_SCOPED_REGION("Startup", "ProfileManager::CreateProfileHelper");
1136 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
1139 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path,
1140 Delegate* delegate) {
1141 return Profile::CreateProfile(path,
1142 delegate,
1143 Profile::CREATE_MODE_ASYNCHRONOUS);
1146 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
1147 const base::FilePath& user_data_dir) {
1148 #if defined(OS_CHROMEOS)
1149 base::FilePath default_profile_dir(user_data_dir);
1150 if (!logged_in_) {
1151 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1152 Profile* profile = GetProfile(default_profile_dir);
1153 // For cros, return the OTR profile so we never accidentally keep
1154 // user data in an unencrypted profile. But doing this makes
1155 // many of the browser and ui tests fail. We do return the OTR profile
1156 // if the login-profile switch is passed so that we can test this.
1157 if (ShouldGoOffTheRecord(profile))
1158 return profile->GetOffTheRecordProfile();
1159 DCHECK(!user_manager::UserManager::Get()->IsLoggedInAsGuest());
1160 return profile;
1163 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1164 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
1165 // Fallback to default off-the-record profile, if user profile has not fully
1166 // loaded yet.
1167 if (profile_info && !profile_info->created)
1168 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
1170 Profile* profile = GetProfile(default_profile_dir);
1171 // Some unit tests didn't initialize the UserManager.
1172 if (user_manager::UserManager::IsInitialized() &&
1173 user_manager::UserManager::Get()->IsLoggedInAsGuest())
1174 return profile->GetOffTheRecordProfile();
1175 return profile;
1176 #else
1177 base::FilePath default_profile_dir(user_data_dir);
1178 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1179 return GetProfile(default_profile_dir);
1180 #endif
1183 bool ProfileManager::AddProfile(Profile* profile) {
1184 TRACE_EVENT0("browser", "ProfileManager::AddProfile");
1185 TRACK_SCOPED_REGION("Startup", "ProfileManager::AddProfile");
1187 DCHECK(profile);
1189 // Make sure that we're not loading a profile with the same ID as a profile
1190 // that's already loaded.
1191 if (GetProfileByPathInternal(profile->GetPath())) {
1192 NOTREACHED() << "Attempted to add profile with the same path (" <<
1193 profile->GetPath().value() <<
1194 ") as an already-loaded profile.";
1195 return false;
1198 RegisterProfile(profile, true);
1199 InitProfileUserPrefs(profile);
1200 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
1201 return true;
1204 Profile* ProfileManager::CreateAndInitializeProfile(
1205 const base::FilePath& profile_dir) {
1206 TRACE_EVENT0("browser", "ProfileManager::CreateAndInitializeProfile");
1207 TRACK_SCOPED_REGION(
1208 "Startup", "ProfileManager::CreateAndInitializeProfile");
1209 SCOPED_UMA_HISTOGRAM_LONG_TIMER("Profile.CreateAndInitializeProfile");
1211 // CHECK that we are not trying to load the same profile twice, to prevent
1212 // profile corruption. Note that this check also covers the case when we have
1213 // already started loading the profile but it is not fully initialized yet,
1214 // which would make Bad Things happen if we returned it.
1215 CHECK(!GetProfileByPathInternal(profile_dir));
1216 Profile* profile = CreateProfileHelper(profile_dir);
1217 DCHECK(profile);
1218 if (profile) {
1219 bool result = AddProfile(profile);
1220 DCHECK(result);
1222 return profile;
1225 void ProfileManager::FinishDeletingProfile(
1226 const base::FilePath& profile_dir,
1227 const base::FilePath& new_active_profile_dir) {
1228 // Update the last used profile pref before closing browser windows. This
1229 // way the correct last used profile is set for any notification observers.
1230 profiles::SetLastUsedProfile(
1231 new_active_profile_dir.BaseName().MaybeAsASCII());
1233 ProfileInfoCache& cache = GetProfileInfoCache();
1234 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1235 // start deleting the profile instance we need to close background apps too.
1236 Profile* profile = GetProfileByPath(profile_dir);
1238 if (profile) {
1239 // TODO: Migrate additional code in this block to observe this notification
1240 // instead of being implemented here.
1241 content::NotificationService::current()->Notify(
1242 chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
1243 content::Source<Profile>(profile),
1244 content::NotificationService::NoDetails());
1246 // By this point, all in-progress downloads for the profile being deleted
1247 // must have been canceled (crbug.com/336725).
1248 DCHECK(DownloadServiceFactory::GetForBrowserContext(profile)->
1249 NonMaliciousDownloadCount() == 0);
1250 BrowserList::CloseAllBrowsersWithProfile(profile);
1252 // Disable sync for doomed profile.
1253 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1254 profile)) {
1255 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1256 profile)->RequestStop(ProfileSyncService::CLEAR_DATA);
1259 ProfileMetrics::LogProfileDelete(cache.ProfileIsAuthenticatedAtIndex(
1260 cache.GetIndexOfProfileWithPath(profile_dir)));
1261 // Some platforms store passwords in keychains. They should be removed.
1262 scoped_refptr<password_manager::PasswordStore> password_store =
1263 PasswordStoreFactory::GetForProfile(
1264 profile, ServiceAccessType::EXPLICIT_ACCESS).get();
1265 if (password_store.get()) {
1266 password_store->RemoveLoginsCreatedBetween(
1267 base::Time(), base::Time::Max(), base::Closure());
1270 // The Profile Data doesn't get wiped until Chrome closes. Since we promised
1271 // that the user's data would be removed, do so immediately.
1272 profiles::RemoveBrowsingDataForProfile(profile_dir);
1273 } else {
1274 // It is safe to delete a not yet loaded Profile from disk.
1275 BrowserThread::PostTask(
1276 BrowserThread::FILE, FROM_HERE,
1277 base::Bind(&NukeProfileFromDisk, profile_dir));
1280 // Queue even a profile that was nuked so it will be MarkedForDeletion and so
1281 // CreateProfileAsync can't create it.
1282 QueueProfileDirectoryForDeletion(profile_dir);
1283 cache.DeleteProfileFromCache(profile_dir);
1284 ProfileMetrics::UpdateReportedProfilesStatistics(this);
1287 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
1288 Profile* profile,
1289 bool created) {
1290 TRACE_EVENT0("browser", "ProfileManager::RegisterProfile");
1291 ProfileInfo* info = new ProfileInfo(profile, created);
1292 profiles_info_.insert(
1293 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
1294 return info;
1297 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath(
1298 const base::FilePath& path) const {
1299 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
1300 return (iter == profiles_info_.end()) ? NULL : iter->second.get();
1303 void ProfileManager::AddProfileToCache(Profile* profile) {
1304 TRACE_EVENT0("browser", "ProfileManager::AddProfileToCache");
1305 if (profile->IsGuestSession() || profile->IsSystemProfile())
1306 return;
1307 ProfileInfoCache& cache = GetProfileInfoCache();
1308 if (profile->GetPath().DirName() != cache.GetUserDataDir())
1309 return;
1311 SigninManagerBase* signin_manager =
1312 SigninManagerFactory::GetForProfile(profile);
1313 AccountTrackerService* account_tracker =
1314 AccountTrackerServiceFactory::GetForProfile(profile);
1315 AccountInfo account_info = account_tracker->GetAccountInfo(
1316 signin_manager->GetAuthenticatedAccountId());
1317 base::string16 username = base::UTF8ToUTF16(account_info.email);
1319 size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
1320 if (profile_index != std::string::npos) {
1321 // The ProfileInfoCache's info must match the Signin Manager.
1322 cache.SetAuthInfoOfProfileAtIndex(profile_index, account_info.gaia,
1323 username);
1324 return;
1327 // Profile name and avatar are set by InitProfileUserPrefs and stored in the
1328 // profile. Use those values to setup the cache entry.
1329 base::string16 profile_name =
1330 base::UTF8ToUTF16(profile->GetPrefs()->GetString(prefs::kProfileName));
1332 size_t icon_index = profile->GetPrefs()->GetInteger(
1333 prefs::kProfileAvatarIndex);
1335 std::string supervised_user_id =
1336 profile->GetPrefs()->GetString(prefs::kSupervisedUserId);
1338 cache.AddProfileToCache(profile->GetPath(),
1339 profile_name,
1340 account_info.gaia,
1341 username,
1342 icon_index,
1343 supervised_user_id);
1345 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) {
1346 cache.SetProfileIsEphemeralAtIndex(
1347 cache.GetIndexOfProfileWithPath(profile->GetPath()), true);
1351 void ProfileManager::SetNonPersonalProfilePrefs(Profile* profile) {
1352 PrefService* prefs = profile->GetPrefs();
1353 prefs->SetBoolean(prefs::kSigninAllowed, false);
1354 prefs->SetBoolean(bookmarks::prefs::kEditBookmarksEnabled, false);
1355 prefs->SetBoolean(bookmarks::prefs::kShowBookmarkBar, false);
1356 prefs->ClearPref(DefaultSearchManager::kDefaultSearchProviderDataPrefName);
1359 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) {
1360 #if defined(OS_CHROMEOS)
1361 if (profile->GetPath().BaseName().value() == chrome::kInitialProfile) {
1362 return true;
1364 #endif
1365 return profile->IsGuestSession() || profile->IsSystemProfile();
1368 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks,
1369 Profile* profile,
1370 Profile::CreateStatus status) {
1371 for (size_t i = 0; i < callbacks.size(); ++i)
1372 callbacks[i].Run(profile, status);
1375 ProfileManager::ProfileInfo::ProfileInfo(
1376 Profile* profile,
1377 bool created)
1378 : profile(profile),
1379 created(created) {
1382 ProfileManager::ProfileInfo::~ProfileInfo() {
1383 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1386 #if !defined(OS_ANDROID) && !defined(OS_IOS)
1387 void ProfileManager::UpdateLastUser(Profile* last_active) {
1388 PrefService* local_state = g_browser_process->local_state();
1389 DCHECK(local_state);
1390 // Only keep track of profiles that we are managing; tests may create others.
1391 // Also never consider the SystemProfile as "active".
1392 if (profiles_info_.find(last_active->GetPath()) != profiles_info_.end() &&
1393 !last_active->IsSystemProfile()) {
1394 std::string profile_path_base =
1395 last_active->GetPath().BaseName().MaybeAsASCII();
1396 if (profile_path_base != GetLastUsedProfileName())
1397 profiles::SetLastUsedProfile(profile_path_base);
1399 ProfileInfoCache& cache = GetProfileInfoCache();
1400 size_t profile_index =
1401 cache.GetIndexOfProfileWithPath(last_active->GetPath());
1402 if (profile_index != std::string::npos) {
1403 #if !defined(OS_CHROMEOS)
1404 // Incognito Profiles don't have ProfileKeyedServices.
1405 if (!last_active->IsOffTheRecord()) {
1406 CrossDevicePromoFactory::GetForProfile(last_active)
1407 ->MaybeBrowsingSessionStarted(
1408 cache.GetProfileActiveTimeAtIndex(profile_index));
1410 #endif
1411 cache.SetProfileActiveTimeAtIndex(profile_index);
1416 ProfileManager::BrowserListObserver::BrowserListObserver(
1417 ProfileManager* manager)
1418 : profile_manager_(manager) {
1419 BrowserList::AddObserver(this);
1422 ProfileManager::BrowserListObserver::~BrowserListObserver() {
1423 BrowserList::RemoveObserver(this);
1426 void ProfileManager::BrowserListObserver::OnBrowserAdded(
1427 Browser* browser) {}
1429 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
1430 Browser* browser) {
1431 Profile* profile = browser->profile();
1432 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1433 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1434 // Not the last window for this profile.
1435 return;
1438 // If the last browser of a profile that is scheduled for deletion is closed
1439 // do that now.
1440 base::FilePath path = profile->GetPath();
1441 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
1442 !IsProfileMarkedForDeletion(path)) {
1443 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
1444 path, ProfileManager::CreateCallback());
1448 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
1449 Browser* browser) {
1450 // If all browsers are being closed (e.g. the user is in the process of
1451 // shutting down), this event will be fired after each browser is
1452 // closed. This does not represent a user intention to change the active
1453 // browser so is not handled here.
1454 if (profile_manager_->closing_all_browsers_)
1455 return;
1457 Profile* last_active = browser->profile();
1459 // Don't remember ephemeral profiles as last because they are not going to
1460 // persist after restart.
1461 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
1462 return;
1464 profile_manager_->UpdateLastUser(last_active);
1466 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
1468 void ProfileManager::OnNewActiveProfileLoaded(
1469 const base::FilePath& profile_to_delete_path,
1470 const base::FilePath& new_active_profile_path,
1471 const CreateCallback& original_callback,
1472 Profile* loaded_profile,
1473 Profile::CreateStatus status) {
1474 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
1475 status != Profile::CREATE_STATUS_REMOTE_FAIL);
1477 // Only run the code if the profile initialization has finished completely.
1478 if (status != Profile::CREATE_STATUS_INITIALIZED)
1479 return;
1481 if (IsProfileMarkedForDeletion(new_active_profile_path)) {
1482 // If the profile we tried to load as the next active profile has been
1483 // deleted, then retry deleting this profile to redo the logic to load
1484 // the next available profile.
1485 ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
1486 return;
1489 FinishDeletingProfile(profile_to_delete_path, new_active_profile_path);
1490 if (!original_callback.is_null())
1491 original_callback.Run(loaded_profile, status);
1494 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1495 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) {