Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |