1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/input/input_handler_manager.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/trace_event/trace_event.h"
10 #include "cc/input/input_handler.h"
11 #include "content/renderer/input/input_event_filter.h"
12 #include "content/renderer/input/input_handler_manager_client.h"
13 #include "content/renderer/input/input_handler_wrapper.h"
14 #include "content/renderer/input/input_scroll_elasticity_controller.h"
15 #include "content/renderer/scheduler/renderer_scheduler.h"
17 using blink::WebInputEvent
;
23 InputEventAckState
InputEventDispositionToAck(
24 InputHandlerProxy::EventDisposition disposition
) {
25 switch (disposition
) {
26 case InputHandlerProxy::DID_HANDLE
:
27 return INPUT_EVENT_ACK_STATE_CONSUMED
;
28 case InputHandlerProxy::DID_NOT_HANDLE
:
29 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
30 case InputHandlerProxy::DROP_EVENT
:
31 return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
;
34 return INPUT_EVENT_ACK_STATE_UNKNOWN
;
39 InputHandlerManager::InputHandlerManager(
40 const scoped_refptr
<base::MessageLoopProxy
>& message_loop_proxy
,
41 InputHandlerManagerClient
* client
,
42 RendererScheduler
* renderer_scheduler
)
43 : message_loop_proxy_(message_loop_proxy
),
45 renderer_scheduler_(renderer_scheduler
) {
47 client_
->SetBoundHandler(base::Bind(&InputHandlerManager::HandleInputEvent
,
48 base::Unretained(this)));
51 InputHandlerManager::~InputHandlerManager() {
52 client_
->SetBoundHandler(InputHandlerManagerClient::Handler());
55 void InputHandlerManager::AddInputHandler(
57 const base::WeakPtr
<cc::InputHandler
>& input_handler
,
58 const base::WeakPtr
<RenderViewImpl
>& render_view_impl
) {
59 if (message_loop_proxy_
->BelongsToCurrentThread()) {
60 AddInputHandlerOnCompositorThread(routing_id
,
61 base::MessageLoopProxy::current(),
65 message_loop_proxy_
->PostTask(
67 base::Bind(&InputHandlerManager::AddInputHandlerOnCompositorThread
,
68 base::Unretained(this),
70 base::MessageLoopProxy::current(),
76 void InputHandlerManager::AddInputHandlerOnCompositorThread(
78 const scoped_refptr
<base::MessageLoopProxy
>& main_loop
,
79 const base::WeakPtr
<cc::InputHandler
>& input_handler
,
80 const base::WeakPtr
<RenderViewImpl
>& render_view_impl
) {
81 DCHECK(message_loop_proxy_
->BelongsToCurrentThread());
83 // The handler could be gone by this point if the compositor has shut down.
87 // The same handler may be registered for a route multiple times.
88 if (input_handlers_
.count(routing_id
) != 0)
92 "InputHandlerManager::AddInputHandlerOnCompositorThread",
93 "result", "AddingRoute");
94 client_
->DidAddInputHandler(routing_id
, input_handler
.get());
95 input_handlers_
.add(routing_id
,
96 make_scoped_ptr(new InputHandlerWrapper(this,
97 routing_id
, main_loop
, input_handler
, render_view_impl
)));
100 void InputHandlerManager::RemoveInputHandler(int routing_id
) {
101 DCHECK(message_loop_proxy_
->BelongsToCurrentThread());
102 DCHECK(input_handlers_
.contains(routing_id
));
104 TRACE_EVENT0("input", "InputHandlerManager::RemoveInputHandler");
106 client_
->DidRemoveInputHandler(routing_id
);
107 input_handlers_
.erase(routing_id
);
110 void InputHandlerManager::ObserveWheelEventAndResultOnMainThread(
112 const blink::WebMouseWheelEvent
& wheel_event
,
113 const cc::InputHandlerScrollResult
& scroll_result
) {
114 message_loop_proxy_
->PostTask(
117 &InputHandlerManager::ObserveWheelEventAndResultOnCompositorThread
,
118 base::Unretained(this), routing_id
, wheel_event
, scroll_result
));
121 void InputHandlerManager::ObserveWheelEventAndResultOnCompositorThread(
123 const blink::WebMouseWheelEvent
& wheel_event
,
124 const cc::InputHandlerScrollResult
& scroll_result
) {
125 auto it
= input_handlers_
.find(routing_id
);
126 if (it
== input_handlers_
.end())
129 InputHandlerProxy
* proxy
= it
->second
->input_handler_proxy();
130 DCHECK(proxy
->scroll_elasticity_controller());
131 proxy
->scroll_elasticity_controller()->ObserveWheelEventAndResult(
132 wheel_event
, scroll_result
);
135 InputEventAckState
InputHandlerManager::HandleInputEvent(
137 const WebInputEvent
* input_event
,
138 ui::LatencyInfo
* latency_info
) {
139 DCHECK(message_loop_proxy_
->BelongsToCurrentThread());
141 auto it
= input_handlers_
.find(routing_id
);
142 if (it
== input_handlers_
.end()) {
143 TRACE_EVENT1("input", "InputHandlerManager::HandleInputEvent",
144 "result", "NoInputHandlerFound");
145 // Oops, we no longer have an interested input handler..
146 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
149 InputHandlerProxy
* proxy
= it
->second
->input_handler_proxy();
150 return InputEventDispositionToAck(
151 proxy
->HandleInputEventWithLatencyInfo(*input_event
, latency_info
));
154 void InputHandlerManager::DidOverscroll(int routing_id
,
155 const DidOverscrollParams
& params
) {
156 client_
->DidOverscroll(routing_id
, params
);
159 void InputHandlerManager::DidStopFlinging(int routing_id
) {
160 client_
->DidStopFlinging(routing_id
);
163 void InputHandlerManager::DidReceiveInputEvent(
164 const blink::WebInputEvent
& web_input_event
) {
165 renderer_scheduler_
->DidReceiveInputEventOnCompositorThread(web_input_event
);
168 void InputHandlerManager::DidAnimateForInput() {
169 renderer_scheduler_
->DidAnimateForInputOnCompositorThread();
172 } // namespace content