Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / content / renderer / input / input_handler_manager.cc
blob3a298e36964709fcd2ce543932249c0555e4d862
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"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/trace_event/trace_event.h"
12 #include "cc/input/input_handler.h"
13 #include "components/scheduler/renderer/renderer_scheduler.h"
14 #include "content/renderer/input/input_event_filter.h"
15 #include "content/renderer/input/input_handler_manager_client.h"
16 #include "content/renderer/input/input_handler_wrapper.h"
17 #include "content/renderer/input/input_scroll_elasticity_controller.h"
19 using blink::WebInputEvent;
20 using scheduler::RendererScheduler;
22 namespace content {
24 namespace {
26 InputEventAckState InputEventDispositionToAck(
27 InputHandlerProxy::EventDisposition disposition) {
28 switch (disposition) {
29 case InputHandlerProxy::DID_HANDLE:
30 return INPUT_EVENT_ACK_STATE_CONSUMED;
31 case InputHandlerProxy::DID_NOT_HANDLE:
32 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
33 case InputHandlerProxy::DROP_EVENT:
34 return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
36 NOTREACHED();
37 return INPUT_EVENT_ACK_STATE_UNKNOWN;
40 } // namespace
42 InputHandlerManager::InputHandlerManager(
43 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
44 InputHandlerManagerClient* client,
45 scheduler::RendererScheduler* renderer_scheduler)
46 : task_runner_(task_runner),
47 client_(client),
48 renderer_scheduler_(renderer_scheduler) {
49 DCHECK(client_);
50 client_->SetBoundHandler(base::Bind(&InputHandlerManager::HandleInputEvent,
51 base::Unretained(this)));
54 InputHandlerManager::~InputHandlerManager() {
55 client_->SetBoundHandler(InputHandlerManagerClient::Handler());
58 void InputHandlerManager::AddInputHandler(
59 int routing_id,
60 const base::WeakPtr<cc::InputHandler>& input_handler,
61 const base::WeakPtr<RenderViewImpl>& render_view_impl) {
62 if (task_runner_->BelongsToCurrentThread()) {
63 AddInputHandlerOnCompositorThread(routing_id,
64 base::ThreadTaskRunnerHandle::Get(),
65 input_handler, render_view_impl);
66 } else {
67 task_runner_->PostTask(
68 FROM_HERE,
69 base::Bind(&InputHandlerManager::AddInputHandlerOnCompositorThread,
70 base::Unretained(this), routing_id,
71 base::ThreadTaskRunnerHandle::Get(), input_handler,
72 render_view_impl));
76 void InputHandlerManager::AddInputHandlerOnCompositorThread(
77 int routing_id,
78 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
79 const base::WeakPtr<cc::InputHandler>& input_handler,
80 const base::WeakPtr<RenderViewImpl>& render_view_impl) {
81 DCHECK(task_runner_->BelongsToCurrentThread());
83 // The handler could be gone by this point if the compositor has shut down.
84 if (!input_handler)
85 return;
87 // The same handler may be registered for a route multiple times.
88 if (input_handlers_.count(routing_id) != 0)
89 return;
91 TRACE_EVENT1("input",
92 "InputHandlerManager::AddInputHandlerOnCompositorThread",
93 "result", "AddingRoute");
94 scoped_ptr<InputHandlerWrapper> wrapper(new InputHandlerWrapper(
95 this, routing_id, main_task_runner, input_handler, render_view_impl));
96 client_->DidAddInputHandler(routing_id, input_handler.get(),
97 wrapper->input_handler_proxy());
98 input_handlers_.add(routing_id, wrapper.Pass());
101 void InputHandlerManager::RemoveInputHandler(int routing_id) {
102 DCHECK(task_runner_->BelongsToCurrentThread());
103 DCHECK(input_handlers_.contains(routing_id));
105 TRACE_EVENT0("input", "InputHandlerManager::RemoveInputHandler");
107 client_->DidRemoveInputHandler(routing_id);
108 input_handlers_.erase(routing_id);
111 void InputHandlerManager::ObserveWheelEventAndResultOnMainThread(
112 int routing_id,
113 const blink::WebMouseWheelEvent& wheel_event,
114 const cc::InputHandlerScrollResult& scroll_result) {
115 task_runner_->PostTask(
116 FROM_HERE,
117 base::Bind(
118 &InputHandlerManager::ObserveWheelEventAndResultOnCompositorThread,
119 base::Unretained(this), routing_id, wheel_event, scroll_result));
122 void InputHandlerManager::ObserveWheelEventAndResultOnCompositorThread(
123 int routing_id,
124 const blink::WebMouseWheelEvent& wheel_event,
125 const cc::InputHandlerScrollResult& scroll_result) {
126 auto it = input_handlers_.find(routing_id);
127 if (it == input_handlers_.end())
128 return;
130 InputHandlerProxy* proxy = it->second->input_handler_proxy();
131 DCHECK(proxy->scroll_elasticity_controller());
132 proxy->scroll_elasticity_controller()->ObserveWheelEventAndResult(
133 wheel_event, scroll_result);
136 InputEventAckState InputHandlerManager::HandleInputEvent(
137 int routing_id,
138 const WebInputEvent* input_event,
139 ui::LatencyInfo* latency_info) {
140 DCHECK(task_runner_->BelongsToCurrentThread());
142 auto it = input_handlers_.find(routing_id);
143 if (it == input_handlers_.end()) {
144 TRACE_EVENT1("input", "InputHandlerManager::HandleInputEvent",
145 "result", "NoInputHandlerFound");
146 // Oops, we no longer have an interested input handler..
147 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
150 InputHandlerProxy* proxy = it->second->input_handler_proxy();
151 InputEventAckState input_event_ack_state = InputEventDispositionToAck(
152 proxy->HandleInputEventWithLatencyInfo(*input_event, latency_info));
153 switch (input_event_ack_state) {
154 case INPUT_EVENT_ACK_STATE_CONSUMED:
155 renderer_scheduler_->DidHandleInputEventOnCompositorThread(
156 *input_event,
157 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
158 break;
159 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
160 renderer_scheduler_->DidHandleInputEventOnCompositorThread(
161 *input_event,
162 RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
163 break;
164 default:
165 break;
167 return input_event_ack_state;
170 void InputHandlerManager::DidOverscroll(int routing_id,
171 const DidOverscrollParams& params) {
172 client_->DidOverscroll(routing_id, params);
175 void InputHandlerManager::DidStopFlinging(int routing_id) {
176 client_->DidStopFlinging(routing_id);
179 void InputHandlerManager::DidAnimateForInput() {
180 renderer_scheduler_->DidAnimateForInputOnCompositorThread();
183 } // namespace content