blob: b36175591a53cb13f32d9c53b56e0d3fd6dee81a [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
#include "ash/multi_profile_uma.h"
#include "ash/session_state_observer.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/chromeos/login/screen_locker.h"
#include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_adding_screen.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "google_apis/gaia/gaia_auth_util.h"
SessionStateDelegateChromeos::SessionStateDelegateChromeos() {
chromeos::UserManager::Get()->AddSessionStateObserver(this);
}
SessionStateDelegateChromeos::~SessionStateDelegateChromeos() {
}
int SessionStateDelegateChromeos::GetMaximumNumberOfLoggedInUsers() const {
// TODO(nkostylev): Show some UI messages why no more users could be added
// to this session. http://crbug.com/230863
// We limit list of logged in users to 10 due to memory constraints.
// Note that 10 seems excessive, but we want to test how many users are
// actually added to a session.
// TODO(nkostylev): Adjust this limitation based on device capabilites.
// http://crbug.com/230865
return 10;
}
int SessionStateDelegateChromeos::NumberOfLoggedInUsers() const {
return chromeos::UserManager::Get()->GetLoggedInUsers().size();
}
bool SessionStateDelegateChromeos::IsActiveUserSessionStarted() const {
return chromeos::UserManager::Get()->IsSessionStarted();
}
bool SessionStateDelegateChromeos::CanLockScreen() const {
const chromeos::UserList unlock_users =
chromeos::UserManager::Get()->GetUnlockUsers();
DCHECK_LE(unlock_users.size(), 1u);
return !unlock_users.empty() && unlock_users[0]->can_lock();
}
bool SessionStateDelegateChromeos::IsScreenLocked() const {
return chromeos::ScreenLocker::default_screen_locker() &&
chromeos::ScreenLocker::default_screen_locker()->locked();
}
bool SessionStateDelegateChromeos::ShouldLockScreenBeforeSuspending() const {
const chromeos::UserList unlock_users =
chromeos::UserManager::Get()->GetUnlockUsers();
DCHECK_LE(unlock_users.size(), 1u);
Profile* profile =
!unlock_users.empty()
? chromeos::UserManager::Get()->GetProfileByUser(unlock_users[0])
: NULL;
return profile && profile->GetPrefs()->GetBoolean(prefs::kEnableScreenLock);
}
void SessionStateDelegateChromeos::LockScreen() {
if (!CanLockScreen())
return;
VLOG(1) << "Requesting screen lock from SessionStateDelegate";
chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
RequestLockScreen();
}
void SessionStateDelegateChromeos::UnlockScreen() {
// This is used only for testing thus far.
NOTIMPLEMENTED();
}
bool SessionStateDelegateChromeos::IsUserSessionBlocked() const {
bool has_login_manager = CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kLoginManager);
return (has_login_manager && !IsActiveUserSessionStarted()) ||
IsScreenLocked() ||
chromeos::UserAddingScreen::Get()->IsRunning();
}
const base::string16 SessionStateDelegateChromeos::GetUserDisplayName(
ash::MultiProfileIndex index) const {
DCHECK_LT(index, NumberOfLoggedInUsers());
return chromeos::UserManager::Get()->
GetLRULoggedInUsers()[index]->display_name();
}
const std::string SessionStateDelegateChromeos::GetUserEmail(
ash::MultiProfileIndex index) const {
DCHECK_LT(index, NumberOfLoggedInUsers());
return chromeos::UserManager::Get()->
GetLRULoggedInUsers()[index]->display_email();
}
const std::string SessionStateDelegateChromeos::GetUserID(
ash::MultiProfileIndex index) const {
DCHECK_LT(index, NumberOfLoggedInUsers());
return gaia::CanonicalizeEmail(gaia::SanitizeEmail(
chromeos::UserManager::Get()->
GetLRULoggedInUsers()[index]->email()));
}
const gfx::ImageSkia& SessionStateDelegateChromeos::GetUserImage(
ash::MultiProfileIndex index) const {
DCHECK_LT(index, NumberOfLoggedInUsers());
return chromeos::UserManager::Get()->GetLRULoggedInUsers()[index]->image();
}
void SessionStateDelegateChromeos::GetLoggedInUsers(ash::UserIdList* users) {
const chromeos::UserList& logged_in_users =
chromeos::UserManager::Get()->GetLoggedInUsers();
for (chromeos::UserList::const_iterator it = logged_in_users.begin();
it != logged_in_users.end(); ++it) {
const chromeos::User* user = (*it);
users->push_back(user->email());
}
}
void SessionStateDelegateChromeos::SwitchActiveUser(
const std::string& user_id) {
// Disallow switching to an already active user since that might crash.
// Also check that we got a user id and not an email address.
DCHECK_EQ(user_id,
gaia::CanonicalizeEmail(gaia::SanitizeEmail(user_id)));
if (user_id == chromeos::UserManager::Get()->GetActiveUser()->email())
return;
chromeos::UserManager::Get()->SwitchActiveUser(user_id);
}
void SessionStateDelegateChromeos::CycleActiveUser(CycleUser cycle_user) {
// Make sure there is a user to switch to.
if (NumberOfLoggedInUsers() <= 1)
return;
const chromeos::UserList& logged_in_users =
chromeos::UserManager::Get()->GetLoggedInUsers();
std::string user_id = chromeos::UserManager::Get()->GetActiveUser()->email();
// Get an iterator positioned at the active user.
chromeos::UserList::const_iterator it;
for (it = logged_in_users.begin();
it != logged_in_users.end(); ++it) {
if ((*it)->email() == user_id)
break;
}
// Active user not found.
if (it == logged_in_users.end())
return;
// Get the user's email to select, wrapping to the start/end of the list if
// necessary.
switch (cycle_user) {
case CYCLE_TO_NEXT_USER:
if (++it == logged_in_users.end())
user_id = (*logged_in_users.begin())->email();
else
user_id = (*it)->email();
break;
case CYCLE_TO_PREVIOUS_USER:
if (it == logged_in_users.begin())
it = logged_in_users.end();
user_id = (*(--it))->email();
break;
}
// Switch using the transformed |user_id|.
chromeos::UserManager::Get()->SwitchActiveUser(user_id);
}
void SessionStateDelegateChromeos::AddSessionStateObserver(
ash::SessionStateObserver* observer) {
session_state_observer_list_.AddObserver(observer);
}
void SessionStateDelegateChromeos::RemoveSessionStateObserver(
ash::SessionStateObserver* observer) {
session_state_observer_list_.RemoveObserver(observer);
}
bool SessionStateDelegateChromeos::TransferWindowToDesktopOfUser(
aura::Window* window,
ash::MultiProfileIndex index) {
if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
return false;
chrome::MultiUserWindowManager* window_manager =
chrome::MultiUserWindowManager::GetInstance();
if (window_manager->GetWindowOwner(window).empty())
return false;
ash::MultiProfileUMA::RecordTeleportAction(
ash::MultiProfileUMA::TELEPORT_WINDOW_DRAG_AND_DROP);
DCHECK_LT(index, NumberOfLoggedInUsers());
window_manager->ShowWindowForUser(window,
chromeos::UserManager::Get()->GetLRULoggedInUsers()[index]->email());
return true;
}
void SessionStateDelegateChromeos::ActiveUserChanged(
const chromeos::User* active_user) {
FOR_EACH_OBSERVER(ash::SessionStateObserver,
session_state_observer_list_,
ActiveUserChanged(active_user->email()));
}
void SessionStateDelegateChromeos::UserAddedToSession(
const chromeos::User* added_user) {
FOR_EACH_OBSERVER(ash::SessionStateObserver,
session_state_observer_list_,
UserAddedToSession(added_user->email()));
}