123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- // Copyright 2015 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_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
- #define ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
- #include <stdint.h>
- #include <memory>
- #include "ash/ash_export.h"
- #include "ash/display/display_configuration_controller.h"
- #include "base/callback_forward.h"
- #include "base/memory/weak_ptr.h"
- #include "base/observer_list.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "ui/display/display.h"
- namespace aura {
- class Window;
- } // namespace aura
- namespace ui {
- class LayerTreeOwner;
- class ScopedAnimationDurationScaleMode;
- } // namespace ui
- namespace viz {
- class CopyOutputRequest;
- class CopyOutputResult;
- } // namespace viz
- namespace ash {
- class ScreenRotationAnimatorObserver;
- // Utility to perform a screen rotation with an animation.
- class ASH_EXPORT ScreenRotationAnimator {
- public:
- static ScreenRotationAnimator* GetForRootWindow(aura::Window* root_window);
- explicit ScreenRotationAnimator(aura::Window* root_window);
- ScreenRotationAnimator(const ScreenRotationAnimator&) = delete;
- ScreenRotationAnimator& operator=(const ScreenRotationAnimator&) = delete;
- virtual ~ScreenRotationAnimator();
- // Rotates the display::Display specified by |display_id| of the |root_window|
- // to the |new_rotation| orientation, for the given |source|. The rotation
- // will also become active. |screen_rotation_animator_observer_| will be
- // notified when rotation is finished and there is no more pending rotation
- // request. Otherwise, any ongoing animation will be stopped and progressed to
- // the target position, followed by a new |Rotate()| call with the pending
- // rotation request.
- void Rotate(display::Display::Rotation new_rotation,
- display::Display::RotationSource source,
- DisplayConfigurationController::RotationAnimation mode);
- void AddObserver(ScreenRotationAnimatorObserver* observer);
- void RemoveObserver(ScreenRotationAnimatorObserver* observer);
- // When screen rotation animation is ended or aborted, calls |Rotate()| with
- // the pending rotation request if the request queue is not empty. Otherwise
- // notifies |screen_rotation_animator_observer_|.
- void ProcessAnimationQueue();
- // True if the screen is in rotating state (not IDLE).
- bool IsRotating() const;
- // Returns the target (new) rotation. This will return the last requested
- // orientation if |IsRotating()| is false.
- display::Display::Rotation GetTargetRotation() const;
- static void SetScreenRotationAnimatorForTest(
- aura::Window* root_window,
- std::unique_ptr<ScreenRotationAnimator> animator);
- protected:
- using CopyCallback =
- base::OnceCallback<void(std::unique_ptr<viz::CopyOutputResult> result)>;
- struct ScreenRotationRequest {
- ScreenRotationRequest(
- int64_t id,
- int64_t display_id,
- display::Display::Rotation to_rotation,
- display::Display::RotationSource from_source,
- DisplayConfigurationController::RotationAnimation mode)
- : id(id),
- display_id(display_id),
- new_rotation(to_rotation),
- source(from_source),
- mode(mode) {}
- int64_t id;
- int64_t display_id;
- display::Display::Rotation old_rotation;
- display::Display::Rotation new_rotation;
- display::Display::RotationSource source;
- DisplayConfigurationController::RotationAnimation mode;
- };
- // This function can be overridden in unit test to test removing external
- // display.
- virtual CopyCallback CreateAfterCopyCallbackBeforeRotation(
- std::unique_ptr<ScreenRotationRequest> rotation_request);
- // This function can be overridden in unit test to test removing external
- // display.
- virtual CopyCallback CreateAfterCopyCallbackAfterRotation(
- std::unique_ptr<ScreenRotationRequest> rotation_request);
- private:
- friend class ScreenRotationAnimatorTestApi;
- void StartRotationAnimation(
- std::unique_ptr<ScreenRotationRequest> rotation_request);
- // The code path to start "slow animation". The difference between the "slow"
- // and "smooth" animation, is that "slow animation" will recreate all the
- // layers before rotation and use the recreated layers and rotated layers for
- // cross-fading animation. This is slow by adding multiple layer animation
- // elements. The "smooth animation" copies the layer output before and after
- // rotation, and use them for cross-fading animation. The output copy layer
- // flatten the layer hierarchy and makes the animation smooth.
- void StartSlowAnimation(
- std::unique_ptr<ScreenRotationRequest> rotation_request);
- // A wrapper to call |display_manager| to set screen rotation and rotate the
- // |old_layer_tree| to the |old_rotation|.
- void SetRotation(int64_t display_id,
- display::Display::Rotation old_rotation,
- display::Display::Rotation new_rotation,
- display::Display::RotationSource source);
- // This is an asynchronous call to request copy output of root layer.
- void RequestCopyScreenRotationContainerLayer(
- std::unique_ptr<viz::CopyOutputRequest> copy_output_request);
- // The callback in |RequestCopyScreenRotationContainerLayer()| before screen
- // rotation.
- void OnScreenRotationContainerLayerCopiedBeforeRotation(
- std::unique_ptr<ScreenRotationRequest> rotation_request,
- std::unique_ptr<viz::CopyOutputResult> result);
- // The callback in |RequestCopyScreenRotationContainerLayer()| after screen
- // rotation.
- void OnScreenRotationContainerLayerCopiedAfterRotation(
- std::unique_ptr<ScreenRotationRequest> rotation_request,
- std::unique_ptr<viz::CopyOutputResult> result);
- // Recreates all |root_window| layers and their layer tree owner.
- void CreateOldLayerTreeForSlowAnimation();
- // Creates a new layer and its layer tree owner from |CopyOutputResult|.
- std::unique_ptr<ui::LayerTreeOwner> CopyLayerTree(
- std::unique_ptr<viz::CopyOutputResult> result);
- // Note: Only call this function when the |old_layer_tree_owner_| is set up
- // properly.
- // Sets the screen orientation to |new_rotation| and animate the change. The
- // animation will rotate the initial orientation's layer towards the new
- // orientation through |rotation_degrees| while fading out, and the new
- // orientation's layer will be rotated in to the |new_orientation| through
- // |rotation_degrees| arc.
- void AnimateRotation(std::unique_ptr<ScreenRotationRequest> rotation_request);
- void NotifyAnimationFinished(bool canceled);
- void set_disable_animation_timers_for_test(bool disable_timers) {
- disable_animation_timers_for_test_ = disable_timers;
- }
- void StopAnimating();
- aura::Window* root_window_;
- // For current slow rotation animation, there are two states |ROTATING| and
- // |IDLE|. For the smooth rotation animation, we need to send copy request
- // and get copy result before animating.
- enum ScreenRotationState {
- COPY_REQUESTED,
- ROTATING,
- IDLE,
- };
- ScreenRotationState screen_rotation_state_;
- // Rotation request id, used to ignore copy request callback if we decide to
- // cancel the previous rotation request.
- int64_t rotation_request_id_;
- // Only set in unittest to disable animation timers.
- bool disable_animation_timers_for_test_;
- base::ObserverList<ScreenRotationAnimatorObserver>::Unchecked
- screen_rotation_animator_observers_;
- std::unique_ptr<ui::LayerTreeOwner> old_layer_tree_owner_;
- std::unique_ptr<ui::LayerTreeOwner> new_layer_tree_owner_;
- std::unique_ptr<ui::LayerTreeOwner> mask_layer_tree_owner_;
- std::unique_ptr<ScreenRotationRequest> last_pending_request_;
- absl::optional<ScreenRotationRequest> current_async_rotation_request_;
- display::Display::Rotation target_rotation_ = display::Display::ROTATE_0;
- std::unique_ptr<ui::ScopedAnimationDurationScaleMode> animation_scale_mode_;
- base::WeakPtrFactory<ScreenRotationAnimator> weak_factory_{this};
- };
- } // namespace ash
- #endif // ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
|