OLD | NEW |
| (Empty) |
1 // Copyright 2015 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/mus/compositor_mus_connection.h" | |
6 | |
7 #include "base/memory/ptr_util.h" | |
8 #include "base/single_thread_task_runner.h" | |
9 #include "content/renderer/input/input_handler_manager.h" | |
10 #include "content/renderer/mus/render_widget_mus_connection.h" | |
11 #include "ui/events/blink/blink_event_util.h" | |
12 #include "ui/events/blink/web_input_event.h" | |
13 #include "ui/events/blink/web_input_event_traits.h" | |
14 #include "ui/events/latency_info.h" | |
15 #include "ui/events/mojo/event.mojom.h" | |
16 | |
17 using ui::mojom::EventResult; | |
18 | |
19 namespace { | |
20 | |
21 void DoNothingWithEventResult(EventResult result) {} | |
22 | |
23 gfx::Point GetScreenLocationFromEvent(const ui::LocatedEvent& event) { | |
24 return event.root_location(); | |
25 } | |
26 | |
27 } // namespace | |
28 | |
29 namespace content { | |
30 | |
31 CompositorMusConnection::CompositorMusConnection( | |
32 int routing_id, | |
33 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, | |
34 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, | |
35 mojo::InterfaceRequest<ui::mojom::WindowTreeClient> request, | |
36 InputHandlerManager* input_handler_manager) | |
37 : routing_id_(routing_id), | |
38 root_(nullptr), | |
39 main_task_runner_(main_task_runner), | |
40 compositor_task_runner_(compositor_task_runner), | |
41 input_handler_manager_(input_handler_manager) { | |
42 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
43 compositor_task_runner_->PostTask( | |
44 FROM_HERE, base::Bind(&CompositorMusConnection:: | |
45 CreateWindowTreeClientOnCompositorThread, | |
46 this, base::Passed(std::move(request)))); | |
47 } | |
48 | |
49 void CompositorMusConnection::AttachCompositorFrameSinkOnMainThread( | |
50 std::unique_ptr<ui::WindowCompositorFrameSinkBinding> | |
51 compositor_frame_sink_binding) { | |
52 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
53 compositor_task_runner_->PostTask( | |
54 FROM_HERE, | |
55 base::Bind( | |
56 &CompositorMusConnection::AttachCompositorFrameSinkOnCompositorThread, | |
57 this, base::Passed(std::move(compositor_frame_sink_binding)))); | |
58 } | |
59 | |
60 CompositorMusConnection::~CompositorMusConnection() { | |
61 base::AutoLock auto_lock(window_tree_client_lock_); | |
62 // Destruction must happen on the compositor task runner. | |
63 DCHECK(!window_tree_client_); | |
64 } | |
65 | |
66 void CompositorMusConnection::AttachCompositorFrameSinkOnCompositorThread( | |
67 std::unique_ptr<ui::WindowCompositorFrameSinkBinding> | |
68 compositor_frame_sink_binding) { | |
69 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | |
70 window_compositor_frame_sink_binding_ = | |
71 std::move(compositor_frame_sink_binding); | |
72 if (root_) { | |
73 root_->AttachCompositorFrameSink( | |
74 std::move(window_compositor_frame_sink_binding_)); | |
75 } | |
76 } | |
77 | |
78 void CompositorMusConnection::CreateWindowTreeClientOnCompositorThread( | |
79 mojo::InterfaceRequest<ui::mojom::WindowTreeClient> request) { | |
80 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | |
81 DCHECK(!window_tree_client_); | |
82 std::unique_ptr<ui::WindowTreeClient> window_tree_client = | |
83 base::MakeUnique<ui::WindowTreeClient>(this, nullptr, std::move(request)); | |
84 base::AutoLock auto_lock(window_tree_client_lock_); | |
85 window_tree_client_ = std::move(window_tree_client); | |
86 } | |
87 | |
88 void CompositorMusConnection::OnConnectionLostOnMainThread() { | |
89 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
90 RenderWidgetMusConnection* connection = | |
91 RenderWidgetMusConnection::Get(routing_id_); | |
92 if (!connection) | |
93 return; | |
94 connection->OnConnectionLost(); | |
95 } | |
96 | |
97 void CompositorMusConnection::OnWindowInputEventOnMainThread( | |
98 blink::WebScopedInputEvent web_event, | |
99 const base::Callback<void(EventResult)>& ack) { | |
100 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
101 RenderWidgetMusConnection* connection = | |
102 RenderWidgetMusConnection::Get(routing_id_); | |
103 if (!connection) { | |
104 ack.Run(EventResult::UNHANDLED); | |
105 return; | |
106 } | |
107 connection->OnWindowInputEvent(std::move(web_event), ack); | |
108 } | |
109 | |
110 void CompositorMusConnection::OnWindowInputEventAckOnMainThread( | |
111 const base::Callback<void(EventResult)>& ack, | |
112 EventResult result) { | |
113 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
114 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(ack, result)); | |
115 } | |
116 | |
117 std::unique_ptr<blink::WebInputEvent> CompositorMusConnection::Convert( | |
118 const ui::Event& event) { | |
119 if (event.IsMousePointerEvent()) { | |
120 const ui::MouseEvent mouse_event(*event.AsPointerEvent()); | |
121 blink::WebMouseEvent blink_event = ui::MakeWebMouseEvent( | |
122 mouse_event, base::Bind(&GetScreenLocationFromEvent)); | |
123 return base::MakeUnique<blink::WebMouseEvent>(blink_event); | |
124 } else if (event.IsTouchPointerEvent()) { | |
125 ui::TouchEvent touch_event(*event.AsPointerEvent()); | |
126 pointer_state_.OnTouch(touch_event); | |
127 blink::WebTouchEvent blink_event = ui::CreateWebTouchEventFromMotionEvent( | |
128 pointer_state_, touch_event.may_cause_scrolling()); | |
129 pointer_state_.CleanupRemovedTouchPoints(touch_event); | |
130 return base::MakeUnique<blink::WebTouchEvent>(blink_event); | |
131 } else if (event.IsMouseWheelEvent()) { | |
132 blink::WebMouseWheelEvent blink_event = ui::MakeWebMouseWheelEvent( | |
133 *event.AsMouseWheelEvent(), base::Bind(&GetScreenLocationFromEvent)); | |
134 return base::MakeUnique<blink::WebMouseWheelEvent>(blink_event); | |
135 } else if (event.IsKeyEvent()) { | |
136 blink::WebKeyboardEvent blink_event = | |
137 ui::MakeWebKeyboardEvent(*event.AsKeyEvent()); | |
138 return base::MakeUnique<blink::WebKeyboardEvent>(blink_event); | |
139 } | |
140 return nullptr; | |
141 } | |
142 | |
143 void CompositorMusConnection::DeleteWindowTreeClient() { | |
144 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | |
145 std::unique_ptr<ui::WindowTreeClient> window_tree_client; | |
146 { | |
147 base::AutoLock auto_lock(window_tree_client_lock_); | |
148 window_tree_client = std::move(window_tree_client_); | |
149 } | |
150 main_task_runner_->PostTask( | |
151 FROM_HERE, | |
152 base::Bind(&CompositorMusConnection::OnConnectionLostOnMainThread, this)); | |
153 } | |
154 | |
155 void CompositorMusConnection::OnEmbed(ui::Window* root) { | |
156 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | |
157 root_ = root; | |
158 root_->set_input_event_handler(this); | |
159 if (window_compositor_frame_sink_binding_) { | |
160 root->AttachCompositorFrameSink( | |
161 std::move(window_compositor_frame_sink_binding_)); | |
162 } | |
163 } | |
164 | |
165 void CompositorMusConnection::OnEmbedRootDestroyed(ui::Window* window) { | |
166 DeleteWindowTreeClient(); | |
167 } | |
168 | |
169 void CompositorMusConnection::OnLostConnection(ui::WindowTreeClient* client) { | |
170 DeleteWindowTreeClient(); | |
171 } | |
172 | |
173 void CompositorMusConnection::OnPointerEventObserved( | |
174 const ui::PointerEvent& event, | |
175 ui::Window* target) { | |
176 // Compositor does not use StartPointerWatcher(). | |
177 } | |
178 | |
179 void CompositorMusConnection::OnWindowInputEvent( | |
180 ui::Window* window, | |
181 const ui::Event& event, | |
182 std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback) { | |
183 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | |
184 | |
185 // Take ownership of the callback, indicating that we will handle it. | |
186 std::unique_ptr<base::Callback<void(EventResult)>> callback = | |
187 std::move(*ack_callback); | |
188 blink::WebScopedInputEvent web_event(Convert(event).release()); | |
189 // TODO(sad): We probably need to plumb LatencyInfo through Mus. | |
190 ui::LatencyInfo info; | |
191 input_handler_manager_->HandleInputEvent( | |
192 routing_id_, std::move(web_event), info, | |
193 base::Bind( | |
194 &CompositorMusConnection::DidHandleWindowInputEventAndOverscroll, | |
195 this, base::Passed(std::move(callback)))); | |
196 } | |
197 | |
198 void CompositorMusConnection::DidHandleWindowInputEventAndOverscroll( | |
199 std::unique_ptr<base::Callback<void(EventResult)>> ack_callback, | |
200 InputEventAckState ack_state, | |
201 blink::WebScopedInputEvent web_event, | |
202 const ui::LatencyInfo& latency_info, | |
203 std::unique_ptr<ui::DidOverscrollParams> overscroll_params) { | |
204 // TODO(jonross): We probably need to ack the event based on the consumed | |
205 // state. | |
206 if (ack_state != INPUT_EVENT_ACK_STATE_NOT_CONSUMED) { | |
207 // We took the ownership of the callback, so we need to send the ack, and | |
208 // mark the event as not consumed to preserve existing behavior. | |
209 ack_callback->Run(EventResult::UNHANDLED); | |
210 return; | |
211 } | |
212 base::Callback<void(EventResult)> ack = | |
213 base::Bind(&::DoNothingWithEventResult); | |
214 const bool send_ack = | |
215 ui::WebInputEventTraits::ShouldBlockEventStream(*web_event); | |
216 if (send_ack) { | |
217 // Ultimately, this ACK needs to go back to the Mus client lib which is not | |
218 // thread-safe and lives on the compositor thread. For ACKs that are passed | |
219 // to the main thread we pass them back to the compositor thread via | |
220 // OnWindowInputEventAckOnMainThread. | |
221 ack = | |
222 base::Bind(&CompositorMusConnection::OnWindowInputEventAckOnMainThread, | |
223 this, *ack_callback); | |
224 } else { | |
225 // We took the ownership of the callback, so we need to send the ack, and | |
226 // mark the event as not consumed to preserve existing behavior. | |
227 ack_callback->Run(EventResult::UNHANDLED); | |
228 } | |
229 ack_callback.reset(); | |
230 | |
231 main_task_runner_->PostTask( | |
232 FROM_HERE, | |
233 base::Bind(&CompositorMusConnection::OnWindowInputEventOnMainThread, this, | |
234 base::Passed(std::move(web_event)), ack)); | |
235 } | |
236 | |
237 } // namespace content | |
OLD | NEW |