#ifndef ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
#define ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
#include <stdint.h>
#include <memory>
#include <optional>
#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 "ui/display/display.h"
namespace aura {
class Window;
}
namespace gfx {
class ScopedAnimationDurationScaleMode;
}
namespace ui {
class LayerTreeOwner;
}
namespace viz {
class CopyOutputRequest;
class CopyOutputResult;
}
namespace ash {
class ScreenRotationAnimatorObserver;
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();
void Rotate(display::Display::Rotation new_rotation,
display::Display::RotationSource source,
DisplayConfigurationController::RotationAnimation mode);
void AddObserver(ScreenRotationAnimatorObserver* observer);
void RemoveObserver(ScreenRotationAnimatorObserver* observer);
void ProcessAnimationQueue();
bool IsRotating() const;
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;
};
virtual CopyCallback CreateAfterCopyCallbackBeforeRotation(
std::unique_ptr<ScreenRotationRequest> rotation_request);
virtual CopyCallback CreateAfterCopyCallbackAfterRotation(
std::unique_ptr<ScreenRotationRequest> rotation_request);
private:
friend class ScreenRotationAnimatorTestApi;
void StartRotationAnimation(
std::unique_ptr<ScreenRotationRequest> rotation_request);
void StartSlowAnimation(
std::unique_ptr<ScreenRotationRequest> rotation_request);
void SetRotation(int64_t display_id,
display::Display::Rotation old_rotation,
display::Display::Rotation new_rotation,
display::Display::RotationSource source);
void RequestCopyScreenRotationContainerLayer(
std::unique_ptr<viz::CopyOutputRequest> copy_output_request);
void OnScreenRotationContainerLayerCopiedBeforeRotation(
std::unique_ptr<ScreenRotationRequest> rotation_request,
std::unique_ptr<viz::CopyOutputResult> result);
void OnScreenRotationContainerLayerCopiedAfterRotation(
std::unique_ptr<ScreenRotationRequest> rotation_request,
std::unique_ptr<viz::CopyOutputResult> result);
void CreateOldLayerTreeForSlowAnimation();
std::unique_ptr<ui::LayerTreeOwner> CopyLayerTree(
std::unique_ptr<viz::CopyOutputResult> result);
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_;
enum ScreenRotationState {
COPY_REQUESTED,
ROTATING,
IDLE,
};
ScreenRotationState screen_rotation_state_;
int64_t rotation_request_id_;
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_;
std::optional<ScreenRotationRequest> current_async_rotation_request_;
display::Display::Rotation target_rotation_ = display::Display::ROTATE_0;
std::unique_ptr<gfx::ScopedAnimationDurationScaleMode> animation_scale_mode_;
base::WeakPtrFactory<ScreenRotationAnimator> weak_factory_{this};
};
}
#endif