123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef ASH_DISPLAY_SCREEN_ORIENTATION_CONTROLLER_H_
- #define ASH_DISPLAY_SCREEN_ORIENTATION_CONTROLLER_H_
- #include <unordered_map>
- #include "ash/accelerometer/accelerometer_reader.h"
- #include "ash/accelerometer/accelerometer_types.h"
- #include "ash/ash_export.h"
- #include "ash/display/display_configuration_controller.h"
- #include "ash/display/window_tree_host_manager.h"
- #include "ash/public/cpp/tablet_mode_observer.h"
- #include "ash/wm/splitview/split_view_controller.h"
- #include "ash/wm/splitview/split_view_observer.h"
- #include "base/observer_list.h"
- #include "chromeos/ui/base/display_util.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "ui/aura/window_observer.h"
- #include "ui/display/display.h"
- #include "ui/display/display_observer.h"
- #include "ui/wm/public/activation_change_observer.h"
- namespace aura {
- class Window;
- }
- namespace ash {
- ASH_EXPORT chromeos::OrientationType GetCurrentScreenOrientation();
- ASH_EXPORT bool IsCurrentScreenOrientationLandscape();
- ASH_EXPORT bool IsCurrentScreenOrientationPrimary();
- ASH_EXPORT std::ostream& operator<<(std::ostream& out,
- const chromeos::OrientationType& lock);
- // Implements ChromeOS specific functionality for ScreenOrientationProvider.
- class ASH_EXPORT ScreenOrientationController
- : public ::wm::ActivationChangeObserver,
- public aura::WindowObserver,
- public AccelerometerReader::Observer,
- public WindowTreeHostManager::Observer,
- public TabletModeObserver,
- public SplitViewObserver,
- public display::DisplayObserver {
- public:
- // Observer that reports changes to the state of ScreenOrientationProvider's
- // rotation lock.
- class Observer {
- public:
- // Invoked when rotation is locked or unlocked by a user.
- virtual void OnUserRotationLockChanged() {}
- protected:
- virtual ~Observer() = default;
- };
- // Controls the behavior after lock is applied to the window (when the window
- // becomes the active window). |DisableSensor| disables the sensor-based
- // rotation and locks to the specific orientation. For example, PORTRAIT may
- // rotate to PORTRAIT_PRIMARY or PORTRAIT_SECONDARY, and will allow rotation
- // between these two. |DisableSensor| disallows the sensor-based rotation by
- // locking the rotation to whichever specific orientation is applied.
- enum class LockCompletionBehavior {
- None,
- DisableSensor,
- };
- ScreenOrientationController();
- ScreenOrientationController(const ScreenOrientationController&) = delete;
- ScreenOrientationController& operator=(const ScreenOrientationController&) =
- delete;
- ~ScreenOrientationController() override;
- chromeos::OrientationType natural_orientation() const {
- return natural_orientation_;
- }
- // Add/Remove observers.
- void AddObserver(Observer* observer);
- void RemoveObserver(Observer* observer);
- // Allows/unallows a window to lock the screen orientation.
- void LockOrientationForWindow(aura::Window* requesting_window,
- chromeos::OrientationType orientation_lock);
- void UnlockOrientationForWindow(aura::Window* window);
- // Unlock all and set the rotation back to the user specified rotation.
- void UnlockAll();
- // Returns true if the user has locked the orientation to portrait, false if
- // the user has locked the orientation to landscape or not locked the
- // orientation.
- bool IsUserLockedOrientationPortrait();
- // Returns the chromeos::OrientationType that is applied on based on whether a
- // rotation lock was requested for an app window, and whether the current
- // system state allows it to lock the rotation (e.g. being in tablet mode, on
- // the internal display, and splitview is inactive).
- chromeos::OrientationType GetCurrentAppRequestedOrientationLock() const;
- bool ignore_display_configuration_updates() const {
- return ignore_display_configuration_updates_;
- }
- // True if |rotation_lock_| has been set and accelerometer updates should not
- // rotate the display.
- bool rotation_locked() const { return rotation_locked_; }
- bool user_rotation_locked() const {
- return user_locked_orientation_ != chromeos::OrientationType::kAny;
- }
- // Trun on/off the user rotation lock. When turned on, it will lock
- // the orientation to the current orientation.
- // |user_rotation_locked()| method returns the current state of the
- // user rotation lock.
- void ToggleUserRotationLock();
- // Set locked to the given |rotation| and save it.
- void SetLockToRotation(display::Display::Rotation rotation);
- // Gets current screen orientation type.
- chromeos::OrientationType GetCurrentOrientation() const;
- // Returns true if auto-rotation is allowed. It happens when the device is in
- // a physical tablet state or kSupportsClamshellAutoRotation is set.
- bool IsAutoRotationAllowed() const;
- // wm::ActivationChangeObserver:
- void OnWindowActivated(
- ::wm::ActivationChangeObserver::ActivationReason reason,
- aura::Window* gained_active,
- aura::Window* lost_active) override;
- // aura::WindowObserver:
- void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override;
- void OnWindowDestroying(aura::Window* window) override;
- void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
- // AccelerometerReader::Observer:
- void OnECLidAngleDriverStatusChanged(bool is_supported) override {}
- void OnAccelerometerUpdated(const AccelerometerUpdate& update) override;
- // WindowTreeHostManager::Observer:
- void OnDisplayConfigurationChanged() override;
- // TabletModeObserver:
- void OnTabletModeStarted() override;
- void OnTabletModeEnded() override;
- void OnTabletPhysicalStateChanged() override;
- // SplitViewObserver:
- void OnSplitViewStateChanged(SplitViewController::State previous_state,
- SplitViewController::State state) override;
- // display::DisplayObserver:
- void OnWillProcessDisplayChanges() override;
- void OnDidProcessDisplayChanges() override;
- private:
- friend class ScreenOrientationControllerTestApi;
- struct LockInfo {
- LockInfo(chromeos::OrientationType lock, aura::Window* root)
- : orientation_lock(lock), root_window(root) {}
- chromeos::OrientationType orientation_lock =
- chromeos::OrientationType::kAny;
- // Tracks the requesting window's root window and is updated whenever it
- // changes.
- aura::Window* root_window = nullptr;
- LockCompletionBehavior lock_completion_behavior =
- LockCompletionBehavior::None;
- };
- // Sets the display rotation for the given |source|. The new |rotation| will
- // also become active. Display changed notifications are suppressed for this
- // change.
- void SetDisplayRotation(
- display::Display::Rotation rotation,
- display::Display::RotationSource source,
- DisplayConfigurationController::RotationAnimation mode =
- DisplayConfigurationController::ANIMATION_ASYNC);
- void SetRotationLockedInternal(bool rotation_locked);
- // A helper method that set locked to the given |orientation| and save it.
- void SetLockToOrientation(chromeos::OrientationType orientation);
- // Sets the display rotation to |rotation|. Future accelerometer updates
- // should not be used to change the rotation. SetRotationLocked(false) removes
- // the rotation lock.
- void LockRotation(display::Display::Rotation rotation,
- display::Display::RotationSource source);
- // Sets the display rotation based on |lock_orientation|. Future accelerometer
- // updates should not be used to change the rotation. SetRotationLocked(false)
- // removes the rotation lock.
- void LockRotationToOrientation(chromeos::OrientationType lock_orientation);
- // For orientations that do not specify primary or secondary, locks to the
- // current rotation if it matches |lock_orientation|. Otherwise locks to a
- // matching rotation.
- void LockToRotationMatchingOrientation(
- chromeos::OrientationType lock_orientation);
- // Detect screen rotation from |lid| accelerometer and automatically rotate
- // screen.
- void HandleScreenRotation(const AccelerometerReading& lid);
- // Checks DisplayManager for registered rotation lock, and rotation,
- // preferences. These are then applied.
- void LoadDisplayRotationProperties();
- // Determines the rotation lock, and orientation, for the top-most window on
- // the internal display, and applies it. If there is none, rotation lock will
- // be removed.
- // TODO(oshima|afakhry): This behavior needs to be revised when Android
- // implements multi-display support.
- void ApplyLockForTopMostWindowOnInternalDisplay();
- // If there is a rotation lock that can be applied to window, applies it and
- // returns true. Otherwise returns false.
- bool ApplyLockForWindowIfPossible(const aura::Window* window);
- // Both |chromeos::OrientationType::kLandscape| and
- // |OrientationLock::kPortrait| allow for rotation between the
- // two angles of the same screen orientation
- // (http://www.w3.org/TR/screen-orientation/). Returns true if |rotation| is
- // supported for the current |rotation_locked_orientation_|.
- bool IsRotationAllowedInLockedState(display::Display::Rotation rotation);
- // Certain orientation locks allow for rotation between the two angles of the
- // same screen orientation. Returns true if |rotation_locked_orientation_|
- // allows rotation.
- bool CanRotateInLockedState();
- void UpdateNaturalOrientationForTest();
- // The orientation of the display when at a rotation of 0.
- chromeos::OrientationType natural_orientation_;
- // True when changes being applied cause OnDisplayConfigurationChanged() to be
- // called, and for which these changes should be ignored.
- bool ignore_display_configuration_updates_;
- // When true then accelerometer updates should not rotate the display.
- bool rotation_locked_;
- // True while the displays are being updated by the display manager, so that
- // we don't set the display rotation while this operation is in progress.
- bool suspend_orientation_lock_refreshes_ = false;
- // True if there was a request to refresh the orientation lock while the
- // display manager is in the process of updating the displays. When the
- // display manager is done, we check this value to see if we need to refresh
- // the orientation lock.
- bool is_orientation_lock_refresh_pending_ = false;
- // The orientation to which the current |rotation_locked_| was applied.
- chromeos::OrientationType rotation_locked_orientation_;
- // The rotation of the display set by the user. This rotation will be
- // restored upon exiting tablet mode.
- display::Display::Rotation user_rotation_;
- // The orientation of the device locked by the user.
- chromeos::OrientationType user_locked_orientation_ =
- chromeos::OrientationType::kAny;
- // The currently applied orientation lock that was requested by an app if any.
- absl::optional<chromeos::OrientationType>
- current_app_requested_orientation_lock_ = absl::nullopt;
- // The current rotation set by ScreenOrientationController for the internal
- // display.
- display::Display::Rotation current_rotation_;
- // Rotation Lock observers.
- base::ObserverList<Observer>::Unchecked observers_;
- // Tracks all windows that have requested a lock, as well as the requested
- // orientation.
- std::unordered_map<aura::Window*, LockInfo> lock_info_map_;
- // Register for DisplayObserver callbacks.
- display::ScopedDisplayObserver display_observer_{this};
- };
- } // namespace ash
- #endif // ASH_DISPLAY_SCREEN_ORIENTATION_CONTROLLER_H_
|