blob: be84b53d598f371689a9963d7ce4d81c3f759369 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_LEGACY_INPUT_ROUTER_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_LEGACY_INPUT_ROUTER_IMPL_H_
#include <stdint.h>
#include <map>
#include <memory>
#include "base/containers/circular_deque.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "cc/input/touch_action.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/input_router.h"
#include "content/browser/renderer_host/input/mouse_wheel_event_queue.h"
#include "content/browser/renderer_host/input/touch_action_filter.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
#include "content/common/input/input_event_dispatch_type.h"
#include "content/common/input/input_event_stream_validator.h"
#include "content/public/browser/native_web_keyboard_event.h"
namespace IPC {
class Sender;
}
namespace ui {
class LatencyInfo;
struct DidOverscrollParams;
}
namespace content {
class InputDispositionHandler;
class InputRouterClient;
struct InputEventAck;
// An implementation for browser input event routing based on
// Chrome IPC. This class is named "legacy" because it is largely tied to
// Chrome IPC which is deprecated. This class will be replaced with a Mojo
// backed transport. See crbug.com/722928.
class CONTENT_EXPORT LegacyInputRouterImpl
: public InputRouter,
public GestureEventQueueClient,
public MouseWheelEventQueueClient,
public TouchEventQueueClient,
public TouchpadTapSuppressionControllerClient {
public:
LegacyInputRouterImpl(IPC::Sender* sender,
InputRouterClient* client,
InputDispositionHandler* disposition_handler,
int routing_id,
const Config& config);
~LegacyInputRouterImpl() override;
bool SendInput(std::unique_ptr<IPC::Message> message);
// InputRouter
void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override;
void SendWheelEvent(
const MouseWheelEventWithLatencyInfo& wheel_event) override;
void SendKeyboardEvent(
const NativeWebKeyboardEventWithLatencyInfo& key_event) override;
void SendGestureEvent(
const GestureEventWithLatencyInfo& gesture_event) override;
void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override;
void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override;
bool HasPendingEvents() const override;
void SetDeviceScaleFactor(float device_scale_factor) override;
void BindHost(mojom::WidgetInputHandlerHostRequest request,
bool frame_handler) override;
// IPC::Listener
bool OnMessageReceived(const IPC::Message& message) override;
void SetFrameTreeNodeId(int frameTreeNodeId) override;
cc::TouchAction AllowedTouchAction() override;
void SetForceEnableZoom(bool enabled) override;
int routing_id() const { return routing_id_; }
private:
friend class LegacyInputRouterImplTest;
FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
SubframeTouchEventRouting);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
MainframeTouchEventRouting);
// Keeps track of last position of touch points and sets MovementXY for them.
void SetMovementXYForTouchPoints(blink::WebTouchEvent* event);
// TouchpadTapSuppressionControllerClient
void SendMouseEventImmediately(
const MouseEventWithLatencyInfo& mouse_event) override;
// TouchEventQueueClient
void SendTouchEventImmediately(
const TouchEventWithLatencyInfo& touch_event) override;
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override;
// GestureEventFilterClient
void SendGestureEventImmediately(
const GestureEventWithLatencyInfo& gesture_event) override;
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
InputEventAckSource ack_source,
InputEventAckState ack_result) override;
// MouseWheelEventQueueClient
void SendMouseWheelEventImmediately(
const MouseWheelEventWithLatencyInfo& touch_event) override;
void OnMouseWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void ForwardGestureEventWithLatencyInfo(
const blink::WebGestureEvent& gesture_event,
const ui::LatencyInfo& latency_info) override;
bool SendMoveCaret(std::unique_ptr<IPC::Message> message);
bool SendSelectMessage(std::unique_ptr<IPC::Message> message);
bool Send(IPC::Message* message);
// Filters and forwards |input_event| to the appropriate handler.
void FilterAndSendWebInputEvent(const blink::WebInputEvent& input_event,
const ui::LatencyInfo& latency_info);
// Utility routine for filtering and forwarding |input_event| to the
// appropriate handler. |input_event| will be offered to the overscroll
// controller, client and renderer, in that order.
void OfferToHandlers(const blink::WebInputEvent& input_event,
const ui::LatencyInfo& latency_info);
// Returns true if |input_event| was consumed by the client.
bool OfferToClient(const blink::WebInputEvent& input_event,
const ui::LatencyInfo& latency_info);
// Returns true if |input_event| was successfully sent to the renderer
// as an async IPC Message.
bool OfferToRenderer(const blink::WebInputEvent& input_event,
const ui::LatencyInfo& latency_info,
InputEventDispatchType dispatch_type);
// IPC message handlers
void OnInputEventAck(const InputEventAck& ack);
void OnDidOverscroll(const ui::DidOverscrollParams& params);
void OnMsgMoveCaretAck();
void OnSelectMessageAck();
void OnHasTouchEventHandlers(bool has_handlers);
void OnSetTouchAction(cc::TouchAction touch_action);
void OnSetWhiteListedTouchAction(cc::TouchAction white_listed_touch_action,
uint32_t unique_touch_event_id,
InputEventAckState ack_result);
void OnDidStopFlinging();
// Note: This function may result in |this| being deleted, and as such
// should be the last method called in any internal chain of event handling.
void ProcessInputEventAck(blink::WebInputEvent::Type event_type,
InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
uint32_t unique_touch_event_id);
// Dispatches the ack'ed event to |ack_handler_|.
void ProcessKeyboardAck(blink::WebInputEvent::Type type,
InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Forwards a valid |next_mouse_move_| if |type| is MouseMove.
void ProcessMouseAck(blink::WebInputEvent::Type type,
InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Dispatches the ack'ed event to |ack_handler_|, forwarding queued events
// from |coalesced_mouse_wheel_events_|.
void ProcessWheelAck(InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Forwards the event ack to |gesture_event_queue|, potentially triggering
// dispatch of queued gesture events.
void ProcessGestureAck(blink::WebInputEvent::Type type,
InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Forwards the event ack to |touch_event_queue_|, potentially triggering
// dispatch of queued touch events, or the creation of gesture events.
void ProcessTouchAck(InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency,
uint32_t unique_touch_event_id);
// 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();
IPC::Sender* sender_;
InputRouterClient* client_;
InputDispositionHandler* disposition_handler_;
int routing_id_;
int frame_tree_node_id_;
// (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK
// or MoveRangeSelectionExtent_ACK.
bool select_message_pending_;
// Queue of pending select messages to send after receiving the next select
// message ack.
base::circular_deque<std::unique_ptr<IPC::Message>> pending_select_messages_;
// True while waiting for MoveCaret_ACK.
bool move_caret_pending_;
// The next MoveCaret to send, if any.
std::unique_ptr<IPC::Message> next_move_caret_;
// A queue of the mouse move events sent to the renderer. Similar
// to |key_queue_|.
using MouseEventQueue = base::circular_deque<MouseEventWithLatencyInfo>;
MouseEventQueue mouse_event_queue_;
// A queue of keyboard events. We can't trust data from the renderer so we
// stuff key events into a queue and pop them out on ACK, feeding our copy
// back to whatever unhandled handler instead of the returned version.
using KeyQueue = base::circular_deque<NativeWebKeyboardEventWithLatencyInfo>;
KeyQueue key_queue_;
// Whether there are any active flings in the renderer. As the fling
// end notification is asynchronous, we use a count rather than a boolean
// to avoid races in bookkeeping when starting a new fling.
int active_renderer_fling_count_;
// Whether the TouchScrollStarted event has been sent for the current
// gesture scroll yet.
bool touch_scroll_started_sent_;
bool wheel_scroll_latching_enabled_;
MouseWheelEventQueue wheel_event_queue_;
std::unique_ptr<TouchEventQueue> touch_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.
std::map<int, gfx::Point> global_touch_position_;
DISALLOW_COPY_AND_ASSIGN(LegacyInputRouterImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_LEGACY_INPUT_ROUTER_IMPL_H_