power_button_controller.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright (c) 2012 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. #ifndef ASH_SYSTEM_POWER_POWER_BUTTON_CONTROLLER_H_
  5. #define ASH_SYSTEM_POWER_POWER_BUTTON_CONTROLLER_H_
  6. #include <memory>
  7. #include "ash/accelerometer/accelerometer_reader.h"
  8. #include "ash/ash_export.h"
  9. #include "ash/public/cpp/session/session_observer.h"
  10. #include "ash/public/cpp/system/power/power_button_controller_base.h"
  11. #include "ash/public/cpp/tablet_mode_observer.h"
  12. #include "ash/shutdown_reason.h"
  13. #include "ash/system/power/backlights_forced_off_setter.h"
  14. #include "ash/wm/lock_state_observer.h"
  15. #include "base/memory/weak_ptr.h"
  16. #include "base/timer/timer.h"
  17. #include "chromeos/dbus/power/power_manager_client.h"
  18. #include "ui/display/manager/display_configurator.h"
  19. #include "ui/views/widget/widget.h"
  20. namespace base {
  21. class TickClock;
  22. class TimeTicks;
  23. } // namespace base
  24. namespace ash {
  25. class LockStateController;
  26. class PowerButtonDisplayController;
  27. class PowerButtonScreenshotController;
  28. // Handles power button and lock button events. Holding the power button
  29. // displays a menu and later shuts down on all devices. Tapping the power button
  30. // of convertible/slate/detachable devices (except forced clamshell set by
  31. // command line) will turn screen off but nothing will happen for clamshell
  32. // devices. In tablet mode, power button may also be consumed to take a
  33. // screenshot.
  34. class ASH_EXPORT PowerButtonController
  35. : public PowerButtonControllerBase,
  36. public display::DisplayConfigurator::Observer,
  37. public chromeos::PowerManagerClient::Observer,
  38. public AccelerometerReader::Observer,
  39. public ScreenBacklightObserver,
  40. public TabletModeObserver,
  41. public LockStateObserver,
  42. public SessionObserver {
  43. public:
  44. enum class ButtonType {
  45. // Indicates normal power button type.
  46. NORMAL,
  47. // Indicates legacy power button type. It could be set by command-line
  48. // switch telling us that we're running on hardware that misreports power
  49. // button releases.
  50. LEGACY,
  51. };
  52. // The physical display side of power button.
  53. enum class PowerButtonPosition { NONE, LEFT, TOP, RIGHT, BOTTOM };
  54. // Amount of time since last screen state change that power button event needs
  55. // to be ignored.
  56. static constexpr base::TimeDelta kScreenStateChangeDelay =
  57. base::Milliseconds(500);
  58. // Ignore button-up events occurring within this many milliseconds of the
  59. // previous button-up event. This prevents us from falling behind if the power
  60. // button is pressed repeatedly.
  61. static constexpr base::TimeDelta kIgnoreRepeatedButtonUpDelay =
  62. base::Milliseconds(500);
  63. // Amount of time since last SuspendDone() that power button event needs to be
  64. // ignored.
  65. static constexpr base::TimeDelta kIgnorePowerButtonAfterResumeDelay =
  66. base::Seconds(2);
  67. // Value of switches::kAshPowerButtonPosition stored in JSON format. These
  68. // are the field names of the flag.
  69. static constexpr const char* kEdgeField = "edge";
  70. static constexpr const char* kPositionField = "position";
  71. // Value of |kEdgeField|.
  72. static constexpr const char* kLeftEdge = "left";
  73. static constexpr const char* kRightEdge = "right";
  74. static constexpr const char* kTopEdge = "top";
  75. static constexpr const char* kBottomEdge = "bottom";
  76. explicit PowerButtonController(
  77. BacklightsForcedOffSetter* backlights_forced_off_setter);
  78. PowerButtonController(const PowerButtonController&) = delete;
  79. PowerButtonController& operator=(const PowerButtonController&) = delete;
  80. ~PowerButtonController() override;
  81. // Handles events from "legacy" ACPI power buttons. On devices with these
  82. // buttons (typically Chromeboxes), button releases are misreported
  83. // immediately after button presses, regardless of how long the button
  84. // is actually held.
  85. void OnLegacyPowerButtonEvent(bool down);
  86. // Handles events from "normal" power buttons where button presses and
  87. // releases are both reported accurately.
  88. void OnPowerButtonEvent(bool down, const base::TimeTicks& timestamp);
  89. // Handles lock button behavior.
  90. void OnLockButtonEvent(bool down, const base::TimeTicks& timestamp);
  91. // True if the menu is opened.
  92. bool IsMenuOpened() const;
  93. // Dismisses the menu.
  94. void DismissMenu();
  95. // Do not force backlights to be turned off.
  96. void StopForcingBacklightsOff();
  97. // PowerButtonControllerBase:
  98. void OnArcPowerButtonMenuEvent() override;
  99. void CancelPowerButtonEvent() override;
  100. // display::DisplayConfigurator::Observer:
  101. void OnDisplayModeChanged(
  102. const display::DisplayConfigurator::DisplayStateList& outputs) override;
  103. // chromeos::PowerManagerClient::Observer:
  104. void ScreenBrightnessChanged(
  105. const power_manager::BacklightBrightnessChange& change) override;
  106. void PowerButtonEventReceived(bool down, base::TimeTicks timestamp) override;
  107. void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
  108. void SuspendDone(base::TimeDelta sleep_duration) override;
  109. // SessionObserver:
  110. void OnLoginStatusChanged(LoginStatus status) override;
  111. // Initializes |screenshot_controller_| according to the tablet mode switch in
  112. // |result|.
  113. void OnGetSwitchStates(
  114. absl::optional<chromeos::PowerManagerClient::SwitchStates> result);
  115. // TODO(minch): Remove this if/when all applicable devices expose a tablet
  116. // mode switch: https://crbug.com/798646.
  117. // AccelerometerReader::Observer:
  118. void OnECLidAngleDriverStatusChanged(bool is_supported) override {}
  119. void OnAccelerometerUpdated(const AccelerometerUpdate& update) override;
  120. // BacklightsForcedOffSetter::Observer:
  121. void OnBacklightsForcedOffChanged(bool forced_off) override;
  122. void OnScreenBacklightStateChanged(
  123. ScreenBacklightState screen_backlight_state) override;
  124. // TabletModeObserver:
  125. void OnTabletModeStarted() override;
  126. void OnTabletModeEnded() override;
  127. // LockStateObserver:
  128. void OnLockStateEvent(LockStateObserver::EventType event) override;
  129. private:
  130. friend class PowerButtonControllerTestApi;
  131. // Returns true if tablet power button behavior (i.e. tapping the button turns
  132. // the screen off) should currently be used.
  133. bool UseTabletBehavior() const;
  134. // Stops |power_button_menu_timer_|, |shutdown_timer_| and dismisses the power
  135. // button menu.
  136. void StopTimersAndDismissMenu();
  137. // Starts the power menu animation. Called when a clamshell device's power
  138. // button is pressed, or when |power_button_menu_timer_| fires, or by arc
  139. // power button to show the PowerButtonMenu.
  140. void StartPowerMenuAnimation(ShutdownReason reason);
  141. // Called by |pre_shutdown_timer_| to start the cancellable pre-shutdown
  142. // animation.
  143. void OnPreShutdownTimeout();
  144. // Updates |button_type_| and power button position info based on the current
  145. // command line.
  146. void ProcessCommandLine();
  147. // Initializes tablet power button behavior related member
  148. // |screenshot_controller_|.
  149. void InitTabletPowerButtonMembers();
  150. // Locks the screen if the "Show lock screen when waking from sleep" pref is
  151. // set and locking is possible.
  152. void LockScreenIfRequired();
  153. // Sets |show_menu_animation_done_| to true.
  154. void SetShowMenuAnimationDone();
  155. // A helper function called by ProcessCommandLine to parse the value of
  156. // switches::kAshPowerButtonPosition.
  157. void ParsePowerButtonPositionSwitch();
  158. // Updates UMA histogram of power button press according to the power button
  159. // up state. |up_state| is a bit field containing values from the
  160. // PowerButtonUpState enum defined in the .cc file.
  161. void UpdatePowerButtonEventUMAHistogram(uint32_t up_state);
  162. // Are the power or lock buttons currently held?
  163. bool power_button_down_ = false;
  164. bool lock_button_down_ = false;
  165. // Passed in StartPowerMenuAnimation(ShutdownReason reason). When it is not
  166. // POWER_BUTTON such as when called from arc, we do not start
  167. // |pre_shutdown_timer_|.
  168. ShutdownReason shutdown_reason_ = ShutdownReason::POWER_BUTTON;
  169. // True if the device is currently in tablet mode (per TabletModeController).
  170. bool in_tablet_mode_ = false;
  171. // Has the screen brightness been reduced to 0%?
  172. bool brightness_is_zero_ = false;
  173. // True if an internal display is off while an external display is on (e.g.
  174. // for Chrome OS's docked mode, where a Chromebook's lid is closed while an
  175. // external display is connected).
  176. bool internal_display_off_and_external_display_on_ = false;
  177. // True after the animation that shows the power menu has finished.
  178. bool show_menu_animation_done_ = false;
  179. // Saves the button type for this power button.
  180. ButtonType button_type_ = ButtonType::NORMAL;
  181. // True if the kForceTabletPowerButton flag is set. This forces tablet power
  182. // button behavior even while in laptop mode.
  183. bool force_tablet_power_button_ = false;
  184. // True if the screen was off when the power button was pressed.
  185. bool screen_off_when_power_button_down_ = false;
  186. // True if power menu is already shown when pressing the power button.
  187. bool menu_shown_when_power_button_down_ = false;
  188. // True if the next button release event should force the display off.
  189. bool force_off_on_button_up_ = false;
  190. // Used to force backlights off, when needed.
  191. BacklightsForcedOffSetter* backlights_forced_off_setter_; // Not owned.
  192. LockStateController* lock_state_controller_; // Not owned.
  193. // Time source for performed action times.
  194. const base::TickClock* tick_clock_;
  195. // Used to interact with the display.
  196. std::unique_ptr<PowerButtonDisplayController> display_controller_;
  197. // Handles events for power button screenshot.
  198. std::unique_ptr<PowerButtonScreenshotController> screenshot_controller_;
  199. // Saves the most recent timestamp that powerd resumed from suspend,
  200. // updated in SuspendDone().
  201. base::TimeTicks last_resume_time_;
  202. // Saves the most recent timestamp that power button was released.
  203. base::TimeTicks last_button_up_time_;
  204. // Started when |show_menu_animation_done_| is set to true and stopped when
  205. // power button is released. Runs OnPreShutdownTimeout() to start the
  206. // cancellable pre-shutdown animation.
  207. base::OneShotTimer pre_shutdown_timer_;
  208. // Started when the power button of convertible/slate/detachable devices is
  209. // pressed and stopped when it's released. Runs StartPowerMenuAnimation() to
  210. // show the power button menu.
  211. base::OneShotTimer power_button_menu_timer_;
  212. // The fullscreen widget of power button menu.
  213. std::unique_ptr<views::Widget> menu_widget_;
  214. // The physical display side of power button in landscape primary.
  215. PowerButtonPosition power_button_position_ = PowerButtonPosition::NONE;
  216. // The center of the power button's offset from the top of the screen (for
  217. // left/right) or left side of the screen (for top/bottom) in
  218. // landscape_primary. Values are in [0.0, 1.0] and express a fraction of the
  219. // display's height or width, respectively.
  220. double power_button_offset_percentage_ = 0.f;
  221. base::ScopedObservation<BacklightsForcedOffSetter, ScreenBacklightObserver>
  222. backlights_forced_off_observation_{this};
  223. // Used to maintain active state of the active window that exists before
  224. // showing menu.
  225. std::unique_ptr<views::Widget::PaintAsActiveLock>
  226. active_window_paint_as_active_lock_;
  227. base::WeakPtrFactory<PowerButtonController> weak_factory_{this};
  228. };
  229. } // namespace ash
  230. #endif // ASH_SYSTEM_POWER_POWER_BUTTON_CONTROLLER_H_