Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / ash / session_state_delegate_chromeos.cc
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.
4
5 #include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
6
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_window_manager.h"
22 #include "chrome/common/pref_names.h"
23 #include "chromeos/chromeos_switches.h"
24 #include "chromeos/dbus/dbus_thread_manager.h"
25 #include "chromeos/dbus/session_manager_client.h"
26 #include "chromeos/login/login_state.h"
27 #include "components/user_manager/user.h"
28 #include "components/user_manager/user_manager.h"
29 #include "google_apis/gaia/gaia_auth_util.h"
30
31 SessionStateDelegateChromeos::SessionStateDelegateChromeos()
32     : session_state_(SESSION_STATE_LOGIN_PRIMARY) {
33   user_manager::UserManager::Get()->AddSessionStateObserver(this);
34   chromeos::UserAddingScreen::Get()->AddObserver(this);
35
36   // LoginState is not initialized in unit_tests.
37   if (chromeos::LoginState::IsInitialized()) {
38     chromeos::LoginState::Get()->AddObserver(this);
39     SetSessionState(chromeos::LoginState::Get()->IsUserLoggedIn() ?
40         SESSION_STATE_ACTIVE : SESSION_STATE_LOGIN_PRIMARY, true);
41   }
42 }
43
44 SessionStateDelegateChromeos::~SessionStateDelegateChromeos() {
45   user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
46   chromeos::UserAddingScreen::Get()->RemoveObserver(this);
47
48   // LoginState is not initialized in unit_tests.
49   if (chromeos::LoginState::IsInitialized())
50     chromeos::LoginState::Get()->RemoveObserver(this);
51 }
52
53 content::BrowserContext* SessionStateDelegateChromeos::GetBrowserContextByIndex(
54     ash::MultiProfileIndex index) {
55   DCHECK_LT(index, NumberOfLoggedInUsers());
56   user_manager::User* user =
57       user_manager::UserManager::Get()->GetLRULoggedInUsers()[index];
58   CHECK(user);
59   return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user);
60 }
61
62 content::BrowserContext*
63 SessionStateDelegateChromeos::GetBrowserContextForWindow(
64     aura::Window* window) {
65   const std::string& user_id =
66       chrome::MultiUserWindowManager::GetInstance()->GetWindowOwner(window);
67   const user_manager::User* user =
68       user_manager::UserManager::Get()->FindUser(user_id);
69   DCHECK(user);
70   return chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user);
71 }
72
73 int SessionStateDelegateChromeos::GetMaximumNumberOfLoggedInUsers() const {
74   // We limit list of logged in users to 10 due to memory constraints.
75   // Note that 10 seems excessive, but we want to test how many users are
76   // actually added to a session.
77   // TODO(nkostylev): Adjust this limitation based on device capabilites.
78   // http://crbug.com/230865
79   return 10;
80 }
81
82 int SessionStateDelegateChromeos::NumberOfLoggedInUsers() const {
83   return user_manager::UserManager::Get()->GetLoggedInUsers().size();
84 }
85
86 bool SessionStateDelegateChromeos::CanAddUserToMultiProfile(
87     AddUserError* error) const {
88   if (user_manager::UserManager::Get()
89           ->GetUsersAllowedForMultiProfile()
90           .size() == 0) {
91     if (error)
92       *error = ADD_USER_ERROR_OUT_OF_USERS;
93     return false;
94   }
95   return SessionStateDelegate::CanAddUserToMultiProfile(error);
96 }
97
98 bool SessionStateDelegateChromeos::IsActiveUserSessionStarted() const {
99   return user_manager::UserManager::Get()->IsSessionStarted();
100 }
101
102 bool SessionStateDelegateChromeos::CanLockScreen() const {
103   const user_manager::UserList unlock_users =
104       user_manager::UserManager::Get()->GetUnlockUsers();
105   return !unlock_users.empty();
106 }
107
108 bool SessionStateDelegateChromeos::IsScreenLocked() const {
109   return chromeos::ScreenLocker::default_screen_locker() &&
110          chromeos::ScreenLocker::default_screen_locker()->locked();
111 }
112
113 bool SessionStateDelegateChromeos::ShouldLockScreenBeforeSuspending() const {
114   const user_manager::UserList logged_in_users =
115       user_manager::UserManager::Get()->GetLoggedInUsers();
116   for (user_manager::UserList::const_iterator it = logged_in_users.begin();
117        it != logged_in_users.end();
118        ++it) {
119     user_manager::User* user = (*it);
120     Profile* profile =
121         chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user);
122     if (profile->GetPrefs()->GetBoolean(prefs::kEnableAutoScreenLock))
123       return true;
124   }
125   return false;
126 }
127
128 void SessionStateDelegateChromeos::LockScreen() {
129   if (!CanLockScreen())
130     return;
131
132   VLOG(1) << "Requesting screen lock from SessionStateDelegate";
133   chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
134       RequestLockScreen();
135 }
136
137 void SessionStateDelegateChromeos::UnlockScreen() {
138   // This is used only for testing thus far.
139   NOTIMPLEMENTED();
140 }
141
142 bool SessionStateDelegateChromeos::IsUserSessionBlocked() const {
143   bool has_login_manager = CommandLine::ForCurrentProcess()->HasSwitch(
144           chromeos::switches::kLoginManager);
145   return (has_login_manager && !IsActiveUserSessionStarted()) ||
146          IsScreenLocked() ||
147          chromeos::UserAddingScreen::Get()->IsRunning();
148 }
149
150 ash::SessionStateDelegate::SessionState
151 SessionStateDelegateChromeos::GetSessionState() const {
152   return session_state_;
153 }
154
155 const user_manager::UserInfo* SessionStateDelegateChromeos::GetUserInfo(
156     ash::MultiProfileIndex index) const {
157   DCHECK_LT(index, NumberOfLoggedInUsers());
158   return user_manager::UserManager::Get()->GetLRULoggedInUsers()[index];
159 }
160
161 const user_manager::UserInfo* SessionStateDelegateChromeos::GetUserInfo(
162     content::BrowserContext* context) const {
163   DCHECK(context);
164   return chromeos::ProfileHelper::Get()->GetUserByProfile(
165       Profile::FromBrowserContext(context));
166 }
167
168 bool SessionStateDelegateChromeos::ShouldShowAvatar(
169     aura::Window* window) const {
170   return chrome::MultiUserWindowManager::GetInstance()->
171       ShouldShowAvatar(window);
172 }
173
174 void SessionStateDelegateChromeos::SwitchActiveUser(
175     const std::string& user_id) {
176   // Disallow switching to an already active user since that might crash.
177   // Also check that we got a user id and not an email address.
178   DCHECK_EQ(user_id,
179             gaia::CanonicalizeEmail(gaia::SanitizeEmail(user_id)));
180   if (user_id == user_manager::UserManager::Get()->GetActiveUser()->email())
181     return;
182   TryToSwitchUser(user_id);
183 }
184
185 void SessionStateDelegateChromeos::CycleActiveUser(CycleUser cycle_user) {
186   // Make sure there is a user to switch to.
187   if (NumberOfLoggedInUsers() <= 1)
188     return;
189
190   const user_manager::UserList& logged_in_users =
191       user_manager::UserManager::Get()->GetLoggedInUsers();
192
193   std::string user_id =
194       user_manager::UserManager::Get()->GetActiveUser()->email();
195
196   // Get an iterator positioned at the active user.
197   user_manager::UserList::const_iterator it;
198   for (it = logged_in_users.begin();
199        it != logged_in_users.end(); ++it) {
200     if ((*it)->email() == user_id)
201       break;
202   }
203
204   // Active user not found.
205   if (it == logged_in_users.end())
206     return;
207
208   // Get the user's email to select, wrapping to the start/end of the list if
209   // necessary.
210   switch (cycle_user) {
211     case CYCLE_TO_NEXT_USER:
212       if (++it == logged_in_users.end())
213         user_id = (*logged_in_users.begin())->email();
214       else
215         user_id = (*it)->email();
216       break;
217     case CYCLE_TO_PREVIOUS_USER:
218       if (it == logged_in_users.begin())
219         it = logged_in_users.end();
220       user_id = (*(--it))->email();
221       break;
222   }
223
224   // Switch using the transformed |user_id|.
225   TryToSwitchUser(user_id);
226 }
227
228 bool SessionStateDelegateChromeos::IsMultiProfileAllowedByPrimaryUserPolicy()
229     const {
230   return chromeos::MultiProfileUserController::GetPrimaryUserPolicy() ==
231          chromeos::MultiProfileUserController::ALLOWED;
232 }
233
234 void SessionStateDelegateChromeos::AddSessionStateObserver(
235     ash::SessionStateObserver* observer) {
236   session_state_observer_list_.AddObserver(observer);
237 }
238
239 void SessionStateDelegateChromeos::RemoveSessionStateObserver(
240     ash::SessionStateObserver* observer) {
241   session_state_observer_list_.RemoveObserver(observer);
242 }
243
244 void SessionStateDelegateChromeos::LoggedInStateChanged() {
245   SetSessionState(chromeos::LoginState::Get()->IsUserLoggedIn() ?
246       SESSION_STATE_ACTIVE : SESSION_STATE_LOGIN_PRIMARY, false);
247 }
248
249 void SessionStateDelegateChromeos::ActiveUserChanged(
250     const user_manager::User* active_user) {
251   FOR_EACH_OBSERVER(ash::SessionStateObserver,
252                     session_state_observer_list_,
253                     ActiveUserChanged(active_user->email()));
254 }
255
256 void SessionStateDelegateChromeos::UserAddedToSession(
257     const user_manager::User* added_user) {
258   FOR_EACH_OBSERVER(ash::SessionStateObserver,
259                     session_state_observer_list_,
260                     UserAddedToSession(added_user->email()));
261 }
262
263 void SessionStateDelegateChromeos::OnUserAddingStarted() {
264   SetSessionState(SESSION_STATE_LOGIN_SECONDARY, false);
265 }
266
267 void SessionStateDelegateChromeos::OnUserAddingFinished() {
268   SetSessionState(SESSION_STATE_ACTIVE, false);
269 }
270
271 void SessionStateDelegateChromeos::SetSessionState(SessionState new_state,
272                                                    bool force) {
273   if (session_state_ == new_state && !force)
274     return;
275
276   session_state_ = new_state;
277   NotifySessionStateChanged();
278 }
279
280 void SessionStateDelegateChromeos::NotifySessionStateChanged() {
281   FOR_EACH_OBSERVER(ash::SessionStateObserver,
282                     session_state_observer_list_,
283                     SessionStateChanged(session_state_));
284 }
285
286 void DoSwitchUser(const std::string& user_id) {
287   user_manager::UserManager::Get()->SwitchActiveUser(user_id);
288 }
289
290 void SessionStateDelegateChromeos::TryToSwitchUser(
291     const std::string& user_id) {
292   ash::TrySwitchingActiveUser(base::Bind(&DoSwitchUser, user_id));
293 }