session_controller_impl_unittest.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  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
  3. // found in the LICENSE file.
  4. #include "ash/session/session_controller_impl.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "ash/login_status.h"
  10. #include "ash/public/cpp/ash_prefs.h"
  11. #include "ash/public/cpp/session/session_observer.h"
  12. #include "ash/session/test_session_controller_client.h"
  13. #include "ash/shell.h"
  14. #include "ash/system/tray/system_tray_notifier.h"
  15. #include "ash/test/ash_test_base.h"
  16. #include "ash/wm/window_state.h"
  17. #include "ash/wm/window_util.h"
  18. #include "base/bind.h"
  19. #include "base/callback.h"
  20. #include "base/run_loop.h"
  21. #include "base/test/bind.h"
  22. #include "base/threading/thread_task_runner_handle.h"
  23. #include "components/prefs/testing_pref_service.h"
  24. #include "components/user_manager/user_type.h"
  25. #include "testing/gtest/include/gtest/gtest.h"
  26. #include "ui/aura/client/aura_constants.h"
  27. #include "ui/aura/window.h"
  28. #include "ui/views/widget/widget.h"
  29. #include "ui/views/window/dialog_delegate.h"
  30. using session_manager::SessionState;
  31. namespace ash {
  32. namespace {
  33. class TestSessionObserver : public SessionObserver {
  34. public:
  35. TestSessionObserver() : active_account_id_(EmptyAccountId()) {}
  36. TestSessionObserver(const TestSessionObserver&) = delete;
  37. TestSessionObserver& operator=(const TestSessionObserver&) = delete;
  38. ~TestSessionObserver() override = default;
  39. // SessionObserver:
  40. void OnActiveUserSessionChanged(const AccountId& account_id) override {
  41. active_account_id_ = account_id;
  42. }
  43. void OnUserSessionAdded(const AccountId& account_id) override {
  44. user_session_account_ids_.push_back(account_id);
  45. }
  46. void OnFirstSessionStarted() override { first_session_started_ = true; }
  47. void OnSessionStateChanged(SessionState state) override { state_ = state; }
  48. void OnActiveUserPrefServiceChanged(PrefService* pref_service) override {
  49. DCHECK_NE(last_user_pref_service_, pref_service);
  50. last_user_pref_service_ = pref_service;
  51. ++user_prefs_changed_count_;
  52. }
  53. std::string GetUserSessionEmails() const {
  54. std::string emails;
  55. for (const auto& account_id : user_session_account_ids_) {
  56. emails += account_id.GetUserEmail() + ",";
  57. }
  58. return emails;
  59. }
  60. SessionState state() const { return state_; }
  61. const AccountId& active_account_id() const { return active_account_id_; }
  62. bool first_session_started() const { return first_session_started_; }
  63. const std::vector<AccountId>& user_session_account_ids() const {
  64. return user_session_account_ids_;
  65. }
  66. PrefService* last_user_pref_service() const {
  67. return last_user_pref_service_;
  68. }
  69. void clear_last_user_pref_service() { last_user_pref_service_ = nullptr; }
  70. int user_prefs_changed_count() const { return user_prefs_changed_count_; }
  71. private:
  72. SessionState state_ = SessionState::UNKNOWN;
  73. AccountId active_account_id_;
  74. bool first_session_started_ = false;
  75. std::vector<AccountId> user_session_account_ids_;
  76. PrefService* last_user_pref_service_ = nullptr;
  77. int user_prefs_changed_count_ = 0;
  78. };
  79. void FillDefaultSessionInfo(SessionInfo* info) {
  80. info->can_lock_screen = true;
  81. info->should_lock_screen_automatically = true;
  82. info->is_running_in_app_mode = false;
  83. info->add_user_session_policy = AddUserSessionPolicy::ALLOWED;
  84. info->state = SessionState::LOGIN_PRIMARY;
  85. }
  86. class SessionControllerImplTest : public testing::Test {
  87. public:
  88. SessionControllerImplTest() = default;
  89. SessionControllerImplTest(const SessionControllerImplTest&) = delete;
  90. SessionControllerImplTest& operator=(const SessionControllerImplTest&) =
  91. delete;
  92. ~SessionControllerImplTest() override = default;
  93. // testing::Test:
  94. void SetUp() override {
  95. controller_ = std::make_unique<SessionControllerImpl>();
  96. controller_->AddObserver(&observer_);
  97. }
  98. void TearDown() override { controller_->RemoveObserver(&observer_); }
  99. void SetSessionInfo(const SessionInfo& info) {
  100. controller_->SetSessionInfo(info);
  101. }
  102. void UpdateSession(uint32_t session_id, const std::string& email) {
  103. UserSession session;
  104. session.session_id = session_id;
  105. session.user_info.type = user_manager::USER_TYPE_REGULAR;
  106. session.user_info.account_id = AccountId::FromUserEmail(email);
  107. session.user_info.display_name = email;
  108. session.user_info.display_email = email;
  109. session.user_info.is_new_profile = false;
  110. controller_->UpdateUserSession(session);
  111. }
  112. std::string GetUserSessionEmails() const {
  113. std::string emails;
  114. for (const auto& session : controller_->GetUserSessions()) {
  115. emails += session->user_info.display_email + ",";
  116. }
  117. return emails;
  118. }
  119. SessionControllerImpl* controller() { return controller_.get(); }
  120. const TestSessionObserver* observer() const { return &observer_; }
  121. private:
  122. std::unique_ptr<SessionControllerImpl> controller_;
  123. TestSessionObserver observer_;
  124. };
  125. class SessionControllerImplWithShellTest : public AshTestBase {
  126. public:
  127. SessionControllerImplWithShellTest() = default;
  128. SessionControllerImplWithShellTest(
  129. const SessionControllerImplWithShellTest&) = delete;
  130. SessionControllerImplWithShellTest& operator=(
  131. const SessionControllerImplWithShellTest&) = delete;
  132. ~SessionControllerImplWithShellTest() override = default;
  133. // AshTestBase:
  134. void SetUp() override {
  135. AshTestBase::SetUp();
  136. controller()->AddObserver(&observer_);
  137. }
  138. void TearDown() override {
  139. controller()->RemoveObserver(&observer_);
  140. window_.reset();
  141. AshTestBase::TearDown();
  142. }
  143. void CreateFullscreenWindow() {
  144. window_ = CreateTestWindow();
  145. window_->SetProperty(aura::client::kShowStateKey,
  146. ui::SHOW_STATE_FULLSCREEN);
  147. window_state_ = WindowState::Get(window_.get());
  148. }
  149. SessionControllerImpl* controller() {
  150. return Shell::Get()->session_controller();
  151. }
  152. const TestSessionObserver* observer() const { return &observer_; }
  153. protected:
  154. WindowState* window_state_ = nullptr;
  155. private:
  156. TestSessionObserver observer_;
  157. std::unique_ptr<aura::Window> window_;
  158. };
  159. // Tests that the simple session info is reflected properly.
  160. TEST_F(SessionControllerImplTest, SimpleSessionInfo) {
  161. SessionInfo info;
  162. FillDefaultSessionInfo(&info);
  163. SetSessionInfo(info);
  164. UpdateSession(1u, "user1@test.com");
  165. EXPECT_TRUE(controller()->CanLockScreen());
  166. EXPECT_TRUE(controller()->ShouldLockScreenAutomatically());
  167. EXPECT_FALSE(controller()->IsRunningInAppMode());
  168. info.can_lock_screen = false;
  169. SetSessionInfo(info);
  170. EXPECT_FALSE(controller()->CanLockScreen());
  171. EXPECT_TRUE(controller()->ShouldLockScreenAutomatically());
  172. EXPECT_FALSE(controller()->IsRunningInAppMode());
  173. info.should_lock_screen_automatically = false;
  174. SetSessionInfo(info);
  175. EXPECT_FALSE(controller()->CanLockScreen());
  176. EXPECT_FALSE(controller()->ShouldLockScreenAutomatically());
  177. EXPECT_FALSE(controller()->IsRunningInAppMode());
  178. info.is_running_in_app_mode = true;
  179. SetSessionInfo(info);
  180. EXPECT_FALSE(controller()->CanLockScreen());
  181. EXPECT_FALSE(controller()->ShouldLockScreenAutomatically());
  182. EXPECT_TRUE(controller()->IsRunningInAppMode());
  183. }
  184. TEST_F(SessionControllerImplTest, OnFirstSessionStarted) {
  185. // Simulate chrome starting a user session.
  186. SessionInfo info;
  187. FillDefaultSessionInfo(&info);
  188. SetSessionInfo(info);
  189. UpdateSession(1u, "user1@test.com");
  190. controller()->SetUserSessionOrder({1u});
  191. // Observer is notified.
  192. EXPECT_TRUE(observer()->first_session_started());
  193. }
  194. // Tests that the CanLockScreen is only true with an active user session.
  195. TEST_F(SessionControllerImplTest, CanLockScreen) {
  196. SessionInfo info;
  197. FillDefaultSessionInfo(&info);
  198. ASSERT_TRUE(info.can_lock_screen); // Check can_lock_screen default to true.
  199. SetSessionInfo(info);
  200. // Cannot lock screen when there is no active user session.
  201. EXPECT_FALSE(controller()->IsActiveUserSessionStarted());
  202. EXPECT_FALSE(controller()->CanLockScreen());
  203. UpdateSession(1u, "user1@test.com");
  204. EXPECT_TRUE(controller()->IsActiveUserSessionStarted());
  205. EXPECT_TRUE(controller()->CanLockScreen());
  206. }
  207. // Tests that AddUserSessionPolicy is set properly.
  208. TEST_F(SessionControllerImplTest, AddUserPolicy) {
  209. const AddUserSessionPolicy kTestCases[] = {
  210. AddUserSessionPolicy::ALLOWED,
  211. AddUserSessionPolicy::ERROR_NOT_ALLOWED_PRIMARY_USER,
  212. AddUserSessionPolicy::ERROR_NO_ELIGIBLE_USERS,
  213. AddUserSessionPolicy::ERROR_MAXIMUM_USERS_REACHED,
  214. };
  215. SessionInfo info;
  216. FillDefaultSessionInfo(&info);
  217. for (const auto& policy : kTestCases) {
  218. info.add_user_session_policy = policy;
  219. SetSessionInfo(info);
  220. EXPECT_EQ(policy, controller()->GetAddUserPolicy())
  221. << "Test case policy=" << static_cast<int>(policy);
  222. }
  223. }
  224. // Tests that session state can be set and reflected properly.
  225. TEST_F(SessionControllerImplWithShellTest, SessionState) {
  226. const struct {
  227. SessionState state;
  228. bool expected_is_screen_locked;
  229. bool expected_is_user_session_blocked;
  230. } kTestCases[] = {
  231. {SessionState::OOBE, false, true},
  232. {SessionState::LOGIN_PRIMARY, false, true},
  233. {SessionState::LOGGED_IN_NOT_ACTIVE, false, false},
  234. {SessionState::ACTIVE, false, false},
  235. {SessionState::LOCKED, true, true},
  236. {SessionState::LOGIN_SECONDARY, false, true},
  237. };
  238. SessionInfo info;
  239. FillDefaultSessionInfo(&info);
  240. for (const auto& test_case : kTestCases) {
  241. info.state = test_case.state;
  242. controller()->SetSessionInfo(info);
  243. EXPECT_EQ(test_case.state, controller()->GetSessionState())
  244. << "Test case state=" << static_cast<int>(test_case.state);
  245. EXPECT_EQ(observer()->state(), controller()->GetSessionState())
  246. << "Test case state=" << static_cast<int>(test_case.state);
  247. EXPECT_EQ(test_case.expected_is_screen_locked,
  248. controller()->IsScreenLocked())
  249. << "Test case state=" << static_cast<int>(test_case.state);
  250. EXPECT_EQ(test_case.expected_is_user_session_blocked,
  251. controller()->IsUserSessionBlocked())
  252. << "Test case state=" << static_cast<int>(test_case.state);
  253. }
  254. }
  255. // Tests that LoginStatus is computed correctly for most session states.
  256. TEST_F(SessionControllerImplTest, GetLoginStatus) {
  257. const struct {
  258. SessionState state;
  259. LoginStatus expected_status;
  260. } kTestCases[] = {
  261. {SessionState::UNKNOWN, LoginStatus::NOT_LOGGED_IN},
  262. {SessionState::OOBE, LoginStatus::NOT_LOGGED_IN},
  263. {SessionState::LOGIN_PRIMARY, LoginStatus::NOT_LOGGED_IN},
  264. {SessionState::LOGGED_IN_NOT_ACTIVE, LoginStatus::NOT_LOGGED_IN},
  265. {SessionState::LOCKED, LoginStatus::LOCKED},
  266. // TODO(jamescook): Add LOGIN_SECONDARY if we added a status for it.
  267. };
  268. SessionInfo info;
  269. FillDefaultSessionInfo(&info);
  270. for (const auto& test_case : kTestCases) {
  271. info.state = test_case.state;
  272. SetSessionInfo(info);
  273. EXPECT_EQ(test_case.expected_status, controller()->login_status())
  274. << "Test case state=" << static_cast<int>(test_case.state);
  275. }
  276. }
  277. // Tests that LoginStatus is computed correctly for active sessions.
  278. TEST_F(SessionControllerImplTest, GetLoginStateForActiveSession) {
  279. // Simulate an active user session.
  280. SessionInfo info;
  281. FillDefaultSessionInfo(&info);
  282. info.state = SessionState::ACTIVE;
  283. SetSessionInfo(info);
  284. const struct {
  285. user_manager::UserType user_type;
  286. LoginStatus expected_status;
  287. } kTestCases[] = {
  288. {user_manager::USER_TYPE_REGULAR, LoginStatus::USER},
  289. {user_manager::USER_TYPE_GUEST, LoginStatus::GUEST},
  290. {user_manager::USER_TYPE_PUBLIC_ACCOUNT, LoginStatus::PUBLIC},
  291. {user_manager::USER_TYPE_KIOSK_APP, LoginStatus::KIOSK_APP},
  292. {user_manager::USER_TYPE_CHILD, LoginStatus::CHILD},
  293. {user_manager::USER_TYPE_ARC_KIOSK_APP, LoginStatus::KIOSK_APP},
  294. {user_manager::USER_TYPE_WEB_KIOSK_APP, LoginStatus::KIOSK_APP}
  295. // TODO(jamescook): Add USER_TYPE_ACTIVE_DIRECTORY if we add a status for
  296. // it.
  297. };
  298. for (const auto& test_case : kTestCases) {
  299. UserSession session;
  300. session.session_id = 1u;
  301. session.user_info.type = test_case.user_type;
  302. session.user_info.account_id = AccountId::FromUserEmail("user1@test.com");
  303. session.user_info.display_name = "User 1";
  304. session.user_info.display_email = "user1@test.com";
  305. controller()->UpdateUserSession(session);
  306. EXPECT_EQ(test_case.expected_status, controller()->login_status())
  307. << "Test case user_type=" << static_cast<int>(test_case.user_type);
  308. }
  309. }
  310. // Tests that user sessions can be set and updated.
  311. TEST_F(SessionControllerImplTest, UserSessions) {
  312. EXPECT_FALSE(controller()->IsActiveUserSessionStarted());
  313. UpdateSession(1u, "user1@test.com");
  314. EXPECT_TRUE(controller()->IsActiveUserSessionStarted());
  315. EXPECT_EQ("user1@test.com,", GetUserSessionEmails());
  316. EXPECT_EQ(GetUserSessionEmails(), observer()->GetUserSessionEmails());
  317. EXPECT_EQ("user1@test.com",
  318. controller()->GetPrimaryUserSession()->user_info.display_email);
  319. UpdateSession(2u, "user2@test.com");
  320. EXPECT_TRUE(controller()->IsActiveUserSessionStarted());
  321. EXPECT_EQ("user1@test.com,user2@test.com,", GetUserSessionEmails());
  322. EXPECT_EQ(GetUserSessionEmails(), observer()->GetUserSessionEmails());
  323. EXPECT_EQ("user1@test.com",
  324. controller()->GetPrimaryUserSession()->user_info.display_email);
  325. UpdateSession(1u, "user1_changed@test.com");
  326. EXPECT_EQ("user1_changed@test.com,user2@test.com,", GetUserSessionEmails());
  327. // TODO(xiyuan): Verify observer gets the updated user session info.
  328. }
  329. // Tests that user sessions can be ordered.
  330. TEST_F(SessionControllerImplTest, ActiveSession) {
  331. UpdateSession(1u, "user1@test.com");
  332. UpdateSession(2u, "user2@test.com");
  333. EXPECT_EQ("user1@test.com",
  334. controller()->GetPrimaryUserSession()->user_info.display_email);
  335. std::vector<uint32_t> order = {1u, 2u};
  336. controller()->SetUserSessionOrder(order);
  337. EXPECT_EQ("user1@test.com,user2@test.com,", GetUserSessionEmails());
  338. EXPECT_EQ("user1@test.com", observer()->active_account_id().GetUserEmail());
  339. EXPECT_EQ("user1@test.com",
  340. controller()->GetPrimaryUserSession()->user_info.display_email);
  341. order = {2u, 1u};
  342. controller()->SetUserSessionOrder(order);
  343. EXPECT_EQ("user2@test.com,user1@test.com,", GetUserSessionEmails());
  344. EXPECT_EQ("user2@test.com", observer()->active_account_id().GetUserEmail());
  345. EXPECT_EQ("user1@test.com",
  346. controller()->GetPrimaryUserSession()->user_info.display_email);
  347. order = {1u, 2u};
  348. controller()->SetUserSessionOrder(order);
  349. EXPECT_EQ("user1@test.com,user2@test.com,", GetUserSessionEmails());
  350. EXPECT_EQ("user1@test.com", observer()->active_account_id().GetUserEmail());
  351. EXPECT_EQ("user1@test.com",
  352. controller()->GetPrimaryUserSession()->user_info.display_email);
  353. }
  354. // Tests that user session is unblocked with a running unlock animation so that
  355. // focus rules can find a correct activatable window after screen lock is
  356. // dismissed.
  357. TEST_F(SessionControllerImplWithShellTest,
  358. UserSessionUnblockedWithRunningUnlockAnimation) {
  359. SessionInfo info;
  360. FillDefaultSessionInfo(&info);
  361. // LOCKED means blocked user session.
  362. info.state = SessionState::LOCKED;
  363. controller()->SetSessionInfo(info);
  364. EXPECT_TRUE(controller()->IsUserSessionBlocked());
  365. const struct {
  366. SessionState state;
  367. bool expect_blocked_after_unlock_animation;
  368. } kTestCases[] = {
  369. {SessionState::LOCKED, false},
  370. {SessionState::OOBE, true},
  371. {SessionState::LOGIN_PRIMARY, true},
  372. {SessionState::LOGGED_IN_NOT_ACTIVE, false},
  373. {SessionState::ACTIVE, false},
  374. {SessionState::LOGIN_SECONDARY, true},
  375. };
  376. for (const auto& test_case : kTestCases) {
  377. info.state = test_case.state;
  378. controller()->SetSessionInfo(info);
  379. // Mark a running unlock animation.
  380. base::RunLoop run_loop;
  381. controller()->RunUnlockAnimation(base::BindLambdaForTesting(
  382. [&run_loop](bool aborted) { run_loop.Quit(); }));
  383. run_loop.Run();
  384. EXPECT_EQ(test_case.expect_blocked_after_unlock_animation,
  385. controller()->IsUserSessionBlocked())
  386. << "Test case state=" << static_cast<int>(test_case.state);
  387. }
  388. }
  389. TEST_F(SessionControllerImplTest, IsUserChild) {
  390. UserSession session;
  391. session.session_id = 1u;
  392. session.user_info.type = user_manager::USER_TYPE_CHILD;
  393. controller()->UpdateUserSession(session);
  394. EXPECT_TRUE(controller()->IsUserChild());
  395. }
  396. using SessionControllerImplPrefsTest = NoSessionAshTestBase;
  397. // Verifies that SessionObserver is notified for PrefService changes.
  398. TEST_F(SessionControllerImplPrefsTest, Observer) {
  399. constexpr char kUser1[] = "user1@test.com";
  400. constexpr char kUser2[] = "user2@test.com";
  401. const AccountId kUserAccount1 = AccountId::FromUserEmail(kUser1);
  402. const AccountId kUserAccount2 = AccountId::FromUserEmail(kUser2);
  403. TestSessionObserver observer;
  404. SessionControllerImpl* controller = Shell::Get()->session_controller();
  405. controller->AddObserver(&observer);
  406. // Setup 2 users.
  407. TestSessionControllerClient* session = GetSessionControllerClient();
  408. // Disable auto-provision of PrefService for each user.
  409. constexpr bool kProvidePrefService = false;
  410. session->AddUserSession(kUser1, user_manager::USER_TYPE_REGULAR,
  411. kProvidePrefService);
  412. session->AddUserSession(kUser2, user_manager::USER_TYPE_REGULAR,
  413. kProvidePrefService);
  414. // The observer is not notified because the PrefService for kUser1 is not yet
  415. // ready.
  416. session->SwitchActiveUser(kUserAccount1);
  417. EXPECT_EQ(nullptr, observer.last_user_pref_service());
  418. auto pref_service = std::make_unique<TestingPrefServiceSimple>();
  419. RegisterUserProfilePrefs(pref_service->registry(), true /* for_test */);
  420. session->SetUserPrefService(kUserAccount1, std::move(pref_service));
  421. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1),
  422. observer.last_user_pref_service());
  423. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1),
  424. controller->GetLastActiveUserPrefService());
  425. observer.clear_last_user_pref_service();
  426. // Switching to a user for which prefs are not ready does not notify and
  427. // GetLastActiveUserPrefService() returns the old PrefService.
  428. session->SwitchActiveUser(kUserAccount2);
  429. EXPECT_EQ(nullptr, observer.last_user_pref_service());
  430. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1),
  431. controller->GetLastActiveUserPrefService());
  432. session->SwitchActiveUser(kUserAccount1);
  433. EXPECT_EQ(nullptr, observer.last_user_pref_service());
  434. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1),
  435. controller->GetLastActiveUserPrefService());
  436. // There should be no notification about a PrefService for an inactive user
  437. // becoming initialized.
  438. pref_service = std::make_unique<TestingPrefServiceSimple>();
  439. RegisterUserProfilePrefs(pref_service->registry(), true /* for_test */);
  440. session->SetUserPrefService(kUserAccount2, std::move(pref_service));
  441. EXPECT_EQ(nullptr, observer.last_user_pref_service());
  442. session->SwitchActiveUser(kUserAccount2);
  443. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount2),
  444. observer.last_user_pref_service());
  445. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount2),
  446. controller->GetLastActiveUserPrefService());
  447. controller->RemoveObserver(&observer);
  448. }
  449. // Verifies that SessionObserver is notified only once for the same user prefs.
  450. TEST_F(SessionControllerImplPrefsTest, NotifyOnce) {
  451. constexpr char kUser1[] = "user1@test.com";
  452. constexpr char kUser2[] = "user2@test.com";
  453. const AccountId kUserAccount1 = AccountId::FromUserEmail(kUser1);
  454. const AccountId kUserAccount2 = AccountId::FromUserEmail(kUser2);
  455. TestSessionObserver observer;
  456. SessionControllerImpl* controller = Shell::Get()->session_controller();
  457. controller->AddObserver(&observer);
  458. ASSERT_EQ(0, observer.user_prefs_changed_count());
  459. SimulateUserLogin(kUser1);
  460. EXPECT_EQ(1, observer.user_prefs_changed_count());
  461. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1),
  462. observer.last_user_pref_service());
  463. SimulateUserLogin(kUser2);
  464. EXPECT_EQ(2, observer.user_prefs_changed_count());
  465. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount2),
  466. observer.last_user_pref_service());
  467. GetSessionControllerClient()->SwitchActiveUser(kUserAccount1);
  468. EXPECT_EQ(3, observer.user_prefs_changed_count());
  469. EXPECT_EQ(controller->GetUserPrefServiceForUser(kUserAccount1),
  470. observer.last_user_pref_service());
  471. controller->RemoveObserver(&observer);
  472. }
  473. TEST_F(SessionControllerImplTest, GetUserType) {
  474. // Child accounts
  475. UserSession session;
  476. session.session_id = 1u;
  477. session.user_info.type = user_manager::USER_TYPE_CHILD;
  478. controller()->UpdateUserSession(session);
  479. EXPECT_EQ(user_manager::USER_TYPE_CHILD, controller()->GetUserType());
  480. // Regular accounts
  481. session = UserSession();
  482. session.session_id = 1u;
  483. session.user_info.type = user_manager::USER_TYPE_REGULAR;
  484. controller()->UpdateUserSession(session);
  485. EXPECT_EQ(user_manager::USER_TYPE_REGULAR, controller()->GetUserType());
  486. }
  487. TEST_F(SessionControllerImplTest, IsUserPrimary) {
  488. controller()->ClearUserSessionsForTest();
  489. // The first added user is a primary user
  490. UserSession session;
  491. session.session_id = 1u;
  492. session.user_info.type = user_manager::USER_TYPE_REGULAR;
  493. controller()->UpdateUserSession(session);
  494. EXPECT_TRUE(controller()->IsUserPrimary());
  495. // The users added thereafter are not primary users
  496. session = UserSession();
  497. session.session_id = 2u;
  498. session.user_info.type = user_manager::USER_TYPE_REGULAR;
  499. controller()->UpdateUserSession(session);
  500. // Simulates user switching by changing the order of session_ids.
  501. controller()->SetUserSessionOrder({2u, 1u});
  502. EXPECT_FALSE(controller()->IsUserPrimary());
  503. }
  504. TEST_F(SessionControllerImplTest, IsUserFirstLogin) {
  505. UserSession session;
  506. session.session_id = 1u;
  507. session.user_info.type = user_manager::USER_TYPE_REGULAR;
  508. controller()->UpdateUserSession(session);
  509. EXPECT_FALSE(controller()->IsUserFirstLogin());
  510. // user_info->is_new_profile being true means the user is first time login.
  511. session = UserSession();
  512. session.session_id = 1u;
  513. session.user_info.type = user_manager::USER_TYPE_REGULAR;
  514. session.user_info.is_new_profile = true;
  515. controller()->UpdateUserSession(session);
  516. EXPECT_TRUE(controller()->IsUserFirstLogin());
  517. }
  518. class CanSwitchUserTest : public AshTestBase {
  519. public:
  520. // The action type to perform / check for upon user switching.
  521. enum ActionType {
  522. NO_DIALOG, // No dialog should be shown.
  523. ACCEPT_DIALOG, // A dialog should be shown and we should accept it.
  524. DECLINE_DIALOG, // A dialog should be shown and we do not accept it.
  525. };
  526. CanSwitchUserTest() = default;
  527. CanSwitchUserTest(const CanSwitchUserTest&) = delete;
  528. CanSwitchUserTest& operator=(const CanSwitchUserTest&) = delete;
  529. ~CanSwitchUserTest() override = default;
  530. void TearDown() override {
  531. base::RunLoop().RunUntilIdle();
  532. AshTestBase::TearDown();
  533. }
  534. // Accessing the capture session functionality.
  535. // Simulates a screen capture session start.
  536. void StartCaptureSession() {
  537. Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
  538. base::BindRepeating(&CanSwitchUserTest::StopCaptureCallback,
  539. base::Unretained(this)),
  540. base::RepeatingClosure(), std::u16string());
  541. }
  542. // The callback which gets called when the screen capture gets stopped.
  543. void StopCaptureSession() {
  544. Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
  545. }
  546. // Simulates a screen capture session stop.
  547. void StopCaptureCallback() { stop_capture_callback_hit_count_++; }
  548. // Accessing the share session functionality.
  549. // Simulate a Screen share session start.
  550. void StartShareSession() {
  551. Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
  552. base::BindRepeating(&CanSwitchUserTest::StopShareCallback,
  553. base::Unretained(this)),
  554. std::u16string());
  555. }
  556. // Simulates a screen share session stop.
  557. void StopShareSession() {
  558. Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
  559. }
  560. // The callback which gets called when the screen share gets stopped.
  561. void StopShareCallback() { stop_share_callback_hit_count_++; }
  562. // Issuing a switch user call which might or might not create a dialog.
  563. // The passed |action| type parameter defines the outcome (which will be
  564. // checked) and the action the user will choose.
  565. void SwitchUser(ActionType action) {
  566. base::ThreadTaskRunnerHandle::Get()->PostTask(
  567. FROM_HERE, base::BindOnce(&CloseMessageBox, action));
  568. Shell::Get()->session_controller()->CanSwitchActiveUser(base::BindOnce(
  569. &CanSwitchUserTest::SwitchCallback, base::Unretained(this)));
  570. base::RunLoop().RunUntilIdle();
  571. }
  572. // Called when the user will get actually switched.
  573. void SwitchCallback(bool switch_user) {
  574. if (switch_user)
  575. switch_callback_hit_count_++;
  576. }
  577. // Various counter accessors.
  578. int stop_capture_callback_hit_count() const {
  579. return stop_capture_callback_hit_count_;
  580. }
  581. int stop_share_callback_hit_count() const {
  582. return stop_share_callback_hit_count_;
  583. }
  584. int switch_callback_hit_count() const { return switch_callback_hit_count_; }
  585. private:
  586. static void CloseMessageBox(ActionType action) {
  587. aura::Window* active_window = window_util::GetActiveWindow();
  588. views::DialogDelegate* dialog =
  589. active_window ? views::Widget::GetWidgetForNativeWindow(active_window)
  590. ->widget_delegate()
  591. ->AsDialogDelegate()
  592. : nullptr;
  593. switch (action) {
  594. case NO_DIALOG:
  595. EXPECT_FALSE(dialog);
  596. return;
  597. case ACCEPT_DIALOG:
  598. ASSERT_TRUE(dialog);
  599. EXPECT_TRUE(dialog->Accept());
  600. return;
  601. case DECLINE_DIALOG:
  602. ASSERT_TRUE(dialog);
  603. EXPECT_TRUE(dialog->Close());
  604. return;
  605. }
  606. }
  607. // Various counters to query for.
  608. int stop_capture_callback_hit_count_ = 0;
  609. int stop_share_callback_hit_count_ = 0;
  610. int switch_callback_hit_count_ = 0;
  611. };
  612. // Test that when there is no screen operation going on the user switch will be
  613. // performed as planned.
  614. TEST_F(CanSwitchUserTest, NoLock) {
  615. EXPECT_EQ(0, switch_callback_hit_count());
  616. SwitchUser(CanSwitchUserTest::NO_DIALOG);
  617. EXPECT_EQ(1, switch_callback_hit_count());
  618. }
  619. // Test that with a screen capture operation going on, the user will need to
  620. // confirm. Declining will neither change the running state or switch users.
  621. TEST_F(CanSwitchUserTest, CaptureActiveDeclined) {
  622. EXPECT_EQ(0, switch_callback_hit_count());
  623. StartCaptureSession();
  624. SwitchUser(CanSwitchUserTest::DECLINE_DIALOG);
  625. EXPECT_EQ(0, switch_callback_hit_count());
  626. EXPECT_EQ(0, stop_capture_callback_hit_count());
  627. EXPECT_EQ(0, stop_share_callback_hit_count());
  628. StopCaptureSession();
  629. EXPECT_EQ(0, switch_callback_hit_count());
  630. EXPECT_EQ(1, stop_capture_callback_hit_count());
  631. EXPECT_EQ(0, stop_share_callback_hit_count());
  632. }
  633. // Test that with a screen share operation going on, the user will need to
  634. // confirm. Declining will neither change the running state or switch users.
  635. TEST_F(CanSwitchUserTest, ShareActiveDeclined) {
  636. EXPECT_EQ(0, switch_callback_hit_count());
  637. StartShareSession();
  638. SwitchUser(CanSwitchUserTest::DECLINE_DIALOG);
  639. EXPECT_EQ(0, switch_callback_hit_count());
  640. EXPECT_EQ(0, stop_capture_callback_hit_count());
  641. EXPECT_EQ(0, stop_share_callback_hit_count());
  642. StopShareSession();
  643. EXPECT_EQ(0, switch_callback_hit_count());
  644. EXPECT_EQ(0, stop_capture_callback_hit_count());
  645. EXPECT_EQ(1, stop_share_callback_hit_count());
  646. }
  647. // Test that with both operations going on, the user will need to confirm.
  648. // Declining will neither change the running state or switch users.
  649. TEST_F(CanSwitchUserTest, BothActiveDeclined) {
  650. EXPECT_EQ(0, switch_callback_hit_count());
  651. StartShareSession();
  652. StartCaptureSession();
  653. SwitchUser(CanSwitchUserTest::DECLINE_DIALOG);
  654. EXPECT_EQ(0, switch_callback_hit_count());
  655. EXPECT_EQ(0, stop_capture_callback_hit_count());
  656. EXPECT_EQ(0, stop_share_callback_hit_count());
  657. StopShareSession();
  658. StopCaptureSession();
  659. EXPECT_EQ(0, switch_callback_hit_count());
  660. EXPECT_EQ(1, stop_capture_callback_hit_count());
  661. EXPECT_EQ(1, stop_share_callback_hit_count());
  662. }
  663. // Test that with a screen capture operation going on, the user will need to
  664. // confirm. Accepting will change to stopped state and switch users.
  665. TEST_F(CanSwitchUserTest, CaptureActiveAccepted) {
  666. EXPECT_EQ(0, switch_callback_hit_count());
  667. StartCaptureSession();
  668. SwitchUser(CanSwitchUserTest::ACCEPT_DIALOG);
  669. EXPECT_EQ(1, switch_callback_hit_count());
  670. EXPECT_EQ(1, stop_capture_callback_hit_count());
  671. EXPECT_EQ(0, stop_share_callback_hit_count());
  672. // Another stop should have no effect.
  673. StopCaptureSession();
  674. EXPECT_EQ(1, switch_callback_hit_count());
  675. EXPECT_EQ(1, stop_capture_callback_hit_count());
  676. EXPECT_EQ(0, stop_share_callback_hit_count());
  677. }
  678. // Test that with a screen share operation going on, the user will need to
  679. // confirm. Accepting will change to stopped state and switch users.
  680. TEST_F(CanSwitchUserTest, ShareActiveAccepted) {
  681. EXPECT_EQ(0, switch_callback_hit_count());
  682. StartShareSession();
  683. SwitchUser(CanSwitchUserTest::ACCEPT_DIALOG);
  684. EXPECT_EQ(1, switch_callback_hit_count());
  685. EXPECT_EQ(0, stop_capture_callback_hit_count());
  686. EXPECT_EQ(1, stop_share_callback_hit_count());
  687. // Another stop should have no effect.
  688. StopShareSession();
  689. EXPECT_EQ(1, switch_callback_hit_count());
  690. EXPECT_EQ(0, stop_capture_callback_hit_count());
  691. EXPECT_EQ(1, stop_share_callback_hit_count());
  692. }
  693. // Test that with both operations going on, the user will need to confirm.
  694. // Accepting will change to stopped state and switch users.
  695. TEST_F(CanSwitchUserTest, BothActiveAccepted) {
  696. EXPECT_EQ(0, switch_callback_hit_count());
  697. StartShareSession();
  698. StartCaptureSession();
  699. SwitchUser(CanSwitchUserTest::ACCEPT_DIALOG);
  700. EXPECT_EQ(1, switch_callback_hit_count());
  701. EXPECT_EQ(1, stop_capture_callback_hit_count());
  702. EXPECT_EQ(1, stop_share_callback_hit_count());
  703. // Another stop should have no effect.
  704. StopShareSession();
  705. StopCaptureSession();
  706. EXPECT_EQ(1, switch_callback_hit_count());
  707. EXPECT_EQ(1, stop_capture_callback_hit_count());
  708. EXPECT_EQ(1, stop_share_callback_hit_count());
  709. }
  710. using SessionControllerImplUnblockTest = NoSessionAshTestBase;
  711. TEST_F(SessionControllerImplUnblockTest, ActiveWindowAfterUnblocking) {
  712. EXPECT_TRUE(Shell::Get()->session_controller()->IsUserSessionBlocked());
  713. auto widget = CreateTestWidget();
  714. // |widget| should not be active as it is blocked by SessionControllerImpl.
  715. EXPECT_FALSE(widget->IsActive());
  716. SimulateUserLogin("user@test.com");
  717. EXPECT_FALSE(Shell::Get()->session_controller()->IsUserSessionBlocked());
  718. // |widget| should now be active as SessionControllerImpl no longer is
  719. // blocking windows from becoming active.
  720. EXPECT_TRUE(widget->IsActive());
  721. }
  722. TEST_F(SessionControllerImplWithShellTest, ExitFullscreenBeforeLock) {
  723. CreateFullscreenWindow();
  724. EXPECT_TRUE(window_state_->IsFullscreen());
  725. base::RunLoop run_loop;
  726. Shell::Get()->session_controller()->PrepareForLock(run_loop.QuitClosure());
  727. EXPECT_FALSE(window_state_->IsFullscreen());
  728. }
  729. } // namespace
  730. } // namespace ash