| Index: trunk/src/chrome/browser/chromeos/login/screens/user_selection_screen.cc
|
| ===================================================================
|
| --- trunk/src/chrome/browser/chromeos/login/screens/user_selection_screen.cc (revision 275554)
|
| +++ trunk/src/chrome/browser/chromeos/login/screens/user_selection_screen.cc (working copy)
|
| @@ -4,24 +4,144 @@
|
|
|
| #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/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/signin/screenlock_bridge.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,
|
| + ScreenlockBridge::LockHandler::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) {
|
| @@ -51,4 +171,102 @@
|
| 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_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)) {
|
| + ScreenlockBridge::LockHandler::AuthType initial_auth_type =
|
| + ShouldForceOnlineSignIn(*it)
|
| + ? ScreenlockBridge::LockHandler::ONLINE_SIGN_IN
|
| + : ScreenlockBridge::LockHandler::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::HandleGetUsers() {
|
| + SendUserList(false);
|
| +}
|
| +
|
| +void UserSelectionScreen::SetAuthType(
|
| + const std::string& username,
|
| + ScreenlockBridge::LockHandler::AuthType auth_type) {
|
| + user_auth_type_map_[username] = auth_type;
|
| +}
|
| +
|
| +ScreenlockBridge::LockHandler::AuthType UserSelectionScreen::GetAuthType(
|
| + const std::string& username) const {
|
| + if (user_auth_type_map_.find(username) == user_auth_type_map_.end())
|
| + return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
|
| + return user_auth_type_map_.find(username)->second;
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|