| Index: chrome/browser/chromeos/login/screens/user_selection_screen.cc
|
| diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
|
| index 5ee3d7c0d6a3c056006474640e286fbd1388e0d5..9115d8127058cb94357a80cbc2df2247f3c60c81 100644
|
| --- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc
|
| +++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
|
| @@ -4,24 +4,143 @@
|
|
|
| #include "chrome/browser/chromeos/login/screens/user_selection_screen.h"
|
|
|
| +#include "ash/shell.h"
|
| #include "base/logging.h"
|
| -#include "chrome/browser/chromeos/login/screens/screen_observer.h"
|
| +#include "base/prefs/pref_service.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/chromeos/login/lock/screen_locker.h"
|
| +#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
|
| +#include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
|
| +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
|
| #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "ui/wm/core/user_activity_detector.h"
|
|
|
| namespace chromeos {
|
|
|
| +namespace {
|
| +
|
| +// User dictionary keys.
|
| +const char kKeyUsername[] = "username";
|
| +const char kKeyDisplayName[] = "displayName";
|
| +const char kKeyEmailAddress[] = "emailAddress";
|
| +const char kKeyEnterpriseDomain[] = "enterpriseDomain";
|
| +const char kKeyPublicAccount[] = "publicAccount";
|
| +const char kKeyLocallyManagedUser[] = "locallyManagedUser";
|
| +const char kKeySignedIn[] = "signedIn";
|
| +const char kKeyCanRemove[] = "canRemove";
|
| +const char kKeyIsOwner[] = "isOwner";
|
| +const char kKeyInitialAuthType[] = "initialAuthType";
|
| +const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed";
|
| +const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy";
|
| +
|
| +// Max number of users to show.
|
| +const size_t kMaxUsers = 18;
|
| +
|
| +const int kPasswordClearTimeoutSec = 60;
|
| +
|
| +} // namespace
|
| +
|
| UserSelectionScreen::UserSelectionScreen() : handler_(NULL) {
|
| }
|
|
|
| UserSelectionScreen::~UserSelectionScreen() {
|
| + wm::UserActivityDetector* activity_detector =
|
| + ash::Shell::GetInstance()->user_activity_detector();
|
| + if (activity_detector->HasObserver(this))
|
| + activity_detector->RemoveObserver(this);
|
| +}
|
| +
|
| +// static
|
| +void UserSelectionScreen::FillUserDictionary(User* user,
|
| + bool is_owner,
|
| + bool is_signin_to_add,
|
| + LoginDisplay::AuthType auth_type,
|
| + base::DictionaryValue* user_dict) {
|
| + const std::string& user_id = user->email();
|
| + const bool is_public_account =
|
| + user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
|
| + const bool is_locally_managed_user =
|
| + user->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
|
| +
|
| + user_dict->SetString(kKeyUsername, user_id);
|
| + user_dict->SetString(kKeyEmailAddress, user->display_email());
|
| + user_dict->SetString(kKeyDisplayName, user->GetDisplayName());
|
| + user_dict->SetBoolean(kKeyPublicAccount, is_public_account);
|
| + user_dict->SetBoolean(kKeyLocallyManagedUser, is_locally_managed_user);
|
| + user_dict->SetInteger(kKeyInitialAuthType, auth_type);
|
| + user_dict->SetBoolean(kKeySignedIn, user->is_logged_in());
|
| + user_dict->SetBoolean(kKeyIsOwner, is_owner);
|
| +
|
| + // Fill in multi-profiles related fields.
|
| + if (is_signin_to_add) {
|
| + MultiProfileUserController* multi_profile_user_controller =
|
| + UserManager::Get()->GetMultiProfileUserController();
|
| + std::string behavior =
|
| + multi_profile_user_controller->GetCachedValue(user_id);
|
| + user_dict->SetBoolean(kKeyMultiProfilesAllowed,
|
| + multi_profile_user_controller->IsUserAllowedInSession(
|
| + user_id) == MultiProfileUserController::ALLOWED);
|
| + user_dict->SetString(kKeyMultiProfilesPolicy, behavior);
|
| + } else {
|
| + user_dict->SetBoolean(kKeyMultiProfilesAllowed, true);
|
| + }
|
| +
|
| + if (is_public_account) {
|
| + policy::BrowserPolicyConnectorChromeOS* policy_connector =
|
| + g_browser_process->platform_part()->browser_policy_connector_chromeos();
|
| +
|
| + if (policy_connector->IsEnterpriseManaged()) {
|
| + user_dict->SetString(kKeyEnterpriseDomain,
|
| + policy_connector->GetEnterpriseDomain());
|
| + }
|
| + }
|
| +}
|
| +
|
| +// static
|
| +bool UserSelectionScreen::ShouldForceOnlineSignIn(const User* user) {
|
| + // Public sessions are always allowed to log in offline.
|
| + // Supervised user are allowed to log in offline if their OAuth token status
|
| + // is unknown or valid.
|
| + // For all other users, force online sign in if:
|
| + // * The flag to force online sign-in is set for the user.
|
| + // * The user's OAuth token is invalid.
|
| + // * The user's OAuth token status is unknown (except supervised users,
|
| + // see above).
|
| + if (user->is_logged_in())
|
| + return false;
|
| +
|
| + const User::OAuthTokenStatus token_status = user->oauth_token_status();
|
| + const bool is_locally_managed_user =
|
| + user->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
|
| + const bool is_public_session =
|
| + user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
|
| +
|
| + if (is_locally_managed_user &&
|
| + token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN) {
|
| + return false;
|
| + }
|
| +
|
| + if (is_public_session)
|
| + return false;
|
| +
|
| + return user->force_online_signin() ||
|
| + (token_status == User::OAUTH2_TOKEN_STATUS_INVALID) ||
|
| + (token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN);
|
| }
|
|
|
| void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) {
|
| handler_ = handler;
|
| }
|
|
|
| -void UserSelectionScreen::Init(const UserList& users) {
|
| +void UserSelectionScreen::Init(const UserList& users, bool show_guest) {
|
| users_ = users;
|
| + show_guest_ = show_guest;
|
| +
|
| + wm::UserActivityDetector* activity_detector =
|
| + ash::Shell::GetInstance()->user_activity_detector();
|
| + if (!activity_detector->HasObserver(this))
|
| + activity_detector->AddObserver(this);
|
| }
|
|
|
| void UserSelectionScreen::OnBeforeUserRemoved(const std::string& username) {
|
| @@ -48,12 +167,28 @@ void UserSelectionScreen::OnUserImageChanged(const User& user) {
|
| }
|
|
|
| void UserSelectionScreen::ShowUserPodButton(
|
| - const std::string& username,
|
| + const std::string& user_id,
|
| const std::string& iconURL,
|
| const base::Closure& click_callback) {
|
| if (!handler_)
|
| return;
|
| - handler_->ShowUserPodButton(username, iconURL, click_callback);
|
| + user_pod_button_callback_map_[user_id] = click_callback;
|
| +
|
| + handler_->ShowUserPodButton(user_id, iconURL);
|
| +
|
| + // TODO(tengs): Move this code once we move unlocking to native code.
|
| + if (ScreenLocker::default_screen_locker()) {
|
| + UserManager* user_manager = UserManager::Get();
|
| + const User* user = user_manager->FindUser(user_id);
|
| + if (!user)
|
| + return;
|
| + PrefService* profile_prefs =
|
| + user_manager->GetProfileByUser(user)->GetPrefs();
|
| + if (profile_prefs->GetBoolean(prefs::kEasyUnlockShowTutorial)) {
|
| + handler_->ShowEasyUnlockBubble();
|
| + profile_prefs->SetBoolean(prefs::kEasyUnlockShowTutorial, false);
|
| + }
|
| + }
|
| }
|
|
|
| void UserSelectionScreen::HideUserPodButton(const std::string& username) {
|
| @@ -66,4 +201,115 @@ const UserList& UserSelectionScreen::GetUsers() const {
|
| return users_;
|
| }
|
|
|
| +void UserSelectionScreen::OnPasswordClearTimerExpired() {
|
| + if (handler_)
|
| + handler_->ClearUserPodPassword();
|
| +}
|
| +
|
| +void UserSelectionScreen::OnUserActivity(const ui::Event* event) {
|
| + if (!password_clear_timer_.IsRunning()) {
|
| + password_clear_timer_.Start(
|
| + FROM_HERE,
|
| + base::TimeDelta::FromSeconds(kPasswordClearTimeoutSec),
|
| + this,
|
| + &UserSelectionScreen::OnPasswordClearTimerExpired);
|
| + }
|
| + password_clear_timer_.Reset();
|
| +}
|
| +
|
| +void UserSelectionScreen::SendUserList(bool animated) {
|
| + base::ListValue users_list;
|
| + const UserList& users = GetUsers();
|
| +
|
| + // TODO(nkostylev): Move to a separate method in UserManager.
|
| + // http://crbug.com/230852
|
| + bool is_signin_to_add = LoginDisplayHostImpl::default_host() &&
|
| + UserManager::Get()->IsUserLoggedIn();
|
| +
|
| + user_pod_button_callback_map_.clear();
|
| + user_auth_type_map_.clear();
|
| +
|
| + bool single_user = users.size() == 1;
|
| + std::string owner;
|
| + chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
|
| + bool has_owner = owner.size() > 0;
|
| + size_t max_non_owner_users = has_owner ? kMaxUsers - 1 : kMaxUsers;
|
| + size_t non_owner_count = 0;
|
| +
|
| + policy::BrowserPolicyConnectorChromeOS* connector =
|
| + g_browser_process->platform_part()->browser_policy_connector_chromeos();
|
| +
|
| + bool is_enterprise_managed = connector->IsEnterpriseManaged();
|
| +
|
| + for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
|
| + const std::string& user_id = (*it)->email();
|
| + bool is_owner = (user_id == owner);
|
| + bool is_public_account =
|
| + ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT);
|
| +
|
| + if ((is_public_account && !is_signin_to_add) || is_owner ||
|
| + (!is_public_account && non_owner_count < max_non_owner_users)) {
|
| + LoginDisplay::AuthType initial_auth_type =
|
| + ShouldForceOnlineSignIn(*it) ? LoginDisplay::ONLINE_SIGN_IN
|
| + : LoginDisplay::OFFLINE_PASSWORD;
|
| + user_auth_type_map_[user_id] = initial_auth_type;
|
| +
|
| + base::DictionaryValue* user_dict = new base::DictionaryValue();
|
| + FillUserDictionary(
|
| + *it, is_owner, is_signin_to_add, initial_auth_type, user_dict);
|
| + bool signed_in = (*it)->is_logged_in();
|
| + // Single user check here is necessary because owner info might not be
|
| + // available when running into login screen on first boot.
|
| + // See http://crosbug.com/12723
|
| + bool can_remove_user =
|
| + ((!single_user || is_enterprise_managed) && !user_id.empty() &&
|
| + !is_owner && !is_public_account && !signed_in && !is_signin_to_add);
|
| + user_dict->SetBoolean(kKeyCanRemove, can_remove_user);
|
| +
|
| + if (!is_owner)
|
| + ++non_owner_count;
|
| + if (is_owner && users_list.GetSize() > kMaxUsers) {
|
| + // Owner is always in the list.
|
| + users_list.Insert(kMaxUsers - 1, user_dict);
|
| + while (users_list.GetSize() > kMaxUsers)
|
| + users_list.Remove(kMaxUsers, NULL);
|
| + } else if (users_list.GetSize() < kMaxUsers) {
|
| + users_list.Append(user_dict);
|
| + }
|
| + }
|
| + }
|
| +
|
| + handler_->LoadUsers(users_list, animated, show_guest_);
|
| +}
|
| +
|
| +void UserSelectionScreen::SetAuthType(const std::string& user_id,
|
| + LoginDisplay::AuthType auth_type,
|
| + const std::string& initial_value) {
|
| + user_auth_type_map_[user_id] = auth_type;
|
| + if (handler_)
|
| + handler_->SetAuthType(user_id, auth_type, initial_value);
|
| +}
|
| +
|
| +LoginDisplay::AuthType UserSelectionScreen::GetAuthType(
|
| + const std::string& user_id) const {
|
| + if (user_auth_type_map_.find(user_id) == user_auth_type_map_.end())
|
| + return LoginDisplay::OFFLINE_PASSWORD;
|
| + return user_auth_type_map_.find(user_id)->second;
|
| +}
|
| +
|
| +void UserSelectionScreen::HandleCustomButtonClicked(
|
| + const std::string& user_id) {
|
| + if (user_pod_button_callback_map_.find(user_id) ==
|
| + user_pod_button_callback_map_.end()) {
|
| + LOG(WARNING) << "User pod custom button clicked but no callback found for"
|
| + << user_id;
|
| + return;
|
| + }
|
| + user_pod_button_callback_map_[user_id].Run();
|
| +}
|
| +
|
| +void UserSelectionScreen::HandleGetUsers() {
|
| + SendUserList(false);
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|