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

Side by Side Diff: chrome/browser/chromeos/login/user_manager.cc

Issue 9405035: Implement ephemeral users (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Comments addressed. Created 8 years, 9 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
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/chromeos/login/user_manager.h" 5 #include "chrome/browser/chromeos/login/user_manager.h"
6 6
7 #include <vector> 7 #include <vector>
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 18 matching lines...) Expand all
29 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h" 29 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h"
30 #include "chrome/browser/chromeos/dbus/cryptohome_client.h" 30 #include "chrome/browser/chromeos/dbus/cryptohome_client.h"
31 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" 31 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
32 #include "chrome/browser/chromeos/input_method/input_method_manager.h" 32 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
33 #include "chrome/browser/chromeos/login/default_user_images.h" 33 #include "chrome/browser/chromeos/login/default_user_images.h"
34 #include "chrome/browser/chromeos/login/helper.h" 34 #include "chrome/browser/chromeos/login/helper.h"
35 #include "chrome/browser/chromeos/login/login_display.h" 35 #include "chrome/browser/chromeos/login/login_display.h"
36 #include "chrome/browser/chromeos/login/ownership_service.h" 36 #include "chrome/browser/chromeos/login/ownership_service.h"
37 #include "chrome/browser/chromeos/login/remove_user_delegate.h" 37 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
38 #include "chrome/browser/chromeos/system/runtime_environment.h" 38 #include "chrome/browser/chromeos/system/runtime_environment.h"
39 #include "chrome/browser/policy/browser_policy_connector.h"
39 #include "chrome/browser/prefs/pref_service.h" 40 #include "chrome/browser/prefs/pref_service.h"
40 #include "chrome/browser/prefs/scoped_user_pref_update.h" 41 #include "chrome/browser/prefs/scoped_user_pref_update.h"
41 #include "chrome/browser/profiles/profile_downloader.h" 42 #include "chrome/browser/profiles/profile_downloader.h"
42 #include "chrome/browser/profiles/profile_manager.h" 43 #include "chrome/browser/profiles/profile_manager.h"
43 #include "chrome/browser/sync/profile_sync_service.h" 44 #include "chrome/browser/sync/profile_sync_service.h"
44 #include "chrome/browser/sync/profile_sync_service_factory.h" 45 #include "chrome/browser/sync/profile_sync_service_factory.h"
45 #include "chrome/browser/ui/webui/web_ui_util.h" 46 #include "chrome/browser/ui/webui/web_ui_util.h"
46 #include "chrome/common/chrome_notification_types.h" 47 #include "chrome/common/chrome_notification_types.h"
47 #include "chrome/common/chrome_paths.h" 48 #include "chrome/common/chrome_paths.h"
48 #include "chrome/common/chrome_switches.h" 49 #include "chrome/common/chrome_switches.h"
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 const_cast<UserManager*>(this)->EnsureUsersLoaded(); 316 const_cast<UserManager*>(this)->EnsureUsersLoaded();
316 return users_; 317 return users_;
317 } 318 }
318 319
319 void UserManager::UserLoggedIn(const std::string& email) { 320 void UserManager::UserLoggedIn(const std::string& email) {
320 DCHECK(!user_is_logged_in_); 321 DCHECK(!user_is_logged_in_);
321 322
322 user_is_logged_in_ = true; 323 user_is_logged_in_ = true;
323 324
324 if (email == kGuestUser) { 325 if (email == kGuestUser) {
326 current_user_is_ephemeral_ = true;
325 GuestUserLoggedIn(); 327 GuestUserLoggedIn();
326 return; 328 return;
327 } 329 }
328 330
329 if (email == kDemoUser) { 331 if (email == kDemoUser) {
332 current_user_is_ephemeral_ = true;
330 DemoUserLoggedIn(); 333 DemoUserLoggedIn();
331 return; 334 return;
332 } 335 }
333 336
337 if (IsEphemeralUser(email)) {
338 current_user_is_ephemeral_ = true;
339 logged_in_user_ = CreateUser(email);
340 NotifyOnLogin();
341 return;
342 }
343
334 EnsureUsersLoaded(); 344 EnsureUsersLoaded();
335 345
336 // Clear the prefs view of the users. 346 // Clear the prefs view of the users.
337 PrefService* prefs = g_browser_process->local_state(); 347 PrefService* prefs = g_browser_process->local_state();
338 ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers); 348 ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers);
339 prefs_users_update->Clear(); 349 prefs_users_update->Clear();
340 350
341 // Make sure this user is first. 351 // Make sure this user is first.
342 prefs_users_update->Append(Value::CreateStringValue(email)); 352 prefs_users_update->Append(Value::CreateStringValue(email));
343 UserList::iterator logged_in_user = users_.end(); 353 UserList::iterator logged_in_user = users_.end();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 base::Unretained(this), 483 base::Unretained(this),
474 image_path)); 484 image_path));
475 } 485 }
476 } 486 }
477 487
478 bool UserManager::IsKnownUser(const std::string& email) const { 488 bool UserManager::IsKnownUser(const std::string& email) const {
479 return FindUser(email) != NULL; 489 return FindUser(email) != NULL;
480 } 490 }
481 491
482 const User* UserManager::FindUser(const std::string& email) const { 492 const User* UserManager::FindUser(const std::string& email) const {
483 // Speed up search by checking the logged-in user first.
484 if (logged_in_user_ && logged_in_user_->email() == email) 493 if (logged_in_user_ && logged_in_user_->email() == email)
485 return logged_in_user_; 494 return logged_in_user_;
486 const UserList& users = GetUsers(); 495 return FindUserInList(email);
487 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
488 if ((*it)->email() == email)
489 return *it;
490 }
491 return NULL;
492 } 496 }
493 497
494 bool UserManager::IsDisplayNameUnique(const std::string& display_name) const { 498 bool UserManager::IsDisplayNameUnique(const std::string& display_name) const {
495 return display_name_count_[display_name] < 2; 499 return display_name_count_[display_name] < 2;
496 } 500 }
497 501
498 void UserManager::SaveUserOAuthStatus( 502 void UserManager::SaveUserOAuthStatus(
499 const std::string& username, 503 const std::string& username,
500 User::OAuthTokenStatus oauth_token_status) { 504 User::OAuthTokenStatus oauth_token_status) {
501 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
502 PrefService* local_state = g_browser_process->local_state(); 506
503 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
504 oauth_status_update->SetWithoutPathExpansion(username,
505 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
506 DVLOG(1) << "Saving user OAuth token status in Local State"; 507 DVLOG(1) << "Saving user OAuth token status in Local State";
507 User* user = const_cast<User*>(FindUser(username)); 508 User* user = const_cast<User*>(FindUser(username));
508 if (user) 509 if (user)
509 user->set_oauth_token_status(oauth_token_status); 510 user->set_oauth_token_status(oauth_token_status);
511
512 // Do not update local store if the user is ephemeral.
513 if (IsEphemeralUser(username))
514 return;
515
516 PrefService* local_state = g_browser_process->local_state();
517
518 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
519 oauth_status_update->SetWithoutPathExpansion(username,
520 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
510 } 521 }
511 522
512 User::OAuthTokenStatus UserManager::LoadUserOAuthStatus( 523 User::OAuthTokenStatus UserManager::LoadUserOAuthStatus(
513 const std::string& username) const { 524 const std::string& username) const {
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
515 526
516 if (CommandLine::ForCurrentProcess()->HasSwitch( 527 if (CommandLine::ForCurrentProcess()->HasSwitch(
517 switches::kSkipOAuthLogin)) { 528 switches::kSkipOAuthLogin)) {
518 // Use OAUTH_TOKEN_STATUS_VALID flag if kSkipOAuthLogin is present. 529 // Use OAUTH_TOKEN_STATUS_VALID flag if kSkipOAuthLogin is present.
519 return User::OAUTH_TOKEN_STATUS_VALID; 530 return User::OAUTH_TOKEN_STATUS_VALID;
(...skipping 16 matching lines...) Expand all
536 void UserManager::SaveUserDisplayEmail(const std::string& username, 547 void UserManager::SaveUserDisplayEmail(const std::string& username,
537 const std::string& display_email) { 548 const std::string& display_email) {
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
539 550
540 User* user = const_cast<User*>(FindUser(username)); 551 User* user = const_cast<User*>(FindUser(username));
541 if (!user) 552 if (!user)
542 return; // Ignore if there is no such user. 553 return; // Ignore if there is no such user.
543 554
544 user->set_display_email(display_email); 555 user->set_display_email(display_email);
545 556
557 // Do not update local store if the user is ephemeral.
Ivan Korotkov 2012/03/01 13:37:50 You don't need most of these checks, only those wh
use bartfab instead 2012/03/01 18:33:43 Done.
558 if (IsEphemeralUser(username))
559 return;
560
546 PrefService* local_state = g_browser_process->local_state(); 561 PrefService* local_state = g_browser_process->local_state();
547 562
548 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail); 563 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
549 display_email_update->SetWithoutPathExpansion( 564 display_email_update->SetWithoutPathExpansion(
550 username, 565 username,
551 base::Value::CreateStringValue(display_email)); 566 base::Value::CreateStringValue(display_email));
552 } 567 }
553 568
554 std::string UserManager::GetUserDisplayEmail( 569 std::string UserManager::GetUserDisplayEmail(
555 const std::string& username) const { 570 const std::string& username) const {
556 const User* user = FindUser(username); 571 const User* user = FindUser(username);
557 return user ? user->display_email() : username; 572 return user ? user->display_email() : username;
558 } 573 }
559 574
560 void UserManager::SaveUserDefaultImageIndex(const std::string& username, 575 void UserManager::SaveUserDefaultImageIndex(const std::string& username,
561 int image_index) { 576 int image_index) {
562 DCHECK(image_index >= 0 && image_index < kDefaultImagesCount); 577 DCHECK(image_index >= 0 && image_index < kDefaultImagesCount);
578
579 // Ignore for ephemeral users.
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
580 if (IsEphemeralUser(username))
581 return;
582
563 SetUserImage(username, image_index, GetDefaultImage(image_index)); 583 SetUserImage(username, image_index, GetDefaultImage(image_index));
564 SaveImageToLocalState(username, "", image_index, false); 584 SaveImageToLocalState(username, "", image_index, false);
565 } 585 }
566 586
567 void UserManager::SaveUserImage(const std::string& username, 587 void UserManager::SaveUserImage(const std::string& username,
568 const SkBitmap& image) { 588 const SkBitmap& image) {
589 // Ignore for ephemeral users.
590 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
591 return;
592
569 SaveUserImageInternal(username, User::kExternalImageIndex, image); 593 SaveUserImageInternal(username, User::kExternalImageIndex, image);
570 } 594 }
571 595
572 void UserManager::SaveUserImageFromFile(const std::string& username, 596 void UserManager::SaveUserImageFromFile(const std::string& username,
573 const FilePath& path) { 597 const FilePath& path) {
598 // Ignore for ephemeral users.
599 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
600 return;
601
574 image_loader_->Start( 602 image_loader_->Start(
575 path.value(), login::kUserImageSize, 603 path.value(), login::kUserImageSize,
576 base::Bind(&UserManager::SaveUserImage, 604 base::Bind(&UserManager::SaveUserImage,
577 base::Unretained(this), username)); 605 base::Unretained(this), username));
578 } 606 }
579 607
580 void UserManager::SaveUserImageFromProfileImage(const std::string& username) { 608 void UserManager::SaveUserImageFromProfileImage(const std::string& username) {
609 // Ignore for ephemeral users.
610 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
611 return;
612
581 if (!downloaded_profile_image_.empty()) { 613 if (!downloaded_profile_image_.empty()) {
582 // Profile image has already been downloaded, so save it to file right now. 614 // Profile image has already been downloaded, so save it to file right now.
583 SaveUserImageInternal(username, User::kProfileImageIndex, 615 SaveUserImageInternal(username, User::kProfileImageIndex,
584 downloaded_profile_image_); 616 downloaded_profile_image_);
585 } else { 617 } else {
586 // No profile image - use the stub image (gray avatar). 618 // No profile image - use the stub image (gray avatar).
587 SetUserImage(username, User::kProfileImageIndex, SkBitmap()); 619 SetUserImage(username, User::kProfileImageIndex, SkBitmap());
588 SaveImageToLocalState(username, "", User::kProfileImageIndex, false); 620 SaveImageToLocalState(username, "", User::kProfileImageIndex, false);
589 } 621 }
590 } 622 }
591 623
592 void UserManager::DownloadProfileImage(const std::string& reason) { 624 void UserManager::DownloadProfileImage(const std::string& reason) {
593 if (profile_image_downloader_.get()) { 625 if (profile_image_downloader_.get()) {
594 // Another download is already in progress 626 // Another download is already in progress
595 return; 627 return;
596 } 628 }
597 629
598 if (logged_in_user().email().empty()) { 630 if (logged_in_user().email().empty()) {
599 // This is a guest login so there's no profile image to download. 631 // This is a guest login so there's no profile image to download.
600 return; 632 return;
601 } 633 }
602 634
635 if (current_user_is_ephemeral_) {
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
636 // Ignore for ephemeral users.
637 return;
638 }
639
603 profile_image_download_reason_ = reason; 640 profile_image_download_reason_ = reason;
604 profile_image_load_start_time_ = base::Time::Now(); 641 profile_image_load_start_time_ = base::Time::Now();
605 profile_image_downloader_.reset(new ProfileDownloader(this)); 642 profile_image_downloader_.reset(new ProfileDownloader(this));
606 profile_image_downloader_->Start(); 643 profile_image_downloader_->Start();
607 } 644 }
608 645
609 void UserManager::Observe(int type, 646 void UserManager::Observe(int type,
610 const content::NotificationSource& source, 647 const content::NotificationSource& source,
611 const content::NotificationDetails& details) { 648 const content::NotificationDetails& details) {
612 switch (type) { 649 switch (type) {
613 case chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED: 650 case chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED:
614 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 651 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
615 base::Bind(&UserManager::CheckOwnership, 652 base::Bind(&UserManager::CheckOwnership,
616 base::Unretained(this))); 653 base::Unretained(this)));
654 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
655 base::Bind(&UserManager::RetrieveTrustedDevicePolicies,
656 base::Unretained(this)));
617 break; 657 break;
618 case chrome::NOTIFICATION_PROFILE_ADDED: 658 case chrome::NOTIFICATION_PROFILE_ADDED:
619 if (user_is_logged_in() && !IsLoggedInAsGuest()) { 659 if (user_is_logged_in() && !IsLoggedInAsGuest()) {
620 Profile* profile = content::Source<Profile>(source).ptr(); 660 Profile* profile = content::Source<Profile>(source).ptr();
621 if (!profile->IsOffTheRecord() && 661 if (!profile->IsOffTheRecord() &&
622 profile == ProfileManager::GetDefaultProfile()) { 662 profile == ProfileManager::GetDefaultProfile()) {
623 DCHECK(NULL == observed_sync_service_); 663 DCHECK(NULL == observed_sync_service_);
624 observed_sync_service_ = 664 observed_sync_service_ =
625 ProfileSyncServiceFactory::GetForProfile(profile); 665 ProfileSyncServiceFactory::GetForProfile(profile);
626 if (observed_sync_service_) 666 if (observed_sync_service_)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 observer_list_.RemoveObserver(obs); 712 observer_list_.RemoveObserver(obs);
673 } 713 }
674 714
675 void UserManager::NotifyLocalStateChanged() { 715 void UserManager::NotifyLocalStateChanged() {
676 FOR_EACH_OBSERVER( 716 FOR_EACH_OBSERVER(
677 Observer, 717 Observer,
678 observer_list_, 718 observer_list_,
679 LocalStateChanged(this)); 719 LocalStateChanged(this));
680 } 720 }
681 721
722 void UserManager::RetrieveTrustedDevicePolicies() {
723 ephemeral_users_enabled_.reset();
724 owner_.reset();
725
726 CrosSettings* cros_settings = CrosSettings::Get();
727 // Schedule a callback if device policy has not yet been verified.
728 if (!cros_settings->GetTrusted(
729 kAccountsPrefEphemeralUsersEnabled,
730 base::Bind(&UserManager::RetrieveTrustedDevicePolicies,
731 base::Unretained(this))))
732 return;
Ivan Korotkov 2012/03/01 13:37:50 Multiline if conditions require braces, too.
use bartfab instead 2012/03/01 18:33:43 Done.
733 bool* ephemeral_users_enabled = new bool;
734 cros_settings->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
735 ephemeral_users_enabled);
736 ephemeral_users_enabled_.reset(ephemeral_users_enabled);
737
738 if (g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) {
739 owner_.reset(new std::string);
Ivan Korotkov 2012/03/01 13:37:50 There are alredy pieces of code that fetch owner (
use bartfab instead 2012/03/01 18:33:43 The problem is that GetTrusted() must be provided
Ivan Korotkov 2012/03/01 20:16:30 Right, I'm sorry for the confusion. In that case,
use bartfab instead 2012/03/05 18:07:32 This will not work I fear. What if the owner_ has
740 } else {
741 std::string* owner = new std::string;
742 cros_settings->GetString(kDeviceOwner, owner);
743 owner_.reset(owner);
744 }
745
746 if (*ephemeral_users_enabled_)
747 RemoveAllExceptOwnerFromList();
748 }
749
682 // Protected constructor and destructor. 750 // Protected constructor and destructor.
683 UserManager::UserManager() 751 UserManager::UserManager()
684 : ALLOW_THIS_IN_INITIALIZER_LIST(image_loader_(new UserImageLoader)), 752 : ALLOW_THIS_IN_INITIALIZER_LIST(image_loader_(new UserImageLoader)),
685 demo_user_(kDemoUser, false), 753 demo_user_(kDemoUser, false),
686 guest_user_(kGuestUser, true), 754 guest_user_(kGuestUser, true),
687 stub_user_(kStubUser, false), 755 stub_user_(kStubUser, false),
688 logged_in_user_(NULL), 756 logged_in_user_(NULL),
689 current_user_is_owner_(false), 757 current_user_is_owner_(false),
690 current_user_is_new_(false), 758 current_user_is_new_(false),
759 current_user_is_ephemeral_(false),
691 user_is_logged_in_(false), 760 user_is_logged_in_(false),
692 observed_sync_service_(NULL), 761 observed_sync_service_(NULL),
693 last_image_set_async_(false), 762 last_image_set_async_(false),
694 downloaded_profile_image_data_url_(chrome::kAboutBlankURL) { 763 downloaded_profile_image_data_url_(chrome::kAboutBlankURL) {
695 // Use stub as the logged-in user for test paths without login. 764 // Use stub as the logged-in user for test paths without login.
696 if (!system::runtime_environment::IsRunningOnChromeOS()) 765 if (!system::runtime_environment::IsRunningOnChromeOS())
697 StubUserLoggedIn(); 766 StubUserLoggedIn();
698 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED, 767 registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
699 content::NotificationService::AllSources()); 768 content::NotificationService::AllSources());
700 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, 769 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
701 content::NotificationService::AllSources()); 770 content::NotificationService::AllSources());
771 RetrieveTrustedDevicePolicies();
702 } 772 }
703 773
704 UserManager::~UserManager() { 774 UserManager::~UserManager() {
705 } 775 }
706 776
707 FilePath UserManager::GetImagePathForUser(const std::string& username) { 777 FilePath UserManager::GetImagePathForUser(const std::string& username) {
708 std::string filename = username + ".png"; 778 std::string filename = username + ".png";
709 FilePath user_data_dir; 779 FilePath user_data_dir;
710 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 780 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
711 return user_data_dir.AppendASCII(filename); 781 return user_data_dir.AppendASCII(filename);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 if (prefs_display_emails && 857 if (prefs_display_emails &&
788 prefs_display_emails->GetStringWithoutPathExpansion( 858 prefs_display_emails->GetStringWithoutPathExpansion(
789 email, &display_email)) { 859 email, &display_email)) {
790 user->set_display_email(display_email); 860 user->set_display_email(display_email);
791 } 861 }
792 } 862 }
793 } 863 }
794 } 864 }
795 } 865 }
796 866
867 bool UserManager::AreEphemeralUsersEnabled() const {
868 return ephemeral_users_enabled_.get() &&
869 *ephemeral_users_enabled_ &&
870 owner_.get();
871 }
872
873 bool UserManager::IsEphemeralUser(const std::string& email) const {
874 // The guest user always is ephemeral.
875 if (email == guest_user_.email())
876 return true;
877
878 // The currently logged-in user is ephemeral iff logged in as ephemeral.
879 if (logged_in_user_ && (email == logged_in_user_->email()))
880 return current_user_is_ephemeral_;
881
882 // Any other user is ephemeral iff ephemeral users are enabled, the user is
883 // not the owner and is not in the persistent list.
884 return AreEphemeralUsersEnabled() &&
885 (email != *owner_) &&
886 !FindUserInList(email);
887 }
888
889 const User* UserManager::FindUserInList(const std::string& email) const {
890 const UserList& users = GetUsers();
891 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
892 if ((*it)->email() == email)
893 return *it;
894 }
895 return NULL;
896 }
897
797 void UserManager::StubUserLoggedIn() { 898 void UserManager::StubUserLoggedIn() {
798 logged_in_user_ = &stub_user_; 899 logged_in_user_ = &stub_user_;
799 stub_user_.SetImage(GetDefaultImage(kStubDefaultImageIndex), 900 stub_user_.SetImage(GetDefaultImage(kStubDefaultImageIndex),
800 kStubDefaultImageIndex); 901 kStubDefaultImageIndex);
801 } 902 }
802 903
803 void UserManager::NotifyOnLogin() { 904 void UserManager::NotifyOnLogin() {
804 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 905 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
805 content::NotificationService::current()->Notify( 906 content::NotificationService::current()->Notify(
806 chrome::NOTIFICATION_LOGIN_USER_CHANGED, 907 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
(...skipping 20 matching lines...) Expand all
827 cert_library->RequestCertificates(); 928 cert_library->RequestCertificates();
828 } 929 }
829 930
830 // Schedules current user ownership check on file thread. 931 // Schedules current user ownership check on file thread.
831 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 932 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
832 base::Bind(&UserManager::CheckOwnership, 933 base::Bind(&UserManager::CheckOwnership,
833 base::Unretained(this))); 934 base::Unretained(this)));
834 } 935 }
835 936
836 void UserManager::SetInitialUserImage(const std::string& username) { 937 void UserManager::SetInitialUserImage(const std::string& username) {
938 // Ignore for ephemeral users.
939 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
940 return;
941
837 // Choose a random default image. 942 // Choose a random default image.
838 int image_id = base::RandInt(0, kDefaultImagesCount - 1); 943 int image_id = base::RandInt(0, kDefaultImagesCount - 1);
839 SaveUserDefaultImageIndex(username, image_id); 944 SaveUserDefaultImageIndex(username, image_id);
840 } 945 }
841 946
842 void UserManager::SetUserImage(const std::string& username, 947 void UserManager::SetUserImage(const std::string& username,
843 int image_index, 948 int image_index,
844 const SkBitmap& image) { 949 const SkBitmap& image) {
950 // Ignore for ephemeral users.
951 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 Not needed.
use bartfab instead 2012/03/01 18:33:43 Done.
952 return;
953
845 User* user = const_cast<User*>(FindUser(username)); 954 User* user = const_cast<User*>(FindUser(username));
846 // User may have been removed by now. 955 // User may have been removed by now.
847 if (user) { 956 if (user) {
848 // For existing users, a valid image index should have been set upon loading 957 // For existing users, a valid image index should have been set upon loading
849 // them from Local State. 958 // them from Local State.
850 DCHECK(user->image_index() != User::kInvalidImageIndex || 959 DCHECK(user->image_index() != User::kInvalidImageIndex ||
851 current_user_is_new_); 960 current_user_is_new_);
852 bool image_changed = user->image_index() != User::kInvalidImageIndex; 961 bool image_changed = user->image_index() != User::kInvalidImageIndex;
853 if (!image.empty()) 962 if (!image.empty())
854 user->SetImage(image, image_index); 963 user->SetImage(image, image_index);
(...skipping 12 matching lines...) Expand all
867 content::Details<const User>(user)); 976 content::Details<const User>(user));
868 } 977 }
869 } 978 }
870 } 979 }
871 980
872 void UserManager::SaveUserImageInternal(const std::string& username, 981 void UserManager::SaveUserImageInternal(const std::string& username,
873 int image_index, 982 int image_index,
874 const SkBitmap& image) { 983 const SkBitmap& image) {
875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 984 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
876 985
986 // Ignore for ephemeral users.
987 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 This should be after SetUserImage.
use bartfab instead 2012/03/01 18:33:43 Done.
Ivan Korotkov 2012/03/01 20:16:30 Hey, it's gone now. I meant that it should be afte
use bartfab instead 2012/03/05 18:07:32 Done. I do not understand how this makes sense tho
Ivan Korotkov 2012/03/06 20:37:17 The point is that the picture should be still set
988 return;
989
877 SetUserImage(username, image_index, image); 990 SetUserImage(username, image_index, image);
878 991
879 FilePath image_path = GetImagePathForUser(username); 992 FilePath image_path = GetImagePathForUser(username);
880 DVLOG(1) << "Saving user image to " << image_path.value(); 993 DVLOG(1) << "Saving user image to " << image_path.value();
881 994
882 last_image_set_async_ = true; 995 last_image_set_async_ = true;
883 996
884 BrowserThread::PostTask( 997 BrowserThread::PostTask(
885 BrowserThread::FILE, 998 BrowserThread::FILE,
886 FROM_HERE, 999 FROM_HERE,
887 base::Bind(&UserManager::SaveImageToFile, 1000 base::Bind(&UserManager::SaveImageToFile,
888 base::Unretained(this), 1001 base::Unretained(this),
889 username, image, image_path, image_index)); 1002 username, image, image_path, image_index));
890 } 1003 }
891 1004
892 void UserManager::SaveImageToFile(const std::string& username, 1005 void UserManager::SaveImageToFile(const std::string& username,
893 const SkBitmap& image, 1006 const SkBitmap& image,
894 const FilePath& image_path, 1007 const FilePath& image_path,
895 int image_index) { 1008 int image_index) {
896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1009 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
897 1010
1011 // Ignore for ephemeral users.
1012 if (IsEphemeralUser(username))
Ivan Korotkov 2012/03/01 13:37:50 Not needed (never reached).
use bartfab instead 2012/03/01 18:33:43 Done.
1013 return;
1014
898 std::vector<unsigned char> encoded_image; 1015 std::vector<unsigned char> encoded_image;
899 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &encoded_image)) { 1016 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &encoded_image)) {
900 LOG(ERROR) << "Failed to PNG encode the image."; 1017 LOG(ERROR) << "Failed to PNG encode the image.";
901 return; 1018 return;
902 } 1019 }
903 1020
904 if (file_util::WriteFile(image_path, 1021 if (file_util::WriteFile(image_path,
905 reinterpret_cast<char*>(&encoded_image[0]), 1022 reinterpret_cast<char*>(&encoded_image[0]),
906 encoded_image.size()) == -1) { 1023 encoded_image.size()) == -1) {
907 LOG(ERROR) << "Failed to save image to file."; 1024 LOG(ERROR) << "Failed to save image to file.";
908 return; 1025 return;
909 } 1026 }
910 1027
911 BrowserThread::PostTask( 1028 BrowserThread::PostTask(
912 BrowserThread::UI, 1029 BrowserThread::UI,
913 FROM_HERE, 1030 FROM_HERE,
914 base::Bind(&UserManager::SaveImageToLocalState, 1031 base::Bind(&UserManager::SaveImageToLocalState,
915 base::Unretained(this), 1032 base::Unretained(this),
916 username, image_path.value(), image_index, true)); 1033 username, image_path.value(), image_index, true));
917 } 1034 }
918 1035
919 void UserManager::SaveImageToLocalState(const std::string& username, 1036 void UserManager::SaveImageToLocalState(const std::string& username,
920 const std::string& image_path, 1037 const std::string& image_path,
921 int image_index, 1038 int image_index,
922 bool is_async) { 1039 bool is_async) {
923 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1040 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
924 1041
1042 // Ignore for ephemeral users.
Ivan Korotkov 2012/03/01 13:37:50 Here it's ok.
use bartfab instead 2012/03/01 18:33:43 Done.
1043 if (IsEphemeralUser(username))
1044 return;
1045
925 // TODO(ivankr): use unique filenames for user images each time 1046 // TODO(ivankr): use unique filenames for user images each time
926 // a new image is set so that only the last image update is saved 1047 // a new image is set so that only the last image update is saved
927 // to Local State and notified. 1048 // to Local State and notified.
928 if (is_async && !last_image_set_async_) { 1049 if (is_async && !last_image_set_async_) {
929 DVLOG(1) << "Ignoring saved image because it has changed"; 1050 DVLOG(1) << "Ignoring saved image because it has changed";
930 return; 1051 return;
931 } else if (!is_async) { 1052 } else if (!is_async) {
932 // Reset the async image save flag if called directly from the UI thread. 1053 // Reset the async image save flag if called directly from the UI thread.
933 last_image_set_async_ = false; 1054 last_image_set_async_ = false;
934 } 1055 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 } 1187 }
1067 1188
1068 User* UserManager::CreateUser(const std::string& email) const { 1189 User* UserManager::CreateUser(const std::string& email) const {
1069 User* user = new User(email, email == kGuestUser); 1190 User* user = new User(email, email == kGuestUser);
1070 user->set_oauth_token_status(LoadUserOAuthStatus(email)); 1191 user->set_oauth_token_status(LoadUserOAuthStatus(email));
1071 // Used to determine whether user's display name is unique. 1192 // Used to determine whether user's display name is unique.
1072 ++display_name_count_[user->GetDisplayName()]; 1193 ++display_name_count_[user->GetDisplayName()];
1073 return user; 1194 return user;
1074 } 1195 }
1075 1196
1197 void UserManager::RemoveAllExceptOwnerFromList() {
1198 if (!AreEphemeralUsersEnabled())
Ivan Korotkov 2012/03/01 13:37:50 No point in this check.
use bartfab instead 2012/03/01 18:33:43 Done.
1199 return;
1200
1201 const std::string owner_email = *owner_;
Ivan Korotkov 2012/03/01 13:37:50 This looks overly complicated. Since this should b
use bartfab instead 2012/03/01 18:33:43 I considered this but it will not work: RemoveUse
Ivan Korotkov 2012/03/01 20:16:30 Ah, I see. Add a comment about that, please.
rkc 2012/03/01 22:17:37 Another option could be to refactor RemoveUserFrom
use bartfab instead 2012/03/05 18:07:32 Good idea. I implemented it like this using a new
1202 // If a user is currently logged in and the login occurred before ephemeral
1203 // users were enabled, this user should not be deleted yet either.
1204 std::string logged_in_user_email;
1205 if (user_is_logged_in_ && !current_user_is_ephemeral_)
1206 logged_in_user_email = logged_in_user_->email();
1207
1208 PrefService* prefs = g_browser_process->local_state();
1209 ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers);
1210 DictionaryPrefUpdate prefs_images_update(prefs, kUserImages);
1211 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1212 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1213
1214 base::ListValue* users = prefs_users_update->DeepCopy();
1215 prefs_users_update->Clear();
1216 for (base::ListValue::const_iterator user = users->begin();
1217 user != users->end(); ++user) {
1218 std::string user_email;
1219 (*user)->GetAsString(&user_email);
1220 if (user_email == owner_email || user_email == logged_in_user_email) {
1221 prefs_users_update->Append(Value::CreateStringValue(user_email));
1222 continue;
1223 }
1224 std::string image_path_string;
1225 prefs_images_update->GetStringWithoutPathExpansion(user_email,
1226 &image_path_string);
1227 prefs_images_update->RemoveWithoutPathExpansion(user_email, NULL);
1228 prefs_oauth_update->RemoveWithoutPathExpansion(user_email, NULL);
1229 prefs_display_email_update->RemoveWithoutPathExpansion(user_email, NULL);
1230
1231 int default_image_id = User::kInvalidImageIndex;
1232 if (!image_path_string.empty() &&
1233 !IsDefaultImagePath(image_path_string, &default_image_id)) {
1234 FilePath image_path(image_path_string);
1235 BrowserThread::PostTask(
1236 BrowserThread::FILE,
1237 FROM_HERE,
1238 base::Bind(&UserManager::DeleteUserImage,
1239 base::Unretained(this),
1240 image_path));
1241 }
1242 }
1243 delete users;
Nikita (slow) 2012/03/01 10:01:58 scoped_ptr<>?
use bartfab instead 2012/03/01 18:33:43 Done.
1244
1245 if (!users_.empty()) {
1246 UserList users_update;
1247 for (UserList::iterator user = users_.begin(); user != users_.end();
1248 ++user) {
1249 if ((*user)->email() == owner_email || *user == logged_in_user_) {
1250 users_update.push_back(*user);
1251 } else {
1252 --display_name_count_[(*user)->GetDisplayName()];
1253 delete *user;
1254 }
1255 }
1256 users_ = users_update;
1257 // Trigger a redraw of the login window.
1258 content::NotificationService::current()->Notify(
1259 chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED,
1260 content::Source<UserManager>(this),
1261 content::NotificationService::NoDetails());
1262 }
1263 }
1264
1076 } // namespace chromeos 1265 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698