| 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 |