// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_INPUT_INPUT_ROUTER_IMPL_H_
#define COMPONENTS_INPUT_INPUT_ROUTER_IMPL_H_

#include <stdint.h>

#include <memory>

#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/memory/advanced_memory_safety_checks.h"
#include "base/memory/raw_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "cc/input/touch_action.h"
#include "components/input/gesture_event_queue.h"
#include "components/input/input_event_stream_validator.h"
#include "components/input/input_router.h"
#include "components/input/input_router_client.h"
#include "components/input/mouse_wheel_event_queue.h"
#include "components/input/passthrough_touch_event_queue.h"
#include "components/input/touch_action_filter.h"
#include "components/input/touchpad_pinch_event_queue.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
#include "third_party/blink/public/mojom/input/input_handler.mojom.h"

namespace ui {
class LatencyInfo;
}  // namespace ui

namespace content {
class InputRouterImplTest;
class InputRouterImplTestBase;
class MockRenderWidgetHost;
class RenderWidgetHostSitePerProcessTest;
class SitePerProcessBrowserTouchActionTest;
} // namespace content

namespace input {

class InputDispositionHandler;

// A default implementation for browser input event routing.
class COMPONENT_EXPORT(INPUT) InputRouterImpl
    : public InputRouter,
      public GestureEventQueueClient,
      public FlingControllerEventSenderClient,
      public MouseWheelEventQueueClient,
      public PassthroughTouchEventQueueClient,
      public TouchpadPinchEventQueueClient,
      public TouchActionFilterClient,
      public blink::mojom::WidgetInputHandlerHost {
  // TODO(crbug.com/422044720): Remove this macro once the bug gets fixed.
  ADVANCED_MEMORY_SAFETY_CHECKS();

 public:
  InputRouterImpl(InputRouterClient* client,
                  InputDispositionHandler* disposition_handler,
                  FlingControllerSchedulerClient* fling_scheduler_client,
                  const Config& config);

  InputRouterImpl(const InputRouterImpl&) = delete;
  InputRouterImpl& operator=(const InputRouterImpl&) = delete;

  ~InputRouterImpl() override;

  // InputRouter
  bool IsActive() const override;
  void MakeActive() override;
  void MakeInactiveForTesting() override;
  void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event,
                      MouseEventCallback event_result_callback,
                      DispatchToRendererCallback& dispatch_callback) override;
  void SendWheelEvent(const MouseWheelEventWithLatencyInfo& wheel_event,
                      DispatchToRendererCallback& dispatch_callback) override;
  void SendKeyboardEvent(
      const NativeWebKeyboardEventWithLatencyInfo& key_event,
      KeyboardEventCallback event_result_callback,
      DispatchToRendererCallback& dispatch_callback) override;
  void SendGestureEvent(const GestureEventWithLatencyInfo& gesture_event,
                        DispatchToRendererCallback& dispatch_callback) override;
  void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event,
                      DispatchToRendererCallback& dispatch_callback) override;
  void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override;
  bool HasPendingEvents() const override;
  void SetDeviceScaleFactor(float device_scale_factor) override;
  void SetForceEnableZoom(bool enabled) override;
  std::optional<cc::TouchAction> AllowedTouchAction() override;
  std::optional<cc::TouchAction> ActiveTouchAction() override;
  mojo::PendingRemote<blink::mojom::WidgetInputHandlerHost> BindNewHost(
      scoped_refptr<base::SequencedTaskRunner> task_runner) override;
  void StopFling() override;
  void ForceSetTouchActionAuto() override;

  // InputHandlerHost impl
  void SetTouchActionFromMain(cc::TouchAction touch_action) override;
  void SetPanAction(blink::mojom::PanAction pan_action) override;
  void DidOverscroll(blink::mojom::DidOverscrollParamsPtr params) override;
  void ImeCancelComposition() override;
  void DidStartScrollingViewport() override;
  void ImeCompositionRangeChanged(
      const gfx::Range& range,
      const std::optional<std::vector<gfx::Rect>>& character_bounds) override;
  void SetMouseCapture(bool capture) override;
  void SetAutoscrollSelectionActiveInMainFrame(
      bool autoscroll_selection) override;
  void RequestMouseLock(bool from_user_gesture,
                        bool unadjusted_movement,
                        RequestMouseLockCallback response) override;
  // Notifies touch action filter and touch event queue whether there are
  // JavaScript touch event handlers or not, or whether the platform has
  // hit-testable scrollbars.
  void OnHasTouchEventConsumers(
      blink::mojom::TouchEventConsumersPtr consumers) override;
  void WaitForInputProcessed(base::OnceClosure callback) override;

  // Exposed so that tests can swap out the implementation and intercept calls.
  mojo::Receiver<blink::mojom::WidgetInputHandlerHost>&
  host_receiver_for_testing() {
    return host_receiver_;
  }

  void ForceResetTouchActionForTest();

  bool IsFlingActiveForTest();

  // TouchActionFilterClient
  void OnUnconfirmedTapConvertedToTap() override;

 private:
  friend class content::InputRouterImplTest;
  friend class content::InputRouterImplTestBase;
  friend class content::MockRenderWidgetHost;
  friend class content::RenderWidgetHostSitePerProcessTest;
  friend class content::SitePerProcessBrowserTouchActionTest;

  // Keeps track of last position of touch points and sets MovementXY for them.
  void SetMovementXYForTouchPoints(blink::WebTouchEvent* event);

  void SendMouseEventImmediately(const MouseEventWithLatencyInfo& mouse_event,
                                 MouseEventCallback event_result_callback,
                                 DispatchToRendererCallback& dispatch_callback);

  // PassthroughTouchEventQueueClient
  void SendTouchEventImmediately(
      const TouchEventWithLatencyInfo& touch_event,
      DispatchToRendererCallback& dispatch_callback) override;
  void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
                       blink::mojom::InputEventResultSource ack_source,
                       blink::mojom::InputEventResultState ack_result) override;
  void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override;
  void FlushDeferredGestureQueue() override;
  DispatchToRendererCallback GetDispatchToRendererCallback() override;

  // GestureEventFilterClient
  void SendGestureEventImmediately(
      const GestureEventWithLatencyInfo& gesture_event,
      DispatchToRendererCallback& dispatch_callback) override;
  void OnGestureEventAck(
      const GestureEventWithLatencyInfo& event,
      blink::mojom::InputEventResultSource ack_source,
      blink::mojom::InputEventResultState ack_result) override;

  // FlingControllerEventSenderClient
  void SendGeneratedWheelEvent(
      const MouseWheelEventWithLatencyInfo& wheel_event) override;
  void SendGeneratedGestureScrollEvents(
      const GestureEventWithLatencyInfo& gesture_event) override;
  gfx::Size GetRootWidgetViewportSize() override;

  // MouseWheelEventQueueClient
  void SendMouseWheelEventImmediately(
      const MouseWheelEventWithLatencyInfo& touch_event,
      MouseWheelEventQueueClient::MouseWheelEventHandledCallback callback,
      DispatchToRendererCallback& dispatch_callback) override;
  void OnMouseWheelEventAck(
      const MouseWheelEventWithLatencyInfo& event,
      blink::mojom::InputEventResultSource ack_source,
      blink::mojom::InputEventResultState ack_result) override;
  void ForwardGestureEventWithLatencyInfo(
      const blink::WebGestureEvent& gesture_event,
      const ui::LatencyInfo& latency_info) override;
  bool IsWheelScrollInProgress() override;
  bool IsAutoscrollInProgress() override;

  // TouchpadPinchEventQueueClient
  void SendMouseWheelEventForPinchImmediately(
      const blink::WebGestureEvent& pinch_event,
      const MouseWheelEventWithLatencyInfo& event,
      TouchpadPinchEventQueueClient::MouseWheelEventHandledCallback callback,
      DispatchToRendererCallback& dispatch_callback) override;
  void OnGestureEventForPinchAck(
      const GestureEventWithLatencyInfo& event,
      blink::mojom::InputEventResultSource ack_source,
      blink::mojom::InputEventResultState ack_result) override;

  bool HandleGestureScrollForStylusWriting(const blink::WebGestureEvent& event);

  void FilterAndSendWebInputEvent(
      const blink::WebInputEvent& input_event,
      const ui::LatencyInfo& latency_info,
      blink::mojom::WidgetInputHandler::DispatchEventCallback callback,
      DispatchToRendererCallback& dispatch_callback);

  void KeyboardEventHandled(
      const NativeWebKeyboardEventWithLatencyInfo& event,
      KeyboardEventCallback event_result_callback,
      blink::mojom::InputEventResultSource source,
      const ui::LatencyInfo& latency,
      blink::mojom::InputEventResultState state,
      blink::mojom::DidOverscrollParamsPtr overscroll,
      blink::mojom::TouchActionOptionalPtr touch_action);
  void MouseEventHandled(const MouseEventWithLatencyInfo& event,
                         MouseEventCallback event_result_callback,
                         blink::mojom::InputEventResultSource source,
                         const ui::LatencyInfo& latency,
                         blink::mojom::InputEventResultState state,
                         blink::mojom::DidOverscrollParamsPtr overscroll,
                         blink::mojom::TouchActionOptionalPtr touch_action);
  void TouchEventHandled(const TouchEventWithLatencyInfo& touch_event,
                         blink::mojom::InputEventResultSource source,
                         const ui::LatencyInfo& latency,
                         blink::mojom::InputEventResultState state,
                         blink::mojom::DidOverscrollParamsPtr overscroll,
                         blink::mojom::TouchActionOptionalPtr touch_action);
  void GestureEventHandled(
      const GestureEventWithLatencyInfo& gesture_event,
      blink::mojom::InputEventResultSource source,
      const ui::LatencyInfo& latency,
      blink::mojom::InputEventResultState state,
      blink::mojom::DidOverscrollParamsPtr overscroll,
      blink::mojom::TouchActionOptionalPtr touch_action);
  void MouseWheelEventHandled(
      const MouseWheelEventWithLatencyInfo& event,
      MouseWheelEventQueueClient::MouseWheelEventHandledCallback callback,
      blink::mojom::InputEventResultSource source,
      const ui::LatencyInfo& latency,
      blink::mojom::InputEventResultState state,
      blink::mojom::DidOverscrollParamsPtr overscroll,
      blink::mojom::TouchActionOptionalPtr touch_action);

  // Called when a touch timeout-affecting bit has changed, in turn toggling the
  // touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
  // to that determination includes current view properties and the allowed
  // touch action. Note that this will only affect platforms that have a
  // non-zero touch timeout configuration.
  void UpdateTouchAckTimeoutEnabled();

  void SendGestureEventWithoutQueueing(
      GestureEventWithLatencyInfo& gesture_event,
      const FilterGestureEventResult& existing_result,
      DispatchToRendererCallback& dispatch_callback);
  void ProcessDeferredGestureEventQueue();
  void OnSetCompositorAllowedTouchAction(cc::TouchAction touch_action);

  raw_ptr<InputRouterClient> client_;
  raw_ptr<InputDispositionHandler> disposition_handler_;

  // True if the router accepts input events.
  bool active_ = false;

  // Whether the TouchScrollStarted event has been sent for the current
  // gesture scroll yet.
  bool touch_scroll_started_sent_;

  // Whether stylus writing has started.
  bool stylus_writing_started_ = false;

  // Stores the pan action possible for element under hovering pointer. Ex:
  // stylus writing, moving cursor or scrolling. This is set from main thread.
  blink::mojom::PanAction pan_action_ = blink::mojom::PanAction::kNone;

  MouseWheelEventQueue wheel_event_queue_;
  PassthroughTouchEventQueue touch_event_queue_;
  TouchpadPinchEventQueue touchpad_pinch_event_queue_;
  GestureEventQueue gesture_event_queue_;
  TouchActionFilter touch_action_filter_;
  InputEventStreamValidator input_stream_validator_;
  InputEventStreamValidator output_stream_validator_;

  float device_scale_factor_;

  // Last touch position relative to screen. Used to compute movementX/Y.
  base::flat_map<int, gfx::Point> global_touch_position_;

  // The host receiver associated with the widget input handler from
  // the widget.
  mojo::Receiver<blink::mojom::WidgetInputHandlerHost> host_receiver_{this};

  // The last touch move event that was received. If the
  // kSendEmptyGestureScrollUpdate flag is enabled, `last_touch_move_event_` is
  // stored until a gesture scroll update event is received and the two are sent
  // to the renderer together. Otherwise, this is not used.
  std::optional<std::unique_ptr<blink::WebCoalescedInputEvent>>
      last_touch_move_event_;

  base::WeakPtr<InputRouterImpl> weak_this_;
  base::WeakPtrFactory<InputRouterImpl> weak_ptr_factory_{this};
};

}  // namespace input

#endif  // COMPONENTS_INPUT_INPUT_ROUTER_IMPL_H_
