1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
7 #include "ash/multi_profile_uma.h"
8 #include "ash/session/session_state_observer.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/chromeos/login/screen_locker.h"
13 #include "chrome/browser/chromeos/login/user.h"
14 #include "chrome/browser/chromeos/login/user_adding_screen.h"
15 #include "chrome/browser/chromeos/login/user_manager.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
19 #include "chrome/common/pref_names.h"
20 #include "chromeos/chromeos_switches.h"
21 #include "chromeos/dbus/dbus_thread_manager.h"
22 #include "chromeos/dbus/session_manager_client.h"
23 #include "chromeos/login/login_state.h"
24 #include "google_apis/gaia/gaia_auth_util.h"
26 SessionStateDelegateChromeos::SessionStateDelegateChromeos()
27 : session_state_(SESSION_STATE_LOGIN_PRIMARY
) {
28 chromeos::UserManager::Get()->AddSessionStateObserver(this);
29 chromeos::UserAddingScreen::Get()->AddObserver(this);
31 // LoginState is not initialized in unit_tests.
32 if (chromeos::LoginState::IsInitialized()) {
33 chromeos::LoginState::Get()->AddObserver(this);
34 SetSessionState(chromeos::LoginState::Get()->IsUserLoggedIn() ?
35 SESSION_STATE_ACTIVE
: SESSION_STATE_LOGIN_PRIMARY
, true);
39 SessionStateDelegateChromeos::~SessionStateDelegateChromeos() {
40 chromeos::UserManager::Get()->RemoveSessionStateObserver(this);
41 chromeos::UserAddingScreen::Get()->RemoveObserver(this);
43 // LoginState is not initialized in unit_tests.
44 if (chromeos::LoginState::IsInitialized())
45 chromeos::LoginState::Get()->RemoveObserver(this);
48 content::BrowserContext
* SessionStateDelegateChromeos::GetBrowserContextByIndex(
49 ash::MultiProfileIndex index
) {
50 DCHECK_LT(index
, NumberOfLoggedInUsers());
51 chromeos::User
* user
=
52 chromeos::UserManager::Get()->GetLRULoggedInUsers()[index
];
54 return chromeos::UserManager::Get()->GetProfileByUser(user
);
57 content::BrowserContext
*
58 SessionStateDelegateChromeos::GetBrowserContextForWindow(
59 aura::Window
* window
) {
60 const std::string
& user_id
=
61 chrome::MultiUserWindowManager::GetInstance()->GetWindowOwner(window
);
62 const chromeos::User
* user
= chromeos::UserManager::Get()->FindUser(user_id
);
64 return chromeos::UserManager::Get()->GetProfileByUser(user
);
67 int SessionStateDelegateChromeos::GetMaximumNumberOfLoggedInUsers() const {
68 // We limit list of logged in users to 10 due to memory constraints.
69 // Note that 10 seems excessive, but we want to test how many users are
70 // actually added to a session.
71 // TODO(nkostylev): Adjust this limitation based on device capabilites.
72 // http://crbug.com/230865
76 int SessionStateDelegateChromeos::NumberOfLoggedInUsers() const {
77 return chromeos::UserManager::Get()->GetLoggedInUsers().size();
80 bool SessionStateDelegateChromeos::IsActiveUserSessionStarted() const {
81 return chromeos::UserManager::Get()->IsSessionStarted();
84 bool SessionStateDelegateChromeos::CanLockScreen() const {
85 const chromeos::UserList unlock_users
=
86 chromeos::UserManager::Get()->GetUnlockUsers();
87 return !unlock_users
.empty();
90 bool SessionStateDelegateChromeos::IsScreenLocked() const {
91 return chromeos::ScreenLocker::default_screen_locker() &&
92 chromeos::ScreenLocker::default_screen_locker()->locked();
95 bool SessionStateDelegateChromeos::ShouldLockScreenBeforeSuspending() const {
96 const chromeos::UserList logged_in_users
=
97 chromeos::UserManager::Get()->GetLoggedInUsers();
98 for (chromeos::UserList::const_iterator it
= logged_in_users
.begin();
99 it
!= logged_in_users
.end(); ++it
) {
100 chromeos::User
* user
= (*it
);
101 Profile
* profile
= chromeos::UserManager::Get()->GetProfileByUser(user
);
102 if (profile
->GetPrefs()->GetBoolean(prefs::kEnableAutoScreenLock
))
108 void SessionStateDelegateChromeos::LockScreen() {
109 if (!CanLockScreen())
112 VLOG(1) << "Requesting screen lock from SessionStateDelegate";
113 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
117 void SessionStateDelegateChromeos::UnlockScreen() {
118 // This is used only for testing thus far.
122 bool SessionStateDelegateChromeos::IsUserSessionBlocked() const {
123 bool has_login_manager
= CommandLine::ForCurrentProcess()->HasSwitch(
124 chromeos::switches::kLoginManager
);
125 return (has_login_manager
&& !IsActiveUserSessionStarted()) ||
127 chromeos::UserAddingScreen::Get()->IsRunning();
130 ash::SessionStateDelegate::SessionState
131 SessionStateDelegateChromeos::GetSessionState() const {
132 return session_state_
;
135 const ash::UserInfo
* SessionStateDelegateChromeos::GetUserInfo(
136 ash::MultiProfileIndex index
) const {
137 DCHECK_LT(index
, NumberOfLoggedInUsers());
138 return chromeos::UserManager::Get()->GetLRULoggedInUsers()[index
];
141 const ash::UserInfo
* SessionStateDelegateChromeos::GetUserInfo(
142 content::BrowserContext
* context
) const {
144 return chromeos::UserManager::Get()->GetUserByProfile(
145 Profile::FromBrowserContext(context
));
148 bool SessionStateDelegateChromeos::ShouldShowAvatar(
149 aura::Window
* window
) const {
150 return chrome::MultiUserWindowManager::GetInstance()->
151 ShouldShowAvatar(window
);
154 void SessionStateDelegateChromeos::SwitchActiveUser(
155 const std::string
& user_id
) {
156 // Disallow switching to an already active user since that might crash.
157 // Also check that we got a user id and not an email address.
159 gaia::CanonicalizeEmail(gaia::SanitizeEmail(user_id
)));
160 if (user_id
== chromeos::UserManager::Get()->GetActiveUser()->email())
162 chromeos::UserManager::Get()->SwitchActiveUser(user_id
);
165 void SessionStateDelegateChromeos::CycleActiveUser(CycleUser cycle_user
) {
166 // Make sure there is a user to switch to.
167 if (NumberOfLoggedInUsers() <= 1)
170 const chromeos::UserList
& logged_in_users
=
171 chromeos::UserManager::Get()->GetLoggedInUsers();
173 std::string user_id
= chromeos::UserManager::Get()->GetActiveUser()->email();
175 // Get an iterator positioned at the active user.
176 chromeos::UserList::const_iterator it
;
177 for (it
= logged_in_users
.begin();
178 it
!= logged_in_users
.end(); ++it
) {
179 if ((*it
)->email() == user_id
)
183 // Active user not found.
184 if (it
== logged_in_users
.end())
187 // Get the user's email to select, wrapping to the start/end of the list if
189 switch (cycle_user
) {
190 case CYCLE_TO_NEXT_USER
:
191 if (++it
== logged_in_users
.end())
192 user_id
= (*logged_in_users
.begin())->email();
194 user_id
= (*it
)->email();
196 case CYCLE_TO_PREVIOUS_USER
:
197 if (it
== logged_in_users
.begin())
198 it
= logged_in_users
.end();
199 user_id
= (*(--it
))->email();
203 // Switch using the transformed |user_id|.
204 chromeos::UserManager::Get()->SwitchActiveUser(user_id
);
207 void SessionStateDelegateChromeos::AddSessionStateObserver(
208 ash::SessionStateObserver
* observer
) {
209 session_state_observer_list_
.AddObserver(observer
);
212 void SessionStateDelegateChromeos::RemoveSessionStateObserver(
213 ash::SessionStateObserver
* observer
) {
214 session_state_observer_list_
.RemoveObserver(observer
);
217 void SessionStateDelegateChromeos::LoggedInStateChanged() {
218 SetSessionState(chromeos::LoginState::Get()->IsUserLoggedIn() ?
219 SESSION_STATE_ACTIVE
: SESSION_STATE_LOGIN_PRIMARY
, false);
222 void SessionStateDelegateChromeos::ActiveUserChanged(
223 const chromeos::User
* active_user
) {
224 FOR_EACH_OBSERVER(ash::SessionStateObserver
,
225 session_state_observer_list_
,
226 ActiveUserChanged(active_user
->email()));
229 void SessionStateDelegateChromeos::UserAddedToSession(
230 const chromeos::User
* added_user
) {
231 FOR_EACH_OBSERVER(ash::SessionStateObserver
,
232 session_state_observer_list_
,
233 UserAddedToSession(added_user
->email()));
236 void SessionStateDelegateChromeos::OnUserAddingStarted() {
237 SetSessionState(SESSION_STATE_LOGIN_SECONDARY
, false);
240 void SessionStateDelegateChromeos::OnUserAddingFinished() {
241 SetSessionState(SESSION_STATE_ACTIVE
, false);
244 void SessionStateDelegateChromeos::SetSessionState(SessionState new_state
,
246 if (session_state_
== new_state
&& !force
)
249 session_state_
= new_state
;
250 NotifySessionStateChanged();
253 void SessionStateDelegateChromeos::NotifySessionStateChanged() {
254 FOR_EACH_OBSERVER(ash::SessionStateObserver
,
255 session_state_observer_list_
,
256 SessionStateChanged(session_state_
));