• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/renderer/input/input_handler_manager.h"
6 
7 #include "base/bind.h"
8 #include "base/debug/trace_event.h"
9 #include "base/message_loop/message_loop_proxy.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 
15 using blink::WebInputEvent;
16 
17 namespace content {
18 
19 namespace {
20 
InputEventDispositionToAck(InputHandlerProxy::EventDisposition disposition)21 InputEventAckState InputEventDispositionToAck(
22     InputHandlerProxy::EventDisposition disposition) {
23   switch (disposition) {
24     case InputHandlerProxy::DID_HANDLE:
25       return INPUT_EVENT_ACK_STATE_CONSUMED;
26     case InputHandlerProxy::DID_NOT_HANDLE:
27       return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
28     case InputHandlerProxy::DROP_EVENT:
29       return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
30   }
31   NOTREACHED();
32   return INPUT_EVENT_ACK_STATE_UNKNOWN;
33 }
34 
35 } // namespace
36 
InputHandlerManager(const scoped_refptr<base::MessageLoopProxy> & message_loop_proxy,InputHandlerManagerClient * client)37 InputHandlerManager::InputHandlerManager(
38     const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
39     InputHandlerManagerClient* client)
40     : message_loop_proxy_(message_loop_proxy),
41       client_(client) {
42   DCHECK(client_);
43   client_->SetBoundHandler(base::Bind(&InputHandlerManager::HandleInputEvent,
44                                       base::Unretained(this)));
45 }
46 
~InputHandlerManager()47 InputHandlerManager::~InputHandlerManager() {
48   client_->SetBoundHandler(InputHandlerManagerClient::Handler());
49 }
50 
AddInputHandler(int routing_id,const base::WeakPtr<cc::InputHandler> & input_handler,const base::WeakPtr<RenderViewImpl> & render_view_impl)51 void InputHandlerManager::AddInputHandler(
52     int routing_id,
53     const base::WeakPtr<cc::InputHandler>& input_handler,
54     const base::WeakPtr<RenderViewImpl>& render_view_impl) {
55   if (message_loop_proxy_->BelongsToCurrentThread()) {
56     AddInputHandlerOnCompositorThread(routing_id,
57                                       base::MessageLoopProxy::current(),
58                                       input_handler,
59                                       render_view_impl);
60   } else {
61     message_loop_proxy_->PostTask(
62         FROM_HERE,
63         base::Bind(&InputHandlerManager::AddInputHandlerOnCompositorThread,
64                    base::Unretained(this),
65                    routing_id,
66                    base::MessageLoopProxy::current(),
67                    input_handler,
68                    render_view_impl));
69   }
70 }
71 
AddInputHandlerOnCompositorThread(int routing_id,const scoped_refptr<base::MessageLoopProxy> & main_loop,const base::WeakPtr<cc::InputHandler> & input_handler,const base::WeakPtr<RenderViewImpl> & render_view_impl)72 void InputHandlerManager::AddInputHandlerOnCompositorThread(
73     int routing_id,
74     const scoped_refptr<base::MessageLoopProxy>& main_loop,
75     const base::WeakPtr<cc::InputHandler>& input_handler,
76     const base::WeakPtr<RenderViewImpl>& render_view_impl) {
77   DCHECK(message_loop_proxy_->BelongsToCurrentThread());
78 
79   // The handler could be gone by this point if the compositor has shut down.
80   if (!input_handler)
81     return;
82 
83   // The same handler may be registered for a route multiple times.
84   if (input_handlers_.count(routing_id) != 0)
85     return;
86 
87   TRACE_EVENT1("input",
88       "InputHandlerManager::AddInputHandlerOnCompositorThread",
89       "result", "AddingRoute");
90   client_->DidAddInputHandler(routing_id, input_handler.get());
91   input_handlers_.add(routing_id,
92       make_scoped_ptr(new InputHandlerWrapper(this,
93           routing_id, main_loop, input_handler, render_view_impl)));
94 }
95 
RemoveInputHandler(int routing_id)96 void InputHandlerManager::RemoveInputHandler(int routing_id) {
97   DCHECK(message_loop_proxy_->BelongsToCurrentThread());
98   DCHECK(input_handlers_.contains(routing_id));
99 
100   TRACE_EVENT0("input", "InputHandlerManager::RemoveInputHandler");
101 
102   client_->DidRemoveInputHandler(routing_id);
103   input_handlers_.erase(routing_id);
104 }
105 
HandleInputEvent(int routing_id,const WebInputEvent * input_event,ui::LatencyInfo * latency_info)106 InputEventAckState InputHandlerManager::HandleInputEvent(
107     int routing_id,
108     const WebInputEvent* input_event,
109     ui::LatencyInfo* latency_info) {
110   DCHECK(message_loop_proxy_->BelongsToCurrentThread());
111 
112   InputHandlerMap::iterator it = input_handlers_.find(routing_id);
113   if (it == input_handlers_.end()) {
114     TRACE_EVENT1("input", "InputHandlerManager::HandleInputEvent",
115                  "result", "NoInputHandlerFound");
116     // Oops, we no longer have an interested input handler..
117     return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
118   }
119 
120   InputHandlerProxy* proxy = it->second->input_handler_proxy();
121   return InputEventDispositionToAck(
122       proxy->HandleInputEventWithLatencyInfo(*input_event, latency_info));
123 }
124 
DidOverscroll(int routing_id,const DidOverscrollParams & params)125 void InputHandlerManager::DidOverscroll(int routing_id,
126                                         const DidOverscrollParams& params) {
127   client_->DidOverscroll(routing_id, params);
128 }
129 
DidStopFlinging(int routing_id)130 void InputHandlerManager::DidStopFlinging(int routing_id) {
131   client_->DidStopFlinging(routing_id);
132 }
133 
134 }  // namespace content
135