screen_orientation_controller.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. // Copyright 2014 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_DISPLAY_SCREEN_ORIENTATION_CONTROLLER_H_
  5. #define ASH_DISPLAY_SCREEN_ORIENTATION_CONTROLLER_H_
  6. #include <unordered_map>
  7. #include "ash/accelerometer/accelerometer_reader.h"
  8. #include "ash/accelerometer/accelerometer_types.h"
  9. #include "ash/ash_export.h"
  10. #include "ash/display/display_configuration_controller.h"
  11. #include "ash/display/window_tree_host_manager.h"
  12. #include "ash/public/cpp/tablet_mode_observer.h"
  13. #include "ash/wm/splitview/split_view_controller.h"
  14. #include "ash/wm/splitview/split_view_observer.h"
  15. #include "base/observer_list.h"
  16. #include "chromeos/ui/base/display_util.h"
  17. #include "third_party/abseil-cpp/absl/types/optional.h"
  18. #include "ui/aura/window_observer.h"
  19. #include "ui/display/display.h"
  20. #include "ui/display/display_observer.h"
  21. #include "ui/wm/public/activation_change_observer.h"
  22. namespace aura {
  23. class Window;
  24. }
  25. namespace ash {
  26. ASH_EXPORT chromeos::OrientationType GetCurrentScreenOrientation();
  27. ASH_EXPORT bool IsCurrentScreenOrientationLandscape();
  28. ASH_EXPORT bool IsCurrentScreenOrientationPrimary();
  29. ASH_EXPORT std::ostream& operator<<(std::ostream& out,
  30. const chromeos::OrientationType& lock);
  31. // Implements ChromeOS specific functionality for ScreenOrientationProvider.
  32. class ASH_EXPORT ScreenOrientationController
  33. : public ::wm::ActivationChangeObserver,
  34. public aura::WindowObserver,
  35. public AccelerometerReader::Observer,
  36. public WindowTreeHostManager::Observer,
  37. public TabletModeObserver,
  38. public SplitViewObserver,
  39. public display::DisplayObserver {
  40. public:
  41. // Observer that reports changes to the state of ScreenOrientationProvider's
  42. // rotation lock.
  43. class Observer {
  44. public:
  45. // Invoked when rotation is locked or unlocked by a user.
  46. virtual void OnUserRotationLockChanged() {}
  47. protected:
  48. virtual ~Observer() = default;
  49. };
  50. // Controls the behavior after lock is applied to the window (when the window
  51. // becomes the active window). |DisableSensor| disables the sensor-based
  52. // rotation and locks to the specific orientation. For example, PORTRAIT may
  53. // rotate to PORTRAIT_PRIMARY or PORTRAIT_SECONDARY, and will allow rotation
  54. // between these two. |DisableSensor| disallows the sensor-based rotation by
  55. // locking the rotation to whichever specific orientation is applied.
  56. enum class LockCompletionBehavior {
  57. None,
  58. DisableSensor,
  59. };
  60. ScreenOrientationController();
  61. ScreenOrientationController(const ScreenOrientationController&) = delete;
  62. ScreenOrientationController& operator=(const ScreenOrientationController&) =
  63. delete;
  64. ~ScreenOrientationController() override;
  65. chromeos::OrientationType natural_orientation() const {
  66. return natural_orientation_;
  67. }
  68. // Add/Remove observers.
  69. void AddObserver(Observer* observer);
  70. void RemoveObserver(Observer* observer);
  71. // Allows/unallows a window to lock the screen orientation.
  72. void LockOrientationForWindow(aura::Window* requesting_window,
  73. chromeos::OrientationType orientation_lock);
  74. void UnlockOrientationForWindow(aura::Window* window);
  75. // Unlock all and set the rotation back to the user specified rotation.
  76. void UnlockAll();
  77. // Returns true if the user has locked the orientation to portrait, false if
  78. // the user has locked the orientation to landscape or not locked the
  79. // orientation.
  80. bool IsUserLockedOrientationPortrait();
  81. // Returns the chromeos::OrientationType that is applied on based on whether a
  82. // rotation lock was requested for an app window, and whether the current
  83. // system state allows it to lock the rotation (e.g. being in tablet mode, on
  84. // the internal display, and splitview is inactive).
  85. chromeos::OrientationType GetCurrentAppRequestedOrientationLock() const;
  86. bool ignore_display_configuration_updates() const {
  87. return ignore_display_configuration_updates_;
  88. }
  89. // True if |rotation_lock_| has been set and accelerometer updates should not
  90. // rotate the display.
  91. bool rotation_locked() const { return rotation_locked_; }
  92. bool user_rotation_locked() const {
  93. return user_locked_orientation_ != chromeos::OrientationType::kAny;
  94. }
  95. // Trun on/off the user rotation lock. When turned on, it will lock
  96. // the orientation to the current orientation.
  97. // |user_rotation_locked()| method returns the current state of the
  98. // user rotation lock.
  99. void ToggleUserRotationLock();
  100. // Set locked to the given |rotation| and save it.
  101. void SetLockToRotation(display::Display::Rotation rotation);
  102. // Gets current screen orientation type.
  103. chromeos::OrientationType GetCurrentOrientation() const;
  104. // Returns true if auto-rotation is allowed. It happens when the device is in
  105. // a physical tablet state or kSupportsClamshellAutoRotation is set.
  106. bool IsAutoRotationAllowed() const;
  107. // wm::ActivationChangeObserver:
  108. void OnWindowActivated(
  109. ::wm::ActivationChangeObserver::ActivationReason reason,
  110. aura::Window* gained_active,
  111. aura::Window* lost_active) override;
  112. // aura::WindowObserver:
  113. void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override;
  114. void OnWindowDestroying(aura::Window* window) override;
  115. void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
  116. // AccelerometerReader::Observer:
  117. void OnECLidAngleDriverStatusChanged(bool is_supported) override {}
  118. void OnAccelerometerUpdated(const AccelerometerUpdate& update) override;
  119. // WindowTreeHostManager::Observer:
  120. void OnDisplayConfigurationChanged() override;
  121. // TabletModeObserver:
  122. void OnTabletModeStarted() override;
  123. void OnTabletModeEnded() override;
  124. void OnTabletPhysicalStateChanged() override;
  125. // SplitViewObserver:
  126. void OnSplitViewStateChanged(SplitViewController::State previous_state,
  127. SplitViewController::State state) override;
  128. // display::DisplayObserver:
  129. void OnWillProcessDisplayChanges() override;
  130. void OnDidProcessDisplayChanges() override;
  131. private:
  132. friend class ScreenOrientationControllerTestApi;
  133. struct LockInfo {
  134. LockInfo(chromeos::OrientationType lock, aura::Window* root)
  135. : orientation_lock(lock), root_window(root) {}
  136. chromeos::OrientationType orientation_lock =
  137. chromeos::OrientationType::kAny;
  138. // Tracks the requesting window's root window and is updated whenever it
  139. // changes.
  140. aura::Window* root_window = nullptr;
  141. LockCompletionBehavior lock_completion_behavior =
  142. LockCompletionBehavior::None;
  143. };
  144. // Sets the display rotation for the given |source|. The new |rotation| will
  145. // also become active. Display changed notifications are suppressed for this
  146. // change.
  147. void SetDisplayRotation(
  148. display::Display::Rotation rotation,
  149. display::Display::RotationSource source,
  150. DisplayConfigurationController::RotationAnimation mode =
  151. DisplayConfigurationController::ANIMATION_ASYNC);
  152. void SetRotationLockedInternal(bool rotation_locked);
  153. // A helper method that set locked to the given |orientation| and save it.
  154. void SetLockToOrientation(chromeos::OrientationType orientation);
  155. // Sets the display rotation to |rotation|. Future accelerometer updates
  156. // should not be used to change the rotation. SetRotationLocked(false) removes
  157. // the rotation lock.
  158. void LockRotation(display::Display::Rotation rotation,
  159. display::Display::RotationSource source);
  160. // Sets the display rotation based on |lock_orientation|. Future accelerometer
  161. // updates should not be used to change the rotation. SetRotationLocked(false)
  162. // removes the rotation lock.
  163. void LockRotationToOrientation(chromeos::OrientationType lock_orientation);
  164. // For orientations that do not specify primary or secondary, locks to the
  165. // current rotation if it matches |lock_orientation|. Otherwise locks to a
  166. // matching rotation.
  167. void LockToRotationMatchingOrientation(
  168. chromeos::OrientationType lock_orientation);
  169. // Detect screen rotation from |lid| accelerometer and automatically rotate
  170. // screen.
  171. void HandleScreenRotation(const AccelerometerReading& lid);
  172. // Checks DisplayManager for registered rotation lock, and rotation,
  173. // preferences. These are then applied.
  174. void LoadDisplayRotationProperties();
  175. // Determines the rotation lock, and orientation, for the top-most window on
  176. // the internal display, and applies it. If there is none, rotation lock will
  177. // be removed.
  178. // TODO(oshima|afakhry): This behavior needs to be revised when Android
  179. // implements multi-display support.
  180. void ApplyLockForTopMostWindowOnInternalDisplay();
  181. // If there is a rotation lock that can be applied to window, applies it and
  182. // returns true. Otherwise returns false.
  183. bool ApplyLockForWindowIfPossible(const aura::Window* window);
  184. // Both |chromeos::OrientationType::kLandscape| and
  185. // |OrientationLock::kPortrait| allow for rotation between the
  186. // two angles of the same screen orientation
  187. // (http://www.w3.org/TR/screen-orientation/). Returns true if |rotation| is
  188. // supported for the current |rotation_locked_orientation_|.
  189. bool IsRotationAllowedInLockedState(display::Display::Rotation rotation);
  190. // Certain orientation locks allow for rotation between the two angles of the
  191. // same screen orientation. Returns true if |rotation_locked_orientation_|
  192. // allows rotation.
  193. bool CanRotateInLockedState();
  194. void UpdateNaturalOrientationForTest();
  195. // The orientation of the display when at a rotation of 0.
  196. chromeos::OrientationType natural_orientation_;
  197. // True when changes being applied cause OnDisplayConfigurationChanged() to be
  198. // called, and for which these changes should be ignored.
  199. bool ignore_display_configuration_updates_;
  200. // When true then accelerometer updates should not rotate the display.
  201. bool rotation_locked_;
  202. // True while the displays are being updated by the display manager, so that
  203. // we don't set the display rotation while this operation is in progress.
  204. bool suspend_orientation_lock_refreshes_ = false;
  205. // True if there was a request to refresh the orientation lock while the
  206. // display manager is in the process of updating the displays. When the
  207. // display manager is done, we check this value to see if we need to refresh
  208. // the orientation lock.
  209. bool is_orientation_lock_refresh_pending_ = false;
  210. // The orientation to which the current |rotation_locked_| was applied.
  211. chromeos::OrientationType rotation_locked_orientation_;
  212. // The rotation of the display set by the user. This rotation will be
  213. // restored upon exiting tablet mode.
  214. display::Display::Rotation user_rotation_;
  215. // The orientation of the device locked by the user.
  216. chromeos::OrientationType user_locked_orientation_ =
  217. chromeos::OrientationType::kAny;
  218. // The currently applied orientation lock that was requested by an app if any.
  219. absl::optional<chromeos::OrientationType>
  220. current_app_requested_orientation_lock_ = absl::nullopt;
  221. // The current rotation set by ScreenOrientationController for the internal
  222. // display.
  223. display::Display::Rotation current_rotation_;
  224. // Rotation Lock observers.
  225. base::ObserverList<Observer>::Unchecked observers_;
  226. // Tracks all windows that have requested a lock, as well as the requested
  227. // orientation.
  228. std::unordered_map<aura::Window*, LockInfo> lock_info_map_;
  229. // Register for DisplayObserver callbacks.
  230. display::ScopedDisplayObserver display_observer_{this};
  231. };
  232. } // namespace ash
  233. #endif // ASH_DISPLAY_SCREEN_ORIENTATION_CONTROLLER_H_