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