Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / ash / session_state_delegate_chromeos.cc
bloba0082c172fc83fdc835f8ce791a32eec9c1a2167
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 "ash/system/chromeos/multi_user/user_switch_util.h"
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/prefs/pref_service.h"
15 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
16 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
17 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
18 #include "chrome/browser/chromeos/profiles/profile_helper.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
22 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
23 #include "chrome/common/pref_names.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/dbus/session_manager_client.h"
27 #include "chromeos/login/login_state.h"
28 #include "components/user_manager/user.h"
29 #include "components/user_manager/user_manager.h"
30 #include "google_apis/gaia/gaia_auth_util.h"
32 SessionStateDelegateChromeos::SessionStateDelegateChromeos()
33 : session_state_(SESSION_STATE_LOGIN_PRIMARY) {
34 user_manager::UserManager::Get()->AddSessionStateObserver(this);
35 chromeos::UserAddingScreen::Get()->AddObserver(this);
37 // LoginState is not initialized in unit_tests.
38 if (chromeos::LoginState::IsInitialized()) {
39 chromeos::LoginState::Get()->AddObserver(this);
40 SetSessionState(chromeos::LoginState::Get()->IsUserLoggedIn() ?
41 SESSION_STATE_ACTIVE : SESSION_STATE_LOGIN_PRIMARY, true);
45 SessionStateDelegateChromeos::~SessionStateDelegateChromeos() {
46 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
47 chromeos::UserAddingScreen::Get()->RemoveObserver(this);
49 // LoginState is not initialized in unit_tests.
50 if (chromeos::LoginState::IsInitialized())
51 chromeos::LoginState::Get()->RemoveObserver(this);
54 content::BrowserContext* SessionStateDelegateChromeos::GetBrowserContextByIndex(
55 ash::MultiProfileIndex index) {
56 DCHECK_LT(index, NumberOfLoggedInUsers());
57 user_manager::User* user =
58 user_manager::UserManager::Get()->GetLRULoggedInUsers()[index];
59 CHECK(user);
60 return chromeos::ProfileHelper::Get()->GetProfileByUser(user);
63 content::BrowserContext*
64 SessionStateDelegateChromeos::GetBrowserContextForWindow(
65 aura::Window* window) {
66 const std::string& user_id =
67 chrome::MultiUserWindowManager::GetInstance()->GetWindowOwner(window);
68 return user_id.empty() ? NULL
69 : multi_user_util::GetProfileFromUserID(user_id);
72 content::BrowserContext*
73 SessionStateDelegateChromeos::GetUserPresentingBrowserContextForWindow(
74 aura::Window* window) {
75 const std::string& user_id =
76 chrome::MultiUserWindowManager::GetInstance()->GetUserPresentingWindow(
77 window);
78 return user_id.empty() ? NULL
79 : multi_user_util::GetProfileFromUserID(user_id);
82 int SessionStateDelegateChromeos::GetMaximumNumberOfLoggedInUsers() const {
83 // We limit list of logged in users to 10 due to memory constraints.
84 // Note that 10 seems excessive, but we want to test how many users are
85 // actually added to a session.
86 // TODO(nkostylev): Adjust this limitation based on device capabilites.
87 // http://crbug.com/230865
88 return 10;
91 int SessionStateDelegateChromeos::NumberOfLoggedInUsers() const {
92 return user_manager::UserManager::Get()->GetLoggedInUsers().size();
95 bool SessionStateDelegateChromeos::CanAddUserToMultiProfile(
96 AddUserError* error) const {
97 if (user_manager::UserManager::Get()
98 ->GetUsersAllowedForMultiProfile()
99 .size() == 0) {
100 if (error)
101 *error = ADD_USER_ERROR_OUT_OF_USERS;
102 return false;
104 return SessionStateDelegate::CanAddUserToMultiProfile(error);
107 bool SessionStateDelegateChromeos::IsActiveUserSessionStarted() const {
108 return user_manager::UserManager::Get()->IsSessionStarted();
111 bool SessionStateDelegateChromeos::CanLockScreen() const {
112 const user_manager::UserList unlock_users =
113 user_manager::UserManager::Get()->GetUnlockUsers();
114 return !unlock_users.empty();
117 bool SessionStateDelegateChromeos::IsScreenLocked() const {
118 return chromeos::ScreenLocker::default_screen_locker() &&
119 chromeos::ScreenLocker::default_screen_locker()->locked();
122 bool SessionStateDelegateChromeos::ShouldLockScreenBeforeSuspending() const {
123 const user_manager::UserList logged_in_users =
124 user_manager::UserManager::Get()->GetLoggedInUsers();
125 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
126 it != logged_in_users.end();
127 ++it) {
128 user_manager::User* user = (*it);
129 Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user);
130 if (profile &&
131 profile->GetPrefs()->GetBoolean(prefs::kEnableAutoScreenLock)) {
132 return true;
135 return false;
138 void SessionStateDelegateChromeos::LockScreen() {
139 if (!CanLockScreen())
140 return;
142 VLOG(1) << "Requesting screen lock from SessionStateDelegate";
143 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
144 RequestLockScreen();
147 void SessionStateDelegateChromeos::UnlockScreen() {
148 // This is used only for testing thus far.
149 NOTIMPLEMENTED();
152 bool SessionStateDelegateChromeos::IsUserSessionBlocked() const {
153 bool has_login_manager = base::CommandLine::ForCurrentProcess()->HasSwitch(
154 chromeos::switches::kLoginManager);
155 return (has_login_manager && !IsActiveUserSessionStarted()) ||
156 IsScreenLocked() ||
157 chromeos::UserAddingScreen::Get()->IsRunning();
160 ash::SessionStateDelegate::SessionState
161 SessionStateDelegateChromeos::GetSessionState() const {
162 return session_state_;
165 const user_manager::UserInfo* SessionStateDelegateChromeos::GetUserInfo(
166 ash::MultiProfileIndex index) const {
167 DCHECK_LT(index, NumberOfLoggedInUsers());
168 return user_manager::UserManager::Get()->GetLRULoggedInUsers()[index];
171 const user_manager::UserInfo* SessionStateDelegateChromeos::GetUserInfo(
172 content::BrowserContext* context) const {
173 DCHECK(context);
174 return chromeos::ProfileHelper::Get()->GetUserByProfile(
175 Profile::FromBrowserContext(context));
178 bool SessionStateDelegateChromeos::ShouldShowAvatar(
179 aura::Window* window) const {
180 return chrome::MultiUserWindowManager::GetInstance()->
181 ShouldShowAvatar(window);
184 void SessionStateDelegateChromeos::SwitchActiveUser(
185 const std::string& user_id) {
186 // Disallow switching to an already active user since that might crash.
187 // Also check that we got a user id and not an email address.
188 DCHECK_EQ(user_id,
189 gaia::CanonicalizeEmail(gaia::SanitizeEmail(user_id)));
190 if (user_id == user_manager::UserManager::Get()->GetActiveUser()->email())
191 return;
192 TryToSwitchUser(user_id);
195 void SessionStateDelegateChromeos::CycleActiveUser(CycleUser cycle_user) {
196 // Make sure there is a user to switch to.
197 if (NumberOfLoggedInUsers() <= 1)
198 return;
200 const user_manager::UserList& logged_in_users =
201 user_manager::UserManager::Get()->GetLoggedInUsers();
203 std::string user_id =
204 user_manager::UserManager::Get()->GetActiveUser()->email();
206 // Get an iterator positioned at the active user.
207 user_manager::UserList::const_iterator it;
208 for (it = logged_in_users.begin();
209 it != logged_in_users.end(); ++it) {
210 if ((*it)->email() == user_id)
211 break;
214 // Active user not found.
215 if (it == logged_in_users.end())
216 return;
218 // Get the user's email to select, wrapping to the start/end of the list if
219 // necessary.
220 switch (cycle_user) {
221 case CYCLE_TO_NEXT_USER:
222 if (++it == logged_in_users.end())
223 user_id = (*logged_in_users.begin())->email();
224 else
225 user_id = (*it)->email();
226 break;
227 case CYCLE_TO_PREVIOUS_USER:
228 if (it == logged_in_users.begin())
229 it = logged_in_users.end();
230 user_id = (*(--it))->email();
231 break;
234 // Switch using the transformed |user_id|.
235 TryToSwitchUser(user_id);
238 bool SessionStateDelegateChromeos::IsMultiProfileAllowedByPrimaryUserPolicy()
239 const {
240 return chromeos::MultiProfileUserController::GetPrimaryUserPolicy() ==
241 chromeos::MultiProfileUserController::ALLOWED;
244 void SessionStateDelegateChromeos::AddSessionStateObserver(
245 ash::SessionStateObserver* observer) {
246 session_state_observer_list_.AddObserver(observer);
249 void SessionStateDelegateChromeos::RemoveSessionStateObserver(
250 ash::SessionStateObserver* observer) {
251 session_state_observer_list_.RemoveObserver(observer);
254 void SessionStateDelegateChromeos::LoggedInStateChanged() {
255 SetSessionState(chromeos::LoginState::Get()->IsUserLoggedIn() ?
256 SESSION_STATE_ACTIVE : SESSION_STATE_LOGIN_PRIMARY, false);
259 void SessionStateDelegateChromeos::ActiveUserChanged(
260 const user_manager::User* active_user) {
261 FOR_EACH_OBSERVER(ash::SessionStateObserver,
262 session_state_observer_list_,
263 ActiveUserChanged(active_user->email()));
266 void SessionStateDelegateChromeos::UserAddedToSession(
267 const user_manager::User* added_user) {
268 FOR_EACH_OBSERVER(ash::SessionStateObserver,
269 session_state_observer_list_,
270 UserAddedToSession(added_user->email()));
273 void SessionStateDelegateChromeos::OnUserAddingStarted() {
274 SetSessionState(SESSION_STATE_LOGIN_SECONDARY, false);
277 void SessionStateDelegateChromeos::OnUserAddingFinished() {
278 SetSessionState(SESSION_STATE_ACTIVE, false);
281 void SessionStateDelegateChromeos::SetSessionState(SessionState new_state,
282 bool force) {
283 if (session_state_ == new_state && !force)
284 return;
286 session_state_ = new_state;
287 NotifySessionStateChanged();
290 void SessionStateDelegateChromeos::NotifySessionStateChanged() {
291 FOR_EACH_OBSERVER(ash::SessionStateObserver,
292 session_state_observer_list_,
293 SessionStateChanged(session_state_));
296 void DoSwitchUser(const std::string& user_id) {
297 user_manager::UserManager::Get()->SwitchActiveUser(user_id);
300 void SessionStateDelegateChromeos::TryToSwitchUser(
301 const std::string& user_id) {
302 ash::TrySwitchingActiveUser(base::Bind(&DoSwitchUser, user_id));