Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(476)

Side by Side Diff: chrome/browser/profiles/profile_manager.cc

Issue 132713002: Getting rid of GetDefaultProfile(), clean up of ProfileManager (which was in a serious mess) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed macos build problems Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/profiles/profile_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/profiles/profile_manager.h" 5 #include "chrome/browser/profiles/profile_manager.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 return; 183 return;
184 } 184 }
185 if (!is_mounted) 185 if (!is_mounted)
186 LOG(ERROR) << "Cryptohome is not mounted."; 186 LOG(ERROR) << "Cryptohome is not mounted.";
187 } 187 }
188 188
189 #endif 189 #endif
190 190
191 } // namespace 191 } // namespace
192 192
193 ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
194 : user_data_dir_(user_data_dir),
195 logged_in_(false),
196 #if !defined(OS_ANDROID) && !defined(OS_IOS)
197 browser_list_observer_(this),
198 #endif
199 closing_all_browsers_(false) {
200 #if defined(OS_CHROMEOS)
201 registrar_.Add(
202 this,
203 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
204 content::NotificationService::AllSources());
205 #endif
206 registrar_.Add(
207 this,
208 chrome::NOTIFICATION_BROWSER_OPENED,
209 content::NotificationService::AllSources());
210 registrar_.Add(
211 this,
212 chrome::NOTIFICATION_BROWSER_CLOSED,
213 content::NotificationService::AllSources());
214 registrar_.Add(
215 this,
216 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
217 content::NotificationService::AllSources());
218 registrar_.Add(
219 this,
220 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
221 content::NotificationService::AllSources());
222 registrar_.Add(
223 this,
224 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
225 content::NotificationService::AllSources());
226
227 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty())
228 profile_shortcut_manager_.reset(ProfileShortcutManager::Create(
229 this));
230 }
231
232 ProfileManager::~ProfileManager() {
233 }
234
193 #if defined(ENABLE_SESSION_SERVICE) 235 #if defined(ENABLE_SESSION_SERVICE)
194 // static 236 // static
195 void ProfileManager::ShutdownSessionServices() { 237 void ProfileManager::ShutdownSessionServices() {
196 ProfileManager* pm = g_browser_process->profile_manager(); 238 ProfileManager* pm = g_browser_process->profile_manager();
197 if (!pm) // Is NULL when running unit tests. 239 if (!pm) // Is NULL when running unit tests.
198 return; 240 return;
199 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); 241 std::vector<Profile*> profiles(pm->GetLoadedProfiles());
200 for (size_t i = 0; i < profiles.size(); ++i) 242 for (size_t i = 0; i < profiles.size(); ++i)
201 SessionServiceFactory::ShutdownForProfile(profiles[i]); 243 SessionServiceFactory::ShutdownForProfile(profiles[i]);
202 } 244 }
203 #endif 245 #endif
204 246
205 // static 247 // static
206 void ProfileManager::NukeDeletedProfilesFromDisk() { 248 void ProfileManager::NukeDeletedProfilesFromDisk() {
207 for (std::vector<base::FilePath>::iterator it = 249 for (std::vector<base::FilePath>::iterator it =
208 ProfilesToDelete().begin(); 250 ProfilesToDelete().begin();
209 it != ProfilesToDelete().end(); 251 it != ProfilesToDelete().end();
210 ++it) { 252 ++it) {
211 NukeProfileFromDisk(*it); 253 NukeProfileFromDisk(*it);
212 } 254 }
213 ProfilesToDelete().clear(); 255 ProfilesToDelete().clear();
214 } 256 }
215 257
216 // static 258 // static
217 // TODO(skuhne): Remove this method once all clients are migrated.
218 Profile* ProfileManager::GetDefaultProfile() {
219 ProfileManager* profile_manager = g_browser_process->profile_manager();
220 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
221 profile_manager->user_data_dir_);
222 }
223
224 // static
225 Profile* ProfileManager::GetLastUsedProfile() { 259 Profile* ProfileManager::GetLastUsedProfile() {
226 ProfileManager* profile_manager = g_browser_process->profile_manager(); 260 ProfileManager* profile_manager = g_browser_process->profile_manager();
227 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_); 261 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_);
228 } 262 }
229 263
230 // static 264 // static
231 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() { 265 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() {
232 Profile* profile = GetLastUsedProfile(); 266 Profile* profile = GetLastUsedProfile();
233 if (IncognitoModePrefs::GetAvailability(profile->GetPrefs()) == 267 if (IncognitoModePrefs::GetAvailability(profile->GetPrefs()) ==
234 IncognitoModePrefs::FORCED) { 268 IncognitoModePrefs::FORCED) {
235 return profile->GetOffTheRecordProfile(); 269 return profile->GetOffTheRecordProfile();
236 } 270 }
237 return profile; 271 return profile;
238 } 272 }
239 273
240 // static 274 // static
241 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() { 275 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() {
242 ProfileManager* profile_manager = g_browser_process->profile_manager(); 276 ProfileManager* profile_manager = g_browser_process->profile_manager();
243 return profile_manager->GetLastOpenedProfiles( 277 return profile_manager->GetLastOpenedProfiles(
244 profile_manager->user_data_dir_); 278 profile_manager->user_data_dir_);
245 } 279 }
246 280
247 ProfileManager::ProfileManager(const base::FilePath& user_data_dir) 281 // static
248 : user_data_dir_(user_data_dir), 282 Profile* ProfileManager::GetPrimaryUserProfile() {
249 logged_in_(false), 283 ProfileManager* profile_manager = g_browser_process->profile_manager();
250 284 #if defined(OS_CHROMEOS)
251 #if !defined(OS_ANDROID) && !defined(OS_IOS) 285 if (!profile_manager->IsLoggedIn() || !chromeos::UserManager::IsInitialized())
252 browser_list_observer_(this), 286 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
287 profile_manager->user_data_dir());
288 chromeos::UserManager* manager = chromeos::UserManager::Get();
289 // Note: The user manager will take care of guest profiles.
290 return manager->GetProfileByUser(manager->GetPrimaryUser());
291 #else
292 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
293 profile_manager->user_data_dir());
253 #endif 294 #endif
254 closing_all_browsers_(false) {
255 #if defined(OS_CHROMEOS)
256 registrar_.Add(
257 this,
258 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
259 content::NotificationService::AllSources());
260 #endif
261 registrar_.Add(
262 this,
263 chrome::NOTIFICATION_BROWSER_OPENED,
264 content::NotificationService::AllSources());
265 registrar_.Add(
266 this,
267 chrome::NOTIFICATION_BROWSER_CLOSED,
268 content::NotificationService::AllSources());
269 registrar_.Add(
270 this,
271 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
272 content::NotificationService::AllSources());
273 registrar_.Add(
274 this,
275 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
276 content::NotificationService::AllSources());
277 registrar_.Add(
278 this,
279 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
280 content::NotificationService::AllSources());
281
282 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty())
283 profile_shortcut_manager_.reset(ProfileShortcutManager::Create(
284 this));
285 } 295 }
286 296
287 ProfileManager::~ProfileManager() { 297 // static
298 Profile* ProfileManager::GetActiveUserProfile() {
299 ProfileManager* profile_manager = g_browser_process->profile_manager();
300 #if defined(OS_CHROMEOS)
301 if (!chromeos::UserManager::IsMultipleProfilesAllowed() ||
302 !profile_manager->IsLoggedIn() ||
303 !chromeos::UserManager::IsInitialized())
304 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
305 profile_manager->user_data_dir());
306 chromeos::UserManager* manager = chromeos::UserManager::Get();
307 // Note: The user manager will take care of guest profiles.
308 return manager->GetProfileByUser(manager->GetActiveUser());
309 #else
310 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath(
311 profile_manager->user_data_dir());
312 #endif
313 }
314
315 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) {
316 TRACE_EVENT0("browser", "ProfileManager::GetProfile")
317 // If the profile is already loaded (e.g., chrome.exe launched twice), just
318 // return it.
319 Profile* profile = GetProfileByPath(profile_dir);
320 if (NULL != profile)
321 return profile;
322
323 profile = CreateProfileHelper(profile_dir);
324 DCHECK(profile);
325 if (profile) {
326 bool result = AddProfile(profile);
327 DCHECK(result);
328 }
329 return profile;
330 }
331
332 size_t ProfileManager::GetNumberOfProfiles() {
333 return GetProfileInfoCache().GetNumberOfProfiles();
334 }
335
336 void ProfileManager::CreateProfileAsync(
337 const base::FilePath& profile_path,
338 const CreateCallback& callback,
339 const base::string16& name,
340 const base::string16& icon_url,
341 const std::string& managed_user_id) {
342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
343
344 // Make sure that this profile is not pending deletion.
345 if (IsProfileMarkedForDeletion(profile_path)) {
346 if (!callback.is_null())
347 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
348 return;
349 }
350
351 // Create the profile if needed and collect its ProfileInfo.
352 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
353 ProfileInfo* info = NULL;
354
355 if (iter != profiles_info_.end()) {
356 info = iter->second.get();
357 } else {
358 // Initiate asynchronous creation process.
359 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false);
360 ProfileInfoCache& cache = GetProfileInfoCache();
361 // Get the icon index from the user's icon url
362 size_t icon_index;
363 std::string icon_url_std = UTF16ToASCII(icon_url);
364 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) {
365 // add profile to cache with user selected name and avatar
366 cache.AddProfileToCache(profile_path, name, base::string16(), icon_index,
367 managed_user_id);
368 }
369
370 if (!managed_user_id.empty()) {
371 content::RecordAction(
372 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
373 }
374
375 ProfileMetrics::UpdateReportedProfilesStatistics(this);
376 }
377
378 // Call or enqueue the callback.
379 if (!callback.is_null()) {
380 if (iter != profiles_info_.end() && info->created) {
381 Profile* profile = info->profile.get();
382 // If this was the guest profile, apply settings.
383 if (profile->GetPath() == ProfileManager::GetGuestProfilePath())
384 SetGuestProfilePrefs(profile);
385 // Profile has already been created. Run callback immediately.
386 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
387 } else {
388 // Profile is either already in the process of being created, or new.
389 // Add callback to the list.
390 info->callbacks.push_back(callback);
391 }
392 }
393 }
394
395 bool ProfileManager::IsValidProfile(Profile* profile) {
396 for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
397 iter != profiles_info_.end(); ++iter) {
398 if (iter->second->created) {
399 Profile* candidate = iter->second->profile.get();
400 if (candidate == profile ||
401 (candidate->HasOffTheRecordProfile() &&
402 candidate->GetOffTheRecordProfile() == profile)) {
403 return true;
404 }
405 }
406 }
407 return false;
288 } 408 }
289 409
290 base::FilePath ProfileManager::GetInitialProfileDir() { 410 base::FilePath ProfileManager::GetInitialProfileDir() {
291 base::FilePath relative_profile_dir; 411 base::FilePath relative_profile_dir;
292 #if defined(OS_CHROMEOS) 412 #if defined(OS_CHROMEOS)
293 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 413 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
294 if (logged_in_) { 414 if (logged_in_) {
295 base::FilePath profile_dir; 415 base::FilePath profile_dir;
296 // If the user has logged in, pick up the new profile. 416 // If the user has logged in, pick up the new profile.
297 if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) { 417 if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 if (!(*it)->GetAsString(&profile) || profile.empty()) { 510 if (!(*it)->GetAsString(&profile) || profile.empty()) {
391 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive; 511 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive;
392 continue; 512 continue;
393 } 513 }
394 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile))); 514 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile)));
395 } 515 }
396 } 516 }
397 return to_return; 517 return to_return;
398 } 518 }
399 519
400 Profile* ProfileManager::GetPrimaryUserProfile() {
401 #if defined(OS_CHROMEOS)
402 ProfileManager* profile_manager = g_browser_process->profile_manager();
403 if (!profile_manager->IsLoggedIn() || !chromeos::UserManager::IsInitialized())
404 return GetDefaultProfile();
405 chromeos::UserManager* manager = chromeos::UserManager::Get();
406 // Note: The user manager will take care of guest profiles.
407 return manager->GetProfileByUser(manager->GetPrimaryUser());
408 #else
409 return GetDefaultProfile();
410 #endif
411 }
412
413 Profile* ProfileManager::GetActiveUserProfile() {
414 #if defined(OS_CHROMEOS)
415 ProfileManager* profile_manager = g_browser_process->profile_manager();
416 if (!chromeos::UserManager::IsMultipleProfilesAllowed() ||
417 !profile_manager->IsLoggedIn() ||
418 !chromeos::UserManager::IsInitialized())
419 return GetDefaultProfile();
420 chromeos::UserManager* manager = chromeos::UserManager::Get();
421 // Note: The user manager will take care of guest profiles.
422 return manager->GetProfileByUser(manager->GetActiveUser());
423 #else
424 return GetDefaultProfile();
425 #endif
426 }
427
428 bool ProfileManager::IsValidProfile(Profile* profile) {
429 for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
430 iter != profiles_info_.end(); ++iter) {
431 if (iter->second->created) {
432 Profile* candidate = iter->second->profile.get();
433 if (candidate == profile ||
434 (candidate->HasOffTheRecordProfile() &&
435 candidate->GetOffTheRecordProfile() == profile)) {
436 return true;
437 }
438 }
439 }
440 return false;
441 }
442
443 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const { 520 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const {
444 std::vector<Profile*> profiles; 521 std::vector<Profile*> profiles;
445 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin(); 522 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin();
446 iter != profiles_info_.end(); ++iter) { 523 iter != profiles_info_.end(); ++iter) {
447 if (iter->second->created) 524 if (iter->second->created)
448 profiles.push_back(iter->second->profile.get()); 525 profiles.push_back(iter->second->profile.get());
449 } 526 }
450 return profiles; 527 return profiles;
451 } 528 }
452 529
453 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) {
454 TRACE_EVENT0("browser", "ProfileManager::GetProfile")
455 // If the profile is already loaded (e.g., chrome.exe launched twice), just
456 // return it.
457 Profile* profile = GetProfileByPath(profile_dir);
458 if (NULL != profile)
459 return profile;
460
461 profile = CreateProfileHelper(profile_dir);
462 DCHECK(profile);
463 if (profile) {
464 bool result = AddProfile(profile);
465 DCHECK(result);
466 }
467 return profile;
468 }
469
470 void ProfileManager::CreateProfileAsync(
471 const base::FilePath& profile_path,
472 const CreateCallback& callback,
473 const base::string16& name,
474 const base::string16& icon_url,
475 const std::string& managed_user_id) {
476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
477
478 // Make sure that this profile is not pending deletion.
479 if (IsProfileMarkedForDeletion(profile_path)) {
480 if (!callback.is_null())
481 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL);
482 return;
483 }
484
485 // Create the profile if needed and collect its ProfileInfo.
486 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path);
487 ProfileInfo* info = NULL;
488
489 if (iter != profiles_info_.end()) {
490 info = iter->second.get();
491 } else {
492 // Initiate asynchronous creation process.
493 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false);
494 ProfileInfoCache& cache = GetProfileInfoCache();
495 // Get the icon index from the user's icon url
496 size_t icon_index;
497 std::string icon_url_std = UTF16ToASCII(icon_url);
498 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) {
499 // add profile to cache with user selected name and avatar
500 cache.AddProfileToCache(profile_path, name, base::string16(), icon_index,
501 managed_user_id);
502 }
503
504 if (!managed_user_id.empty()) {
505 content::RecordAction(
506 UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
507 }
508
509 ProfileMetrics::UpdateReportedProfilesStatistics(this);
510 }
511
512 // Call or enqueue the callback.
513 if (!callback.is_null()) {
514 if (iter != profiles_info_.end() && info->created) {
515 Profile* profile = info->profile.get();
516 // If this was the guest profile, apply settings.
517 if (profile->GetPath() == ProfileManager::GetGuestProfilePath())
518 SetGuestProfilePrefs(profile);
519 // Profile has already been created. Run callback immediately.
520 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
521 } else {
522 // Profile is either already in the process of being created, or new.
523 // Add callback to the list.
524 info->callbacks.push_back(callback);
525 }
526 }
527 }
528
529 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
530 const base::FilePath& user_data_dir) {
531 #if defined(OS_CHROMEOS)
532 base::FilePath default_profile_dir(user_data_dir);
533 if (!logged_in_) {
534 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
535 Profile* profile = GetProfile(default_profile_dir);
536 // For cros, return the OTR profile so we never accidentally keep
537 // user data in an unencrypted profile. But doing this makes
538 // many of the browser and ui tests fail. We do return the OTR profile
539 // if the login-profile switch is passed so that we can test this.
540 if (ShouldGoOffTheRecord(profile))
541 return profile->GetOffTheRecordProfile();
542 DCHECK(!chromeos::UserManager::Get()->IsLoggedInAsGuest());
543 return profile;
544 }
545
546 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
547 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
548 // Fallback to default off-the-record profile, if user profile has not fully
549 // loaded yet.
550 if (profile_info && !profile_info->created)
551 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
552
553 Profile* profile = GetProfile(default_profile_dir);
554 // Some unit tests didn't initialize the UserManager.
555 if (chromeos::UserManager::IsInitialized() &&
556 chromeos::UserManager::Get()->IsLoggedInAsGuest())
557 return profile->GetOffTheRecordProfile();
558 return profile;
559 #else
560 base::FilePath default_profile_dir(user_data_dir);
561 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
562 return GetProfile(default_profile_dir);
563 #endif
564 }
565
566 bool ProfileManager::AddProfile(Profile* profile) {
567 DCHECK(profile);
568
569 // Make sure that we're not loading a profile with the same ID as a profile
570 // that's already loaded.
571 if (GetProfileByPath(profile->GetPath())) {
572 NOTREACHED() << "Attempted to add profile with the same path (" <<
573 profile->GetPath().value() <<
574 ") as an already-loaded profile.";
575 return false;
576 }
577
578 RegisterProfile(profile, true);
579 InitProfileUserPrefs(profile);
580 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
581 return true;
582 }
583
584 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
585 Profile* profile,
586 bool created) {
587 ProfileInfo* info = new ProfileInfo(profile, created);
588 profiles_info_.insert(
589 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
590 return info;
591 }
592
593 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath(
594 const base::FilePath& path) const {
595 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
596 return (iter == profiles_info_.end()) ? NULL : iter->second.get();
597 }
598
599 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { 530 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const {
600 ProfileInfo* profile_info = GetProfileInfoByPath(path); 531 ProfileInfo* profile_info = GetProfileInfoByPath(path);
601 return profile_info ? profile_info->profile.get() : NULL; 532 return profile_info ? profile_info->profile.get() : NULL;
602 } 533 }
603 534
535 // static
536 base::FilePath ProfileManager::CreateMultiProfileAsync(
537 const base::string16& name,
538 const base::string16& icon_url,
539 const CreateCallback& callback,
540 const std::string& managed_user_id) {
541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
542
543 ProfileManager* profile_manager = g_browser_process->profile_manager();
544
545 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
546
547 profile_manager->CreateProfileAsync(new_path,
548 callback,
549 name,
550 icon_url,
551 managed_user_id);
552 return new_path;
553 }
554
555 // static
556 base::FilePath ProfileManager::GetGuestProfilePath() {
557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
558
559 ProfileManager* profile_manager = g_browser_process->profile_manager();
560
561 base::FilePath guest_path = profile_manager->user_data_dir();
562 return guest_path.Append(chrome::kGuestProfileDir);
563 }
564
565 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() {
566 PrefService* local_state = g_browser_process->local_state();
567 DCHECK(local_state);
568
569 DCHECK(profiles::IsMultipleProfilesEnabled());
570
571 // Create the next profile in the next available directory slot.
572 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated);
573 std::string profile_name = chrome::kMultiProfileDirPrefix;
574 profile_name.append(base::IntToString(next_directory));
575 base::FilePath new_path = user_data_dir_;
576 #if defined(OS_WIN)
577 new_path = new_path.Append(base::ASCIIToUTF16(profile_name));
578 #else
579 new_path = new_path.Append(profile_name);
580 #endif
581 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory);
582 return new_path;
583 }
584
585 ProfileInfoCache& ProfileManager::GetProfileInfoCache() {
586 if (!profile_info_cache_) {
587 profile_info_cache_.reset(new ProfileInfoCache(
588 g_browser_process->local_state(), user_data_dir_));
589 }
590 return *profile_info_cache_.get();
591 }
592
593 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
594 return profile_shortcut_manager_.get();
595 }
596
597 void ProfileManager::ScheduleProfileForDeletion(
598 const base::FilePath& profile_dir,
599 const CreateCallback& callback) {
600 DCHECK(profiles::IsMultipleProfilesEnabled());
601 PrefService* local_state = g_browser_process->local_state();
602 ProfileInfoCache& cache = GetProfileInfoCache();
603
604 if (profile_dir.BaseName().MaybeAsASCII() ==
605 local_state->GetString(prefs::kProfileLastUsed)) {
606 // Update the last used profile pref before closing browser windows. This
607 // way the correct last used profile is set for any notification observers.
608 base::FilePath last_non_managed_profile_path;
609 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
610 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
611 // Make sure that this profile is not pending deletion.
612 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) &&
613 !IsProfileMarkedForDeletion(cur_path)) {
614 last_non_managed_profile_path = cur_path;
615 break;
616 }
617 }
618
619 // If we're deleting the last (non-managed) profile, then create a new
620 // profile in its place.
621 const std::string last_non_managed_profile =
622 last_non_managed_profile_path.BaseName().MaybeAsASCII();
623 if (last_non_managed_profile.empty()) {
624 base::FilePath new_path = GenerateNextProfileDirectoryPath();
625 // Make sure the last used profile path is pointing at it. This way the
626 // correct last used profile is set for any notification observers.
627 local_state->SetString(prefs::kProfileLastUsed,
628 new_path.BaseName().MaybeAsASCII());
629 CreateProfileAsync(new_path,
630 callback,
631 base::string16(),
632 base::string16(),
633 std::string());
634 } else {
635 // On the Mac, the browser process is not killed when all browser windows
636 // are closed, so just in case we are deleting the active profile, and no
637 // other profile has been loaded, we must pre-load a next one.
638 #if defined(OS_MACOSX)
639 CreateProfileAsync(last_non_managed_profile_path,
640 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
641 base::Unretained(this),
642 profile_dir,
643 last_non_managed_profile_path,
644 callback),
645 base::string16(),
646 base::string16(),
647 std::string());
648 return;
649 #else
650 // For OS_MACOSX the pref is updated in the callback to make sure that
651 // it isn't used before the profile is actually loaded.
652 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile);
653 #endif
654 }
655 }
656 FinishDeletingProfile(profile_dir);
657 }
658
659 // static
660 void ProfileManager::CleanUpStaleProfiles(
661 const std::vector<base::FilePath>& profile_paths) {
662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
663
664 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin();
665 it != profile_paths.end(); ++it) {
666 NukeProfileFromDisk(*it);
667 }
668 }
669
670 void ProfileManager::AutoloadProfiles() {
671 // If running in the background is disabled for the browser, do not autoload
672 // any profiles.
673 PrefService* local_state = g_browser_process->local_state();
674 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
675 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
676 return;
677 }
678
679 ProfileInfoCache& cache = GetProfileInfoCache();
680 size_t number_of_profiles = cache.GetNumberOfProfiles();
681 for (size_t p = 0; p < number_of_profiles; ++p) {
682 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) {
683 // If status is true, that profile is running background apps. By calling
684 // GetProfile, we automatically cause the profile to be loaded which will
685 // register it with the BackgroundModeManager.
686 GetProfile(cache.GetPathOfProfileAtIndex(p));
687 }
688 }
689 }
690
691 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
692 ProfileInfoCache& cache = GetProfileInfoCache();
693
694 if (profile->GetPath().DirName() != cache.GetUserDataDir())
695 return;
696
697 size_t avatar_index;
698 std::string profile_name;
699 std::string managed_user_id;
700 if (profile->IsGuestSession()) {
701 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
702 avatar_index = 0;
703 } else {
704 size_t profile_cache_index =
705 cache.GetIndexOfProfileWithPath(profile->GetPath());
706 // If the cache has an entry for this profile, use the cache data.
707 if (profile_cache_index != std::string::npos) {
708 avatar_index =
709 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
710 profile_name =
711 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
712 managed_user_id =
713 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index);
714 } else if (profile->GetPath() ==
715 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
716 avatar_index = 0;
717 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
718 } else {
719 avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
720 profile_name =
721 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
722 }
723 }
724
725 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
726 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
727
728 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
729 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
730
731 CommandLine* command_line = CommandLine::ForCurrentProcess();
732 bool force_managed_user_id =
733 command_line->HasSwitch(switches::kManagedUserId);
734 if (force_managed_user_id) {
735 managed_user_id =
736 command_line->GetSwitchValueASCII(switches::kManagedUserId);
737 }
738 if (force_managed_user_id ||
739 !profile->GetPrefs()->HasPrefPath(prefs::kManagedUserId)) {
740 profile->GetPrefs()->SetString(prefs::kManagedUserId, managed_user_id);
741 }
742 }
743
744 void ProfileManager::RegisterTestingProfile(Profile* profile,
745 bool add_to_cache,
746 bool start_deferred_task_runners) {
747 RegisterProfile(profile, true);
748 if (add_to_cache) {
749 InitProfileUserPrefs(profile);
750 AddProfileToCache(profile);
751 }
752 if (start_deferred_task_runners) {
753 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
754 StartDeferredTaskRunners();
755 }
756 }
757
604 void ProfileManager::Observe( 758 void ProfileManager::Observe(
605 int type, 759 int type,
606 const content::NotificationSource& source, 760 const content::NotificationSource& source,
607 const content::NotificationDetails& details) { 761 const content::NotificationDetails& details) {
608 #if defined(OS_CHROMEOS) 762 #if defined(OS_CHROMEOS)
609 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { 763 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
610 logged_in_ = true; 764 logged_in_ = true;
611 765
612 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 766 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
613 if (!command_line.HasSwitch(switches::kTestType)) { 767 if (!command_line.HasSwitch(switches::kTestType)) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 // Some profiles might become ephemeral after they are created. 858 // Some profiles might become ephemeral after they are created.
705 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && 859 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
706 profile_paths.find(profile_path) == profile_paths.end()) { 860 profile_paths.find(profile_path) == profile_paths.end()) {
707 profile_paths.insert(profile_path); 861 profile_paths.insert(profile_path);
708 profile_list->Append(new base::StringValue(profile_path)); 862 profile_list->Append(new base::StringValue(profile_path));
709 } 863 }
710 } 864 }
711 } 865 }
712 } 866 }
713 867
714 #if !defined(OS_ANDROID) && !defined(OS_IOS) 868 void ProfileManager::OnProfileCreated(Profile* profile,
715 ProfileManager::BrowserListObserver::BrowserListObserver( 869 bool success,
716 ProfileManager* manager) 870 bool is_new_profile) {
717 : profile_manager_(manager) { 871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
718 BrowserList::AddObserver(this);
719 }
720 872
721 ProfileManager::BrowserListObserver::~BrowserListObserver() { 873 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath());
722 BrowserList::RemoveObserver(this); 874 DCHECK(iter != profiles_info_.end());
723 } 875 ProfileInfo* info = iter->second.get();
724 876
725 void ProfileManager::BrowserListObserver::OnBrowserAdded( 877 std::vector<CreateCallback> callbacks;
726 Browser* browser) {} 878 info->callbacks.swap(callbacks);
727 879
728 void ProfileManager::BrowserListObserver::OnBrowserRemoved( 880 // Invoke CREATED callback for normal profiles.
729 Browser* browser) { 881 bool go_off_the_record = ShouldGoOffTheRecord(profile);
730 Profile* profile = browser->profile(); 882 if (success && !go_off_the_record)
731 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 883 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
732 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) 884
733 // Not the last window for this profile. 885 // Perform initialization.
734 return; 886 if (success) {
887 DoFinalInit(profile, go_off_the_record);
888 if (go_off_the_record)
889 profile = profile->GetOffTheRecordProfile();
890 info->created = true;
891 } else {
892 profile = NULL;
893 profiles_info_.erase(iter);
735 } 894 }
736 895
737 // If the last browser of a profile that is scheduled for deletion is closed 896 if (profile) {
738 // do that now. 897 // If this was the guest profile, finish setting its incognito status.
739 base::FilePath path = profile->GetPath(); 898 if (profile->GetPath() == ProfileManager::GetGuestProfilePath())
740 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && 899 SetGuestProfilePrefs(profile);
741 !IsProfileMarkedForDeletion(path)) { 900
742 g_browser_process->profile_manager()->ScheduleProfileForDeletion( 901 // Invoke CREATED callback for incognito profiles.
743 path, ProfileManager::CreateCallback()); 902 if (go_off_the_record)
903 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
744 } 904 }
905
906 // Invoke INITIALIZED or FAIL for all profiles.
907 RunCallbacks(callbacks, profile,
908 profile ? Profile::CREATE_STATUS_INITIALIZED :
909 Profile::CREATE_STATUS_LOCAL_FAIL);
745 } 910 }
746 911
747 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
748 Browser* browser) {
749 // If all browsers are being closed (e.g. the user is in the process of
750 // shutting down), this event will be fired after each browser is
751 // closed. This does not represent a user intention to change the active
752 // browser so is not handled here.
753 if (profile_manager_->closing_all_browsers_)
754 return;
755
756 Profile* last_active = browser->profile();
757
758 // Don't remember ephemeral profiles as last because they are not going to
759 // persist after restart.
760 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
761 return;
762
763 PrefService* local_state = g_browser_process->local_state();
764 DCHECK(local_state);
765 // Only keep track of profiles that we are managing; tests may create others.
766 if (profile_manager_->profiles_info_.find(
767 last_active->GetPath()) != profile_manager_->profiles_info_.end()) {
768 local_state->SetString(prefs::kProfileLastUsed,
769 last_active->GetPath().BaseName().MaybeAsASCII());
770 }
771 }
772 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
773
774 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) { 912 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) {
775 DoFinalInitForServices(profile, go_off_the_record); 913 DoFinalInitForServices(profile, go_off_the_record);
776 AddProfileToCache(profile); 914 AddProfileToCache(profile);
777 DoFinalInitLogging(profile); 915 DoFinalInitLogging(profile);
778 916
779 ProfileMetrics::LogNumberOfProfiles(this); 917 ProfileMetrics::LogNumberOfProfiles(this);
780 content::NotificationService::current()->Notify( 918 content::NotificationService::current()->Notify(
781 chrome::NOTIFICATION_PROFILE_ADDED, 919 chrome::NOTIFICATION_PROFILE_ADDED,
782 content::Source<Profile>(profile), 920 content::Source<Profile>(profile),
783 content::NotificationService::NoDetails()); 921 content::NotificationService::NoDetails());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); 967 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
830 } 968 }
831 969
832 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path, 970 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path,
833 Delegate* delegate) { 971 Delegate* delegate) {
834 return Profile::CreateProfile(path, 972 return Profile::CreateProfile(path,
835 delegate, 973 delegate,
836 Profile::CREATE_MODE_ASYNCHRONOUS); 974 Profile::CREATE_MODE_ASYNCHRONOUS);
837 } 975 }
838 976
839 void ProfileManager::OnProfileCreated(Profile* profile, 977 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath(
840 bool success, 978 const base::FilePath& user_data_dir) {
841 bool is_new_profile) { 979 #if defined(OS_CHROMEOS)
842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 980 base::FilePath default_profile_dir(user_data_dir);
843 981 if (!logged_in_) {
844 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); 982 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
845 DCHECK(iter != profiles_info_.end()); 983 Profile* profile = GetProfile(default_profile_dir);
846 ProfileInfo* info = iter->second.get(); 984 // For cros, return the OTR profile so we never accidentally keep
847 985 // user data in an unencrypted profile. But doing this makes
848 std::vector<CreateCallback> callbacks; 986 // many of the browser and ui tests fail. We do return the OTR profile
849 info->callbacks.swap(callbacks); 987 // if the login-profile switch is passed so that we can test this.
850 988 if (ShouldGoOffTheRecord(profile))
851 // Invoke CREATED callback for normal profiles. 989 return profile->GetOffTheRecordProfile();
852 bool go_off_the_record = ShouldGoOffTheRecord(profile); 990 DCHECK(!chromeos::UserManager::Get()->IsLoggedInAsGuest());
853 if (success && !go_off_the_record) 991 return profile;
854 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED);
855
856 // Perform initialization.
857 if (success) {
858 DoFinalInit(profile, go_off_the_record);
859 if (go_off_the_record)
860 profile = profile->GetOffTheRecordProfile();
861 info->created = true;
862 } else {
863 profile = NULL;
864 profiles_info_.erase(iter);
865 } 992 }
866 993
867 if (profile) { 994 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
868 // If this was the guest profile, finish setting its incognito status. 995 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir);
869 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) 996 // Fallback to default off-the-record profile, if user profile has not fully
870 SetGuestProfilePrefs(profile); 997 // loaded yet.
998 if (profile_info && !profile_info->created)
999 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir);
871 1000
872 // Invoke CREATED callback for incognito profiles. 1001 Profile* profile = GetProfile(default_profile_dir);
873 if (go_off_the_record) 1002 // Some unit tests didn't initialize the UserManager.
874 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); 1003 if (chromeos::UserManager::IsInitialized() &&
1004 chromeos::UserManager::Get()->IsLoggedInAsGuest())
1005 return profile->GetOffTheRecordProfile();
1006 return profile;
1007 #else
1008 base::FilePath default_profile_dir(user_data_dir);
1009 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir());
1010 return GetProfile(default_profile_dir);
1011 #endif
1012 }
1013
1014 bool ProfileManager::AddProfile(Profile* profile) {
1015 DCHECK(profile);
1016
1017 // Make sure that we're not loading a profile with the same ID as a profile
1018 // that's already loaded.
1019 if (GetProfileByPath(profile->GetPath())) {
1020 NOTREACHED() << "Attempted to add profile with the same path (" <<
1021 profile->GetPath().value() <<
1022 ") as an already-loaded profile.";
1023 return false;
875 } 1024 }
876 1025
877 // Invoke INITIALIZED or FAIL for all profiles. 1026 RegisterProfile(profile, true);
878 RunCallbacks(callbacks, profile, 1027 InitProfileUserPrefs(profile);
879 profile ? Profile::CREATE_STATUS_INITIALIZED : 1028 DoFinalInit(profile, ShouldGoOffTheRecord(profile));
880 Profile::CREATE_STATUS_LOCAL_FAIL); 1029 return true;
881 } 1030 }
882 1031
883 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() { 1032 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) {
884 PrefService* local_state = g_browser_process->local_state(); 1033 ProfileInfoCache& cache = GetProfileInfoCache();
885 DCHECK(local_state); 1034 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1035 // start deleting the profile instance we need to close background apps too.
1036 Profile* profile = GetProfileByPath(profile_dir);
886 1037
887 DCHECK(profiles::IsMultipleProfilesEnabled()); 1038 if (profile) {
1039 BrowserList::CloseAllBrowsersWithProfile(profile);
888 1040
889 // Create the next profile in the next available directory slot. 1041 // Disable sync for doomed profile.
890 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); 1042 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
891 std::string profile_name = chrome::kMultiProfileDirPrefix; 1043 profile)) {
892 profile_name.append(base::IntToString(next_directory)); 1044 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
893 base::FilePath new_path = user_data_dir_; 1045 profile)->DisableForUser();
894 #if defined(OS_WIN) 1046 }
895 new_path = new_path.Append(base::ASCIIToUTF16(profile_name)); 1047 }
896 #else 1048
897 new_path = new_path.Append(profile_name); 1049 QueueProfileDirectoryForDeletion(profile_dir);
898 #endif 1050 cache.DeleteProfileFromCache(profile_dir);
899 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); 1051 ProfileMetrics::UpdateReportedProfilesStatistics(this);
900 return new_path;
901 } 1052 }
902 1053
903 // static 1054 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(
904 base::FilePath ProfileManager::CreateMultiProfileAsync( 1055 Profile* profile,
905 const base::string16& name, 1056 bool created) {
906 const base::string16& icon_url, 1057 ProfileInfo* info = new ProfileInfo(profile, created);
907 const CreateCallback& callback, 1058 profiles_info_.insert(
908 const std::string& managed_user_id) { 1059 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info)));
909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1060 return info;
910
911 ProfileManager* profile_manager = g_browser_process->profile_manager();
912
913 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
914
915 profile_manager->CreateProfileAsync(new_path,
916 callback,
917 name,
918 icon_url,
919 managed_user_id);
920 return new_path;
921 } 1061 }
922 1062
923 // static 1063 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath(
924 base::FilePath ProfileManager::GetGuestProfilePath() { 1064 const base::FilePath& path) const {
925 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1065 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
926 1066 return (iter == profiles_info_.end()) ? NULL : iter->second.get();
927 ProfileManager* profile_manager = g_browser_process->profile_manager();
928
929 base::FilePath guest_path = profile_manager->user_data_dir();
930 return guest_path.Append(chrome::kGuestProfileDir);
931 }
932
933 size_t ProfileManager::GetNumberOfProfiles() {
934 return GetProfileInfoCache().GetNumberOfProfiles();
935 }
936
937 bool ProfileManager::CompareProfilePathAndName(
938 const ProfileManager::ProfilePathAndName& pair1,
939 const ProfileManager::ProfilePathAndName& pair2) {
940 int name_compare = pair1.second.compare(pair2.second);
941 if (name_compare < 0) {
942 return true;
943 } else if (name_compare > 0) {
944 return false;
945 } else {
946 return pair1.first < pair2.first;
947 }
948 }
949
950 ProfileInfoCache& ProfileManager::GetProfileInfoCache() {
951 if (!profile_info_cache_) {
952 profile_info_cache_.reset(new ProfileInfoCache(
953 g_browser_process->local_state(), user_data_dir_));
954 }
955 return *profile_info_cache_.get();
956 }
957
958 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
959 return profile_shortcut_manager_.get();
960 } 1067 }
961 1068
962 void ProfileManager::AddProfileToCache(Profile* profile) { 1069 void ProfileManager::AddProfileToCache(Profile* profile) {
963 if (profile->IsGuestSession()) 1070 if (profile->IsGuestSession())
964 return; 1071 return;
965 ProfileInfoCache& cache = GetProfileInfoCache(); 1072 ProfileInfoCache& cache = GetProfileInfoCache();
966 if (profile->GetPath().DirName() != cache.GetUserDataDir()) 1073 if (profile->GetPath().DirName() != cache.GetUserDataDir())
967 return; 1074 return;
968 1075
969 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos) 1076 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos)
(...skipping 18 matching lines...) Expand all
988 username, 1095 username,
989 icon_index, 1096 icon_index,
990 managed_user_id); 1097 managed_user_id);
991 1098
992 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) { 1099 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) {
993 cache.SetProfileIsEphemeralAtIndex( 1100 cache.SetProfileIsEphemeralAtIndex(
994 cache.GetIndexOfProfileWithPath(profile->GetPath()), true); 1101 cache.GetIndexOfProfileWithPath(profile->GetPath()), true);
995 } 1102 }
996 } 1103 }
997 1104
998 void ProfileManager::InitProfileUserPrefs(Profile* profile) {
999 ProfileInfoCache& cache = GetProfileInfoCache();
1000
1001 if (profile->GetPath().DirName() != cache.GetUserDataDir())
1002 return;
1003
1004 size_t avatar_index;
1005 std::string profile_name;
1006 std::string managed_user_id;
1007 if (profile->IsGuestSession()) {
1008 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
1009 avatar_index = 0;
1010 } else {
1011 size_t profile_cache_index =
1012 cache.GetIndexOfProfileWithPath(profile->GetPath());
1013 // If the cache has an entry for this profile, use the cache data.
1014 if (profile_cache_index != std::string::npos) {
1015 avatar_index =
1016 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
1017 profile_name =
1018 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
1019 managed_user_id =
1020 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index);
1021 } else if (profile->GetPath() ==
1022 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) {
1023 avatar_index = 0;
1024 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
1025 } else {
1026 avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
1027 profile_name =
1028 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
1029 }
1030 }
1031
1032 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
1033 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
1034
1035 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
1036 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
1037
1038 CommandLine* command_line = CommandLine::ForCurrentProcess();
1039 bool force_managed_user_id =
1040 command_line->HasSwitch(switches::kManagedUserId);
1041 if (force_managed_user_id) {
1042 managed_user_id =
1043 command_line->GetSwitchValueASCII(switches::kManagedUserId);
1044 }
1045 if (force_managed_user_id ||
1046 !profile->GetPrefs()->HasPrefPath(prefs::kManagedUserId)) {
1047 profile->GetPrefs()->SetString(prefs::kManagedUserId, managed_user_id);
1048 }
1049 }
1050
1051 void ProfileManager::SetGuestProfilePrefs(Profile* profile) { 1105 void ProfileManager::SetGuestProfilePrefs(Profile* profile) {
1052 IncognitoModePrefs::SetAvailability(profile->GetPrefs(), 1106 IncognitoModePrefs::SetAvailability(profile->GetPrefs(),
1053 IncognitoModePrefs::FORCED); 1107 IncognitoModePrefs::FORCED);
1054 profile->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false); 1108 profile->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false);
1055 } 1109 }
1056 1110
1057 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) { 1111 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) {
1058 bool go_off_the_record = false; 1112 bool go_off_the_record = false;
1059 #if defined(OS_CHROMEOS) 1113 #if defined(OS_CHROMEOS)
1060 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1114 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1061 if (command_line.HasSwitch(chromeos::switches::kGuestSession) || 1115 if (command_line.HasSwitch(chromeos::switches::kGuestSession) ||
1062 (profile->GetPath().BaseName().value() == chrome::kInitialProfile && 1116 (profile->GetPath().BaseName().value() == chrome::kInitialProfile &&
1063 (!command_line.HasSwitch(switches::kTestType) || 1117 (!command_line.HasSwitch(switches::kTestType) ||
1064 command_line.HasSwitch(chromeos::switches::kLoginProfile)))) { 1118 command_line.HasSwitch(chromeos::switches::kLoginProfile)))) {
1065 go_off_the_record = true; 1119 go_off_the_record = true;
1066 } 1120 }
1067 #endif 1121 #endif
1068 return go_off_the_record; 1122 return go_off_the_record;
1069 } 1123 }
1070 1124
1071 void ProfileManager::ScheduleProfileForDeletion( 1125 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks,
1072 const base::FilePath& profile_dir, 1126 Profile* profile,
1073 const CreateCallback& callback) { 1127 Profile::CreateStatus status) {
1074 DCHECK(profiles::IsMultipleProfilesEnabled()); 1128 for (size_t i = 0; i < callbacks.size(); ++i)
1075 PrefService* local_state = g_browser_process->local_state(); 1129 callbacks[i].Run(profile, status);
1076 ProfileInfoCache& cache = GetProfileInfoCache();
1077
1078 if (profile_dir.BaseName().MaybeAsASCII() ==
1079 local_state->GetString(prefs::kProfileLastUsed)) {
1080 // Update the last used profile pref before closing browser windows. This
1081 // way the correct last used profile is set for any notification observers.
1082 base::FilePath last_non_managed_profile_path;
1083 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
1084 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i);
1085 // Make sure that this profile is not pending deletion.
1086 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) &&
1087 !IsProfileMarkedForDeletion(cur_path)) {
1088 last_non_managed_profile_path = cur_path;
1089 break;
1090 }
1091 }
1092
1093 // If we're deleting the last (non-managed) profile, then create a new
1094 // profile in its place.
1095 const std::string last_non_managed_profile =
1096 last_non_managed_profile_path.BaseName().MaybeAsASCII();
1097 if (last_non_managed_profile.empty()) {
1098 base::FilePath new_path = GenerateNextProfileDirectoryPath();
1099 // Make sure the last used profile path is pointing at it. This way the
1100 // correct last used profile is set for any notification observers.
1101 local_state->SetString(prefs::kProfileLastUsed,
1102 new_path.BaseName().MaybeAsASCII());
1103 CreateProfileAsync(new_path,
1104 callback,
1105 base::string16(),
1106 base::string16(),
1107 std::string());
1108 } else {
1109 // On the Mac, the browser process is not killed when all browser windows
1110 // are closed, so just in case we are deleting the active profile, and no
1111 // other profile has been loaded, we must pre-load a next one.
1112 #if defined(OS_MACOSX)
1113 CreateProfileAsync(last_non_managed_profile_path,
1114 base::Bind(&ProfileManager::OnNewActiveProfileLoaded,
1115 base::Unretained(this),
1116 profile_dir,
1117 last_non_managed_profile_path,
1118 callback),
1119 base::string16(),
1120 base::string16(),
1121 std::string());
1122 return;
1123 #else
1124 // For OS_MACOSX the pref is updated in the callback to make sure that
1125 // it isn't used before the profile is actually loaded.
1126 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile);
1127 #endif
1128 }
1129 }
1130 FinishDeletingProfile(profile_dir);
1131 } 1130 }
1132 1131
1133 // static 1132 ProfileManager::ProfileInfo::ProfileInfo(
1134 void ProfileManager::CleanUpStaleProfiles( 1133 Profile* profile,
1135 const std::vector<base::FilePath>& profile_paths) { 1134 bool created)
1136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1135 : profile(profile),
1136 created(created) {
1137 }
1137 1138
1138 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin(); 1139 ProfileManager::ProfileInfo::~ProfileInfo() {
1139 it != profile_paths.end(); ++it) { 1140 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1140 NukeProfileFromDisk(*it); 1141 }
1142
1143 #if !defined(OS_ANDROID) && !defined(OS_IOS)
1144 ProfileManager::BrowserListObserver::BrowserListObserver(
1145 ProfileManager* manager)
1146 : profile_manager_(manager) {
1147 BrowserList::AddObserver(this);
1148 }
1149
1150 ProfileManager::BrowserListObserver::~BrowserListObserver() {
1151 BrowserList::RemoveObserver(this);
1152 }
1153
1154 void ProfileManager::BrowserListObserver::OnBrowserAdded(
1155 Browser* browser) {}
1156
1157 void ProfileManager::BrowserListObserver::OnBrowserRemoved(
1158 Browser* browser) {
1159 Profile* profile = browser->profile();
1160 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1161 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile())
1162 // Not the last window for this profile.
1163 return;
1164 }
1165
1166 // If the last browser of a profile that is scheduled for deletion is closed
1167 // do that now.
1168 base::FilePath path = profile->GetPath();
1169 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) &&
1170 !IsProfileMarkedForDeletion(path)) {
1171 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
1172 path, ProfileManager::CreateCallback());
1141 } 1173 }
1142 } 1174 }
1143 1175
1176 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
1177 Browser* browser) {
1178 // If all browsers are being closed (e.g. the user is in the process of
1179 // shutting down), this event will be fired after each browser is
1180 // closed. This does not represent a user intention to change the active
1181 // browser so is not handled here.
1182 if (profile_manager_->closing_all_browsers_)
1183 return;
1184
1185 Profile* last_active = browser->profile();
1186
1187 // Don't remember ephemeral profiles as last because they are not going to
1188 // persist after restart.
1189 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
1190 return;
1191
1192 PrefService* local_state = g_browser_process->local_state();
1193 DCHECK(local_state);
1194 // Only keep track of profiles that we are managing; tests may create others.
1195 if (profile_manager_->profiles_info_.find(
1196 last_active->GetPath()) != profile_manager_->profiles_info_.end()) {
1197 local_state->SetString(prefs::kProfileLastUsed,
1198 last_active->GetPath().BaseName().MaybeAsASCII());
1199 }
1200 }
1201 #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
1202
1203 #if defined(OS_MACOSX)
1144 void ProfileManager::OnNewActiveProfileLoaded( 1204 void ProfileManager::OnNewActiveProfileLoaded(
1145 const base::FilePath& profile_to_delete_path, 1205 const base::FilePath& profile_to_delete_path,
1146 const base::FilePath& last_non_managed_profile_path, 1206 const base::FilePath& last_non_managed_profile_path,
1147 const CreateCallback& original_callback, 1207 const CreateCallback& original_callback,
1148 Profile* loaded_profile, 1208 Profile* loaded_profile,
1149 Profile::CreateStatus status) { 1209 Profile::CreateStatus status) {
1150 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && 1210 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL &&
1151 status != Profile::CREATE_STATUS_REMOTE_FAIL); 1211 status != Profile::CREATE_STATUS_REMOTE_FAIL);
1152 1212
1153 // Only run the code if the profile initialization has finished completely. 1213 // Only run the code if the profile initialization has finished completely.
1154 if (status == Profile::CREATE_STATUS_INITIALIZED) { 1214 if (status == Profile::CREATE_STATUS_INITIALIZED) {
1155 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) { 1215 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) {
1156 // If the profile we tried to load as the next active profile has been 1216 // If the profile we tried to load as the next active profile has been
1157 // deleted, then retry deleting this profile to redo the logic to load 1217 // deleted, then retry deleting this profile to redo the logic to load
1158 // the next available profile. 1218 // the next available profile.
1159 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); 1219 ScheduleProfileForDeletion(profile_to_delete_path, original_callback);
1160 } else { 1220 } else {
1161 // Update the local state as promised in the ScheduleProfileForDeletion. 1221 // Update the local state as promised in the ScheduleProfileForDeletion.
1162 g_browser_process->local_state()->SetString( 1222 g_browser_process->local_state()->SetString(
1163 prefs::kProfileLastUsed, 1223 prefs::kProfileLastUsed,
1164 last_non_managed_profile_path.BaseName().MaybeAsASCII()); 1224 last_non_managed_profile_path.BaseName().MaybeAsASCII());
1165 FinishDeletingProfile(profile_to_delete_path); 1225 FinishDeletingProfile(profile_to_delete_path);
1166 } 1226 }
1167 } 1227 }
1168 } 1228 }
1169 1229 #endif
1170 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) {
1171 ProfileInfoCache& cache = GetProfileInfoCache();
1172 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we
1173 // start deleting the profile instance we need to close background apps too.
1174 Profile* profile = GetProfileByPath(profile_dir);
1175
1176 if (profile) {
1177 BrowserList::CloseAllBrowsersWithProfile(profile);
1178
1179 // Disable sync for doomed profile.
1180 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
1181 profile)) {
1182 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
1183 profile)->DisableForUser();
1184 }
1185 }
1186
1187 QueueProfileDirectoryForDeletion(profile_dir);
1188 cache.DeleteProfileFromCache(profile_dir);
1189 ProfileMetrics::UpdateReportedProfilesStatistics(this);
1190 }
1191
1192 void ProfileManager::AutoloadProfiles() {
1193 // If running in the background is disabled for the browser, do not autoload
1194 // any profiles.
1195 PrefService* local_state = g_browser_process->local_state();
1196 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) ||
1197 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) {
1198 return;
1199 }
1200
1201 ProfileInfoCache& cache = GetProfileInfoCache();
1202 size_t number_of_profiles = cache.GetNumberOfProfiles();
1203 for (size_t p = 0; p < number_of_profiles; ++p) {
1204 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) {
1205 // If status is true, that profile is running background apps. By calling
1206 // GetProfile, we automatically cause the profile to be loaded which will
1207 // register it with the BackgroundModeManager.
1208 GetProfile(cache.GetPathOfProfileAtIndex(p));
1209 }
1210 }
1211 }
1212 1230
1213 ProfileManagerWithoutInit::ProfileManagerWithoutInit( 1231 ProfileManagerWithoutInit::ProfileManagerWithoutInit(
1214 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { 1232 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) {
1215 } 1233 }
1216
1217 void ProfileManager::RegisterTestingProfile(Profile* profile,
1218 bool add_to_cache,
1219 bool start_deferred_task_runners) {
1220 RegisterProfile(profile, true);
1221 if (add_to_cache) {
1222 InitProfileUserPrefs(profile);
1223 AddProfileToCache(profile);
1224 }
1225 if (start_deferred_task_runners) {
1226 StartupTaskRunnerServiceFactory::GetForProfile(profile)->
1227 StartDeferredTaskRunners();
1228 }
1229 }
1230
1231 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks,
1232 Profile* profile,
1233 Profile::CreateStatus status) {
1234 for (size_t i = 0; i < callbacks.size(); ++i)
1235 callbacks[i].Run(profile, status);
1236 }
1237
1238 ProfileManager::ProfileInfo::ProfileInfo(
1239 Profile* profile,
1240 bool created)
1241 : profile(profile),
1242 created(created) {
1243 }
1244
1245 ProfileManager::ProfileInfo::~ProfileInfo() {
1246 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release());
1247 }
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698