#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_CONTROLLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_CONTROLLER_H_
#include <atomic>
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
#include "ui/events/blink/fling_booster.h"
namespace blink {
class WebGestureCurve;
}
namespace content {
class FlingController;
class CONTENT_EXPORT FlingControllerEventSenderClient {
public:
virtual ~FlingControllerEventSenderClient() {}
virtual void SendGeneratedWheelEvent(
const MouseWheelEventWithLatencyInfo& wheel_event) = 0;
virtual void SendGeneratedGestureScrollEvents(
const GestureEventWithLatencyInfo& gesture_event) = 0;
virtual gfx::Size GetRootWidgetViewportSize() = 0;
virtual void DynamicFrameLossEvent(const std::string& sceneId, bool isStart) = 0;
};
class CONTENT_EXPORT FlingControllerSchedulerClient {
public:
virtual ~FlingControllerSchedulerClient() {}
virtual void ScheduleFlingProgress(
base::WeakPtr<FlingController> fling_controller) = 0;
virtual void DidStopFlingingOnBrowser(
base::WeakPtr<FlingController> fling_controller) = 0;
virtual bool NeedsBeginFrameForFlingProgress() = 0;
};
class CONTENT_EXPORT FlingController {
public:
struct CONTENT_EXPORT Config {
Config();
TapSuppressionController::Config touchpad_tap_suppression_config;
TapSuppressionController::Config touchscreen_tap_suppression_config;
};
struct ActiveFlingParameters {
gfx::Vector2dF velocity;
gfx::PointF point;
gfx::PointF global_point;
int modifiers;
blink::WebGestureDevice source_device;
base::TimeTicks start_time;
ActiveFlingParameters() : modifiers(0) {}
};
FlingController(FlingControllerEventSenderClient* event_sender_client,
FlingControllerSchedulerClient* scheduler_client,
const Config& config);
FlingController(const FlingController&) = delete;
FlingController& operator=(const FlingController&) = delete;
~FlingController();
void ProgressFling(base::TimeTicks current_time);
void StopFling();
void DynamicFrameLossEvent(const std::string& sceneId, bool isStart);
bool ObserveAndMaybeConsumeGestureEvent(
const GestureEventWithLatencyInfo& gesture_event);
void ProcessGestureFlingStart(
const GestureEventWithLatencyInfo& gesture_event);
void ProcessGestureFlingCancel(
const GestureEventWithLatencyInfo& gesture_event);
bool fling_in_progress() const { return fling_curve_.get(); }
gfx::Vector2dF CurrentFlingVelocity() const;
TouchpadTapSuppressionController* GetTouchpadTapSuppressionController();
void set_clock_for_testing(const base::TickClock* clock) { clock_ = clock; }
void OnWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
blink::mojom::InputEventResultSource ack_source,
blink::mojom::InputEventResultState ack_result);
protected:
ui::FlingBooster fling_booster_;
private:
bool ObserveAndFilterForTapSuppression(
const GestureEventWithLatencyInfo& gesture_event);
void ScheduleFlingProgress();
void GenerateAndSendWheelEvents(base::TimeTicks current_time,
const gfx::Vector2dF& delta,
blink::WebMouseWheelEvent::Phase phase);
void GenerateAndSendGestureScrollEvents(
base::TimeTicks current_time,
blink::WebInputEvent::Type type,
const gfx::Vector2dF& delta = gfx::Vector2dF());
void GenerateAndSendFlingProgressEvents(base::TimeTicks current_time,
const gfx::Vector2dF& delta);
void GenerateAndSendFlingEndEvents(base::TimeTicks current_time);
void EndCurrentFling(base::TimeTicks current_time);
bool UpdateCurrentFlingState(const blink::WebGestureEvent& fling_start_event);
bool first_fling_update_sent() const {
return !last_progress_time_.is_null();
}
raw_ptr<FlingControllerEventSenderClient, DanglingUntriaged>
event_sender_client_;
raw_ptr<FlingControllerSchedulerClient> scheduler_client_;
TouchpadTapSuppressionController touchpad_tap_suppression_controller_;
TouchscreenTapSuppressionController touchscreen_tap_suppression_controller_;
std::unique_ptr<blink::WebGestureCurve> fling_curve_;
ActiveFlingParameters current_fling_parameters_;
base::TimeTicks last_progress_time_;
raw_ptr<const base::TickClock> clock_;
base::TimeTicks last_seen_scroll_update_;
bool last_wheel_event_consumed_ = false;
base::WeakPtrFactory<FlingController> weak_ptr_factory_{this};
static std::atomic<int> instance_count_;
};
}
#endif