#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "content/browser/devtools/protocol/input_handler.h"
#include <stddef.h>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "base/types/expected.h"
#include "components/input/render_widget_host_input_event_router.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/protocol/native_input_event_builder.h"
#include "content/browser/devtools/protocol/protocol.h"
#include "content/browser/renderer_host/data_transfer_util.h"
#include "content/browser/renderer_host/input/touch_emulator_impl.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_pinch_gesture.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
#include "content/common/input/synthetic_pointer_action.h"
#include "content/common/input/synthetic_pointer_driver.h"
#include "content/common/input/synthetic_smooth_scroll_gesture.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input/synthetic_tap_gesture.h"
#include "content/common/input/synthetic_tap_gesture_params.h"
#include "content/public/common/content_features.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/range/range.h"
namespace content::protocol {
namespace {
gfx::PointF CssPixelsToPointF(double x, double y, float scale_factor) { … }
gfx::Vector2dF CssPixelsToVector2dF(double x, double y, float scale_factor) { … }
bool StringToGestureSourceType(Maybe<std::string> in,
content::mojom::GestureSourceType& out) { … }
int GetEventModifiers(int modifiers,
bool auto_repeat,
bool is_keypad,
int location,
int buttons) { … }
base::TimeTicks GetEventTimeTicks(const Maybe<double>& timestamp) { … }
bool SetKeyboardEventText(
base::span<char16_t, blink::WebKeyboardEvent::kTextLengthCap> to,
Maybe<std::string> from) { … }
bool GetMouseEventButton(const std::string& button,
blink::WebPointerProperties::Button* event_button,
int* event_modifiers) { … }
blink::WebInputEvent::Type GetMouseEventType(const std::string& type) { … }
blink::WebInputEvent::Type GetTouchEventType(const std::string& type) { … }
blink::WebPointerProperties::PointerType GetPointerType(
const std::string& type) { … }
SyntheticPointerActionParams::PointerActionType GetTouchPointerActionType(
const std::string& type) { … }
bool GenerateTouchPoints(
blink::WebTouchEvent* event,
blink::WebInputEvent::Type type,
const base::flat_map<int, blink::WebTouchPoint>& points,
const blink::WebTouchPoint& changing) { … }
std::string ValidatePointerEventProperties(double force,
double tangential_pressure,
double tilt_x,
double tilt_y,
int twist) { … }
void SendSynthesizePinchGestureResponse(
std::unique_ptr<Input::Backend::SynthesizePinchGestureCallback> callback,
SyntheticGesture::Result result) { … }
class TapGestureResponse { … };
void SendSynthesizeScrollGestureResponse(
std::unique_ptr<Input::Backend::SynthesizeScrollGestureCallback> callback,
SyntheticGesture::Result result) { … }
void DispatchPointerActionsResponse(
std::unique_ptr<Input::Backend::DispatchTouchEventCallback> callback,
SyntheticGesture::Result result) { … }
DropData ProtocolDragDataToDropData(std::unique_ptr<Input::DragData> data) { … }
base::expected<std::unique_ptr<blink::WebMouseEvent>, protocol::Response>
CreateWebMouseEvent(const std::string& event_type,
double x,
double y,
float scale_factor,
Maybe<int> modifiers,
Maybe<double> timestamp,
Maybe<std::string> button,
Maybe<int> buttons,
Maybe<int> click_count,
Maybe<double> force,
Maybe<double> tangential_pressure,
Maybe<double> tilt_x,
Maybe<double> tilt_y,
Maybe<int> twist,
Maybe<double> delta_x,
Maybe<double> delta_y,
Maybe<std::string> pointer_type) { … }
base::expected<std::vector<blink::WebTouchEvent>, protocol::Response>
CreateWebTouchEvents(
const std::string& event_type,
Maybe<int> modifiers,
Maybe<double> timestamp,
float scale_factor,
base::flat_map<blink::PointerId, blink::WebTouchPoint>& touched_points,
std::unique_ptr<Array<Input::TouchPoint>> touch_points) { … }
}
template <class BackendCallback>
class FailSafe { … };
class InputHandler::InputInjector
: public RenderWidgetHost::InputEventObserver { … };
struct InputHandler::DragController::DragState { … };
struct InputHandler::DragController::InitialState { … };
InputHandler::DragController::DragController(InputHandler& handler)
: … { … }
InputHandler::DragController::~DragController() = default;
bool InputHandler::DragController::HandleMouseEvent(
RenderWidgetHostImpl& host,
const blink::WebMouseEvent& event,
std::unique_ptr<DispatchMouseEventCallback>& callback) { … }
void InputHandler::DragController::EnsureDraggingEntered(
RenderWidgetHostImpl& host,
const blink::WebMouseEvent& event) { … }
void InputHandler::DragController::StartDragging(
const content::DropData& drop_data,
blink::DragOperationsMask drag_operations_mask) { … }
void InputHandler::DragController::CancelDragging(base::OnceClosure callback) { … }
void InputHandler::DragController::UpdateDragging(
RenderWidgetHostImpl& host,
std::unique_ptr<blink::WebMouseEvent> event,
std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback) { … }
void InputHandler::DragController::DragUpdated(
std::unique_ptr<blink::WebMouseEvent> event,
std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback,
ui::mojom::DragOperation operation,
bool document_is_handling_drag) { … }
void InputHandler::DragController::EndDragging(
RenderWidgetHostImpl* host_hint,
std::unique_ptr<blink::WebMouseEvent> event,
std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback) { … }
void InputHandler::DragController::EndDraggingWithRenderWidgetHostAtPoint(
std::unique_ptr<blink::WebMouseEvent> event,
std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback,
base::WeakPtr<RenderWidgetHostViewBase> view,
std::optional<gfx::PointF> maybe_point) { … }
InputHandler::InputHandler(bool allow_file_access,
bool allow_sending_input_to_browser)
: … { … }
InputHandler::~InputHandler() = default;
std::vector<InputHandler*> InputHandler::ForAgentHost(
DevToolsAgentHostImpl* host) { … }
void InputHandler::SetRenderer(int process_host_id,
RenderFrameHostImpl* frame_host) { … }
void InputHandler::Wire(UberDispatcher* dispatcher) { … }
Response InputHandler::Disable() { … }
void InputHandler::DispatchKeyEvent(
const std::string& type,
Maybe<int> modifiers,
Maybe<double> timestamp,
Maybe<std::string> text,
Maybe<std::string> unmodified_text,
Maybe<std::string> key_identifier,
Maybe<std::string> code,
Maybe<std::string> key,
Maybe<int> windows_virtual_key_code,
Maybe<int> native_virtual_key_code,
Maybe<bool> auto_repeat,
Maybe<bool> is_keypad,
Maybe<bool> is_system_key,
Maybe<int> location,
Maybe<Array<std::string>> commands,
std::unique_ptr<DispatchKeyEventCallback> callback) { … }
void InputHandler::InsertText(const std::string& text,
std::unique_ptr<InsertTextCallback> callback) { … }
void InputHandler::ImeSetComposition(
const std::string& text,
int selection_start,
int selection_end,
Maybe<int> replacement_start,
Maybe<int> replacement_end,
std::unique_ptr<ImeSetCompositionCallback> callback) { … }
void InputHandler::DispatchMouseEvent(
const std::string& event_type,
double x,
double y,
Maybe<int> modifiers,
Maybe<double> timestamp,
Maybe<std::string> button,
Maybe<int> buttons,
Maybe<int> click_count,
Maybe<double> force,
Maybe<double> tangential_pressure,
Maybe<double> tilt_x,
Maybe<double> tilt_y,
Maybe<int> twist,
Maybe<double> delta_x,
Maybe<double> delta_y,
Maybe<std::string> pointer_type,
std::unique_ptr<DispatchMouseEventCallback> callback) { … }
void InputHandler::HandleMouseEvent(
std::unique_ptr<blink::WebMouseEvent> event,
std::unique_ptr<DispatchMouseEventCallback> callback) { … }
void InputHandler::DispatchDragEvent(
const std::string& event_type,
double x,
double y,
std::unique_ptr<Input::DragData> data,
Maybe<int> modifiers,
std::unique_ptr<DispatchDragEventCallback> callback) { … }
void InputHandler::OnWidgetForDispatchDragEvent(
const std::string& event_type,
double x,
double y,
std::unique_ptr<Input::DragData> data,
Maybe<int> modifiers,
std::unique_ptr<DispatchDragEventCallback> callback,
base::WeakPtr<RenderWidgetHostViewBase> target,
std::optional<gfx::PointF> maybe_point) { … }
float InputHandler::ScaleFactor() { … }
void InputHandler::StartDragging(const content::DropData& drop_data,
const blink::mojom::DragData& drag_data,
blink::DragOperationsMask drag_operations_mask,
bool* intercepted) { … }
void InputHandler::DragEnded() { … }
Response InputHandler::SetInterceptDrags(bool enabled) { … }
void InputHandler::OnWidgetForDispatchMouseEvent(
std::unique_ptr<DispatchMouseEventCallback> callback,
std::unique_ptr<blink::WebMouseEvent> event,
base::WeakPtr<RenderWidgetHostViewBase> target,
std::optional<gfx::PointF> point) { … }
void InputHandler::DispatchTouchEvent(
const std::string& event_type,
std::unique_ptr<Array<Input::TouchPoint>> touch_points,
protocol::Maybe<int> modifiers,
protocol::Maybe<double> timestamp,
std::unique_ptr<DispatchTouchEventCallback> callback) { … }
void InputHandler::CancelDragging(
std::unique_ptr<CancelDraggingCallback> callback) { … }
void InputHandler::DispatchWebTouchEvent(
const std::string& event_type,
std::unique_ptr<Array<Input::TouchPoint>> touch_points,
protocol::Maybe<int> modifiers,
protocol::Maybe<double> timestamp,
std::unique_ptr<DispatchTouchEventCallback> callback) { … }
void InputHandler::OnWidgetForDispatchWebTouchEvent(
std::unique_ptr<DispatchTouchEventCallback> callback,
std::vector<blink::WebTouchEvent> events,
base::WeakPtr<RenderWidgetHostViewBase> target,
std::optional<gfx::PointF> transformed) { … }
void InputHandler::DispatchSyntheticPointerActionTouch(
const std::string& event_type,
std::unique_ptr<Array<Input::TouchPoint>> touch_points,
protocol::Maybe<int> modifiers,
protocol::Maybe<double> timestamp,
std::unique_ptr<DispatchTouchEventCallback> callback) { … }
SyntheticPointerActionParams InputHandler::PrepareSyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType pointer_action_type,
int id,
double x,
double y,
int key_modifiers,
float radius_x,
float radius_y,
float rotation_angle,
float force) { … }
Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type,
int x,
int y,
const std::string& button,
Maybe<double> timestamp,
Maybe<double> delta_x,
Maybe<double> delta_y,
Maybe<int> modifiers,
Maybe<int> click_count) { … }
Response InputHandler::SetIgnoreInputEvents(bool ignore) { … }
void InputHandler::SynthesizePinchGesture(
double x,
double y,
double scale_factor,
Maybe<int> relative_speed,
Maybe<std::string> gesture_source_type,
std::unique_ptr<SynthesizePinchGestureCallback> callback) { … }
void InputHandler::SynthesizeScrollGesture(
double x,
double y,
Maybe<double> x_distance,
Maybe<double> y_distance,
Maybe<double> x_overscroll,
Maybe<double> y_overscroll,
Maybe<bool> prevent_fling,
Maybe<int> speed,
Maybe<std::string> gesture_source_type,
Maybe<int> repeat_count,
Maybe<int> repeat_delay_ms,
Maybe<std::string> interaction_marker_name,
std::unique_ptr<SynthesizeScrollGestureCallback> callback) { … }
void InputHandler::SynthesizeRepeatingScroll(
SyntheticSmoothScrollGestureParams gesture_params,
int repeat_count,
base::TimeDelta repeat_delay,
std::string interaction_marker_name,
int id,
std::unique_ptr<SynthesizeScrollGestureCallback> callback) { … }
void InputHandler::OnScrollFinished(
SyntheticSmoothScrollGestureParams gesture_params,
int repeat_count,
base::TimeDelta repeat_delay,
std::string interaction_marker_name,
int id,
std::unique_ptr<SynthesizeScrollGestureCallback> callback,
SyntheticGesture::Result result) { … }
void InputHandler::SynthesizeTapGesture(
double x,
double y,
Maybe<int> duration,
Maybe<int> tap_count,
Maybe<std::string> gesture_source_type,
std::unique_ptr<SynthesizeTapGestureCallback> callback) { … }
void InputHandler::ClearInputState() { … }
bool InputHandler::PointIsWithinContents(gfx::PointF point) const { … }
InputHandler::InputInjector* InputHandler::EnsureInjector(
RenderWidgetHostImpl* widget_host) { … }
RenderWidgetHostViewBase* InputHandler::GetRootView() { … }
}