| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/session/session_controller.h" | 5 #include "ash/session/session_controller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "ash/login_status.h" | 12 #include "ash/login_status.h" |
| 13 #include "ash/public/interfaces/session_controller.mojom.h" | 13 #include "ash/public/interfaces/session_controller.mojom.h" |
| 14 #include "ash/session/session_controller.h" | 14 #include "ash/session/session_controller.h" |
| 15 #include "ash/session/session_state_observer.h" | 15 #include "ash/session/session_state_observer.h" |
| 16 #include "base/callback.h" |
| 16 #include "base/macros.h" | 17 #include "base/macros.h" |
| 17 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 18 #include "components/user_manager/user_type.h" | 19 #include "components/user_manager/user_type.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 22 using session_manager::SessionState; |
| 23 |
| 21 namespace ash { | 24 namespace ash { |
| 22 namespace { | 25 namespace { |
| 23 | 26 |
| 24 class TestSessionStateObserver : public SessionStateObserver { | 27 class TestSessionStateObserver : public SessionStateObserver { |
| 25 public: | 28 public: |
| 26 TestSessionStateObserver() : active_account_id_(EmptyAccountId()) {} | 29 TestSessionStateObserver() : active_account_id_(EmptyAccountId()) {} |
| 27 ~TestSessionStateObserver() override {} | 30 ~TestSessionStateObserver() override {} |
| 28 | 31 |
| 29 // SessionStateObserver: | 32 // SessionStateObserver: |
| 30 void ActiveUserChanged(const AccountId& account_id) override { | 33 void ActiveUserChanged(const AccountId& account_id) override { |
| 31 active_account_id_ = account_id; | 34 active_account_id_ = account_id; |
| 32 } | 35 } |
| 33 | 36 |
| 34 void UserAddedToSession(const AccountId& account_id) override { | 37 void UserAddedToSession(const AccountId& account_id) override { |
| 35 user_session_account_ids_.push_back(account_id); | 38 user_session_account_ids_.push_back(account_id); |
| 36 } | 39 } |
| 37 | 40 |
| 38 void SessionStateChanged(session_manager::SessionState state) override { | 41 void SessionStateChanged(SessionState state) override { state_ = state; } |
| 39 state_ = state; | |
| 40 } | |
| 41 | 42 |
| 42 std::string GetUserSessionEmails() const { | 43 std::string GetUserSessionEmails() const { |
| 43 std::string emails; | 44 std::string emails; |
| 44 for (const auto& account_id : user_session_account_ids_) { | 45 for (const auto& account_id : user_session_account_ids_) { |
| 45 emails += account_id.GetUserEmail() + ","; | 46 emails += account_id.GetUserEmail() + ","; |
| 46 } | 47 } |
| 47 return emails; | 48 return emails; |
| 48 } | 49 } |
| 49 | 50 |
| 50 session_manager::SessionState state() const { return state_; } | 51 SessionState state() const { return state_; } |
| 51 const AccountId& active_account_id() const { return active_account_id_; } | 52 const AccountId& active_account_id() const { return active_account_id_; } |
| 52 const std::vector<AccountId>& user_session_account_ids() const { | 53 const std::vector<AccountId>& user_session_account_ids() const { |
| 53 return user_session_account_ids_; | 54 return user_session_account_ids_; |
| 54 } | 55 } |
| 55 | 56 |
| 56 private: | 57 private: |
| 57 session_manager::SessionState state_ = session_manager::SessionState::UNKNOWN; | 58 SessionState state_ = SessionState::UNKNOWN; |
| 58 AccountId active_account_id_; | 59 AccountId active_account_id_; |
| 59 std::vector<AccountId> user_session_account_ids_; | 60 std::vector<AccountId> user_session_account_ids_; |
| 60 | 61 |
| 61 DISALLOW_COPY_AND_ASSIGN(TestSessionStateObserver); | 62 DISALLOW_COPY_AND_ASSIGN(TestSessionStateObserver); |
| 62 }; | 63 }; |
| 63 | 64 |
| 64 void FillDefaultSessionInfo(mojom::SessionInfo* info) { | 65 void FillDefaultSessionInfo(mojom::SessionInfo* info) { |
| 65 info->can_lock_screen = true; | 66 info->can_lock_screen = true; |
| 66 info->should_lock_screen_automatically = true; | 67 info->should_lock_screen_automatically = true; |
| 67 info->add_user_session_policy = AddUserSessionPolicy::ALLOWED; | 68 info->add_user_session_policy = AddUserSessionPolicy::ALLOWED; |
| 68 info->state = session_manager::SessionState::LOGIN_PRIMARY; | 69 info->state = SessionState::LOGIN_PRIMARY; |
| 69 } | 70 } |
| 70 | 71 |
| 71 class SessionControllerTest : public testing::Test { | 72 class SessionControllerTest : public testing::Test { |
| 72 public: | 73 public: |
| 73 SessionControllerTest() {} | 74 SessionControllerTest() {} |
| 74 ~SessionControllerTest() override {} | 75 ~SessionControllerTest() override {} |
| 75 | 76 |
| 76 // testing::Test: | 77 // testing::Test: |
| 77 void SetUp() override { | 78 void SetUp() override { |
| 78 controller_ = base::MakeUnique<SessionController>(); | 79 controller_ = base::MakeUnique<SessionController>(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 info.add_user_session_policy = policy; | 173 info.add_user_session_policy = policy; |
| 173 SetSessionInfo(info); | 174 SetSessionInfo(info); |
| 174 EXPECT_EQ(policy, controller()->GetAddUserPolicy()) | 175 EXPECT_EQ(policy, controller()->GetAddUserPolicy()) |
| 175 << "Test case policy=" << static_cast<int>(policy); | 176 << "Test case policy=" << static_cast<int>(policy); |
| 176 } | 177 } |
| 177 } | 178 } |
| 178 | 179 |
| 179 // Tests that session state can be set and reflected properly. | 180 // Tests that session state can be set and reflected properly. |
| 180 TEST_F(SessionControllerTest, SessionState) { | 181 TEST_F(SessionControllerTest, SessionState) { |
| 181 const struct { | 182 const struct { |
| 182 session_manager::SessionState state; | 183 SessionState state; |
| 183 bool expected_is_screen_locked; | 184 bool expected_is_screen_locked; |
| 184 bool expected_is_user_session_blocked; | 185 bool expected_is_user_session_blocked; |
| 185 } kTestCases[] = { | 186 } kTestCases[] = { |
| 186 {session_manager::SessionState::OOBE, false, true}, | 187 {SessionState::OOBE, false, true}, |
| 187 {session_manager::SessionState::LOGIN_PRIMARY, false, true}, | 188 {SessionState::LOGIN_PRIMARY, false, true}, |
| 188 {session_manager::SessionState::LOGGED_IN_NOT_ACTIVE, false, true}, | 189 {SessionState::LOGGED_IN_NOT_ACTIVE, false, true}, |
| 189 {session_manager::SessionState::ACTIVE, false, false}, | 190 {SessionState::ACTIVE, false, false}, |
| 190 {session_manager::SessionState::LOCKED, true, true}, | 191 {SessionState::LOCKED, true, true}, |
| 191 {session_manager::SessionState::LOGIN_SECONDARY, false, true}, | 192 {SessionState::LOGIN_SECONDARY, false, true}, |
| 192 }; | 193 }; |
| 193 | 194 |
| 194 mojom::SessionInfo info; | 195 mojom::SessionInfo info; |
| 195 FillDefaultSessionInfo(&info); | 196 FillDefaultSessionInfo(&info); |
| 196 for (const auto& test_case : kTestCases) { | 197 for (const auto& test_case : kTestCases) { |
| 197 info.state = test_case.state; | 198 info.state = test_case.state; |
| 198 SetSessionInfo(info); | 199 SetSessionInfo(info); |
| 199 | 200 |
| 200 EXPECT_EQ(test_case.state, controller()->GetSessionState()) | 201 EXPECT_EQ(test_case.state, controller()->GetSessionState()) |
| 201 << "Test case state=" << static_cast<int>(test_case.state); | 202 << "Test case state=" << static_cast<int>(test_case.state); |
| 202 EXPECT_EQ(observer()->state(), controller()->GetSessionState()) | 203 EXPECT_EQ(observer()->state(), controller()->GetSessionState()) |
| 203 << "Test case state=" << static_cast<int>(test_case.state); | 204 << "Test case state=" << static_cast<int>(test_case.state); |
| 204 EXPECT_EQ(test_case.expected_is_screen_locked, | 205 EXPECT_EQ(test_case.expected_is_screen_locked, |
| 205 controller()->IsScreenLocked()) | 206 controller()->IsScreenLocked()) |
| 206 << "Test case state=" << static_cast<int>(test_case.state); | 207 << "Test case state=" << static_cast<int>(test_case.state); |
| 207 EXPECT_EQ(test_case.expected_is_user_session_blocked, | 208 EXPECT_EQ(test_case.expected_is_user_session_blocked, |
| 208 controller()->IsUserSessionBlocked()) | 209 controller()->IsUserSessionBlocked()) |
| 209 << "Test case state=" << static_cast<int>(test_case.state); | 210 << "Test case state=" << static_cast<int>(test_case.state); |
| 210 } | 211 } |
| 211 } | 212 } |
| 212 | 213 |
| 213 // Tests that LoginStatus is computed correctly for most session states. | 214 // Tests that LoginStatus is computed correctly for most session states. |
| 214 TEST_F(SessionControllerTest, GetLoginStatus) { | 215 TEST_F(SessionControllerTest, GetLoginStatus) { |
| 215 using session_manager::SessionState; | |
| 216 | |
| 217 const struct { | 216 const struct { |
| 218 SessionState state; | 217 SessionState state; |
| 219 LoginStatus expected_status; | 218 LoginStatus expected_status; |
| 220 } kTestCases[] = { | 219 } kTestCases[] = { |
| 221 {SessionState::UNKNOWN, LoginStatus::NOT_LOGGED_IN}, | 220 {SessionState::UNKNOWN, LoginStatus::NOT_LOGGED_IN}, |
| 222 {SessionState::OOBE, LoginStatus::NOT_LOGGED_IN}, | 221 {SessionState::OOBE, LoginStatus::NOT_LOGGED_IN}, |
| 223 {SessionState::LOGIN_PRIMARY, LoginStatus::NOT_LOGGED_IN}, | 222 {SessionState::LOGIN_PRIMARY, LoginStatus::NOT_LOGGED_IN}, |
| 224 {SessionState::LOGGED_IN_NOT_ACTIVE, LoginStatus::NOT_LOGGED_IN}, | 223 {SessionState::LOGGED_IN_NOT_ACTIVE, LoginStatus::NOT_LOGGED_IN}, |
| 225 {SessionState::LOCKED, LoginStatus::LOCKED}, | 224 {SessionState::LOCKED, LoginStatus::LOCKED}, |
| 226 // TODO: Add LOGIN_SECONDARY if we added a status for it. | 225 // TODO: Add LOGIN_SECONDARY if we added a status for it. |
| 227 }; | 226 }; |
| 228 | 227 |
| 229 mojom::SessionInfo info; | 228 mojom::SessionInfo info; |
| 230 FillDefaultSessionInfo(&info); | 229 FillDefaultSessionInfo(&info); |
| 231 for (const auto& test_case : kTestCases) { | 230 for (const auto& test_case : kTestCases) { |
| 232 info.state = test_case.state; | 231 info.state = test_case.state; |
| 233 SetSessionInfo(info); | 232 SetSessionInfo(info); |
| 234 EXPECT_EQ(test_case.expected_status, controller()->login_status()) | 233 EXPECT_EQ(test_case.expected_status, controller()->login_status()) |
| 235 << "Test case state=" << static_cast<int>(test_case.state); | 234 << "Test case state=" << static_cast<int>(test_case.state); |
| 236 } | 235 } |
| 237 } | 236 } |
| 238 | 237 |
| 239 // Tests that LoginStatus is computed correctly for active sessions. | 238 // Tests that LoginStatus is computed correctly for active sessions. |
| 240 TEST_F(SessionControllerTest, GetLoginStateForActiveSession) { | 239 TEST_F(SessionControllerTest, GetLoginStateForActiveSession) { |
| 241 // Simulate an active user session. | 240 // Simulate an active user session. |
| 242 mojom::SessionInfo info; | 241 mojom::SessionInfo info; |
| 243 FillDefaultSessionInfo(&info); | 242 FillDefaultSessionInfo(&info); |
| 244 info.state = session_manager::SessionState::ACTIVE; | 243 info.state = SessionState::ACTIVE; |
| 245 SetSessionInfo(info); | 244 SetSessionInfo(info); |
| 246 | 245 |
| 247 const struct { | 246 const struct { |
| 248 user_manager::UserType user_type; | 247 user_manager::UserType user_type; |
| 249 LoginStatus expected_status; | 248 LoginStatus expected_status; |
| 250 } kTestCases[] = { | 249 } kTestCases[] = { |
| 251 {user_manager::USER_TYPE_REGULAR, LoginStatus::USER}, | 250 {user_manager::USER_TYPE_REGULAR, LoginStatus::USER}, |
| 252 {user_manager::USER_TYPE_GUEST, LoginStatus::GUEST}, | 251 {user_manager::USER_TYPE_GUEST, LoginStatus::GUEST}, |
| 253 {user_manager::USER_TYPE_PUBLIC_ACCOUNT, LoginStatus::PUBLIC}, | 252 {user_manager::USER_TYPE_PUBLIC_ACCOUNT, LoginStatus::PUBLIC}, |
| 254 {user_manager::USER_TYPE_SUPERVISED, LoginStatus::SUPERVISED}, | 253 {user_manager::USER_TYPE_SUPERVISED, LoginStatus::SUPERVISED}, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 controller()->SetUserSessionOrder(order); | 304 controller()->SetUserSessionOrder(order); |
| 306 EXPECT_EQ("user2@test.com,user1@test.com,", GetUserSessionEmails()); | 305 EXPECT_EQ("user2@test.com,user1@test.com,", GetUserSessionEmails()); |
| 307 EXPECT_EQ("user2@test.com", observer()->active_account_id().GetUserEmail()); | 306 EXPECT_EQ("user2@test.com", observer()->active_account_id().GetUserEmail()); |
| 308 | 307 |
| 309 order = {1u, 2u}; | 308 order = {1u, 2u}; |
| 310 controller()->SetUserSessionOrder(order); | 309 controller()->SetUserSessionOrder(order); |
| 311 EXPECT_EQ("user1@test.com,user2@test.com,", GetUserSessionEmails()); | 310 EXPECT_EQ("user1@test.com,user2@test.com,", GetUserSessionEmails()); |
| 312 EXPECT_EQ("user1@test.com", observer()->active_account_id().GetUserEmail()); | 311 EXPECT_EQ("user1@test.com", observer()->active_account_id().GetUserEmail()); |
| 313 } | 312 } |
| 314 | 313 |
| 314 // Tests that user session is unblocked with a running unlock animation so that |
| 315 // focus rules can find a correct activatable window after screen lock is |
| 316 // dismissed. |
| 317 TEST_F(SessionControllerTest, UserSessionUnblockedWithRunningUnlockAnimation) { |
| 318 mojom::SessionInfo info; |
| 319 FillDefaultSessionInfo(&info); |
| 320 |
| 321 // LOCKED means blocked user session. |
| 322 info.state = SessionState::LOCKED; |
| 323 SetSessionInfo(info); |
| 324 EXPECT_TRUE(controller()->IsUserSessionBlocked()); |
| 325 |
| 326 // Mark a running unlock animation unblocks user session. |
| 327 controller()->RunUnlockAnimation(base::Closure()); |
| 328 EXPECT_FALSE(controller()->IsUserSessionBlocked()); |
| 329 |
| 330 const struct { |
| 331 SessionState state; |
| 332 bool expected_is_user_session_blocked; |
| 333 } kTestCases[] = { |
| 334 {SessionState::OOBE, true}, |
| 335 {SessionState::LOGIN_PRIMARY, true}, |
| 336 {SessionState::LOGGED_IN_NOT_ACTIVE, true}, |
| 337 {SessionState::ACTIVE, false}, |
| 338 {SessionState::LOGIN_SECONDARY, true}, |
| 339 }; |
| 340 for (const auto& test_case : kTestCases) { |
| 341 info.state = test_case.state; |
| 342 SetSessionInfo(info); |
| 343 |
| 344 // Mark a running unlock animation. |
| 345 controller()->RunUnlockAnimation(base::Closure()); |
| 346 |
| 347 EXPECT_EQ(test_case.expected_is_user_session_blocked, |
| 348 controller()->IsUserSessionBlocked()) |
| 349 << "Test case state=" << static_cast<int>(test_case.state); |
| 350 } |
| 351 } |
| 352 |
| 315 } // namespace | 353 } // namespace |
| 316 } // namespace ash | 354 } // namespace ash |
| OLD | NEW |