power_button_controller_unittest.cc 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  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/system/power/power_button_controller.h"
  5. #include "ash/accessibility/test_accessibility_controller_client.h"
  6. #include "ash/constants/ash_switches.h"
  7. #include "ash/display/screen_orientation_controller.h"
  8. #include "ash/display/screen_orientation_controller_test_api.h"
  9. #include "ash/media/media_controller_impl.h"
  10. #include "ash/session/session_controller_impl.h"
  11. #include "ash/shell.h"
  12. #include "ash/system/power/power_button_controller_test_api.h"
  13. #include "ash/system/power/power_button_menu_item_view.h"
  14. #include "ash/system/power/power_button_menu_view.h"
  15. #include "ash/system/power/power_button_test_base.h"
  16. #include "ash/test_media_client.h"
  17. #include "ash/touch/touch_devices_controller.h"
  18. #include "ash/wm/lock_state_controller_test_api.h"
  19. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  20. #include "ash/wm/test_session_state_animator.h"
  21. #include "ash/wm/window_util.h"
  22. #include "base/command_line.h"
  23. #include "base/json/json_writer.h"
  24. #include "base/run_loop.h"
  25. #include "base/test/simple_test_tick_clock.h"
  26. #include "chromeos/dbus/power/fake_power_manager_client.h"
  27. #include "chromeos/dbus/power_manager/suspend.pb.h"
  28. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  29. #include "ui/display/test/display_manager_test_api.h"
  30. #include "ui/events/event.h"
  31. #include "ui/events/test/event_generator.h"
  32. #include "ui/views/widget/widget.h"
  33. using PowerManagerClient = chromeos::PowerManagerClient;
  34. namespace ash {
  35. namespace {
  36. // A non-zero brightness used for test.
  37. constexpr double kNonZeroBrightness = 10.;
  38. // Width of the display.
  39. constexpr int kDisplayWidth = 2000;
  40. // Height of the display.
  41. constexpr int kDisplayHeight = 1200;
  42. // Power button position offset percentage.
  43. constexpr double kPowerButtonPercentage = 0.9f;
  44. // Shorthand for some long constants.
  45. constexpr power_manager::BacklightBrightnessChange_Cause kUserCause =
  46. power_manager::BacklightBrightnessChange_Cause_USER_REQUEST;
  47. constexpr power_manager::BacklightBrightnessChange_Cause kOtherCause =
  48. power_manager::BacklightBrightnessChange_Cause_OTHER;
  49. } // namespace
  50. using PowerButtonPosition = PowerButtonController::PowerButtonPosition;
  51. class PowerButtonControllerTest : public PowerButtonTestBase {
  52. public:
  53. PowerButtonControllerTest() = default;
  54. PowerButtonControllerTest(const PowerButtonControllerTest&) = delete;
  55. PowerButtonControllerTest& operator=(const PowerButtonControllerTest&) =
  56. delete;
  57. ~PowerButtonControllerTest() override = default;
  58. void SetUp() override {
  59. PowerButtonTestBase::SetUp();
  60. InitPowerButtonControllerMembers(PowerManagerClient::TabletMode::ON);
  61. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  62. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  63. // Advance a duration longer than |kIgnorePowerButtonAfterResumeDelay| to
  64. // avoid events being ignored.
  65. tick_clock_.Advance(
  66. PowerButtonController::kIgnorePowerButtonAfterResumeDelay +
  67. base::Milliseconds(2));
  68. // Run the event loop so that PowerButtonDisplayController can receive the
  69. // initial backlights-forced-off state.
  70. base::RunLoop().RunUntilIdle();
  71. }
  72. protected:
  73. void SendBrightnessChange(
  74. double percent,
  75. power_manager::BacklightBrightnessChange_Cause cause) {
  76. power_manager::BacklightBrightnessChange change;
  77. change.set_percent(percent);
  78. change.set_cause(cause);
  79. power_manager_client()->SendScreenBrightnessChanged(change);
  80. }
  81. bool GetLockedState() {
  82. // LockScreen is an async mojo call.
  83. GetSessionControllerClient()->FlushForTest();
  84. return Shell::Get()->session_controller()->IsScreenLocked();
  85. }
  86. bool GetGlobalTouchscreenEnabled() const {
  87. return Shell::Get()->touch_devices_controller()->GetTouchscreenEnabled(
  88. TouchDeviceEnabledSource::GLOBAL);
  89. }
  90. // Tapping power button when screen is off will turn the screen on but not
  91. // showing the menu.
  92. void TappingPowerButtonWhenScreenIsIdleOff() {
  93. SendBrightnessChange(0, kUserCause);
  94. PressPowerButton();
  95. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  96. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  97. ReleasePowerButton();
  98. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  99. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  100. }
  101. // Press the power button to show the menu.
  102. void OpenPowerButtonMenu() {
  103. PressPowerButton();
  104. if (Shell::Get()->tablet_mode_controller()->InTabletMode()) {
  105. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  106. ASSERT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
  107. }
  108. ReleasePowerButton();
  109. ASSERT_TRUE(power_button_test_api_->IsMenuOpened());
  110. }
  111. // Tap outside of the menu view to dismiss the menu.
  112. void TapToDismissPowerButtonMenu() {
  113. gfx::Rect menu_bounds = power_button_test_api_->GetMenuBoundsInScreen();
  114. gfx::Point point = menu_bounds.bottom_right();
  115. point.Offset(5, 5);
  116. GetEventGenerator()->GestureTapAt(point);
  117. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  118. }
  119. void PressLockButton() {
  120. power_button_controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
  121. }
  122. void ReleaseLockButton() {
  123. power_button_controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
  124. }
  125. };
  126. TEST_F(PowerButtonControllerTest, LockScreenIfRequired) {
  127. Initialize(ButtonType::NORMAL, LoginStatus::USER);
  128. EnableTabletMode(true);
  129. SetShouldLockScreenAutomatically(true);
  130. ASSERT_FALSE(GetLockedState());
  131. // On User logged in status, power-button-press-release should lock screen if
  132. // automatic screen-locking was requested.
  133. PressPowerButton();
  134. ReleasePowerButton();
  135. EXPECT_TRUE(GetLockedState());
  136. // On locked state, power-button-press-release should do nothing.
  137. PressPowerButton();
  138. ReleasePowerButton();
  139. EXPECT_TRUE(GetLockedState());
  140. // Unlock the sceen.
  141. UnlockScreen();
  142. ASSERT_FALSE(GetLockedState());
  143. // power-button-press-release should not lock the screen if automatic
  144. // screen-locking wasn't requested.
  145. SetShouldLockScreenAutomatically(false);
  146. PressPowerButton();
  147. ReleasePowerButton();
  148. EXPECT_FALSE(GetLockedState());
  149. }
  150. // Tests tapping the power button of a clamshell device.
  151. TEST_F(PowerButtonControllerTest, TappingPowerButtonOfClamshell) {
  152. // Should not turn the screen off when screen is on.
  153. InitPowerButtonControllerMembers(PowerManagerClient::TabletMode::UNSUPPORTED);
  154. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  155. PressPowerButton();
  156. power_button_test_api_->SetShowMenuAnimationDone(false);
  157. // Start the showing power menu animation immediately as pressing the
  158. // clamshell power button.
  159. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  160. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  161. ReleasePowerButton();
  162. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  163. // Start the dimissing power menu animation immediately as releasing the
  164. // clamsehll power button if showing animation hasn't finished.
  165. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  166. AdvanceClockToAvoidIgnoring();
  167. // Should turn screen on if screen is off.
  168. TappingPowerButtonWhenScreenIsIdleOff();
  169. ASSERT_TRUE(power_button_test_api_->IsMenuOpened());
  170. AdvanceClockToAvoidIgnoring();
  171. // Should not start the dismissing menu animation if showing menu animation
  172. // has finished.
  173. PressPowerButton();
  174. // Start the showing power menu animation immediately as pressing the
  175. // clamshell power button.
  176. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  177. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  178. power_button_test_api_->SetShowMenuAnimationDone(true);
  179. ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
  180. ReleasePowerButton();
  181. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  182. // Power button menu should keep opened if showing animation has finished.
  183. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  184. // Tapping power button when menu is already shown should keep the screen on
  185. // and dismiss the power menu.
  186. AdvanceClockToAvoidIgnoring();
  187. PressPowerButton();
  188. ReleasePowerButton();
  189. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  190. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  191. }
  192. // Tests tapping the power button of a device that has a tablet mode switch.
  193. TEST_F(PowerButtonControllerTest, TappingPowerButtonOfTablet) {
  194. EnableTabletMode(true);
  195. // Should turn screen off if screen is on and power button menu will not be
  196. // shown.
  197. PressPowerButton();
  198. // Showing power menu animation hasn't started as power menu timer is running.
  199. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  200. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  201. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  202. ReleasePowerButton();
  203. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  204. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  205. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  206. // Should turn screen on if screen is off.
  207. AdvanceClockToAvoidIgnoring();
  208. TappingPowerButtonWhenScreenIsIdleOff();
  209. // Showing power menu animation should start until power menu timer is
  210. // timeout.
  211. AdvanceClockToAvoidIgnoring();
  212. PressPowerButton();
  213. power_button_test_api_->SetShowMenuAnimationDone(false);
  214. EXPECT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
  215. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  216. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  217. ReleasePowerButton();
  218. // Showing animation will continue until show the power button menu even
  219. // release the power button.
  220. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  221. // Tapping power button when menu is already shown should still turn screen
  222. // off and dismiss the menu.
  223. AdvanceClockToAvoidIgnoring();
  224. PressPowerButton();
  225. EXPECT_TRUE(power_button_test_api_->PreShutdownTimerIsRunning());
  226. ReleasePowerButton();
  227. EXPECT_FALSE(power_button_test_api_->PreShutdownTimerIsRunning());
  228. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  229. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  230. // Should turn screen on if screen is off.
  231. AdvanceClockToAvoidIgnoring();
  232. TappingPowerButtonWhenScreenIsIdleOff();
  233. }
  234. // Tests that power button taps turn the screen off while in tablet mode but not
  235. // in laptop mode.
  236. TEST_F(PowerButtonControllerTest, ModeSpecificPowerButton) {
  237. // While the device is in tablet mode, tapping the power button should turn
  238. // the display off (and then back on if pressed a second time).
  239. EnableTabletMode(true);
  240. PressPowerButton();
  241. ReleasePowerButton();
  242. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  243. PressPowerButton();
  244. ReleasePowerButton();
  245. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  246. // In laptop mode, tapping the power button shouldn't turn the screen off.
  247. // Instead, we should start showing the power menu animation.
  248. EnableTabletMode(false);
  249. AdvanceClockToAvoidIgnoring();
  250. PressPowerButton();
  251. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  252. ReleasePowerButton();
  253. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  254. // Tapping power button again in laptop mode when menu is opened should
  255. // dismiss the menu but keep the screen on.
  256. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  257. AdvanceClockToAvoidIgnoring();
  258. PressPowerButton();
  259. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  260. EXPECT_TRUE(power_button_test_api_->PreShutdownTimerIsRunning());
  261. ReleasePowerButton();
  262. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  263. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  264. }
  265. // Tests that when the kForceTabletPowerButton flag is passed (indicating that
  266. // the device is tablet-like) tapping the power button turns the screen off
  267. // regardless of what the tablet mode switch reports.
  268. TEST_F(PowerButtonControllerTest, ForceTabletPowerButton) {
  269. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  270. switches::kForceTabletPowerButton);
  271. ResetPowerButtonController();
  272. PressPowerButton();
  273. ReleasePowerButton();
  274. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  275. PressPowerButton();
  276. ReleasePowerButton();
  277. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  278. EnableTabletMode(false);
  279. AdvanceClockToAvoidIgnoring();
  280. PressPowerButton();
  281. ReleasePowerButton();
  282. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  283. PressPowerButton();
  284. ReleasePowerButton();
  285. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  286. }
  287. // Tests that release power button after menu is opened but before trigger
  288. // shutdown will not turn screen off.
  289. TEST_F(PowerButtonControllerTest, ReleasePowerButtonBeforeTriggerShutdown) {
  290. EnableTabletMode(true);
  291. PressPowerButton();
  292. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  293. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  294. ASSERT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
  295. ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
  296. EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
  297. ReleasePowerButton();
  298. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  299. EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
  300. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  301. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  302. }
  303. // Tests that tapping the power button dismisses the menu while in laptop mode.
  304. TEST_F(PowerButtonControllerTest, HoldPowerButtonWhileMenuShownInLaptopMode) {
  305. // Hold the power button long enough to show the menu and start the
  306. // cancellable shutdown animation. The menu should remain open.
  307. PressPowerButton();
  308. ASSERT_TRUE(power_button_test_api_->IsMenuOpened());
  309. power_button_test_api_->SetShowMenuAnimationDone(true);
  310. ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
  311. ASSERT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
  312. ReleasePowerButton();
  313. EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
  314. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  315. // Hold the power button long enough to start the cancellable shutdown
  316. // animation again. The menu should remain open.
  317. AdvanceClockToAvoidIgnoring();
  318. PressPowerButton();
  319. ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
  320. ASSERT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
  321. ReleasePowerButton();
  322. EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
  323. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  324. // This time, just tap the power button (i.e. release it before the
  325. // cancellable shutdown animation starts). The menu should be dismissed.
  326. AdvanceClockToAvoidIgnoring();
  327. PressPowerButton();
  328. ReleasePowerButton();
  329. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  330. }
  331. // Tests press lock button and power button in sequence.
  332. TEST_F(PowerButtonControllerTest, PressAfterAnotherReleased) {
  333. // Tap power button after press lock button should still turn screen off.
  334. Initialize(ButtonType::NORMAL, LoginStatus::USER);
  335. EnableTabletMode(true);
  336. PressLockButton();
  337. ReleaseLockButton();
  338. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  339. PressPowerButton();
  340. ReleasePowerButton();
  341. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  342. // Press lock button after tap power button should still lock screen.
  343. PressPowerButton();
  344. ReleasePowerButton();
  345. PressLockButton();
  346. ReleaseLockButton();
  347. EXPECT_TRUE(lock_state_test_api_->is_animating_lock());
  348. EXPECT_TRUE(GetLockedState());
  349. }
  350. // Tests press lock/power button before release power/lock button.
  351. TEST_F(PowerButtonControllerTest, PressBeforeAnotherReleased) {
  352. // Press lock button when power button is still being pressed will be ignored
  353. // and continue to turn screen off.
  354. Initialize(ButtonType::NORMAL, LoginStatus::USER);
  355. EnableTabletMode(true);
  356. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  357. PressPowerButton();
  358. PressLockButton();
  359. ReleaseLockButton();
  360. ReleasePowerButton();
  361. EXPECT_FALSE(lock_state_test_api_->is_animating_lock());
  362. EXPECT_FALSE(GetLockedState());
  363. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  364. // Turn the screen on.
  365. PressPowerButton();
  366. ReleasePowerButton();
  367. // Press power button when lock button is still being pressed. The pressing of
  368. // power button will be ignored and continue to lock screen.
  369. PressLockButton();
  370. PressPowerButton();
  371. ReleasePowerButton();
  372. ReleaseLockButton();
  373. EXPECT_TRUE(lock_state_test_api_->is_animating_lock());
  374. EXPECT_TRUE(GetLockedState());
  375. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  376. }
  377. // Tests tapping power button when device is suspended without backlights forced
  378. // off.
  379. TEST_F(PowerButtonControllerTest,
  380. TappingPowerButtonWhenSuspendedWithoutBacklightsForcedOff) {
  381. EnableTabletMode(true);
  382. power_manager_client()->SendSuspendImminent(
  383. power_manager::SuspendImminent_Reason_OTHER);
  384. SendBrightnessChange(0, kUserCause);
  385. // There is a power button pressed here, but PowerButtonEvent is sent later.
  386. power_manager_client()->SendSuspendDone();
  387. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  388. // Send the power button event after a short delay and check that backlights
  389. // are not forced off.
  390. tick_clock_.Advance(base::Milliseconds(500));
  391. PressPowerButton();
  392. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  393. ReleasePowerButton();
  394. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  395. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  396. // Send the power button event after a longer delay and check that backlights
  397. // are forced off.
  398. tick_clock_.Advance(base::Milliseconds(1600));
  399. PressPowerButton();
  400. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  401. ReleasePowerButton();
  402. SendBrightnessChange(0, kUserCause);
  403. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  404. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  405. }
  406. // Tests tapping power button when device is suspended with backlights forced
  407. // off.
  408. TEST_F(PowerButtonControllerTest,
  409. TappingPowerButtonWhenSuspendedWithBacklightsForcedOff) {
  410. EnableTabletMode(true);
  411. PressPowerButton();
  412. ReleasePowerButton();
  413. SendBrightnessChange(0, kUserCause);
  414. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  415. power_manager_client()->SendSuspendImminent(
  416. power_manager::SuspendImminent_Reason_OTHER);
  417. // There is a power button pressed here, but PowerButtonEvent is sent later.
  418. // Because of backlights forced off, resuming system will not restore
  419. // brightness.
  420. power_manager_client()->SendSuspendDone();
  421. // Send the power button event after a short delay and check that backlights
  422. // are not forced off.
  423. tick_clock_.Advance(base::Milliseconds(500));
  424. PressPowerButton();
  425. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  426. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  427. ReleasePowerButton();
  428. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  429. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  430. // Send the power button event after a longer delay and check that backlights
  431. // are forced off.
  432. tick_clock_.Advance(base::Milliseconds(1600));
  433. PressPowerButton();
  434. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  435. ReleasePowerButton();
  436. SendBrightnessChange(0, kUserCause);
  437. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  438. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  439. }
  440. // For convertible device working on tablet mode, keyboard/mouse event should
  441. // not SetBacklightsForcedOff(false) when screen is off.
  442. TEST_F(PowerButtonControllerTest, ConvertibleOnTabletMode) {
  443. EnableTabletMode(true);
  444. PressPowerButton();
  445. ReleasePowerButton();
  446. SendBrightnessChange(0, kUserCause);
  447. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  448. PressKey(ui::VKEY_L);
  449. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  450. GenerateMouseMoveEvent();
  451. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  452. }
  453. // Tests that a single set of power button pressed-and-released operation should
  454. // cause only one SetBacklightsForcedOff call.
  455. TEST_F(PowerButtonControllerTest, IgnorePowerOnKeyEvent) {
  456. ui::KeyEvent power_key_pressed(ui::ET_KEY_PRESSED, ui::VKEY_POWER,
  457. ui::EF_NONE);
  458. ui::KeyEvent power_key_released(ui::ET_KEY_RELEASED, ui::VKEY_POWER,
  459. ui::EF_NONE);
  460. // There are two |power_key_pressed| events and |power_key_released| events
  461. // generated for each pressing and releasing, and multiple repeating pressed
  462. // events depending on holding.
  463. ASSERT_EQ(0, power_manager_client()->num_set_backlights_forced_off_calls());
  464. EnableTabletMode(true);
  465. power_button_test_api_->SendKeyEvent(&power_key_pressed);
  466. power_button_test_api_->SendKeyEvent(&power_key_pressed);
  467. PressPowerButton();
  468. power_button_test_api_->SendKeyEvent(&power_key_pressed);
  469. power_button_test_api_->SendKeyEvent(&power_key_pressed);
  470. power_button_test_api_->SendKeyEvent(&power_key_pressed);
  471. ReleasePowerButton();
  472. power_button_test_api_->SendKeyEvent(&power_key_released);
  473. power_button_test_api_->SendKeyEvent(&power_key_released);
  474. EXPECT_EQ(1, power_manager_client()->num_set_backlights_forced_off_calls());
  475. }
  476. // Tests that when the power button is pressed/released in tablet mode,
  477. // requesting/stopping backlights forced off should update the global
  478. // touchscreen enabled status.
  479. TEST_F(PowerButtonControllerTest, DisableTouchscreenWhileForcedOff) {
  480. // Tests tablet power button.
  481. EnableTabletMode(true);
  482. ASSERT_TRUE(GetGlobalTouchscreenEnabled());
  483. PressPowerButton();
  484. ReleasePowerButton();
  485. SendBrightnessChange(0, kUserCause);
  486. EXPECT_FALSE(GetGlobalTouchscreenEnabled());
  487. PressPowerButton();
  488. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  489. ReleasePowerButton();
  490. EXPECT_TRUE(GetGlobalTouchscreenEnabled());
  491. }
  492. // When the screen is turned off automatically, the touchscreen should also be
  493. // disabled.
  494. TEST_F(PowerButtonControllerTest, DisableTouchscreenForInactivity) {
  495. ASSERT_TRUE(GetGlobalTouchscreenEnabled());
  496. // Turn screen off for automated change (e.g. user is inactive).
  497. SendBrightnessChange(0, kOtherCause);
  498. EXPECT_FALSE(GetGlobalTouchscreenEnabled());
  499. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  500. EXPECT_TRUE(GetGlobalTouchscreenEnabled());
  501. // After decreasing the brightness to zero for a user request, the touchscreen
  502. // should remain enabled.
  503. SendBrightnessChange(0, kUserCause);
  504. EXPECT_TRUE(GetGlobalTouchscreenEnabled());
  505. }
  506. // When user switches convertible device between tablet mode and laptop mode,
  507. // power button may be pressed and held, which may cause unwanted unclean
  508. // shutdown.
  509. TEST_F(PowerButtonControllerTest, LeaveTabletModeWhilePressingPowerButton) {
  510. EnableTabletMode(true);
  511. PressPowerButton();
  512. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  513. EnableTabletMode(false);
  514. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  515. tick_clock_.Advance(base::Milliseconds(1500));
  516. ReleasePowerButton();
  517. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  518. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  519. }
  520. // Tests that repeated power button releases are ignored (crbug.com/675291).
  521. TEST_F(PowerButtonControllerTest, IgnoreRepeatedPowerButtonReleases) {
  522. // Set backlights forced off for starting point.
  523. EnableTabletMode(true);
  524. PressPowerButton();
  525. ReleasePowerButton();
  526. SendBrightnessChange(0, kUserCause);
  527. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  528. // Test that a pressing-releasing operation after a short duration, backlights
  529. // forced off is stopped since we don't drop request for power button pressed.
  530. tick_clock_.Advance(base::Milliseconds(200));
  531. PressPowerButton();
  532. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  533. ReleasePowerButton();
  534. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  535. // Test that after another short duration, backlights will not be forced off
  536. // since this immediately following forcing off request needs to be dropped.
  537. tick_clock_.Advance(base::Milliseconds(200));
  538. PressPowerButton();
  539. ReleasePowerButton();
  540. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  541. // Test that after another long duration, backlights should be forced off.
  542. tick_clock_.Advance(base::Milliseconds(800));
  543. PressPowerButton();
  544. ReleasePowerButton();
  545. SendBrightnessChange(0, kUserCause);
  546. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  547. }
  548. // Tests that repeated power button releases of clamshell should cancel the
  549. // ongoing showing menu animation.
  550. TEST_F(PowerButtonControllerTest,
  551. ClamshellRepeatedPowerButtonReleasesCancelledAnimation) {
  552. InitPowerButtonControllerMembers(PowerManagerClient::TabletMode::UNSUPPORTED);
  553. EnableTabletMode(false);
  554. // Enable animations so that we can make sure that they occur.
  555. ui::ScopedAnimationDurationScaleMode regular_animations(
  556. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  557. PressPowerButton();
  558. ReleasePowerButton();
  559. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  560. tick_clock_.Advance(base::Milliseconds(200));
  561. PressPowerButton();
  562. ReleasePowerButton();
  563. // Showing menu animation should be cancelled and menu is not shown.
  564. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  565. EXPECT_FALSE(power_button_test_api_->PreShutdownTimerIsRunning());
  566. }
  567. // Tests that lid closed events stop forcing off backlights.
  568. TEST_F(PowerButtonControllerTest, LidEventsStopForcingOff) {
  569. // Pressing/releasing power button to set backlights forced off.
  570. EnableTabletMode(true);
  571. PressPowerButton();
  572. ReleasePowerButton();
  573. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  574. // A lid closed event is received, we should stop forcing off backlights.
  575. power_manager_client()->SetLidState(PowerManagerClient::LidState::CLOSED,
  576. tick_clock_.NowTicks());
  577. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  578. }
  579. // Tests that tablet mode events from powerd stop forcing off backlights.
  580. TEST_F(PowerButtonControllerTest, TabletModeEventsStopForcingOff) {
  581. EnableTabletMode(true);
  582. PressPowerButton();
  583. ReleasePowerButton();
  584. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  585. power_manager_client()->SetTabletMode(PowerManagerClient::TabletMode::OFF,
  586. tick_clock_.NowTicks());
  587. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  588. AdvanceClockToAvoidIgnoring();
  589. PressPowerButton();
  590. ReleasePowerButton();
  591. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  592. power_manager_client()->SetTabletMode(PowerManagerClient::TabletMode::ON,
  593. tick_clock_.NowTicks());
  594. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  595. }
  596. // Tests that with system reboot, the global touchscreen enabled status should
  597. // be synced with new backlights forced off state from powerd.
  598. TEST_F(PowerButtonControllerTest, SyncTouchscreenEnabled) {
  599. Shell::Get()->touch_devices_controller()->SetTouchscreenEnabled(
  600. false, TouchDeviceEnabledSource::GLOBAL);
  601. ASSERT_FALSE(GetGlobalTouchscreenEnabled());
  602. // Simulate system reboot by resetting backlights forced off state in powerd
  603. // and PowerButtonController.
  604. power_manager_client()->SetBacklightsForcedOff(false);
  605. ResetPowerButtonController();
  606. SetTabletModeSwitchState(PowerManagerClient::TabletMode::ON);
  607. // Run the event loop for PowerButtonDisplayController to get backlight state
  608. // and check that the global touchscreen status is correct.
  609. base::RunLoop().RunUntilIdle();
  610. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  611. EXPECT_TRUE(GetGlobalTouchscreenEnabled());
  612. }
  613. // Tests that when backlights get forced off due to tablet power button, media
  614. // sessions should be suspended.
  615. TEST_F(PowerButtonControllerTest, SuspendMediaSessions) {
  616. TestMediaClient client;
  617. Shell::Get()->media_controller()->SetClient(&client);
  618. ASSERT_FALSE(client.media_sessions_suspended());
  619. EnableTabletMode(true);
  620. PressPowerButton();
  621. ReleasePowerButton();
  622. // Run the event loop for PowerButtonDisplayController to get backlight state.
  623. base::RunLoop().RunUntilIdle();
  624. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  625. EXPECT_TRUE(client.media_sessions_suspended());
  626. }
  627. // Tests that when system is suspended with backlights forced off, and then
  628. // system resumes due to power button pressed without power button event fired
  629. // (crbug.com/735291), that we stop forcing off backlights.
  630. TEST_F(PowerButtonControllerTest, SuspendDoneStopsForcingOff) {
  631. EnableTabletMode(true);
  632. PressPowerButton();
  633. ReleasePowerButton();
  634. SendBrightnessChange(0, kUserCause);
  635. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  636. // Simulate an edge case that system resumes because of tablet power button
  637. // pressed, but power button event is not delivered.
  638. power_manager_client()->SendSuspendDone();
  639. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  640. }
  641. // Tests that during the interval that the display is turning on, tablet power
  642. // button should not set display off (crbug.com/735225).
  643. TEST_F(PowerButtonControllerTest, IgnoreForcingOffWhenDisplayIsTurningOn) {
  644. EnableTabletMode(true);
  645. PressPowerButton();
  646. ReleasePowerButton();
  647. SendBrightnessChange(0, kUserCause);
  648. ASSERT_TRUE(power_manager_client()->backlights_forced_off());
  649. // Simiulate the backlight no longer being forced off due to a key event
  650. // (which we need to briefly leave tablet mode to receive). Chrome will
  651. // receive a brightness changed signal, but the display may still be off.
  652. EnableTabletMode(false);
  653. PressKey(ui::VKEY_L);
  654. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  655. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  656. // Since display could still be off, ignore additional button presses.
  657. tick_clock_.Advance(PowerButtonController::kScreenStateChangeDelay -
  658. base::Milliseconds(1));
  659. EnableTabletMode(true);
  660. PressPowerButton();
  661. ReleasePowerButton();
  662. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  663. // After waiting long enough, we should be able to force the display off.
  664. AdvanceClockToAvoidIgnoring();
  665. PressPowerButton();
  666. ReleasePowerButton();
  667. SendBrightnessChange(0, kUserCause);
  668. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  669. }
  670. // Tests that a11y alert is sent on tablet power button induced screen state
  671. // change.
  672. TEST_F(PowerButtonControllerTest, A11yAlert) {
  673. TestAccessibilityControllerClient a11y_client;
  674. EnableTabletMode(true);
  675. PressPowerButton();
  676. ReleasePowerButton();
  677. SendBrightnessChange(0, kUserCause);
  678. EXPECT_EQ(AccessibilityAlert::SCREEN_OFF, a11y_client.last_a11y_alert());
  679. PressPowerButton();
  680. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  681. EXPECT_EQ(AccessibilityAlert::SCREEN_ON, a11y_client.last_a11y_alert());
  682. ReleasePowerButton();
  683. }
  684. // Tests that tap outside of the menu bounds should dismiss the menu.
  685. TEST_F(PowerButtonControllerTest, TapToDismissMenu) {
  686. OpenPowerButtonMenu();
  687. TapToDismissPowerButtonMenu();
  688. }
  689. // Test that mouse click outside of the menu bounds should dismiss the menu.
  690. TEST_F(PowerButtonControllerTest, MouseClickToDismissMenu) {
  691. OpenPowerButtonMenu();
  692. gfx::Rect menu_bounds = power_button_test_api_->GetMenuBoundsInScreen();
  693. ui::test::EventGenerator* generator = GetEventGenerator();
  694. generator->MoveMouseTo(gfx::Point(menu_bounds.x() - 5, menu_bounds.y() - 5));
  695. generator->ClickLeftButton();
  696. generator->ReleaseLeftButton();
  697. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  698. }
  699. // Tests the menu items according to the login and screen locked status.
  700. TEST_F(PowerButtonControllerTest, MenuItemsToLoginAndLockedStatus) {
  701. // Should have feedback but not sign out and lock screen items if there is no
  702. // user signed in.
  703. ClearLogin();
  704. Shell::Get()->UpdateAfterLoginStatusChange(LoginStatus::NOT_LOGGED_IN);
  705. OpenPowerButtonMenu();
  706. EXPECT_FALSE(power_button_test_api_->MenuHasSignOutItem());
  707. EXPECT_FALSE(power_button_test_api_->MenuHasLockScreenItem());
  708. EXPECT_TRUE(power_button_test_api_->MenuHasFeedbackItem());
  709. TapToDismissPowerButtonMenu();
  710. // Should have sign out and feedback items if in guest mode (or, generally,
  711. // if screen locking is disabled).
  712. ClearLogin();
  713. Initialize(ButtonType::NORMAL, LoginStatus::GUEST);
  714. OpenPowerButtonMenu();
  715. EXPECT_FALSE(GetLockedState());
  716. EXPECT_TRUE(power_button_test_api_->MenuHasSignOutItem());
  717. EXPECT_FALSE(power_button_test_api_->MenuHasLockScreenItem());
  718. EXPECT_TRUE(power_button_test_api_->MenuHasFeedbackItem());
  719. TapToDismissPowerButtonMenu();
  720. // Should have sign out, lock screen and feedback items if user is logged in
  721. // and screen is unlocked.
  722. ClearLogin();
  723. CreateUserSessions(1);
  724. OpenPowerButtonMenu();
  725. EXPECT_FALSE(GetLockedState());
  726. EXPECT_TRUE(power_button_test_api_->MenuHasSignOutItem());
  727. EXPECT_TRUE(power_button_test_api_->MenuHasLockScreenItem());
  728. EXPECT_TRUE(power_button_test_api_->MenuHasFeedbackItem());
  729. TapToDismissPowerButtonMenu();
  730. // Should have sign out but not lock screen and feedback items if user is
  731. // logged in but screen is locked.
  732. LockScreen();
  733. EXPECT_TRUE(GetLockedState());
  734. OpenPowerButtonMenu();
  735. EXPECT_TRUE(power_button_test_api_->MenuHasSignOutItem());
  736. EXPECT_FALSE(power_button_test_api_->MenuHasLockScreenItem());
  737. EXPECT_FALSE(power_button_test_api_->MenuHasFeedbackItem());
  738. }
  739. // Tests long-pressing the power button when the menu is open.
  740. TEST_F(PowerButtonControllerTest, LongPressButtonWhenMenuIsOpened) {
  741. OpenPowerButtonMenu();
  742. AdvanceClockToAvoidIgnoring();
  743. // Long pressing the power button when menu is opened should not dismiss the
  744. // menu but trigger the pre-shutdown animation instead. Menu should stay
  745. // opened if releasing the button can cancel the animation.
  746. PressPowerButton();
  747. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  748. ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
  749. EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
  750. ReleasePowerButton();
  751. EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
  752. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  753. // Change focus to 'sign out'
  754. PressKey(ui::VKEY_TAB);
  755. EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView()
  756. ->sign_out_item_for_test()
  757. ->HasFocus());
  758. // Long press when menu is opened with focus on 'sign out' item will change
  759. // the focus to 'power off' after starting the pre-shutdown animation.
  760. PressPowerButton();
  761. ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
  762. EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
  763. EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView()
  764. ->power_off_item_for_test()
  765. ->HasFocus());
  766. ReleasePowerButton();
  767. }
  768. // Tests that switches between laptop mode and tablet mode should dismiss the
  769. // opened menu.
  770. TEST_F(PowerButtonControllerTest, EnterOrLeaveTabletModeDismissMenu) {
  771. OpenPowerButtonMenu();
  772. EnableTabletMode(true);
  773. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  774. OpenPowerButtonMenu();
  775. EnableTabletMode(false);
  776. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  777. }
  778. // Tests that screen changes to idle off will dismiss the opened menu.
  779. TEST_F(PowerButtonControllerTest, DismissMenuWhenScreenIsIdleOff) {
  780. OpenPowerButtonMenu();
  781. // Mock screen idle off.
  782. SendBrightnessChange(0, kUserCause);
  783. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  784. }
  785. // Tests that tapping the power button should dimiss the opened menu.
  786. TEST_F(PowerButtonControllerTest, TappingPowerButtonWhenMenuIsOpened) {
  787. EnableTabletMode(true);
  788. OpenPowerButtonMenu();
  789. // Tapping the power button when menu is opened will dismiss the menu.
  790. AdvanceClockToAvoidIgnoring();
  791. PressPowerButton();
  792. ReleasePowerButton();
  793. SendBrightnessChange(0, kUserCause);
  794. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  795. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  796. // Long press the power button when backlights are off will show the menu.
  797. PressPowerButton();
  798. SendBrightnessChange(kNonZeroBrightness, kUserCause);
  799. EXPECT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
  800. ReleasePowerButton();
  801. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  802. // Tapping the power button will dismiss the menu.
  803. AdvanceClockToAvoidIgnoring();
  804. PressPowerButton();
  805. ReleasePowerButton();
  806. SendBrightnessChange(0, kUserCause);
  807. EXPECT_TRUE(power_manager_client()->backlights_forced_off());
  808. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  809. }
  810. // Tests that suspend will dismiss the opened menu.
  811. TEST_F(PowerButtonControllerTest, SuspendWithMenuOn) {
  812. OpenPowerButtonMenu();
  813. power_manager_client()->SendSuspendImminent(
  814. power_manager::SuspendImminent_Reason_OTHER);
  815. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  816. power_manager_client()->SendSuspendDone();
  817. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  818. }
  819. // Tests the formerly-active window state in showing power menu.
  820. TEST_F(PowerButtonControllerTest, FormerlyActiveWindowInShowingMenu) {
  821. std::unique_ptr<views::Widget> widget = CreateTestWidget();
  822. ASSERT_TRUE(widget->IsActive());
  823. OpenPowerButtonMenu();
  824. // The active window becomes inactive after menu is shown but it is still
  825. // painted as active to avoid frame color change.
  826. EXPECT_FALSE(widget->IsActive());
  827. EXPECT_TRUE(widget->ShouldPaintAsActive());
  828. EXPECT_TRUE(widget->non_client_view()->frame_view()->ShouldPaintAsActive());
  829. EXPECT_TRUE(
  830. wm::IsActiveWindow(power_button_test_api_->GetPowerButtonMenuView()
  831. ->GetWidget()
  832. ->GetNativeWindow()));
  833. // Should reset the previous painting as active setting of the active window
  834. // if dismissing the menu.
  835. TapToDismissPowerButtonMenu();
  836. // Focus may fall to the widget if it's the only remaining widget on the
  837. // screen. Deactivate it to verify that it's no longer being forced to render
  838. // as active.
  839. widget->Deactivate();
  840. EXPECT_FALSE(widget->ShouldPaintAsActive());
  841. // A widget which is not the active widget is not affected by opening the
  842. // power button menu.
  843. OpenPowerButtonMenu();
  844. EXPECT_FALSE(widget->ShouldPaintAsActive());
  845. TapToDismissPowerButtonMenu();
  846. // If focus didn't fall to the widget after the menu was closed, focus it.
  847. widget->Activate();
  848. // Dismiss menu should work well after the active window is closed between
  849. // showing and dismissing menu.
  850. OpenPowerButtonMenu();
  851. widget->Close();
  852. TapToDismissPowerButtonMenu();
  853. }
  854. // Tests that cursor is hidden after show the menu and should reappear if mouse
  855. // moves.
  856. TEST_F(PowerButtonControllerTest, HideCursorAfterShowMenu) {
  857. // Cursor is hidden after show the menu.
  858. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  859. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  860. PressPowerButton();
  861. ReleasePowerButton();
  862. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  863. EXPECT_FALSE(cursor_manager->IsCursorVisible());
  864. // Cursor reappears if mouse moves.
  865. GenerateMouseMoveEvent();
  866. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  867. }
  868. // Tests that press VKEY_ESCAPE should dismiss the opened menu.
  869. TEST_F(PowerButtonControllerTest, ESCDismissMenu) {
  870. OpenPowerButtonMenu();
  871. PressKey(ui::VKEY_VOLUME_DOWN);
  872. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  873. PressKey(ui::VKEY_BRIGHTNESS_UP);
  874. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  875. PressKey(ui::VKEY_BROWSER_SEARCH);
  876. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  877. PressKey(ui::VKEY_ESCAPE);
  878. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  879. }
  880. // Tests the navigation of the menu.
  881. TEST_F(PowerButtonControllerTest, MenuNavigation) {
  882. ClearLogin();
  883. Shell::Get()->UpdateAfterLoginStatusChange(LoginStatus::NOT_LOGGED_IN);
  884. OpenPowerButtonMenu();
  885. ASSERT_TRUE(power_button_test_api_->MenuHasFeedbackItem());
  886. auto* menu_view = power_button_test_api_->GetPowerButtonMenuView();
  887. PressKey(ui::VKEY_TAB);
  888. EXPECT_TRUE(menu_view->power_off_item_for_test()->HasFocus());
  889. PressKey(ui::VKEY_TAB);
  890. EXPECT_TRUE(menu_view->feedback_item_for_test()->HasFocus());
  891. TapToDismissPowerButtonMenu();
  892. ClearLogin();
  893. CreateUserSessions(1);
  894. OpenPowerButtonMenu();
  895. ASSERT_TRUE(power_button_test_api_->MenuHasSignOutItem());
  896. ASSERT_TRUE(power_button_test_api_->MenuHasLockScreenItem());
  897. ASSERT_TRUE(power_button_test_api_->MenuHasFeedbackItem());
  898. menu_view = power_button_test_api_->GetPowerButtonMenuView();
  899. PressKey(ui::VKEY_TAB);
  900. EXPECT_TRUE(menu_view->power_off_item_for_test()->HasFocus());
  901. PressKey(ui::VKEY_RIGHT);
  902. EXPECT_TRUE(menu_view->sign_out_item_for_test()->HasFocus());
  903. PressKey(ui::VKEY_DOWN);
  904. EXPECT_TRUE(menu_view->lock_screen_item_for_test()->HasFocus());
  905. PressKey(ui::VKEY_TAB);
  906. EXPECT_TRUE(menu_view->feedback_item_for_test()->HasFocus());
  907. PressKey(ui::VKEY_TAB);
  908. EXPECT_TRUE(menu_view->power_off_item_for_test()->HasFocus());
  909. PressKey(ui::VKEY_UP);
  910. EXPECT_TRUE(menu_view->feedback_item_for_test()->HasFocus());
  911. PressKey(ui::VKEY_UP);
  912. EXPECT_TRUE(menu_view->lock_screen_item_for_test()->HasFocus());
  913. PressKey(ui::VKEY_LEFT);
  914. EXPECT_TRUE(menu_view->sign_out_item_for_test()->HasFocus());
  915. PressKey(ui::VKEY_UP);
  916. EXPECT_TRUE(menu_view->power_off_item_for_test()->HasFocus());
  917. }
  918. // Tests that the partially shown menu will be dismissed by power button up in
  919. // tablet mode, and screen should not be turned off at the same time.
  920. TEST_F(PowerButtonControllerTest, PartiallyShownMenuInTabletMode) {
  921. EnableTabletMode(true);
  922. // Enable animations so that we can make sure that they occur.
  923. ui::ScopedAnimationDurationScaleMode regular_animations(
  924. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  925. PressPowerButton();
  926. EXPECT_TRUE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  927. EXPECT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
  928. EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
  929. // Power menu is in the partially shown state.
  930. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  931. EXPECT_FALSE(power_button_test_api_->ShowMenuAnimationDone());
  932. ReleasePowerButton();
  933. EXPECT_FALSE(power_button_test_api_->ShowMenuAnimationDone());
  934. // The partially shown menu should be dismissed by power button up.
  935. EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
  936. // Screen should not be turned off with power button released.
  937. EXPECT_FALSE(power_manager_client()->backlights_forced_off());
  938. }
  939. class PowerButtonControllerWithPositionTest
  940. : public PowerButtonControllerTest,
  941. public testing::WithParamInterface<PowerButtonPosition> {
  942. public:
  943. PowerButtonControllerWithPositionTest() : power_button_position_(GetParam()) {
  944. base::DictionaryValue position_info;
  945. switch (power_button_position_) {
  946. case PowerButtonPosition::LEFT:
  947. position_info.SetStringKey(PowerButtonController::kEdgeField,
  948. PowerButtonController::kLeftEdge);
  949. break;
  950. case PowerButtonPosition::RIGHT:
  951. position_info.SetStringKey(PowerButtonController::kEdgeField,
  952. PowerButtonController::kRightEdge);
  953. break;
  954. case PowerButtonPosition::TOP:
  955. position_info.SetStringKey(PowerButtonController::kEdgeField,
  956. PowerButtonController::kTopEdge);
  957. break;
  958. case PowerButtonPosition::BOTTOM:
  959. position_info.SetStringKey(PowerButtonController::kEdgeField,
  960. PowerButtonController::kBottomEdge);
  961. break;
  962. default:
  963. return;
  964. }
  965. position_info.SetDoubleKey(PowerButtonController::kPositionField,
  966. kPowerButtonPercentage);
  967. std::string json_position_info;
  968. base::JSONWriter::Write(position_info, &json_position_info);
  969. base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
  970. switches::kAshPowerButtonPosition, json_position_info);
  971. }
  972. PowerButtonControllerWithPositionTest(
  973. const PowerButtonControllerWithPositionTest&) = delete;
  974. PowerButtonControllerWithPositionTest& operator=(
  975. const PowerButtonControllerWithPositionTest&) = delete;
  976. bool IsLeftOrRightPosition() const {
  977. return power_button_position_ == PowerButtonPosition::LEFT ||
  978. power_button_position_ == PowerButtonPosition::RIGHT;
  979. }
  980. // Returns true if it is in tablet mode.
  981. bool IsTabletMode() const {
  982. return Shell::Get()->tablet_mode_controller()->InTabletMode();
  983. }
  984. // Returns true if the menu is at the center of the display.
  985. bool IsMenuCentered() const {
  986. return power_button_test_api_->GetMenuBoundsInScreen().CenterPoint() ==
  987. display::Screen::GetScreen()
  988. ->GetPrimaryDisplay()
  989. .bounds()
  990. .CenterPoint();
  991. }
  992. PowerButtonPosition power_button_position() const {
  993. return power_button_position_;
  994. }
  995. private:
  996. PowerButtonPosition power_button_position_;
  997. };
  998. // TODO(crbug.com/1010194).
  999. TEST_P(PowerButtonControllerWithPositionTest,
  1000. DISABLED_MenuNextToPowerButtonInTabletMode) {
  1001. std::string display =
  1002. std::to_string(kDisplayWidth) + "x" + std::to_string(kDisplayHeight);
  1003. UpdateDisplay(display);
  1004. display::test::ScopedSetInternalDisplayId set_internal(
  1005. display_manager(), GetPrimaryDisplay().id());
  1006. ScreenOrientationControllerTestApi test_api(
  1007. Shell::Get()->screen_orientation_controller());
  1008. // Set the screen orientation to LANDSCAPE_PRIMARY.
  1009. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  1010. display::Display::RotationSource::ACTIVE);
  1011. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1012. chromeos::OrientationType::kLandscapePrimary);
  1013. // Menu is set at the center of the display if it is not in tablet mode.
  1014. OpenPowerButtonMenu();
  1015. ASSERT_FALSE(IsTabletMode());
  1016. EXPECT_TRUE(IsMenuCentered());
  1017. TapToDismissPowerButtonMenu();
  1018. int animation_transform = PowerButtonMenuView::kMenuViewTransformDistanceDp;
  1019. EnableTabletMode(true);
  1020. EXPECT_TRUE(IsTabletMode());
  1021. OpenPowerButtonMenu();
  1022. EXPECT_FALSE(IsMenuCentered());
  1023. if (power_button_position() == PowerButtonPosition::LEFT) {
  1024. EXPECT_EQ(animation_transform,
  1025. power_button_test_api_->GetMenuBoundsInScreen().x());
  1026. } else if (power_button_position() == PowerButtonPosition::RIGHT) {
  1027. EXPECT_EQ(animation_transform,
  1028. kDisplayWidth -
  1029. power_button_test_api_->GetMenuBoundsInScreen().right());
  1030. } else if (power_button_position() == PowerButtonPosition::TOP) {
  1031. EXPECT_EQ(animation_transform,
  1032. power_button_test_api_->GetMenuBoundsInScreen().y());
  1033. } else if (power_button_position() == PowerButtonPosition::BOTTOM) {
  1034. EXPECT_EQ(animation_transform,
  1035. kDisplayHeight -
  1036. power_button_test_api_->GetMenuBoundsInScreen().bottom());
  1037. }
  1038. // Rotate the screen by 270 degree.
  1039. test_api.SetDisplayRotation(display::Display::ROTATE_270,
  1040. display::Display::RotationSource::ACTIVE);
  1041. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1042. chromeos::OrientationType::kPortraitPrimary);
  1043. EXPECT_FALSE(IsMenuCentered());
  1044. if (power_button_position() == PowerButtonPosition::LEFT) {
  1045. EXPECT_EQ(animation_transform,
  1046. power_button_test_api_->GetMenuBoundsInScreen().y());
  1047. } else if (power_button_position() == PowerButtonPosition::RIGHT) {
  1048. EXPECT_EQ(animation_transform,
  1049. kDisplayWidth -
  1050. power_button_test_api_->GetMenuBoundsInScreen().bottom());
  1051. } else if (power_button_position() == PowerButtonPosition::TOP) {
  1052. EXPECT_EQ(animation_transform,
  1053. kDisplayHeight -
  1054. power_button_test_api_->GetMenuBoundsInScreen().right());
  1055. } else if (power_button_position() == PowerButtonPosition::BOTTOM) {
  1056. EXPECT_EQ(animation_transform,
  1057. power_button_test_api_->GetMenuBoundsInScreen().x());
  1058. }
  1059. // Rotate the screen by 180 degree.
  1060. test_api.SetDisplayRotation(display::Display::ROTATE_180,
  1061. display::Display::RotationSource::ACTIVE);
  1062. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1063. chromeos::OrientationType::kLandscapeSecondary);
  1064. EXPECT_FALSE(IsMenuCentered());
  1065. if (power_button_position() == PowerButtonPosition::LEFT) {
  1066. EXPECT_EQ(animation_transform,
  1067. kDisplayWidth -
  1068. power_button_test_api_->GetMenuBoundsInScreen().right());
  1069. } else if (power_button_position() == PowerButtonPosition::RIGHT) {
  1070. EXPECT_EQ(animation_transform,
  1071. power_button_test_api_->GetMenuBoundsInScreen().x());
  1072. } else if (power_button_position() == PowerButtonPosition::TOP) {
  1073. EXPECT_EQ(animation_transform,
  1074. kDisplayHeight -
  1075. power_button_test_api_->GetMenuBoundsInScreen().bottom());
  1076. } else if (power_button_position() == PowerButtonPosition::BOTTOM) {
  1077. EXPECT_EQ(animation_transform,
  1078. power_button_test_api_->GetMenuBoundsInScreen().y());
  1079. }
  1080. // Rotate the screen by 90 degree.
  1081. test_api.SetDisplayRotation(display::Display::ROTATE_90,
  1082. display::Display::RotationSource::ACTIVE);
  1083. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1084. chromeos::OrientationType::kPortraitSecondary);
  1085. EXPECT_FALSE(IsMenuCentered());
  1086. if (power_button_position() == PowerButtonPosition::LEFT) {
  1087. EXPECT_EQ(animation_transform,
  1088. kDisplayWidth -
  1089. power_button_test_api_->GetMenuBoundsInScreen().bottom());
  1090. } else if (power_button_position() == PowerButtonPosition::RIGHT) {
  1091. EXPECT_EQ(animation_transform,
  1092. power_button_test_api_->GetMenuBoundsInScreen().y());
  1093. } else if (power_button_position() == PowerButtonPosition::TOP) {
  1094. EXPECT_EQ(animation_transform,
  1095. power_button_test_api_->GetMenuBoundsInScreen().x());
  1096. } else if (power_button_position() == PowerButtonPosition::BOTTOM) {
  1097. EXPECT_EQ(animation_transform,
  1098. kDisplayHeight -
  1099. power_button_test_api_->GetMenuBoundsInScreen().right());
  1100. }
  1101. }
  1102. // Tests that the menu is always shown at the percentage of position when
  1103. // display has different scale factors.
  1104. TEST_P(PowerButtonControllerWithPositionTest, MenuShownAtPercentageOfPosition) {
  1105. const int scale_factor = 2;
  1106. std::string display = "8000x2400*" + std::to_string(scale_factor);
  1107. UpdateDisplay(display);
  1108. int64_t primary_id = GetPrimaryDisplay().id();
  1109. display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
  1110. primary_id);
  1111. ASSERT_EQ(scale_factor, GetPrimaryDisplay().device_scale_factor());
  1112. EnableTabletMode(true);
  1113. OpenPowerButtonMenu();
  1114. EXPECT_FALSE(IsMenuCentered());
  1115. gfx::Point menu_center_point =
  1116. power_button_test_api_->GetMenuBoundsInScreen().CenterPoint();
  1117. gfx::Rect display_bounds = GetPrimaryDisplay().bounds();
  1118. int original_width = display_bounds.width();
  1119. int original_height = display_bounds.height();
  1120. if (IsLeftOrRightPosition()) {
  1121. EXPECT_EQ(menu_center_point.y(), static_cast<int>(display_bounds.height() *
  1122. kPowerButtonPercentage));
  1123. } else {
  1124. EXPECT_EQ(menu_center_point.x(), static_cast<int>(display_bounds.width() *
  1125. kPowerButtonPercentage));
  1126. }
  1127. TapToDismissPowerButtonMenu();
  1128. display_manager()->UpdateZoomFactor(primary_id, 1.f / scale_factor);
  1129. ASSERT_EQ(1.0f, GetPrimaryDisplay().device_scale_factor());
  1130. display_bounds = GetPrimaryDisplay().bounds();
  1131. int scale_up_width = display_bounds.width();
  1132. int scale_up_height = display_bounds.height();
  1133. EXPECT_EQ(scale_up_width, original_width * scale_factor);
  1134. EXPECT_EQ(scale_up_height, original_height * scale_factor);
  1135. OpenPowerButtonMenu();
  1136. menu_center_point =
  1137. power_button_test_api_->GetMenuBoundsInScreen().CenterPoint();
  1138. // Menu is still at the kPowerButtonPercentage position after scale up screen.
  1139. if (IsLeftOrRightPosition()) {
  1140. EXPECT_EQ(menu_center_point.y(), static_cast<int>(display_bounds.height() *
  1141. kPowerButtonPercentage));
  1142. } else {
  1143. EXPECT_EQ(menu_center_point.x(), static_cast<int>(display_bounds.width() *
  1144. kPowerButtonPercentage));
  1145. }
  1146. }
  1147. TEST_P(PowerButtonControllerWithPositionTest, AdjustMenuShownForDisplaySize) {
  1148. OpenPowerButtonMenu();
  1149. gfx::Rect menu_bounds = power_button_test_api_->GetMenuBoundsInScreen();
  1150. TapToDismissPowerButtonMenu();
  1151. // (1 - kPowerButtonPercentage) * display_height < 0.5 * menu_height makes
  1152. // sure menu will be cut off by display when button is on LEFT/RIGHT, and (1 -
  1153. // kPowerButtonPercentage) * display_width < 0.5 * menu_width makes sure menu
  1154. // will be cut off by display when button is on TOP/BOTTOM.
  1155. int display_width =
  1156. 0.5 / (1.0f - kPowerButtonPercentage) * menu_bounds.width() - 5;
  1157. int display_height =
  1158. 0.5 / (1.0f - kPowerButtonPercentage) * menu_bounds.height() - 5;
  1159. std::string display =
  1160. std::to_string(display_width) + "x" + std::to_string(display_height);
  1161. UpdateDisplay(display);
  1162. display::test::ScopedSetInternalDisplayId set_internal(
  1163. display_manager(), GetPrimaryDisplay().id());
  1164. ScreenOrientationControllerTestApi test_api(
  1165. Shell::Get()->screen_orientation_controller());
  1166. // Set the screen orientation to LANDSCAPE_PRIMARY.
  1167. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  1168. display::Display::RotationSource::ACTIVE);
  1169. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1170. chromeos::OrientationType::kLandscapePrimary);
  1171. EnableTabletMode(true);
  1172. OpenPowerButtonMenu();
  1173. // Menu's bounds is always inside the display.
  1174. EXPECT_TRUE(GetPrimaryDisplay().bounds().Contains(
  1175. power_button_test_api_->GetMenuBoundsInScreen()));
  1176. // Rotate the screen by 270 degrees.
  1177. test_api.SetDisplayRotation(display::Display::ROTATE_270,
  1178. display::Display::RotationSource::ACTIVE);
  1179. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1180. chromeos::OrientationType::kPortraitPrimary);
  1181. EXPECT_TRUE(GetPrimaryDisplay().bounds().Contains(
  1182. power_button_test_api_->GetMenuBoundsInScreen()));
  1183. // Rotate the screen by 180 degrees.
  1184. test_api.SetDisplayRotation(display::Display::ROTATE_180,
  1185. display::Display::RotationSource::ACTIVE);
  1186. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1187. chromeos::OrientationType::kLandscapeSecondary);
  1188. EXPECT_TRUE(GetPrimaryDisplay().bounds().Contains(
  1189. power_button_test_api_->GetMenuBoundsInScreen()));
  1190. // Rotate the screen by 90 degrees.
  1191. test_api.SetDisplayRotation(display::Display::ROTATE_90,
  1192. display::Display::RotationSource::ACTIVE);
  1193. EXPECT_EQ(test_api.GetCurrentOrientation(),
  1194. chromeos::OrientationType::kPortraitSecondary);
  1195. EXPECT_TRUE(GetPrimaryDisplay().bounds().Contains(
  1196. power_button_test_api_->GetMenuBoundsInScreen()));
  1197. }
  1198. // Disabled due to consistent failures. http://crbug.com/1286199
  1199. // Tests that a power button press before the menu is fully shown will not
  1200. // create a new menu.
  1201. TEST_F(PowerButtonControllerTest, DISABLED_LegacyPowerButtonIgnoreExtraPress) {
  1202. Initialize(ButtonType::LEGACY, LoginStatus::USER);
  1203. // Enable animations so that we can make sure that they occur.
  1204. ui::ScopedAnimationDurationScaleMode regular_animations(
  1205. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  1206. PressPowerButton();
  1207. // Power menu is in the partially shown state.
  1208. ASSERT_TRUE(power_button_test_api_->IsMenuOpened());
  1209. ASSERT_FALSE(power_button_test_api_->ShowMenuAnimationDone());
  1210. PowerButtonMenuView* menu_view_before =
  1211. power_button_test_api_->GetPowerButtonMenuView();
  1212. // Press power button again and make sure new PowerButtonMenuView is not
  1213. // created. This makes sure that we do not create a new menu while we are in
  1214. // the process of creating one for an old power button press.
  1215. PressPowerButton();
  1216. EXPECT_EQ(menu_view_before, power_button_test_api_->GetPowerButtonMenuView());
  1217. // This is needed to simulate the shutdown sound having been played,
  1218. // which blocks the shutdown timer.
  1219. // Make sure that the second press did not trigger a shutdown.
  1220. EXPECT_FALSE(lock_state_test_api_->real_shutdown_timer_is_running());
  1221. // Make sure that power menu is still in partially shown state.
  1222. ASSERT_TRUE(power_button_test_api_->IsMenuOpened());
  1223. ASSERT_FALSE(power_button_test_api_->ShowMenuAnimationDone());
  1224. }
  1225. TEST_F(PowerButtonControllerTest,
  1226. ArcPowerButtonEventShowMenuWithoutPreShutdown) {
  1227. LaunchArcPowerButtonEvent();
  1228. ASSERT_TRUE(power_button_test_api_->IsMenuOpened());
  1229. EXPECT_FALSE(power_button_test_api_->TriggerPreShutdownTimeout());
  1230. EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
  1231. EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
  1232. }
  1233. INSTANTIATE_TEST_SUITE_P(AshPowerButtonPosition,
  1234. PowerButtonControllerWithPositionTest,
  1235. testing::Values(PowerButtonPosition::LEFT,
  1236. PowerButtonPosition::RIGHT,
  1237. PowerButtonPosition::TOP,
  1238. PowerButtonPosition::BOTTOM));
  1239. } // namespace ash