1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
// Copyright 2015 The Chromium Authors
// 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/functional/callback_forward.h"
#include "base/memory/raw_ptr.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;
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();
raw_ptr<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_
|