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