login_shelf_view_unittest.cc 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567
  1. // Copyright 2017 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/shelf/login_shelf_view.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "ash/app_list/app_list_controller_impl.h"
  8. #include "ash/constants/ash_features.h"
  9. #include "ash/constants/ash_switches.h"
  10. #include "ash/focus_cycler.h"
  11. #include "ash/lock_screen_action/lock_screen_action_background_controller.h"
  12. #include "ash/lock_screen_action/test_lock_screen_action_background_controller.h"
  13. #include "ash/login/login_screen_controller.h"
  14. #include "ash/login/mock_login_screen_client.h"
  15. #include "ash/login/ui/login_test_base.h"
  16. #include "ash/login/ui/views_utils.h"
  17. #include "ash/public/cpp/kiosk_app_menu.h"
  18. #include "ash/public/cpp/shelf_prefs.h"
  19. #include "ash/root_window_controller.h"
  20. #include "ash/session/session_controller_impl.h"
  21. #include "ash/session/test_session_controller_client.h"
  22. #include "ash/shelf/login_shelf_widget.h"
  23. #include "ash/shelf/shelf.h"
  24. #include "ash/shelf/shelf_navigation_widget.h"
  25. #include "ash/shelf/shelf_shutdown_confirmation_bubble.h"
  26. #include "ash/shelf/shelf_widget.h"
  27. #include "ash/shell.h"
  28. #include "ash/shutdown_controller_impl.h"
  29. #include "ash/system/status_area_widget.h"
  30. #include "ash/test/ash_test_base.h"
  31. #include "ash/test/ash_test_helper.h"
  32. #include "ash/tray_action/test_tray_action_client.h"
  33. #include "ash/tray_action/tray_action.h"
  34. #include "ash/wm/lock_state_controller.h"
  35. #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
  36. #include "base/bind.h"
  37. #include "base/callback_helpers.h"
  38. #include "base/command_line.h"
  39. #include "base/run_loop.h"
  40. #include "base/test/metrics/histogram_tester.h"
  41. #include "base/test/scoped_feature_list.h"
  42. #include "ui/display/manager/display_configurator.h"
  43. #include "ui/display/manager/test/action_logger.h"
  44. #include "ui/display/manager/test/test_native_display_delegate.h"
  45. #include "ui/events/event_utils.h"
  46. #include "ui/events/test/event_generator.h"
  47. #include "ui/views/controls/button/label_button.h"
  48. using session_manager::SessionState;
  49. namespace ash {
  50. namespace {
  51. void ExpectFocused(views::View* view) {
  52. EXPECT_TRUE(view->GetWidget()->IsActive());
  53. EXPECT_TRUE(login_views_utils::HasFocusInAnyChildView(view));
  54. }
  55. void ExpectNotFocused(views::View* view) {
  56. EXPECT_FALSE(view->GetWidget()->IsActive());
  57. EXPECT_FALSE(login_views_utils::HasFocusInAnyChildView(view));
  58. }
  59. // Parameter value represents if the OobeRemoveShutdownButton feature is
  60. // enabled.
  61. class LoginShelfViewTest : public LoginTestBase,
  62. public testing::WithParamInterface<bool> {
  63. public:
  64. LoginShelfViewTest() {
  65. scoped_feature_list_.InitWithFeatureState(
  66. features::kOobeRemoveShutdownButton, GetParam());
  67. }
  68. LoginShelfViewTest(const LoginShelfViewTest&) = delete;
  69. LoginShelfViewTest& operator=(const LoginShelfViewTest&) = delete;
  70. ~LoginShelfViewTest() override = default;
  71. void SetUp() override {
  72. action_background_controller_factory_ = base::BindRepeating(
  73. &LoginShelfViewTest::CreateActionBackgroundController,
  74. base::Unretained(this));
  75. LockScreenActionBackgroundController::SetFactoryCallbackForTesting(
  76. &action_background_controller_factory_);
  77. // Guest Button is visible while session hasn't started.
  78. LoginTestBase::SetUp();
  79. login_shelf_view_ = GetPrimaryShelf()->shelf_widget()->GetLoginShelfView();
  80. Shell::Get()->tray_action()->SetClient(
  81. tray_action_client_.CreateRemoteAndBind(),
  82. mojom::TrayActionState::kNotAvailable);
  83. // Set initial states.
  84. NotifySessionStateChanged(SessionState::OOBE);
  85. NotifyShutdownPolicyChanged(false);
  86. }
  87. void TearDown() override {
  88. LockScreenActionBackgroundController::SetFactoryCallbackForTesting(nullptr);
  89. action_background_controller_ = nullptr;
  90. LoginTestBase::TearDown();
  91. }
  92. protected:
  93. void NotifySessionStateChanged(SessionState state) {
  94. GetSessionControllerClient()->SetSessionState(state);
  95. GetSessionControllerClient()->FlushForTest();
  96. }
  97. void NotifyShutdownPolicyChanged(bool reboot_on_shutdown) {
  98. Shell::Get()->shutdown_controller()->SetRebootOnShutdown(
  99. reboot_on_shutdown);
  100. }
  101. void NotifyLockScreenNoteStateChanged(mojom::TrayActionState state) {
  102. Shell::Get()->tray_action()->UpdateLockScreenNoteState(state);
  103. }
  104. // Simulates a click event on the button.
  105. void Click(LoginShelfView::ButtonId id) {
  106. DCHECK(login_shelf_view_->GetViewByID(id)->GetVisible());
  107. ui::test::EventGenerator* event_generator = GetEventGenerator();
  108. event_generator->MoveMouseTo(
  109. login_shelf_view_->GetViewByID(id)->GetBoundsInScreen().CenterPoint());
  110. event_generator->ClickLeftButton();
  111. base::RunLoop().RunUntilIdle();
  112. }
  113. // Checks if the shelf is only showing the buttons in the list. The IDs in
  114. // the specified list must be unique.
  115. bool ShowsShelfButtons(const std::vector<LoginShelfView::ButtonId>& ids) {
  116. for (LoginShelfView::ButtonId id : ids) {
  117. if (!login_shelf_view_->GetViewByID(id)->GetVisible())
  118. return false;
  119. }
  120. const auto& children = login_shelf_view_->children();
  121. const size_t visible_buttons =
  122. std::count_if(children.cbegin(), login_shelf_view_->children().cend(),
  123. [](const auto* v) { return v->GetVisible(); });
  124. return visible_buttons == ids.size();
  125. }
  126. // Check if the former button is shown before the latter button
  127. bool AreButtonsInOrder(LoginShelfView::ButtonId former,
  128. LoginShelfView::ButtonId latter) {
  129. auto* former_button_view = login_shelf_view_->GetViewByID(former);
  130. auto* latter_button_view = login_shelf_view_->GetViewByID(latter);
  131. EXPECT_TRUE(former_button_view->GetVisible() &&
  132. latter_button_view->GetVisible());
  133. return login_shelf_view_->GetIndexOf(former_button_view) <
  134. login_shelf_view_->GetIndexOf(latter_button_view);
  135. }
  136. // Check whether the button is enabled.
  137. bool IsButtonEnabled(LoginShelfView::ButtonId id) const {
  138. return login_shelf_view_->GetViewByID(id)->GetEnabled();
  139. }
  140. void FocusOnLoginShelfButton() {
  141. // TODO(https://crbug.com/1343114): refactor the code below after the login
  142. // shelf widget is ready.
  143. views::Widget* login_shelf_widget = GetLoginShelfWidget();
  144. if (features::IsUseLoginShelfWidgetEnabled()) {
  145. static_cast<LoginShelfWidget*>(login_shelf_widget)
  146. ->SetDefaultLastFocusableChild(/*reverse=*/false);
  147. } else {
  148. static_cast<ShelfWidget*>(login_shelf_widget)
  149. ->set_default_last_focusable_child(
  150. /*default_last_focusable_child=*/false);
  151. }
  152. Shell::Get()->focus_cycler()->FocusWidget(login_shelf_widget);
  153. ExpectFocused(login_shelf_widget->GetContentsView());
  154. }
  155. // Returns the widget where the login shelf view lives.
  156. views::Widget* GetLoginShelfWidget() {
  157. // TODO(https://crbug.com/1343114): refactor the code below after the login
  158. // shelf widget is ready.
  159. Shelf* shelf =
  160. Shelf::ForWindow(login_shelf_view_->GetWidget()->GetNativeWindow());
  161. return features::IsUseLoginShelfWidgetEnabled()
  162. ? static_cast<views::Widget*>(shelf->login_shelf_widget())
  163. : shelf->shelf_widget();
  164. }
  165. TestTrayActionClient tray_action_client_;
  166. LoginShelfView* login_shelf_view_ = nullptr; // Unowned.
  167. TestLockScreenActionBackgroundController* action_background_controller() {
  168. return action_background_controller_;
  169. }
  170. private:
  171. std::unique_ptr<LockScreenActionBackgroundController>
  172. CreateActionBackgroundController() {
  173. auto result = std::make_unique<TestLockScreenActionBackgroundController>();
  174. EXPECT_FALSE(action_background_controller_);
  175. action_background_controller_ = result.get();
  176. return result;
  177. }
  178. LockScreenActionBackgroundController::FactoryCallback
  179. action_background_controller_factory_;
  180. // LockScreenActionBackgroundController created by
  181. // |CreateActionBackgroundController|.
  182. TestLockScreenActionBackgroundController* action_background_controller_ =
  183. nullptr;
  184. base::test::ScopedFeatureList scoped_feature_list_;
  185. };
  186. // Checks the login shelf updates UI after session state changes.
  187. TEST_P(LoginShelfViewTest, ShouldUpdateUiAfterSessionStateChange) {
  188. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  189. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  190. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  191. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  192. LoginShelfView::kBrowseAsGuest,
  193. LoginShelfView::kAddUser}));
  194. NotifySessionStateChanged(SessionState::LOGGED_IN_NOT_ACTIVE);
  195. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  196. NotifySessionStateChanged(SessionState::ACTIVE);
  197. EXPECT_TRUE(ShowsShelfButtons({}));
  198. NotifySessionStateChanged(SessionState::LOGIN_SECONDARY);
  199. EXPECT_TRUE(
  200. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kCancel}));
  201. NotifySessionStateChanged(SessionState::ACTIVE);
  202. EXPECT_TRUE(ShowsShelfButtons({}));
  203. NotifySessionStateChanged(SessionState::LOCKED);
  204. EXPECT_TRUE(
  205. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  206. }
  207. // Checks that the login shelf is not displayed in Shimless RMA.
  208. TEST_P(LoginShelfViewTest, ShouldHideUiInShimlessRma) {
  209. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  210. NotifySessionStateChanged(SessionState::RMA);
  211. EXPECT_TRUE(ShowsShelfButtons({}));
  212. }
  213. // Checks the login shelf updates UI after shutdown policy change when the
  214. // screen is locked.
  215. TEST_P(LoginShelfViewTest,
  216. ShouldUpdateUiAfterShutdownPolicyChangeAtLockScreen) {
  217. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  218. CreateUserSessions(1);
  219. NotifySessionStateChanged(SessionState::LOCKED);
  220. EXPECT_TRUE(
  221. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  222. NotifyShutdownPolicyChanged(true /*reboot_on_shutdown*/);
  223. EXPECT_TRUE(
  224. ShowsShelfButtons({LoginShelfView::kRestart, LoginShelfView::kSignOut}));
  225. EXPECT_TRUE(
  226. AreButtonsInOrder(LoginShelfView::kRestart, LoginShelfView::kSignOut));
  227. NotifyShutdownPolicyChanged(false /*reboot_on_shutdown*/);
  228. EXPECT_TRUE(
  229. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  230. EXPECT_TRUE(
  231. AreButtonsInOrder(LoginShelfView::kShutdown, LoginShelfView::kSignOut));
  232. }
  233. // Checks shutdown policy change during another session state (e.g. ACTIVE)
  234. // will be reflected when the screen becomes locked.
  235. TEST_P(LoginShelfViewTest, ShouldUpdateUiBasedOnShutdownPolicyInActiveSession) {
  236. // The initial state of |reboot_on_shutdown| is false.
  237. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  238. CreateUserSessions(1);
  239. NotifyShutdownPolicyChanged(true /*reboot_on_shutdown*/);
  240. NotifySessionStateChanged(SessionState::LOCKED);
  241. EXPECT_TRUE(
  242. ShowsShelfButtons({LoginShelfView::kRestart, LoginShelfView::kSignOut}));
  243. EXPECT_TRUE(
  244. AreButtonsInOrder(LoginShelfView::kRestart, LoginShelfView::kSignOut));
  245. }
  246. // Checks that the Apps button is hidden if a session has started
  247. TEST_P(LoginShelfViewTest, ShouldNotShowAppsButtonAfterSessionStarted) {
  248. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  249. std::vector<KioskAppMenuEntry> kiosk_apps(1);
  250. login_shelf_view_->SetKioskApps(kiosk_apps);
  251. EXPECT_TRUE(
  252. login_shelf_view_->GetViewByID(LoginShelfView::kApps)->GetVisible());
  253. CreateUserSessions(1);
  254. EXPECT_FALSE(
  255. login_shelf_view_->GetViewByID(LoginShelfView::kApps)->GetVisible());
  256. }
  257. // Checks that the shutdown or restart buttons shown before the Apps button when
  258. // kiosk mode is enabled
  259. TEST_P(LoginShelfViewTest, ShouldShowShutdownOrRestartButtonsBeforeApps) {
  260. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  261. std::vector<KioskAppMenuEntry> kiosk_apps(1);
  262. login_shelf_view_->SetKioskApps(kiosk_apps);
  263. // |reboot_on_shutdown| is initially off
  264. EXPECT_TRUE(ShowsShelfButtons(
  265. {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest,
  266. LoginShelfView::kAddUser, LoginShelfView::kApps}));
  267. EXPECT_TRUE(
  268. AreButtonsInOrder(LoginShelfView::kShutdown, LoginShelfView::kApps));
  269. NotifyShutdownPolicyChanged(true /*reboot_on_shutdown*/);
  270. EXPECT_TRUE(ShowsShelfButtons(
  271. {LoginShelfView::kRestart, LoginShelfView::kBrowseAsGuest,
  272. LoginShelfView::kAddUser, LoginShelfView::kApps}));
  273. EXPECT_TRUE(
  274. AreButtonsInOrder(LoginShelfView::kRestart, LoginShelfView::kApps));
  275. }
  276. // Checks the login shelf updates UI after lock screen note state changes.
  277. TEST_P(LoginShelfViewTest, ShouldUpdateUiAfterLockScreenNoteState) {
  278. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  279. CreateUserSessions(1);
  280. NotifySessionStateChanged(SessionState::LOCKED);
  281. EXPECT_TRUE(
  282. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  283. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kAvailable);
  284. EXPECT_TRUE(
  285. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  286. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kLaunching);
  287. // Shelf buttons should not be changed until the lock screen action background
  288. // show animation completes.
  289. ASSERT_EQ(LockScreenActionBackgroundState::kShowing,
  290. action_background_controller()->state());
  291. EXPECT_TRUE(
  292. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  293. // Complete lock screen action background animation - this should change the
  294. // visible buttons.
  295. ASSERT_TRUE(action_background_controller()->FinishShow());
  296. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kCloseNote}));
  297. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kActive);
  298. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kCloseNote}));
  299. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kAvailable);
  300. // When lock screen action background is animating to hidden state, the close
  301. // button should immediately be replaced by kShutdown and kSignout buttons.
  302. ASSERT_EQ(LockScreenActionBackgroundState::kHiding,
  303. action_background_controller()->state());
  304. EXPECT_TRUE(
  305. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  306. ASSERT_TRUE(action_background_controller()->FinishHide());
  307. EXPECT_TRUE(
  308. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  309. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kNotAvailable);
  310. EXPECT_TRUE(
  311. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  312. }
  313. TEST_P(LoginShelfViewTest, ShouldUpdateUiAfterKioskAppsLoaded) {
  314. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  315. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  316. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  317. LoginShelfView::kBrowseAsGuest,
  318. LoginShelfView::kAddUser}));
  319. std::vector<KioskAppMenuEntry> kiosk_apps(2);
  320. login_shelf_view_->SetKioskApps(kiosk_apps);
  321. EXPECT_TRUE(ShowsShelfButtons(
  322. {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest,
  323. LoginShelfView::kAddUser, LoginShelfView::kApps}));
  324. EXPECT_TRUE(
  325. AreButtonsInOrder(LoginShelfView::kShutdown, LoginShelfView::kApps));
  326. login_shelf_view_->SetKioskApps({});
  327. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  328. LoginShelfView::kBrowseAsGuest,
  329. LoginShelfView::kAddUser}));
  330. }
  331. TEST_P(LoginShelfViewTest, SetAllowLoginByGuest) {
  332. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  333. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  334. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  335. LoginShelfView::kBrowseAsGuest,
  336. LoginShelfView::kAddUser}));
  337. // SetAllowLoginAsGuest(false) always hides the guest button.
  338. login_shelf_view_->SetAllowLoginAsGuest(false /*allow_guest*/);
  339. EXPECT_TRUE(
  340. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kAddUser}));
  341. // SetAllowLoginAsGuest(true) brings the guest button back.
  342. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  343. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  344. LoginShelfView::kBrowseAsGuest,
  345. LoginShelfView::kAddUser}));
  346. // However, SetAllowLoginAsGuest(true) does not mean that the guest button is
  347. // always visible.
  348. login_shelf_view_->SetLoginDialogState(
  349. OobeDialogState::SAML_PASSWORD_CONFIRM);
  350. if (GetParam()) {
  351. EXPECT_TRUE(ShowsShelfButtons({}));
  352. } else {
  353. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  354. }
  355. }
  356. TEST_P(LoginShelfViewTest, ShouldUpdateUiAfterDialogStateChange) {
  357. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  358. // The conditions in this test should only hold while there are user pods on
  359. // the signin screen.
  360. AddUsers(1);
  361. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  362. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  363. LoginShelfView::kBrowseAsGuest,
  364. LoginShelfView::kAddUser}));
  365. // Add user button is always hidden if dialog state !=
  366. // OobeDialogState::HIDDEN.
  367. login_shelf_view_->SetLoginDialogState(OobeDialogState::GAIA_SIGNIN);
  368. // Shutdown button is only visible when it is first signin step.
  369. login_shelf_view_->SetIsFirstSigninStep(/*is_first=*/true);
  370. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  371. // Guest button is hidden if dialog state ==
  372. // OobeDialogState::WRONG_HWID_WARNING or SAML_PASSWORD_CONFIRM.
  373. login_shelf_view_->SetLoginDialogState(OobeDialogState::HIDDEN);
  374. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  375. LoginShelfView::kBrowseAsGuest,
  376. LoginShelfView::kAddUser}));
  377. login_shelf_view_->SetLoginDialogState(OobeDialogState::WRONG_HWID_WARNING);
  378. if (GetParam()) {
  379. EXPECT_TRUE(ShowsShelfButtons({}));
  380. } else {
  381. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  382. }
  383. login_shelf_view_->SetLoginDialogState(OobeDialogState::HIDDEN);
  384. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  385. LoginShelfView::kBrowseAsGuest,
  386. LoginShelfView::kAddUser}));
  387. login_shelf_view_->SetLoginDialogState(
  388. OobeDialogState::SAML_PASSWORD_CONFIRM);
  389. if (GetParam()) {
  390. EXPECT_TRUE(ShowsShelfButtons({}));
  391. } else {
  392. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  393. }
  394. // By default guest login during gaia is not allowed.
  395. login_shelf_view_->SetLoginDialogState(OobeDialogState::GAIA_SIGNIN);
  396. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  397. // Guest button is hidden if SetAllowLoginAsGuest(false).
  398. login_shelf_view_->SetAllowLoginAsGuest(false /*allow_guest*/);
  399. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  400. // By default apps button is hidden during gaia sign in
  401. login_shelf_view_->SetLoginDialogState(OobeDialogState::GAIA_SIGNIN);
  402. std::vector<KioskAppMenuEntry> kiosk_apps(1);
  403. login_shelf_view_->SetKioskApps(kiosk_apps);
  404. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  405. // Apps button is hidden during SAML_PASSWORD_CONFIRM STATE
  406. login_shelf_view_->SetLoginDialogState(
  407. OobeDialogState::SAML_PASSWORD_CONFIRM);
  408. if (GetParam()) {
  409. EXPECT_TRUE(ShowsShelfButtons({}));
  410. } else {
  411. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  412. }
  413. // Kiosk apps button is visible when dialog state == OobeDialogState::HIDDEN
  414. login_shelf_view_->SetLoginDialogState(OobeDialogState::HIDDEN);
  415. EXPECT_TRUE(
  416. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kAddUser,
  417. LoginShelfView::kApps}));
  418. EXPECT_TRUE(
  419. AreButtonsInOrder(LoginShelfView::kShutdown, LoginShelfView::kApps));
  420. // Kiosk app button is hidden when no app exists.
  421. login_shelf_view_->SetKioskApps({});
  422. EXPECT_TRUE(
  423. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kAddUser}));
  424. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  425. // Only shutdown button is visible when state ==
  426. // OobeDialogState::EXTENSION_LOGIN.
  427. login_shelf_view_->SetLoginDialogState(OobeDialogState::EXTENSION_LOGIN);
  428. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  429. // Hide shutdown button during enrollment.
  430. login_shelf_view_->SetLoginDialogState(OobeDialogState::ENROLLMENT);
  431. EXPECT_TRUE(ShowsShelfButtons({}));
  432. // Shutdown button is hidden during user onboarding, as well as during
  433. // any data migration steps.
  434. login_shelf_view_->SetLoginDialogState(OobeDialogState::ONBOARDING);
  435. EXPECT_TRUE(ShowsShelfButtons({}));
  436. login_shelf_view_->SetLoginDialogState(OobeDialogState::MIGRATION);
  437. EXPECT_TRUE(ShowsShelfButtons({}));
  438. // Only Shutdown button should be available if some device blocking
  439. // screen is shown (e.g. Device Disabled, or Update Required).
  440. login_shelf_view_->SetKioskApps(kiosk_apps);
  441. login_shelf_view_->SetLoginDialogState(OobeDialogState::BLOCKING);
  442. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  443. }
  444. TEST_P(LoginShelfViewTest, ShouldShowGuestButtonWhenNoUserPods) {
  445. login_shelf_view_->SetAllowLoginAsGuest(/*allow_guest=*/true);
  446. login_shelf_view_->SetIsFirstSigninStep(/*is_first=*/true);
  447. SetUserCount(0);
  448. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  449. // When no user pods are visible, the Gaia dialog would normally pop up. We
  450. // need to simulate that behavior in this test.
  451. login_shelf_view_->SetLoginDialogState(OobeDialogState::GAIA_SIGNIN);
  452. EXPECT_TRUE(ShowsShelfButtons(
  453. {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest}));
  454. }
  455. TEST_P(LoginShelfViewTest, ClickShutdownButton) {
  456. Click(LoginShelfView::kShutdown);
  457. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  458. }
  459. TEST_P(LoginShelfViewTest, ClickShutdownButtonOnLockScreen) {
  460. CreateUserSessions(1);
  461. NotifySessionStateChanged(SessionState::LOCKED);
  462. Click(LoginShelfView::kShutdown);
  463. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  464. }
  465. // Tests that shutdown button can be clicked on the lock screen for active
  466. // session that starts with side shelf. See https://crbug.com/1050192.
  467. TEST_P(LoginShelfViewTest,
  468. ClickShutdownButtonOnLockScreenWithVerticalInSessionShelf) {
  469. CreateUserSessions(1);
  470. SetShelfAlignmentPref(
  471. Shell::Get()->session_controller()->GetPrimaryUserPrefService(),
  472. GetPrimaryDisplay().id(), ShelfAlignment::kLeft);
  473. ClearLogin();
  474. CreateUserSessions(1);
  475. NotifySessionStateChanged(SessionState::LOCKED);
  476. Click(LoginShelfView::kShutdown);
  477. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  478. }
  479. TEST_P(LoginShelfViewTest, ClickRestartButton) {
  480. // The Restart button is not available in OOBE session state.
  481. CreateUserSessions(1);
  482. NotifySessionStateChanged(SessionState::LOCKED);
  483. NotifyShutdownPolicyChanged(true /*reboot_on_shutdown*/);
  484. EXPECT_TRUE(
  485. ShowsShelfButtons({LoginShelfView::kRestart, LoginShelfView::kSignOut}));
  486. Click(LoginShelfView::kRestart);
  487. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  488. }
  489. TEST_P(LoginShelfViewTest, ClickSignOutButton) {
  490. CreateUserSessions(1);
  491. EXPECT_EQ(session_manager::SessionState::ACTIVE,
  492. Shell::Get()->session_controller()->GetSessionState());
  493. NotifySessionStateChanged(SessionState::LOCKED);
  494. Click(LoginShelfView::kSignOut);
  495. EXPECT_EQ(session_manager::SessionState::LOGIN_PRIMARY,
  496. Shell::Get()->session_controller()->GetSessionState());
  497. }
  498. TEST_P(LoginShelfViewTest, ClickUnlockButton) {
  499. // The unlock button is visible only when session state is LOCKED and note
  500. // state is kActive or kLaunching.
  501. CreateUserSessions(1);
  502. NotifySessionStateChanged(SessionState::LOCKED);
  503. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kActive);
  504. ASSERT_TRUE(action_background_controller()->FinishShow());
  505. EXPECT_TRUE(tray_action_client_.close_note_reasons().empty());
  506. Click(LoginShelfView::kCloseNote);
  507. EXPECT_EQ(std::vector<mojom::CloseLockScreenNoteReason>(
  508. {mojom::CloseLockScreenNoteReason::kUnlockButtonPressed}),
  509. tray_action_client_.close_note_reasons());
  510. tray_action_client_.ClearRecordedRequests();
  511. NotifyLockScreenNoteStateChanged(mojom::TrayActionState::kLaunching);
  512. EXPECT_TRUE(tray_action_client_.close_note_reasons().empty());
  513. Click(LoginShelfView::kCloseNote);
  514. EXPECT_EQ(std::vector<mojom::CloseLockScreenNoteReason>(
  515. {mojom::CloseLockScreenNoteReason::kUnlockButtonPressed}),
  516. tray_action_client_.close_note_reasons());
  517. }
  518. TEST_P(LoginShelfViewTest, ClickCancelButton) {
  519. auto client = std::make_unique<MockLoginScreenClient>();
  520. EXPECT_CALL(*client, CancelAddUser());
  521. CreateUserSessions(1);
  522. NotifySessionStateChanged(SessionState::LOGIN_SECONDARY);
  523. Click(LoginShelfView::kCancel);
  524. }
  525. TEST_P(LoginShelfViewTest, ClickBrowseAsGuestButton) {
  526. auto client = std::make_unique<MockLoginScreenClient>();
  527. if (features::IsOobeConsolidatedConsentEnabled())
  528. EXPECT_CALL(*client, ShowGuestTosScreen());
  529. else
  530. EXPECT_CALL(*client, LoginAsGuest());
  531. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  532. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  533. Click(LoginShelfView::kBrowseAsGuest);
  534. }
  535. TEST_P(LoginShelfViewTest, ClickEnterpriseEnrollmentButton) {
  536. auto client = std::make_unique<MockLoginScreenClient>();
  537. EXPECT_CALL(*client,
  538. HandleAccelerator(ash::LoginAcceleratorAction::kStartEnrollment));
  539. login_shelf_view_->SetLoginDialogState(OobeDialogState::USER_CREATION);
  540. Click(LoginShelfView::kEnterpriseEnrollment);
  541. }
  542. TEST_P(LoginShelfViewTest, TabGoesFromShelfToStatusAreaAndBackToShelf) {
  543. CreateUserSessions(1);
  544. NotifySessionStateChanged(SessionState::LOCKED);
  545. EXPECT_TRUE(
  546. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  547. gfx::NativeWindow window = login_shelf_view_->GetWidget()->GetNativeWindow();
  548. views::View* status_area = RootWindowController::ForWindow(window)
  549. ->GetStatusAreaWidget()
  550. ->GetContentsView();
  551. // Give focus to the shelf. The tabbing between lock screen and shelf is
  552. // verified by |LockScreenSanityTest::TabGoesFromLockToShelfAndBackToLock|.
  553. FocusOnLoginShelfButton();
  554. ExpectNotFocused(status_area);
  555. EXPECT_TRUE(
  556. login_shelf_view_->GetViewByID(LoginShelfView::kShutdown)->HasFocus());
  557. // Focus from the first button to the second button.
  558. views::View* login_shelf_contents_view =
  559. GetLoginShelfWidget()->GetContentsView();
  560. PressAndReleaseKey(ui::KeyboardCode::VKEY_TAB);
  561. ExpectFocused(login_shelf_contents_view);
  562. ExpectNotFocused(status_area);
  563. EXPECT_TRUE(
  564. login_shelf_view_->GetViewByID(LoginShelfView::kSignOut)->HasFocus());
  565. // Focus from the second button to the status area.
  566. PressAndReleaseKey(ui::KeyboardCode::VKEY_TAB);
  567. ExpectNotFocused(login_shelf_contents_view);
  568. ExpectFocused(status_area);
  569. // A single shift+tab brings focus back to the second shelf button.
  570. PressAndReleaseKey(ui::KeyboardCode::VKEY_TAB, ui::EF_SHIFT_DOWN);
  571. ExpectFocused(login_shelf_contents_view);
  572. ExpectNotFocused(status_area);
  573. EXPECT_TRUE(
  574. login_shelf_view_->GetViewByID(LoginShelfView::kSignOut)->HasFocus());
  575. }
  576. TEST_P(LoginShelfViewTest, ShouldUpdateUiAfterAddButtonStatusChange) {
  577. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  578. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  579. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  580. LoginShelfView::kBrowseAsGuest,
  581. LoginShelfView::kAddUser}));
  582. EXPECT_TRUE(IsButtonEnabled(LoginShelfView::kAddUser));
  583. login_shelf_view_->SetAddUserButtonEnabled(false /*enable_add_user*/);
  584. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  585. LoginShelfView::kBrowseAsGuest,
  586. LoginShelfView::kAddUser}));
  587. EXPECT_FALSE(IsButtonEnabled(LoginShelfView::kAddUser));
  588. login_shelf_view_->SetAddUserButtonEnabled(true /*enable_add_user*/);
  589. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  590. LoginShelfView::kBrowseAsGuest,
  591. LoginShelfView::kAddUser}));
  592. EXPECT_TRUE(IsButtonEnabled(LoginShelfView::kAddUser));
  593. }
  594. TEST_P(LoginShelfViewTest, ShouldUpdateUiAfterShutdownButtonStatusChange) {
  595. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  596. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  597. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  598. LoginShelfView::kBrowseAsGuest,
  599. LoginShelfView::kAddUser}));
  600. EXPECT_TRUE(IsButtonEnabled(LoginShelfView::kShutdown));
  601. login_shelf_view_->SetShutdownButtonEnabled(false /*enable_shutdown_button*/);
  602. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  603. LoginShelfView::kBrowseAsGuest,
  604. LoginShelfView::kAddUser}));
  605. EXPECT_FALSE(IsButtonEnabled(LoginShelfView::kShutdown));
  606. login_shelf_view_->SetShutdownButtonEnabled(true /*enable_shutdown_button*/);
  607. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  608. LoginShelfView::kBrowseAsGuest,
  609. LoginShelfView::kAddUser}));
  610. EXPECT_TRUE(IsButtonEnabled(LoginShelfView::kShutdown));
  611. }
  612. TEST_P(LoginShelfViewTest, ShouldNotShowNavigationAndHotseat) {
  613. gfx::NativeWindow window = login_shelf_view_->GetWidget()->GetNativeWindow();
  614. ShelfWidget* shelf_widget = Shelf::ForWindow(window)->shelf_widget();
  615. EXPECT_FALSE(shelf_widget->navigation_widget()->IsVisible())
  616. << "The navigation widget should not appear in the login shelf.";
  617. EXPECT_FALSE(shelf_widget->hotseat_widget()->IsVisible())
  618. << "The hotseat widget should not appear in the login shelf.";
  619. }
  620. TEST_P(LoginShelfViewTest, ShelfWidgetStackedAtBottomInActiveSession) {
  621. gfx::NativeWindow window = login_shelf_view_->GetWidget()->GetNativeWindow();
  622. ShelfWidget* shelf_widget = Shelf::ForWindow(window)->shelf_widget();
  623. // Focus on the login shelf button (which could happen if user tabs to move
  624. // the focus).
  625. FocusOnLoginShelfButton();
  626. // Verify that shelf widget is no longer focused, and is stacked at the bottom
  627. // of shelf container when the session is activated.
  628. NotifySessionStateChanged(SessionState::ACTIVE);
  629. ExpectNotFocused(shelf_widget->GetContentsView());
  630. EXPECT_EQ(shelf_widget->GetNativeWindow(),
  631. shelf_widget->GetNativeWindow()->parent()->children()[0]);
  632. // Lock screen and focus the shelf again.
  633. NotifySessionStateChanged(SessionState::LOCKED);
  634. Shell::Get()->focus_cycler()->FocusWidget(shelf_widget);
  635. // Move focus away from the shelf, to verify the shelf widget stacking is
  636. // updated even if the widget is not active when the session state changes.
  637. PressAndReleaseKey(ui::KeyboardCode::VKEY_TAB);
  638. PressAndReleaseKey(ui::KeyboardCode::VKEY_TAB);
  639. ExpectNotFocused(shelf_widget->GetContentsView());
  640. // Verify that shelf widget is no longer focused, and is stacked at the bottom
  641. // of shelf container when the session is activated.
  642. NotifySessionStateChanged(SessionState::ACTIVE);
  643. ExpectNotFocused(shelf_widget->GetContentsView());
  644. EXPECT_EQ(shelf_widget->GetNativeWindow(),
  645. shelf_widget->GetNativeWindow()->parent()->children()[0]);
  646. }
  647. TEST_P(LoginShelfViewTest, ParentAccessButtonVisibility) {
  648. // Parent access button should only be visible on lock screen.
  649. Shell::Get()->login_screen_controller()->ShowParentAccessButton(true);
  650. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  651. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  652. LoginShelfView::kBrowseAsGuest,
  653. LoginShelfView::kAddUser}));
  654. NotifySessionStateChanged(SessionState::LOGGED_IN_NOT_ACTIVE);
  655. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  656. NotifySessionStateChanged(SessionState::ACTIVE);
  657. EXPECT_TRUE(ShowsShelfButtons({}));
  658. NotifySessionStateChanged(SessionState::LOGIN_SECONDARY);
  659. EXPECT_TRUE(
  660. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kCancel}));
  661. NotifySessionStateChanged(SessionState::ACTIVE);
  662. EXPECT_TRUE(ShowsShelfButtons({}));
  663. NotifySessionStateChanged(SessionState::LOCKED);
  664. EXPECT_TRUE(
  665. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut,
  666. LoginShelfView::kParentAccess}));
  667. }
  668. TEST_P(LoginShelfViewTest, ParentAccessButtonVisibilityChangeOnLockScreen) {
  669. CreateUserSessions(1);
  670. NotifySessionStateChanged(SessionState::LOCKED);
  671. EXPECT_TRUE(
  672. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  673. Shell::Get()->login_screen_controller()->ShowParentAccessButton(true);
  674. EXPECT_TRUE(
  675. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut,
  676. LoginShelfView::kParentAccess}));
  677. Shell::Get()->login_screen_controller()->ShowParentAccessButton(false);
  678. EXPECT_TRUE(
  679. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  680. }
  681. TEST_P(LoginShelfViewTest, EnterpriseEnrollmentButtonVisibility) {
  682. // Enterprise enrollment button should only be available when user creation
  683. // screen is shown in OOBE.
  684. login_shelf_view_->SetLoginDialogState(OobeDialogState::USER_CREATION);
  685. if (GetParam()) {
  686. NotifySessionStateChanged(SessionState::OOBE);
  687. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kEnterpriseEnrollment}));
  688. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  689. EXPECT_TRUE(ShowsShelfButtons({}));
  690. NotifySessionStateChanged(SessionState::LOGGED_IN_NOT_ACTIVE);
  691. EXPECT_TRUE(ShowsShelfButtons({}));
  692. NotifySessionStateChanged(SessionState::ACTIVE);
  693. EXPECT_TRUE(ShowsShelfButtons({}));
  694. NotifySessionStateChanged(SessionState::LOCKED);
  695. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kSignOut}));
  696. NotifySessionStateChanged(SessionState::LOGIN_SECONDARY);
  697. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kCancel}));
  698. } else {
  699. NotifySessionStateChanged(SessionState::OOBE);
  700. EXPECT_TRUE(ShowsShelfButtons(
  701. {LoginShelfView::kShutdown, LoginShelfView::kEnterpriseEnrollment}));
  702. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  703. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  704. NotifySessionStateChanged(SessionState::LOGGED_IN_NOT_ACTIVE);
  705. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  706. NotifySessionStateChanged(SessionState::ACTIVE);
  707. EXPECT_TRUE(ShowsShelfButtons({}));
  708. NotifySessionStateChanged(SessionState::LOCKED);
  709. EXPECT_TRUE(ShowsShelfButtons(
  710. {LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  711. NotifySessionStateChanged(SessionState::LOGIN_SECONDARY);
  712. EXPECT_TRUE(ShowsShelfButtons(
  713. {LoginShelfView::kShutdown, LoginShelfView::kCancel}));
  714. }
  715. }
  716. TEST_P(LoginShelfViewTest, OsInstallButtonHidden) {
  717. // OS Install Button should be hidden if the kAllowOsInstall switch is
  718. // not set.
  719. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  720. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  721. LoginShelfView::kBrowseAsGuest,
  722. LoginShelfView::kAddUser}));
  723. login_shelf_view_->SetIsFirstSigninStep(/*is_first=*/true);
  724. SetUserCount(0);
  725. // When no user pods are visible, the Gaia dialog would normally pop up. We
  726. // need to simulate that behavior in this test.
  727. login_shelf_view_->SetLoginDialogState(OobeDialogState::GAIA_SIGNIN);
  728. EXPECT_TRUE(ShowsShelfButtons(
  729. {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest}));
  730. }
  731. TEST_P(LoginShelfViewTest, TapShutdownInTabletLoginPrimary) {
  732. NotifySessionStateChanged(session_manager::SessionState::LOGIN_PRIMARY);
  733. TabletModeControllerTestApi().EnterTabletMode();
  734. Click(LoginShelfView::kShutdown);
  735. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  736. }
  737. TEST_P(LoginShelfViewTest, TapShutdownInTabletOobe) {
  738. TabletModeControllerTestApi().EnterTabletMode();
  739. Click(LoginShelfView::kShutdown);
  740. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  741. }
  742. TEST_P(LoginShelfViewTest, MouseWheelOnLoginShelf) {
  743. gfx::NativeWindow window = login_shelf_view_->GetWidget()->GetNativeWindow();
  744. ShelfWidget* const shelf_widget = Shelf::ForWindow(window)->shelf_widget();
  745. const gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
  746. gfx::Point kLocations[] = {
  747. shelf_bounds.left_center() + gfx::Vector2d(10, 0),
  748. shelf_bounds.right_center() + gfx::Vector2d(-10, 0),
  749. shelf_bounds.CenterPoint()};
  750. ui::test::EventGenerator* event_generator = GetEventGenerator();
  751. auto test_mouse_wheel_noop = [&event_generator, &shelf_widget,
  752. &shelf_bounds](const gfx::Point& location) {
  753. event_generator->MoveMouseTo(location);
  754. event_generator->MoveMouseWheel(/*delta_x=*/0, 100);
  755. EXPECT_EQ(shelf_bounds, shelf_widget->GetWindowBoundsInScreen());
  756. EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible());
  757. event_generator->MoveMouseWheel(/*delta_x=*/0, -100);
  758. EXPECT_EQ(shelf_bounds, shelf_widget->GetWindowBoundsInScreen());
  759. EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible());
  760. };
  761. for (const auto& location : kLocations) {
  762. SCOPED_TRACE(testing::Message()
  763. << "Mouse wheel in OOBE at " << location.ToString());
  764. test_mouse_wheel_noop(location);
  765. }
  766. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  767. for (const auto& location : kLocations) {
  768. SCOPED_TRACE(testing::Message()
  769. << "Mouse wheel on login at " << location.ToString());
  770. test_mouse_wheel_noop(location);
  771. }
  772. CreateUserSessions(1);
  773. NotifySessionStateChanged(SessionState::LOCKED);
  774. for (const auto& location : kLocations) {
  775. SCOPED_TRACE(testing::Message()
  776. << "Mouse wheel on lock screen at " << location.ToString());
  777. test_mouse_wheel_noop(location);
  778. }
  779. }
  780. // When display is on Shutdown button clicks should not be blocked.
  781. TEST_P(LoginShelfViewTest, DisplayOn) {
  782. display::DisplayConfigurator* configurator =
  783. ash::Shell::Get()->display_configurator();
  784. ASSERT_TRUE(configurator->IsDisplayOn());
  785. Click(LoginShelfView::kShutdown);
  786. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  787. }
  788. // When display is off Shutdown button clicks should be blocked
  789. // `kMaxDroppedCallsWhenDisplaysOff` times.
  790. TEST_P(LoginShelfViewTest, DisplayOff) {
  791. display::DisplayConfigurator* configurator =
  792. ash::Shell::Get()->display_configurator();
  793. display::test::ActionLogger action_logger;
  794. configurator->SetDelegateForTesting(
  795. std::make_unique<display::test::TestNativeDisplayDelegate>(
  796. &action_logger));
  797. base::RunLoop run_loop;
  798. configurator->SuspendDisplays(base::BindOnce(
  799. [](base::OnceClosure quit_closure, bool success) {
  800. EXPECT_TRUE(success);
  801. std::move(quit_closure).Run();
  802. },
  803. run_loop.QuitClosure()));
  804. run_loop.Run();
  805. ASSERT_FALSE(configurator->IsDisplayOn());
  806. // The first calls are blocked.
  807. constexpr int kMaxDropped =
  808. 3; // correspond to `kMaxDroppedCallsWhenDisplaysOff`
  809. for (int i = 0; i < kMaxDropped; ++i) {
  810. Click(LoginShelfView::kShutdown);
  811. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  812. }
  813. // This should go through.
  814. Click(LoginShelfView::kShutdown);
  815. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  816. }
  817. class OsInstallButtonTest : public LoginShelfViewTest {
  818. public:
  819. OsInstallButtonTest() = default;
  820. ~OsInstallButtonTest() override = default;
  821. OsInstallButtonTest(const OsInstallButtonTest&) = delete;
  822. void operator=(const OsInstallButtonTest&) = delete;
  823. void SetUp() override {
  824. LoginShelfViewTest::SetUp();
  825. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  826. switches::kAllowOsInstall);
  827. }
  828. };
  829. TEST_P(OsInstallButtonTest, ClickOsInstallButton) {
  830. auto client = std::make_unique<MockLoginScreenClient>();
  831. EXPECT_CALL(*client, ShowOsInstallScreen);
  832. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  833. Click(LoginShelfView::kOsInstall);
  834. }
  835. TEST_P(OsInstallButtonTest, OsInstallButtonVisibility) {
  836. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  837. EXPECT_TRUE(ShowsShelfButtons(
  838. {LoginShelfView::kShutdown, LoginShelfView::kBrowseAsGuest,
  839. LoginShelfView::kAddUser, LoginShelfView::kOsInstall}));
  840. NotifySessionStateChanged(SessionState::LOGGED_IN_NOT_ACTIVE);
  841. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  842. NotifySessionStateChanged(SessionState::ACTIVE);
  843. EXPECT_TRUE(ShowsShelfButtons({}));
  844. NotifySessionStateChanged(SessionState::LOCKED);
  845. EXPECT_TRUE(
  846. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  847. NotifySessionStateChanged(SessionState::LOGIN_SECONDARY);
  848. EXPECT_TRUE(
  849. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kCancel}));
  850. // OS Install button should be shown if the user_creation dialog was
  851. // shown during OOBE.
  852. SetUserCount(0);
  853. login_shelf_view_->SetIsFirstSigninStep(/*is_first=*/true);
  854. login_shelf_view_->SetLoginDialogState(OobeDialogState::USER_CREATION);
  855. NotifySessionStateChanged(SessionState::OOBE);
  856. if (GetParam()) {
  857. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kEnterpriseEnrollment,
  858. LoginShelfView::kBrowseAsGuest,
  859. LoginShelfView::kOsInstall}));
  860. } else {
  861. EXPECT_TRUE(ShowsShelfButtons(
  862. {LoginShelfView::kShutdown, LoginShelfView::kEnterpriseEnrollment,
  863. LoginShelfView::kBrowseAsGuest, LoginShelfView::kOsInstall}));
  864. }
  865. // When no user pods are visible, the Gaia dialog would normally pop up. We
  866. // need to simulate that behavior in this test.
  867. login_shelf_view_->SetLoginDialogState(OobeDialogState::GAIA_SIGNIN);
  868. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  869. LoginShelfView::kBrowseAsGuest,
  870. LoginShelfView::kOsInstall}));
  871. // OS Install button should be hidden if the user_creation dialog was
  872. // opened from the primary login screen.
  873. SetUserCount(1);
  874. login_shelf_view_->SetIsFirstSigninStep(/*is_first=*/false);
  875. login_shelf_view_->SetLoginDialogState(OobeDialogState::USER_CREATION);
  876. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  877. if (GetParam()) {
  878. EXPECT_TRUE(ShowsShelfButtons({}));
  879. } else {
  880. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown}));
  881. }
  882. }
  883. namespace {
  884. const char kShelfShutdownConfirmationActionHistogramName[] =
  885. "Ash.Shelf.ShutdownConfirmationBubble.Action";
  886. const char kCancelActionDurationHistogramName[] =
  887. "Ash.Shelf.ShutdownConfirmationBubble.ActionDuration.Cancel";
  888. const char kConfirmActionDurationHistogramName[] =
  889. "Ash.Shelf.ShutdownConfirmationBubble.ActionDuration.Confirm";
  890. const char kDismissActionDurationHistogramName[] =
  891. "Ash.Shelf.ShutdownConfirmationBubble.ActionDuration.Dismiss";
  892. } // namespace
  893. class LoginShelfViewWithShutdownConfirmationTest : public LoginShelfViewTest {
  894. public:
  895. LoginShelfViewWithShutdownConfirmationTest() = default;
  896. LoginShelfViewWithShutdownConfirmationTest(
  897. const LoginShelfViewWithShutdownConfirmationTest&) = delete;
  898. LoginShelfViewWithShutdownConfirmationTest& operator=(
  899. const LoginShelfViewWithShutdownConfirmationTest&) = delete;
  900. ~LoginShelfViewWithShutdownConfirmationTest() override = default;
  901. void SetUp() override {
  902. LoginShelfViewTest::SetUp();
  903. feature_list_.InitAndEnableFeature(features::kShutdownConfirmationBubble);
  904. }
  905. base::HistogramTester& histograms() { return histograms_; }
  906. protected:
  907. // Check whether the shutdown confirmation is visible.
  908. bool IsShutdownConfirmationVisible() {
  909. return login_shelf_view_->GetShutdownConfirmationBubbleForTesting() &&
  910. login_shelf_view_->GetShutdownConfirmationBubbleForTesting()
  911. ->GetWidget()
  912. ->IsVisible();
  913. }
  914. // Cancel shutdown confirmation bubble.
  915. void CancelShutdown() {
  916. ui::test::EventGenerator* event_generator = GetEventGenerator();
  917. event_generator->MoveMouseTo(
  918. login_shelf_view_->GetShutdownConfirmationBubbleForTesting()
  919. ->GetViewByID(static_cast<int>(
  920. ShelfShutdownConfirmationBubble::ButtonId::kCancel))
  921. ->GetBoundsInScreen()
  922. .CenterPoint());
  923. event_generator->ClickLeftButton();
  924. base::RunLoop().RunUntilIdle();
  925. }
  926. // Confirm shutdown confirmation bubble.
  927. void ConfirmShutdown() {
  928. ui::test::EventGenerator* event_generator = GetEventGenerator();
  929. event_generator->MoveMouseTo(
  930. login_shelf_view_->GetShutdownConfirmationBubbleForTesting()
  931. ->GetViewByID(static_cast<int>(
  932. ShelfShutdownConfirmationBubble::ButtonId::kShutdown))
  933. ->GetBoundsInScreen()
  934. .CenterPoint());
  935. event_generator->ClickLeftButton();
  936. base::RunLoop().RunUntilIdle();
  937. }
  938. // Dismiss shutdown confirmation bubble.
  939. void DismissShutdown() {
  940. // Focus on the login shelf button (which could happen if user tabs to move
  941. // the focus).
  942. FocusOnLoginShelfButton();
  943. base::RunLoop().RunUntilIdle();
  944. }
  945. private:
  946. // Histogram value verifier.
  947. base::HistogramTester histograms_;
  948. base::test::ScopedFeatureList feature_list_;
  949. };
  950. // Checks that shutdown confirmation bubble appears after pressing the
  951. // shutdown button on the lockscreen
  952. TEST_P(LoginShelfViewWithShutdownConfirmationTest,
  953. ShouldShowAfterShutdownButtonLockSession) {
  954. CreateUserSessions(1);
  955. NotifySessionStateChanged(SessionState::LOCKED);
  956. EXPECT_TRUE(
  957. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  958. EXPECT_FALSE(IsShutdownConfirmationVisible());
  959. Click(LoginShelfView::kShutdown);
  960. EXPECT_TRUE(IsShutdownConfirmationVisible());
  961. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  962. histograms().ExpectUniqueSample(kShelfShutdownConfirmationActionHistogramName,
  963. ShelfShutdownConfirmationBubble::kOpened, 1);
  964. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  965. 1);
  966. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 0);
  967. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  968. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  969. }
  970. // Checks that shutdown confirmation bubble appears after pressing the
  971. // shutdown button on the lockscreen
  972. TEST_P(LoginShelfViewWithShutdownConfirmationTest,
  973. ShouldShowAfterShutdownButtonOobeSession) {
  974. login_shelf_view_->SetLoginDialogState(OobeDialogState::USER_CREATION);
  975. NotifySessionStateChanged(SessionState::OOBE);
  976. if (GetParam()) {
  977. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kEnterpriseEnrollment}));
  978. return;
  979. }
  980. EXPECT_TRUE(ShowsShelfButtons(
  981. {LoginShelfView::kShutdown, LoginShelfView::kEnterpriseEnrollment}));
  982. EXPECT_FALSE(IsShutdownConfirmationVisible());
  983. Click(LoginShelfView::kShutdown);
  984. EXPECT_TRUE(IsShutdownConfirmationVisible());
  985. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  986. histograms().ExpectUniqueSample(kShelfShutdownConfirmationActionHistogramName,
  987. ShelfShutdownConfirmationBubble::kOpened, 1);
  988. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  989. 1);
  990. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 0);
  991. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  992. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  993. }
  994. // Checks that shutdown confirmation bubble appears after pressing the
  995. // shutdown button on the lockscreen
  996. TEST_P(LoginShelfViewWithShutdownConfirmationTest,
  997. ShouldShowAfterShutdownButtonLoginPrimarySession) {
  998. login_shelf_view_->SetAllowLoginAsGuest(true /*allow_guest*/);
  999. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  1000. EXPECT_TRUE(ShowsShelfButtons({LoginShelfView::kShutdown,
  1001. LoginShelfView::kBrowseAsGuest,
  1002. LoginShelfView::kAddUser}));
  1003. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1004. Click(LoginShelfView::kShutdown);
  1005. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1006. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1007. histograms().ExpectUniqueSample(kShelfShutdownConfirmationActionHistogramName,
  1008. ShelfShutdownConfirmationBubble::kOpened, 1);
  1009. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1010. 1);
  1011. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 0);
  1012. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1013. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  1014. }
  1015. // Checks that shutdown confirmation bubble disappears after pressing the
  1016. // cancel button on the shutdown confirmation bubble and could be shown again.
  1017. TEST_P(LoginShelfViewWithShutdownConfirmationTest,
  1018. ShouldCloseAfterCancelButton) {
  1019. CreateUserSessions(1);
  1020. NotifySessionStateChanged(SessionState::LOCKED);
  1021. EXPECT_TRUE(
  1022. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  1023. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1024. Click(LoginShelfView::kShutdown);
  1025. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1026. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1027. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1028. ShelfShutdownConfirmationBubble::kOpened, 1);
  1029. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1030. 1);
  1031. // Shutdown confirmation is cancelled and disappeared.
  1032. CancelShutdown();
  1033. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1034. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1035. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1036. ShelfShutdownConfirmationBubble::kCancelled,
  1037. 1);
  1038. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1039. 2);
  1040. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 1);
  1041. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1042. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  1043. // Shutdown confirmation could be shown again.
  1044. Click(LoginShelfView::kShutdown);
  1045. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1046. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1047. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1048. ShelfShutdownConfirmationBubble::kOpened, 2);
  1049. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1050. 3);
  1051. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 1);
  1052. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1053. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  1054. }
  1055. // Checks that shutdown confirmation bubble disappears after pressing the
  1056. // confirmation button on the shutdown confirmation bubble and the device shuts
  1057. // down.
  1058. TEST_P(LoginShelfViewWithShutdownConfirmationTest,
  1059. ShouldCloseAndShutdownAfterConfirmButton) {
  1060. CreateUserSessions(1);
  1061. NotifySessionStateChanged(SessionState::LOCKED);
  1062. EXPECT_TRUE(
  1063. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  1064. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1065. Click(LoginShelfView::kShutdown);
  1066. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1067. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1068. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1069. ShelfShutdownConfirmationBubble::kOpened, 1);
  1070. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1071. 1);
  1072. // Shutdown confirmation is confirmed and disappeared.
  1073. ConfirmShutdown();
  1074. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1075. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1076. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1077. ShelfShutdownConfirmationBubble::kConfirmed,
  1078. 1);
  1079. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1080. 2);
  1081. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 0);
  1082. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1083. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 1);
  1084. }
  1085. // Checks that shutdown confirmation bubble disappears after inactive.
  1086. TEST_P(LoginShelfViewWithShutdownConfirmationTest, ShouldCloseAfterInactive) {
  1087. CreateUserSessions(1);
  1088. NotifySessionStateChanged(SessionState::LOCKED);
  1089. EXPECT_TRUE(
  1090. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  1091. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1092. Click(LoginShelfView::kShutdown);
  1093. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1094. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1095. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1096. ShelfShutdownConfirmationBubble::kOpened, 1);
  1097. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1098. 1);
  1099. DismissShutdown();
  1100. // Shutdown confirmation is inactive and disappeared.
  1101. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1102. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1103. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1104. ShelfShutdownConfirmationBubble::kDismissed,
  1105. 1);
  1106. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1107. 2);
  1108. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 0);
  1109. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 1);
  1110. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  1111. }
  1112. // Checks that shutdown confirmation was first cancelled, then confirmed
  1113. TEST_P(LoginShelfViewWithShutdownConfirmationTest,
  1114. ShouldCloseAndShutdownAfterCancelAndConfirmButton) {
  1115. CreateUserSessions(1);
  1116. NotifySessionStateChanged(SessionState::LOCKED);
  1117. EXPECT_TRUE(
  1118. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  1119. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1120. Click(LoginShelfView::kShutdown);
  1121. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1122. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1123. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1124. ShelfShutdownConfirmationBubble::kOpened, 1);
  1125. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1126. 1);
  1127. // Shutdown confirmation is cancelled and disappeared.
  1128. CancelShutdown();
  1129. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1130. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1131. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1132. ShelfShutdownConfirmationBubble::kCancelled,
  1133. 1);
  1134. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1135. 2);
  1136. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 1);
  1137. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1138. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  1139. // Shutdown confirmation could be shown again.
  1140. Click(LoginShelfView::kShutdown);
  1141. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1142. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1143. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1144. ShelfShutdownConfirmationBubble::kOpened, 2);
  1145. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1146. 3);
  1147. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 1);
  1148. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1149. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 0);
  1150. // Shutdown confirmation is confirmed and disappeared.
  1151. ConfirmShutdown();
  1152. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1153. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1154. histograms().ExpectBucketCount(kShelfShutdownConfirmationActionHistogramName,
  1155. ShelfShutdownConfirmationBubble::kConfirmed,
  1156. 1);
  1157. histograms().ExpectTotalCount(kShelfShutdownConfirmationActionHistogramName,
  1158. 4);
  1159. histograms().ExpectTotalCount(kCancelActionDurationHistogramName, 1);
  1160. histograms().ExpectTotalCount(kDismissActionDurationHistogramName, 0);
  1161. histograms().ExpectTotalCount(kConfirmActionDurationHistogramName, 1);
  1162. }
  1163. // When display is on Shutdown button clicks should not be blocked.
  1164. TEST_P(LoginShelfViewWithShutdownConfirmationTest, DisplayOn) {
  1165. display::DisplayConfigurator* configurator =
  1166. ash::Shell::Get()->display_configurator();
  1167. ASSERT_TRUE(configurator->IsDisplayOn());
  1168. Click(LoginShelfView::kShutdown);
  1169. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1170. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1171. }
  1172. // When display is off Shutdown button clicks should be blocked
  1173. // `kMaxDroppedCallsWhenDisplaysOff` times.
  1174. TEST_P(LoginShelfViewWithShutdownConfirmationTest, DisplayOff) {
  1175. display::DisplayConfigurator* configurator =
  1176. ash::Shell::Get()->display_configurator();
  1177. display::test::ActionLogger action_logger;
  1178. configurator->SetDelegateForTesting(
  1179. std::make_unique<display::test::TestNativeDisplayDelegate>(
  1180. &action_logger));
  1181. base::RunLoop run_loop;
  1182. configurator->SuspendDisplays(base::BindOnce(
  1183. [](base::OnceClosure quit_closure, bool success) {
  1184. EXPECT_TRUE(success);
  1185. std::move(quit_closure).Run();
  1186. },
  1187. run_loop.QuitClosure()));
  1188. run_loop.Run();
  1189. ASSERT_FALSE(configurator->IsDisplayOn());
  1190. // The first calls are blocked.
  1191. constexpr int kMaxDropped =
  1192. 3; // correspond to `kMaxDroppedCallsWhenDisplaysOff`
  1193. for (int i = 0; i < kMaxDropped; ++i) {
  1194. Click(LoginShelfView::kShutdown);
  1195. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1196. EXPECT_FALSE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1197. }
  1198. // This should go through.
  1199. Click(LoginShelfView::kShutdown);
  1200. EXPECT_TRUE(IsShutdownConfirmationVisible());
  1201. ConfirmShutdown();
  1202. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1203. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1204. }
  1205. TEST_P(LoginShelfViewWithShutdownConfirmationTest, ClickRestartButton) {
  1206. CreateUserSessions(1);
  1207. NotifySessionStateChanged(SessionState::LOCKED);
  1208. EXPECT_TRUE(
  1209. ShowsShelfButtons({LoginShelfView::kShutdown, LoginShelfView::kSignOut}));
  1210. NotifyShutdownPolicyChanged(true /*reboot_on_shutdown*/);
  1211. EXPECT_TRUE(
  1212. ShowsShelfButtons({LoginShelfView::kRestart, LoginShelfView::kSignOut}));
  1213. Click(LoginShelfView::kRestart);
  1214. EXPECT_FALSE(IsShutdownConfirmationVisible());
  1215. EXPECT_TRUE(Shell::Get()->lock_state_controller()->ShutdownRequested());
  1216. }
  1217. class LoginShelfViewWithKioskLicenseTest : public LoginShelfViewTest {
  1218. public:
  1219. LoginShelfViewWithKioskLicenseTest() {
  1220. scoped_feature_list_.InitAndEnableFeature(
  1221. ash::features::kEnableKioskLoginScreen);
  1222. }
  1223. LoginShelfViewWithKioskLicenseTest(
  1224. const LoginShelfViewWithKioskLicenseTest&) = delete;
  1225. LoginShelfViewWithKioskLicenseTest& operator=(
  1226. const LoginShelfViewWithKioskLicenseTest&) = delete;
  1227. ~LoginShelfViewWithKioskLicenseTest() override = default;
  1228. protected:
  1229. // Check whether the kiosk instruction bubble is visible.
  1230. bool IsKioskInstructionBubbleVisible() {
  1231. return login_shelf_view_->GetKioskInstructionBubbleForTesting() &&
  1232. login_shelf_view_->GetKioskInstructionBubbleForTesting()
  1233. ->GetWidget()
  1234. ->IsVisible();
  1235. }
  1236. void SetKioskLicenseModeForTesting(bool is_kiosk_license_mode) {
  1237. login_shelf_view_->SetKioskLicenseModeForTesting(is_kiosk_license_mode);
  1238. }
  1239. private:
  1240. base::test::ScopedFeatureList scoped_feature_list_;
  1241. };
  1242. // Checks that kiosk app button and kiosk instruction appears if device is with
  1243. // kiosk license.
  1244. TEST_P(LoginShelfViewWithKioskLicenseTest, ShouldShowKioskInstructionBubble) {
  1245. SetKioskLicenseModeForTesting(true);
  1246. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  1247. std::vector<KioskAppMenuEntry> kiosk_apps(1);
  1248. login_shelf_view_->SetKioskApps(kiosk_apps);
  1249. EXPECT_TRUE(
  1250. login_shelf_view_->GetViewByID(LoginShelfView::kApps)->GetVisible());
  1251. EXPECT_TRUE(IsKioskInstructionBubbleVisible());
  1252. }
  1253. // Checks that kiosk app button appears and kiosk instruction hidden if device
  1254. // is not with kiosk license.
  1255. TEST_P(LoginShelfViewWithKioskLicenseTest, ShouldHideKioskInstructionBubble) {
  1256. SetKioskLicenseModeForTesting(false);
  1257. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  1258. std::vector<KioskAppMenuEntry> kiosk_apps(1);
  1259. login_shelf_view_->SetKioskApps(kiosk_apps);
  1260. EXPECT_TRUE(
  1261. login_shelf_view_->GetViewByID(LoginShelfView::kApps)->GetVisible());
  1262. EXPECT_FALSE(IsKioskInstructionBubbleVisible());
  1263. }
  1264. // Checks that kiosk app button appears and kiosk instruction hidden if device
  1265. // is with kiosk license and no kiosk app is set up.
  1266. TEST_P(LoginShelfViewWithKioskLicenseTest,
  1267. ShouldNotShowKioskInstructionBubble) {
  1268. SetKioskLicenseModeForTesting(true);
  1269. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  1270. std::vector<KioskAppMenuEntry> kiosk_apps(0);
  1271. login_shelf_view_->SetKioskApps(kiosk_apps);
  1272. EXPECT_FALSE(
  1273. login_shelf_view_->GetViewByID(LoginShelfView::kApps)->GetVisible());
  1274. EXPECT_FALSE(IsKioskInstructionBubbleVisible());
  1275. }
  1276. // Checks that the button of guest mode is shown if allow_guest_ is set to
  1277. // true for devices with Kiosk SKU.
  1278. TEST_P(LoginShelfViewWithKioskLicenseTest, ShowGuestModeButton) {
  1279. SetKioskLicenseModeForTesting(true);
  1280. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  1281. login_shelf_view_->SetAllowLoginAsGuest(true);
  1282. EXPECT_TRUE(login_shelf_view_->GetViewByID(LoginShelfView::kBrowseAsGuest)
  1283. ->GetVisible());
  1284. }
  1285. // Checks that the button of guest mode is hidden if allow_guest_ is set to
  1286. // false for devices with Kiosk SKU.
  1287. TEST_P(LoginShelfViewWithKioskLicenseTest, HideGuestModeButton) {
  1288. SetKioskLicenseModeForTesting(true);
  1289. NotifySessionStateChanged(SessionState::LOGIN_PRIMARY);
  1290. login_shelf_view_->SetAllowLoginAsGuest(false);
  1291. EXPECT_FALSE(login_shelf_view_->GetViewByID(LoginShelfView::kBrowseAsGuest)
  1292. ->GetVisible());
  1293. }
  1294. INSTANTIATE_TEST_SUITE_P(All, LoginShelfViewTest, testing::Bool());
  1295. INSTANTIATE_TEST_SUITE_P(All, OsInstallButtonTest, testing::Bool());
  1296. INSTANTIATE_TEST_SUITE_P(All,
  1297. LoginShelfViewWithShutdownConfirmationTest,
  1298. testing::Bool());
  1299. INSTANTIATE_TEST_SUITE_P(All,
  1300. LoginShelfViewWithKioskLicenseTest,
  1301. testing::Bool());
  1302. } // namespace
  1303. } // namespace ash