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