OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/devtools/protocol/input_handler.h" | 5 #include "content/browser/devtools/protocol/input_handler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 11 #include "base/threading/thread_task_runner_handle.h" |
12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
13 #include "cc/output/compositor_frame_metadata.h" | 13 #include "cc/output/compositor_frame_metadata.h" |
| 14 #include "content/browser/frame_host/render_frame_host_impl.h" |
14 #include "content/browser/renderer_host/render_widget_host_impl.h" | 15 #include "content/browser/renderer_host/render_widget_host_impl.h" |
15 #include "content/common/input/synthetic_pinch_gesture_params.h" | 16 #include "content/common/input/synthetic_pinch_gesture_params.h" |
16 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" | 17 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" |
17 #include "content/common/input/synthetic_tap_gesture_params.h" | 18 #include "content/common/input/synthetic_tap_gesture_params.h" |
18 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 19 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
19 #include "ui/events/keycodes/dom/keycode_converter.h" | 20 #include "ui/events/keycodes/dom/keycode_converter.h" |
20 #include "ui/gfx/geometry/point.h" | 21 #include "ui/gfx/geometry/point.h" |
21 | 22 |
22 namespace content { | 23 namespace content { |
23 namespace devtools { | 24 namespace protocol { |
24 namespace input { | |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 gfx::PointF CssPixelsToPointF(int x, int y, float page_scale_factor) { | 28 gfx::PointF CssPixelsToPointF(int x, int y, float page_scale_factor) { |
29 return gfx::PointF(x * page_scale_factor, y * page_scale_factor); | 29 return gfx::PointF(x * page_scale_factor, y * page_scale_factor); |
30 } | 30 } |
31 | 31 |
32 gfx::Vector2dF CssPixelsToVector2dF(int x, int y, float page_scale_factor) { | 32 gfx::Vector2dF CssPixelsToVector2dF(int x, int y, float page_scale_factor) { |
33 return gfx::Vector2dF(x * page_scale_factor, y * page_scale_factor); | 33 return gfx::Vector2dF(x * page_scale_factor, y * page_scale_factor); |
34 } | 34 } |
35 | 35 |
36 bool StringToGestureSourceType(const std::string& in, | 36 bool StringToGestureSourceType(Maybe<std::string> in, |
37 SyntheticGestureParams::GestureSourceType& out) { | 37 SyntheticGestureParams::GestureSourceType& out) { |
38 if (in == kGestureSourceTypeDefault) { | 38 if (!in.isJust()) { |
39 out = SyntheticGestureParams::GestureSourceType::DEFAULT_INPUT; | 39 out = SyntheticGestureParams::GestureSourceType::DEFAULT_INPUT; |
40 return true; | 40 return true; |
41 } else if (in == kGestureSourceTypeTouch) { | 41 } |
| 42 if (in.fromJust() == Input::GestureSourceTypeEnum::Default) { |
| 43 out = SyntheticGestureParams::GestureSourceType::DEFAULT_INPUT; |
| 44 return true; |
| 45 } |
| 46 if (in.fromJust() == Input::GestureSourceTypeEnum::Touch) { |
42 out = SyntheticGestureParams::GestureSourceType::TOUCH_INPUT; | 47 out = SyntheticGestureParams::GestureSourceType::TOUCH_INPUT; |
43 return true; | 48 return true; |
44 } else if (in == kGestureSourceTypeMouse) { | 49 } |
| 50 if (in.fromJust() == Input::GestureSourceTypeEnum::Mouse) { |
45 out = SyntheticGestureParams::GestureSourceType::MOUSE_INPUT; | 51 out = SyntheticGestureParams::GestureSourceType::MOUSE_INPUT; |
46 return true; | 52 return true; |
47 } else { | |
48 return false; | |
49 } | 53 } |
| 54 return false; |
50 } | 55 } |
51 | 56 |
52 } | 57 void SetEventModifiers(blink::WebInputEvent* event, int modifiers) { |
53 | 58 if (modifiers & 1) |
54 typedef DevToolsProtocolClient::Response Response; | |
55 | |
56 namespace { | |
57 | |
58 void SetEventModifiers(blink::WebInputEvent* event, const int* modifiers) { | |
59 if (!modifiers) | |
60 return; | |
61 if (*modifiers & 1) | |
62 event->modifiers |= blink::WebInputEvent::AltKey; | 59 event->modifiers |= blink::WebInputEvent::AltKey; |
63 if (*modifiers & 2) | 60 if (modifiers & 2) |
64 event->modifiers |= blink::WebInputEvent::ControlKey; | 61 event->modifiers |= blink::WebInputEvent::ControlKey; |
65 if (*modifiers & 4) | 62 if (modifiers & 4) |
66 event->modifiers |= blink::WebInputEvent::MetaKey; | 63 event->modifiers |= blink::WebInputEvent::MetaKey; |
67 if (*modifiers & 8) | 64 if (modifiers & 8) |
68 event->modifiers |= blink::WebInputEvent::ShiftKey; | 65 event->modifiers |= blink::WebInputEvent::ShiftKey; |
69 } | 66 } |
70 | 67 |
71 void SetEventTimestamp(blink::WebInputEvent* event, const double* timestamp) { | 68 void SetEventTimestamp(blink::WebInputEvent* event, Maybe<double> timestamp) { |
72 // Convert timestamp, in seconds since unix epoch, to an event timestamp | 69 // Convert timestamp, in seconds since unix epoch, to an event timestamp |
73 // which is time ticks since platform start time. | 70 // which is time ticks since platform start time. |
74 base::TimeTicks ticks = timestamp | 71 base::TimeTicks ticks = timestamp.isJust() |
75 ? base::TimeDelta::FromSecondsD(*timestamp) + | 72 ? base::TimeDelta::FromSecondsD(timestamp.fromJust()) + |
76 base::TimeTicks::UnixEpoch() | 73 base::TimeTicks::UnixEpoch() |
77 : base::TimeTicks::Now(); | 74 : base::TimeTicks::Now(); |
78 event->timeStampSeconds = (ticks - base::TimeTicks()).InSecondsF(); | 75 event->timeStampSeconds = (ticks - base::TimeTicks()).InSecondsF(); |
79 } | 76 } |
80 | 77 |
81 bool SetKeyboardEventText(blink::WebUChar* to, const std::string* from) { | 78 bool SetKeyboardEventText(blink::WebUChar* to, Maybe<std::string> from) { |
82 if (!from) | 79 if (!from.isJust()) |
83 return true; | 80 return true; |
84 | 81 |
85 base::string16 text16 = base::UTF8ToUTF16(*from); | 82 base::string16 text16 = base::UTF8ToUTF16(from.fromJust()); |
86 if (text16.size() > blink::WebKeyboardEvent::textLengthCap) | 83 if (text16.size() > blink::WebKeyboardEvent::textLengthCap) |
87 return false; | 84 return false; |
88 | 85 |
89 for (size_t i = 0; i < text16.size(); ++i) | 86 for (size_t i = 0; i < text16.size(); ++i) |
90 to[i] = text16[i]; | 87 to[i] = text16[i]; |
91 return true; | 88 return true; |
92 } | 89 } |
93 | 90 |
94 bool SetMouseEventButton(blink::WebMouseEvent* event, | 91 bool SetMouseEventButton(blink::WebMouseEvent* event, |
95 const std::string* button) { | 92 const std::string& button) { |
96 if (!button) | 93 if (button.empty()) |
97 return true; | 94 return true; |
98 | 95 |
99 if (*button == dispatch_mouse_event::kButtonNone) { | 96 if (button == Input::DispatchMouseEvent::ButtonEnum::None) { |
100 event->button = blink::WebMouseEvent::Button::NoButton; | 97 event->button = blink::WebMouseEvent::Button::NoButton; |
101 } else if (*button == dispatch_mouse_event::kButtonLeft) { | 98 } else if (button == Input::DispatchMouseEvent::ButtonEnum::Left) { |
102 event->button = blink::WebMouseEvent::Button::Left; | 99 event->button = blink::WebMouseEvent::Button::Left; |
103 event->modifiers |= blink::WebInputEvent::LeftButtonDown; | 100 event->modifiers |= blink::WebInputEvent::LeftButtonDown; |
104 } else if (*button == dispatch_mouse_event::kButtonMiddle) { | 101 } else if (button == Input::DispatchMouseEvent::ButtonEnum::Middle) { |
105 event->button = blink::WebMouseEvent::Button::Middle; | 102 event->button = blink::WebMouseEvent::Button::Middle; |
106 event->modifiers |= blink::WebInputEvent::MiddleButtonDown; | 103 event->modifiers |= blink::WebInputEvent::MiddleButtonDown; |
107 } else if (*button == dispatch_mouse_event::kButtonRight) { | 104 } else if (button == Input::DispatchMouseEvent::ButtonEnum::Right) { |
108 event->button = blink::WebMouseEvent::Button::Right; | 105 event->button = blink::WebMouseEvent::Button::Right; |
109 event->modifiers |= blink::WebInputEvent::RightButtonDown; | 106 event->modifiers |= blink::WebInputEvent::RightButtonDown; |
110 } else { | 107 } else { |
111 return false; | 108 return false; |
112 } | 109 } |
113 return true; | 110 return true; |
114 } | 111 } |
115 | 112 |
116 bool SetMouseEventType(blink::WebMouseEvent* event, const std::string& type) { | 113 bool SetMouseEventType(blink::WebMouseEvent* event, const std::string& type) { |
117 if (type == dispatch_mouse_event::kTypeMousePressed) { | 114 if (type == Input::DispatchMouseEvent::TypeEnum::MousePressed) { |
118 event->type = blink::WebInputEvent::MouseDown; | 115 event->type = blink::WebInputEvent::MouseDown; |
119 } else if (type == dispatch_mouse_event::kTypeMouseReleased) { | 116 } else if (type == Input::DispatchMouseEvent::TypeEnum::MouseReleased) { |
120 event->type = blink::WebInputEvent::MouseUp; | 117 event->type = blink::WebInputEvent::MouseUp; |
121 } else if (type == dispatch_mouse_event::kTypeMouseMoved) { | 118 } else if (type == Input::DispatchMouseEvent::TypeEnum::MouseMoved) { |
122 event->type = blink::WebInputEvent::MouseMove; | 119 event->type = blink::WebInputEvent::MouseMove; |
123 } else { | 120 } else { |
124 return false; | 121 return false; |
125 } | 122 } |
126 return true; | 123 return true; |
127 } | 124 } |
128 | 125 |
| 126 void SendSynthesizePinchGestureResponse( |
| 127 std::unique_ptr<Input::Backend::SynthesizePinchGestureCallback> callback, |
| 128 SyntheticGesture::Result result) { |
| 129 if (result == SyntheticGesture::Result::GESTURE_FINISHED) { |
| 130 callback->sendSuccess(); |
| 131 } else { |
| 132 callback->sendFailure(Response::Error( |
| 133 base::StringPrintf("Synthetic pinch failed, result was %d", result))); |
| 134 } |
| 135 } |
| 136 |
| 137 class TapGestureResponse { |
| 138 public: |
| 139 TapGestureResponse( |
| 140 std::unique_ptr<Input::Backend::SynthesizeTapGestureCallback> callback, |
| 141 int count) |
| 142 : callback_(std::move(callback)), |
| 143 count_(count) { |
| 144 } |
| 145 |
| 146 void OnGestureResult(SyntheticGesture::Result result) { |
| 147 --count_; |
| 148 // Still waiting for more taps to finish. |
| 149 if (result == SyntheticGesture::Result::GESTURE_FINISHED && count_) |
| 150 return; |
| 151 if (callback_) { |
| 152 if (result == SyntheticGesture::Result::GESTURE_FINISHED) { |
| 153 callback_->sendSuccess(); |
| 154 } else { |
| 155 callback_->sendFailure(Response::Error( |
| 156 base::StringPrintf("Synthetic tap failed, result was %d", result))); |
| 157 } |
| 158 callback_.reset(); |
| 159 } |
| 160 if (!count_) |
| 161 delete this; |
| 162 } |
| 163 |
| 164 private: |
| 165 std::unique_ptr<Input::Backend::SynthesizeTapGestureCallback> callback_; |
| 166 int count_; |
| 167 }; |
| 168 |
| 169 void SendSynthesizeScrollGestureResponse( |
| 170 std::unique_ptr<Input::Backend::SynthesizeScrollGestureCallback> callback, |
| 171 SyntheticGesture::Result result) { |
| 172 if (result == SyntheticGesture::Result::GESTURE_FINISHED) { |
| 173 callback->sendSuccess(); |
| 174 } else { |
| 175 callback->sendFailure(Response::Error( |
| 176 base::StringPrintf("Synthetic scroll failed, result was %d", result))); |
| 177 } |
| 178 } |
| 179 |
129 } // namespace | 180 } // namespace |
130 | 181 |
131 InputHandler::InputHandler() | 182 InputHandler::InputHandler() |
132 : host_(NULL), | 183 : host_(NULL), |
133 page_scale_factor_(1.0), | 184 page_scale_factor_(1.0), |
| 185 last_id_(0), |
134 weak_factory_(this) { | 186 weak_factory_(this) { |
135 } | 187 } |
136 | 188 |
137 InputHandler::~InputHandler() { | 189 InputHandler::~InputHandler() { |
138 } | 190 } |
139 | 191 |
140 void InputHandler::SetRenderWidgetHost(RenderWidgetHostImpl* host) { | 192 void InputHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { |
141 host_ = host; | 193 host_ = host; |
142 } | 194 } |
143 | 195 |
144 void InputHandler::SetClient(std::unique_ptr<Client> client) { | 196 void InputHandler::Wire(UberDispatcher* dispatcher) { |
145 client_.swap(client); | 197 Input::Dispatcher::wire(dispatcher, this); |
146 } | 198 } |
147 | 199 |
148 void InputHandler::OnSwapCompositorFrame( | 200 void InputHandler::OnSwapCompositorFrame( |
149 const cc::CompositorFrameMetadata& frame_metadata) { | 201 const cc::CompositorFrameMetadata& frame_metadata) { |
150 page_scale_factor_ = frame_metadata.page_scale_factor; | 202 page_scale_factor_ = frame_metadata.page_scale_factor; |
151 scrollable_viewport_size_ = frame_metadata.scrollable_viewport_size; | 203 scrollable_viewport_size_ = frame_metadata.scrollable_viewport_size; |
152 } | 204 } |
153 | 205 |
| 206 Response InputHandler::Disable() { |
| 207 return Response::OK(); |
| 208 } |
| 209 |
154 Response InputHandler::DispatchKeyEvent( | 210 Response InputHandler::DispatchKeyEvent( |
155 const std::string& type, | 211 const std::string& type, |
156 const int* modifiers, | 212 Maybe<int> modifiers, |
157 const double* timestamp, | 213 Maybe<double> timestamp, |
158 const std::string* text, | 214 Maybe<std::string> text, |
159 const std::string* unmodified_text, | 215 Maybe<std::string> unmodified_text, |
160 const std::string* key_identifier, | 216 Maybe<std::string> key_identifier, |
161 const std::string* code, | 217 Maybe<std::string> code, |
162 const std::string* key, | 218 Maybe<std::string> key, |
163 const int* windows_virtual_key_code, | 219 Maybe<int> windows_virtual_key_code, |
164 const int* native_virtual_key_code, | 220 Maybe<int> native_virtual_key_code, |
165 const bool* auto_repeat, | 221 Maybe<bool> auto_repeat, |
166 const bool* is_keypad, | 222 Maybe<bool> is_keypad, |
167 const bool* is_system_key) { | 223 Maybe<bool> is_system_key) { |
168 NativeWebKeyboardEvent event; | 224 NativeWebKeyboardEvent event; |
169 event.skip_in_browser = true; | 225 event.skip_in_browser = true; |
170 | 226 |
171 if (type == dispatch_key_event::kTypeKeyDown) { | 227 if (type == Input::DispatchKeyEvent::TypeEnum::KeyDown) { |
172 event.type = blink::WebInputEvent::KeyDown; | 228 event.type = blink::WebInputEvent::KeyDown; |
173 } else if (type == dispatch_key_event::kTypeKeyUp) { | 229 } else if (type == Input::DispatchKeyEvent::TypeEnum::KeyUp) { |
174 event.type = blink::WebInputEvent::KeyUp; | 230 event.type = blink::WebInputEvent::KeyUp; |
175 } else if (type == dispatch_key_event::kTypeChar) { | 231 } else if (type == Input::DispatchKeyEvent::TypeEnum::Char) { |
176 event.type = blink::WebInputEvent::Char; | 232 event.type = blink::WebInputEvent::Char; |
177 } else if (type == dispatch_key_event::kTypeRawKeyDown) { | 233 } else if (type == Input::DispatchKeyEvent::TypeEnum::RawKeyDown) { |
178 event.type = blink::WebInputEvent::RawKeyDown; | 234 event.type = blink::WebInputEvent::RawKeyDown; |
179 } else { | 235 } else { |
180 return Response::InvalidParams( | 236 return Response::InvalidParams( |
181 base::StringPrintf("Unexpected event type '%s'", type.c_str())); | 237 base::StringPrintf("Unexpected event type '%s'", type.c_str())); |
182 } | 238 } |
183 | 239 |
184 SetEventModifiers(&event, modifiers); | 240 SetEventModifiers(&event, modifiers.fromMaybe(0)); |
185 SetEventTimestamp(&event, timestamp); | 241 SetEventTimestamp(&event, std::move(timestamp)); |
186 if (!SetKeyboardEventText(event.text, text)) | 242 if (!SetKeyboardEventText(event.text, std::move(text))) |
187 return Response::InvalidParams("Invalid 'text' parameter"); | 243 return Response::InvalidParams("Invalid 'text' parameter"); |
188 if (!SetKeyboardEventText(event.unmodifiedText, unmodified_text)) | 244 if (!SetKeyboardEventText(event.unmodifiedText, std::move(unmodified_text))) |
189 return Response::InvalidParams("Invalid 'unmodifiedText' parameter"); | 245 return Response::InvalidParams("Invalid 'unmodifiedText' parameter"); |
190 | 246 |
191 if (windows_virtual_key_code) | 247 if (windows_virtual_key_code.isJust()) |
192 event.windowsKeyCode = *windows_virtual_key_code; | 248 event.windowsKeyCode = windows_virtual_key_code.fromJust(); |
193 if (native_virtual_key_code) | 249 if (native_virtual_key_code.isJust()) |
194 event.nativeKeyCode = *native_virtual_key_code; | 250 event.nativeKeyCode = native_virtual_key_code.fromJust(); |
195 if (auto_repeat && *auto_repeat) | 251 if (auto_repeat.fromMaybe(false)) |
196 event.modifiers |= blink::WebInputEvent::IsAutoRepeat; | 252 event.modifiers |= blink::WebInputEvent::IsAutoRepeat; |
197 if (is_keypad && *is_keypad) | 253 if (is_keypad.fromMaybe(false)) |
198 event.modifiers |= blink::WebInputEvent::IsKeyPad; | 254 event.modifiers |= blink::WebInputEvent::IsKeyPad; |
199 if (is_system_key) | 255 if (is_system_key.isJust()) |
200 event.isSystemKey = *is_system_key; | 256 event.isSystemKey = is_system_key.fromJust(); |
201 | 257 |
202 if (code) { | 258 if (code.isJust()) { |
203 event.domCode = static_cast<int>( | 259 event.domCode = static_cast<int>( |
204 ui::KeycodeConverter::CodeStringToDomCode(*code)); | 260 ui::KeycodeConverter::CodeStringToDomCode(code.fromJust())); |
205 } | 261 } |
206 | 262 |
207 if (key) { | 263 if (key.isJust()) { |
208 event.domKey = static_cast<int>( | 264 event.domKey = static_cast<int>( |
209 ui::KeycodeConverter::KeyStringToDomKey(*key)); | 265 ui::KeycodeConverter::KeyStringToDomKey(key.fromJust())); |
210 } | 266 } |
211 | 267 |
212 if (!host_) | 268 if (!host_ || !host_->GetRenderWidgetHost()) |
213 return Response::ServerError("Could not connect to view"); | 269 return Response::InternalError(); |
214 | 270 |
215 host_->Focus(); | 271 host_->GetRenderWidgetHost()->Focus(); |
216 host_->ForwardKeyboardEvent(event); | 272 host_->GetRenderWidgetHost()->ForwardKeyboardEvent(event); |
217 return Response::OK(); | 273 return Response::OK(); |
218 } | 274 } |
219 | 275 |
220 Response InputHandler::DispatchMouseEvent( | 276 Response InputHandler::DispatchMouseEvent( |
221 const std::string& type, | 277 const std::string& type, |
222 int x, | 278 int x, |
223 int y, | 279 int y, |
224 const int* modifiers, | 280 Maybe<int> modifiers, |
225 const double* timestamp, | 281 Maybe<double> timestamp, |
226 const std::string* button, | 282 Maybe<std::string> button, |
227 const int* click_count) { | 283 Maybe<int> click_count) { |
228 blink::WebMouseEvent event; | 284 blink::WebMouseEvent event; |
229 | 285 |
230 if (!SetMouseEventType(&event, type)) { | 286 if (!SetMouseEventType(&event, type)) { |
231 return Response::InvalidParams( | 287 return Response::InvalidParams( |
232 base::StringPrintf("Unexpected event type '%s'", type.c_str())); | 288 base::StringPrintf("Unexpected event type '%s'", type.c_str())); |
233 } | 289 } |
234 SetEventModifiers(&event, modifiers); | 290 SetEventModifiers(&event, modifiers.fromMaybe(0)); |
235 SetEventTimestamp(&event, timestamp); | 291 SetEventTimestamp(&event, std::move(timestamp)); |
236 if (!SetMouseEventButton(&event, button)) | 292 if (!SetMouseEventButton(&event, button.fromMaybe(""))) |
237 return Response::InvalidParams("Invalid mouse button"); | 293 return Response::InvalidParams("Invalid mouse button"); |
238 | 294 |
239 event.x = x * page_scale_factor_; | 295 event.x = x * page_scale_factor_; |
240 event.y = y * page_scale_factor_; | 296 event.y = y * page_scale_factor_; |
241 event.windowX = x * page_scale_factor_; | 297 event.windowX = x * page_scale_factor_; |
242 event.windowY = y * page_scale_factor_; | 298 event.windowY = y * page_scale_factor_; |
243 event.globalX = x * page_scale_factor_; | 299 event.globalX = x * page_scale_factor_; |
244 event.globalY = y * page_scale_factor_; | 300 event.globalY = y * page_scale_factor_; |
245 event.clickCount = click_count ? *click_count : 0; | 301 event.clickCount = click_count.fromMaybe(0); |
246 event.pointerType = blink::WebPointerProperties::PointerType::Mouse; | 302 event.pointerType = blink::WebPointerProperties::PointerType::Mouse; |
247 | 303 |
248 if (!host_) | 304 if (!host_ || !host_->GetRenderWidgetHost()) |
249 return Response::ServerError("Could not connect to view"); | 305 return Response::InternalError(); |
250 | 306 |
251 host_->Focus(); | 307 host_->GetRenderWidgetHost()->Focus(); |
252 host_->ForwardMouseEvent(event); | 308 host_->GetRenderWidgetHost()->ForwardMouseEvent(event); |
253 return Response::OK(); | 309 return Response::OK(); |
254 } | 310 } |
255 | 311 |
256 Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type, | 312 Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type, |
257 int x, | 313 int x, |
258 int y, | 314 int y, |
259 double timestamp, | 315 double timestamp, |
260 const std::string& button, | 316 const std::string& button, |
261 double* delta_x, | 317 Maybe<double> delta_x, |
262 double* delta_y, | 318 Maybe<double> delta_y, |
263 int* modifiers, | 319 Maybe<int> modifiers, |
264 int* click_count) { | 320 Maybe<int> click_count) { |
265 blink::WebMouseWheelEvent wheel_event; | 321 blink::WebMouseWheelEvent wheel_event; |
266 blink::WebMouseEvent mouse_event; | 322 blink::WebMouseEvent mouse_event; |
267 blink::WebMouseEvent* event = &mouse_event; | 323 blink::WebMouseEvent* event = &mouse_event; |
268 | 324 |
269 if (type == emulate_touch_from_mouse_event::kTypeMouseWheel) { | 325 if (type == Input::EmulateTouchFromMouseEvent::TypeEnum::MouseWheel) { |
270 if (!delta_x || !delta_y) { | 326 if (!delta_x.isJust() || !delta_y.isJust()) { |
271 return Response::InvalidParams( | 327 return Response::InvalidParams( |
272 "'deltaX' and 'deltaY' are expected for mouseWheel event"); | 328 "'deltaX' and 'deltaY' are expected for mouseWheel event"); |
273 } | 329 } |
274 wheel_event.deltaX = static_cast<float>(*delta_x); | 330 wheel_event.deltaX = static_cast<float>(delta_x.fromJust()); |
275 wheel_event.deltaY = static_cast<float>(*delta_y); | 331 wheel_event.deltaY = static_cast<float>(delta_y.fromJust()); |
276 event = &wheel_event; | 332 event = &wheel_event; |
277 event->type = blink::WebInputEvent::MouseWheel; | 333 event->type = blink::WebInputEvent::MouseWheel; |
278 } else if (!SetMouseEventType(event, type)) { | 334 } else if (!SetMouseEventType(event, type)) { |
279 return Response::InvalidParams( | 335 return Response::InvalidParams( |
280 base::StringPrintf("Unexpected event type '%s'", type.c_str())); | 336 base::StringPrintf("Unexpected event type '%s'", type.c_str())); |
281 } | 337 } |
282 | 338 |
283 SetEventModifiers(event, modifiers); | 339 SetEventModifiers(event, modifiers.fromMaybe(0)); |
284 SetEventTimestamp(event, ×tamp); | 340 SetEventTimestamp(event, Maybe<double>(timestamp)); |
285 if (!SetMouseEventButton(event, &button)) | 341 if (!SetMouseEventButton(event, button)) |
286 return Response::InvalidParams("Invalid mouse button"); | 342 return Response::InvalidParams("Invalid mouse button"); |
287 | 343 |
288 event->x = x; | 344 event->x = x; |
289 event->y = y; | 345 event->y = y; |
290 event->windowX = x; | 346 event->windowX = x; |
291 event->windowY = y; | 347 event->windowY = y; |
292 event->globalX = x; | 348 event->globalX = x; |
293 event->globalY = y; | 349 event->globalY = y; |
294 event->clickCount = click_count ? *click_count : 0; | 350 event->clickCount = click_count.fromMaybe(0); |
295 event->pointerType = blink::WebPointerProperties::PointerType::Touch; | 351 event->pointerType = blink::WebPointerProperties::PointerType::Touch; |
296 | 352 |
297 if (!host_) | 353 if (!host_ || !host_->GetRenderWidgetHost()) |
298 return Response::ServerError("Could not connect to view"); | 354 return Response::InternalError(); |
299 | 355 |
300 if (event->type == blink::WebInputEvent::MouseWheel) | 356 if (event->type == blink::WebInputEvent::MouseWheel) |
301 host_->ForwardWheelEvent(wheel_event); | 357 host_->GetRenderWidgetHost()->ForwardWheelEvent(wheel_event); |
302 else | 358 else |
303 host_->ForwardMouseEvent(mouse_event); | 359 host_->GetRenderWidgetHost()->ForwardMouseEvent(mouse_event); |
304 return Response::OK(); | 360 return Response::OK(); |
305 } | 361 } |
306 | 362 |
307 Response InputHandler::SynthesizePinchGesture( | 363 void InputHandler::SynthesizePinchGesture( |
308 DevToolsCommandId command_id, | |
309 int x, | 364 int x, |
310 int y, | 365 int y, |
311 double scale_factor, | 366 double scale_factor, |
312 const int* relative_speed, | 367 Maybe<int> relative_speed, |
313 const std::string* gesture_source_type) { | 368 Maybe<std::string> gesture_source_type, |
314 if (!host_) | 369 std::unique_ptr<SynthesizePinchGestureCallback> callback) { |
315 return Response::ServerError("Could not connect to view"); | 370 if (!host_ || !host_->GetRenderWidgetHost()) { |
| 371 callback->sendFailure(Response::InternalError()); |
| 372 return; |
| 373 } |
316 | 374 |
317 SyntheticPinchGestureParams gesture_params; | 375 SyntheticPinchGestureParams gesture_params; |
318 const int kDefaultRelativeSpeed = 800; | 376 const int kDefaultRelativeSpeed = 800; |
319 | 377 |
320 gesture_params.scale_factor = scale_factor; | 378 gesture_params.scale_factor = scale_factor; |
321 gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_); | 379 gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_); |
322 gesture_params.relative_pointer_speed_in_pixels_s = | 380 gesture_params.relative_pointer_speed_in_pixels_s = |
323 relative_speed ? *relative_speed : kDefaultRelativeSpeed; | 381 relative_speed.fromMaybe(kDefaultRelativeSpeed); |
324 | 382 |
325 if (!StringToGestureSourceType( | 383 if (!StringToGestureSourceType( |
326 gesture_source_type ? *gesture_source_type : kGestureSourceTypeDefault, | 384 std::move(gesture_source_type), |
327 gesture_params.gesture_source_type)) { | 385 gesture_params.gesture_source_type)) { |
328 return Response::InvalidParams("gestureSourceType"); | 386 callback->sendFailure( |
| 387 Response::InvalidParams("Unknown gestureSourceType")); |
| 388 return; |
329 } | 389 } |
330 | 390 |
331 host_->QueueSyntheticGesture( | 391 host_->GetRenderWidgetHost()->QueueSyntheticGesture( |
332 SyntheticGesture::Create(gesture_params), | 392 SyntheticGesture::Create(gesture_params), |
333 base::Bind(&InputHandler::SendSynthesizePinchGestureResponse, | 393 base::Bind(&SendSynthesizePinchGestureResponse, |
334 weak_factory_.GetWeakPtr(), command_id)); | 394 base::Passed(std::move(callback)))); |
335 | |
336 return Response::OK(); | |
337 } | 395 } |
338 | 396 |
339 Response InputHandler::SynthesizeScrollGesture( | 397 void InputHandler::SynthesizeScrollGesture( |
340 DevToolsCommandId command_id, | |
341 int x, | 398 int x, |
342 int y, | 399 int y, |
343 const int* x_distance, | 400 Maybe<int> x_distance, |
344 const int* y_distance, | 401 Maybe<int> y_distance, |
345 const int* x_overscroll, | 402 Maybe<int> x_overscroll, |
346 const int* y_overscroll, | 403 Maybe<int> y_overscroll, |
347 const bool* prevent_fling, | 404 Maybe<bool> prevent_fling, |
348 const int* speed, | 405 Maybe<int> speed, |
349 const std::string* gesture_source_type, | 406 Maybe<std::string> gesture_source_type, |
350 const int* repeat_count, | 407 Maybe<int> repeat_count, |
351 const int* repeat_delay_ms, | 408 Maybe<int> repeat_delay_ms, |
352 const std::string* interaction_marker_name) { | 409 Maybe<std::string> interaction_marker_name, |
353 if (!host_) | 410 std::unique_ptr<SynthesizeScrollGestureCallback> callback) { |
354 return Response::ServerError("Could not connect to view"); | 411 if (!host_ || !host_->GetRenderWidgetHost()) { |
| 412 callback->sendFailure(Response::InternalError()); |
| 413 return; |
| 414 } |
355 | 415 |
356 SyntheticSmoothScrollGestureParams gesture_params; | 416 SyntheticSmoothScrollGestureParams gesture_params; |
357 const bool kDefaultPreventFling = true; | 417 const bool kDefaultPreventFling = true; |
358 const int kDefaultSpeed = 800; | 418 const int kDefaultSpeed = 800; |
359 | 419 |
360 gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_); | 420 gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_); |
361 gesture_params.prevent_fling = | 421 gesture_params.prevent_fling = |
362 prevent_fling ? *prevent_fling : kDefaultPreventFling; | 422 prevent_fling.fromMaybe(kDefaultPreventFling); |
363 gesture_params.speed_in_pixels_s = speed ? *speed : kDefaultSpeed; | 423 gesture_params.speed_in_pixels_s = speed.fromMaybe(kDefaultSpeed); |
364 | 424 |
365 if (x_distance || y_distance) { | 425 if (x_distance.fromJust() || y_distance.fromJust()) { |
366 gesture_params.distances.push_back( | 426 gesture_params.distances.push_back( |
367 CssPixelsToVector2dF(x_distance ? *x_distance : 0, | 427 CssPixelsToVector2dF(x_distance.fromMaybe(0), |
368 y_distance ? *y_distance : 0, page_scale_factor_)); | 428 y_distance.fromMaybe(0), page_scale_factor_)); |
369 } | 429 } |
370 | 430 |
371 if (x_overscroll || y_overscroll) { | 431 if (x_overscroll.isJust() || y_overscroll.isJust()) { |
372 gesture_params.distances.push_back(CssPixelsToVector2dF( | 432 gesture_params.distances.push_back(CssPixelsToVector2dF( |
373 x_overscroll ? -*x_overscroll : 0, y_overscroll ? -*y_overscroll : 0, | 433 -x_overscroll.fromMaybe(0), -y_overscroll.fromMaybe(0), |
374 page_scale_factor_)); | 434 page_scale_factor_)); |
375 } | 435 } |
376 | 436 |
377 if (!StringToGestureSourceType( | 437 if (!StringToGestureSourceType( |
378 gesture_source_type ? *gesture_source_type : kGestureSourceTypeDefault, | 438 std::move(gesture_source_type), |
379 gesture_params.gesture_source_type)) { | 439 gesture_params.gesture_source_type)) { |
380 return Response::InvalidParams("gestureSourceType"); | 440 callback->sendFailure( |
| 441 Response::InvalidParams("Unknown gestureSourceType")); |
| 442 return; |
381 } | 443 } |
382 | 444 |
383 SynthesizeRepeatingScroll( | 445 SynthesizeRepeatingScroll( |
384 gesture_params, repeat_count ? *repeat_count : 0, | 446 gesture_params, repeat_count.fromMaybe(0), |
385 base::TimeDelta::FromMilliseconds(repeat_delay_ms ? *repeat_delay_ms | 447 base::TimeDelta::FromMilliseconds(repeat_delay_ms.fromMaybe(250)), |
386 : 250), | 448 interaction_marker_name.fromMaybe(""), ++last_id_, std::move(callback)); |
387 interaction_marker_name ? *interaction_marker_name : "", command_id); | |
388 | |
389 return Response::OK(); | |
390 } | 449 } |
391 | 450 |
392 void InputHandler::SynthesizeRepeatingScroll( | 451 void InputHandler::SynthesizeRepeatingScroll( |
393 SyntheticSmoothScrollGestureParams gesture_params, | 452 SyntheticSmoothScrollGestureParams gesture_params, |
394 int repeat_count, | 453 int repeat_count, |
395 base::TimeDelta repeat_delay, | 454 base::TimeDelta repeat_delay, |
396 std::string interaction_marker_name, | 455 std::string interaction_marker_name, |
397 DevToolsCommandId command_id) { | 456 int id, |
| 457 std::unique_ptr<SynthesizeScrollGestureCallback> callback) { |
398 if (!interaction_marker_name.empty()) { | 458 if (!interaction_marker_name.empty()) { |
399 // TODO(alexclarke): Can we move this elsewhere? It doesn't really fit here. | 459 // TODO(alexclarke): Can we move this elsewhere? It doesn't really fit here. |
400 TRACE_EVENT_COPY_ASYNC_BEGIN0("benchmark", interaction_marker_name.c_str(), | 460 TRACE_EVENT_COPY_ASYNC_BEGIN0("benchmark", interaction_marker_name.c_str(), |
401 command_id.call_id); | 461 id); |
402 } | 462 } |
403 | 463 |
404 host_->QueueSyntheticGesture( | 464 host_->GetRenderWidgetHost()->QueueSyntheticGesture( |
405 SyntheticGesture::Create(gesture_params), | 465 SyntheticGesture::Create(gesture_params), |
406 base::Bind(&InputHandler::OnScrollFinished, weak_factory_.GetWeakPtr(), | 466 base::Bind(&InputHandler::OnScrollFinished, weak_factory_.GetWeakPtr(), |
407 gesture_params, repeat_count, repeat_delay, | 467 gesture_params, repeat_count, repeat_delay, |
408 interaction_marker_name, command_id)); | 468 interaction_marker_name, id, |
| 469 base::Passed(std::move(callback)))); |
409 } | 470 } |
410 | 471 |
411 void InputHandler::OnScrollFinished( | 472 void InputHandler::OnScrollFinished( |
412 SyntheticSmoothScrollGestureParams gesture_params, | 473 SyntheticSmoothScrollGestureParams gesture_params, |
413 int repeat_count, | 474 int repeat_count, |
414 base::TimeDelta repeat_delay, | 475 base::TimeDelta repeat_delay, |
415 std::string interaction_marker_name, | 476 std::string interaction_marker_name, |
416 DevToolsCommandId command_id, | 477 int id, |
| 478 std::unique_ptr<SynthesizeScrollGestureCallback> callback, |
417 SyntheticGesture::Result result) { | 479 SyntheticGesture::Result result) { |
418 if (!interaction_marker_name.empty()) { | 480 if (!interaction_marker_name.empty()) { |
419 TRACE_EVENT_COPY_ASYNC_END0("benchmark", interaction_marker_name.c_str(), | 481 TRACE_EVENT_COPY_ASYNC_END0("benchmark", interaction_marker_name.c_str(), |
420 command_id.call_id); | 482 id); |
421 } | 483 } |
422 | 484 |
423 if (repeat_count > 0) { | 485 if (repeat_count > 0) { |
424 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 486 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
425 FROM_HERE, | 487 FROM_HERE, |
426 base::Bind(&InputHandler::SynthesizeRepeatingScroll, | 488 base::Bind(&InputHandler::SynthesizeRepeatingScroll, |
427 weak_factory_.GetWeakPtr(), gesture_params, repeat_count - 1, | 489 weak_factory_.GetWeakPtr(), gesture_params, repeat_count - 1, |
428 repeat_delay, interaction_marker_name, command_id), | 490 repeat_delay, interaction_marker_name, id, |
| 491 base::Passed(std::move(callback))), |
429 repeat_delay); | 492 repeat_delay); |
430 } else { | 493 } else { |
431 SendSynthesizeScrollGestureResponse(command_id, result); | 494 SendSynthesizeScrollGestureResponse(std::move(callback), result); |
432 } | 495 } |
433 } | 496 } |
434 | 497 |
435 Response InputHandler::SynthesizeTapGesture( | 498 void InputHandler::SynthesizeTapGesture( |
436 DevToolsCommandId command_id, | |
437 int x, | 499 int x, |
438 int y, | 500 int y, |
439 const int* duration, | 501 Maybe<int> duration, |
440 const int* tap_count, | 502 Maybe<int> tap_count, |
441 const std::string* gesture_source_type) { | 503 Maybe<std::string> gesture_source_type, |
442 if (!host_) | 504 std::unique_ptr<SynthesizeTapGestureCallback> callback) { |
443 return Response::ServerError("Could not connect to view"); | 505 if (!host_ || !host_->GetRenderWidgetHost()) { |
| 506 callback->sendFailure(Response::InternalError()); |
| 507 return; |
| 508 } |
444 | 509 |
445 SyntheticTapGestureParams gesture_params; | 510 SyntheticTapGestureParams gesture_params; |
446 const int kDefaultDuration = 50; | 511 const int kDefaultDuration = 50; |
447 const int kDefaultTapCount = 1; | 512 const int kDefaultTapCount = 1; |
448 | 513 |
449 gesture_params.position = CssPixelsToPointF(x, y, page_scale_factor_); | 514 gesture_params.position = CssPixelsToPointF(x, y, page_scale_factor_); |
450 gesture_params.duration_ms = duration ? *duration : kDefaultDuration; | 515 gesture_params.duration_ms = duration.fromMaybe(kDefaultDuration); |
451 | 516 |
452 if (!StringToGestureSourceType( | 517 if (!StringToGestureSourceType( |
453 gesture_source_type ? *gesture_source_type : kGestureSourceTypeDefault, | 518 std::move(gesture_source_type), |
454 gesture_params.gesture_source_type)) { | 519 gesture_params.gesture_source_type)) { |
455 return Response::InvalidParams("gestureSourceType"); | 520 callback->sendFailure( |
| 521 Response::InvalidParams("Unknown gestureSourceType")); |
| 522 return; |
456 } | 523 } |
457 | 524 |
458 if (!tap_count) | 525 int count = tap_count.fromMaybe(kDefaultTapCount); |
459 tap_count = &kDefaultTapCount; | 526 if (!count) { |
460 | 527 callback->sendSuccess(); |
461 for (int i = 0; i < *tap_count; i++) { | 528 return; |
462 // If we're doing more than one tap, don't send the response to the client | |
463 // until we've completed the last tap. | |
464 bool is_last_tap = i == *tap_count - 1; | |
465 host_->QueueSyntheticGesture( | |
466 SyntheticGesture::Create(gesture_params), | |
467 base::Bind(&InputHandler::SendSynthesizeTapGestureResponse, | |
468 weak_factory_.GetWeakPtr(), command_id, is_last_tap)); | |
469 } | 529 } |
470 | 530 |
471 return Response::OK(); | 531 TapGestureResponse* response = |
472 } | 532 new TapGestureResponse(std::move(callback), count); |
473 | 533 for (int i = 0; i < count; i++) { |
474 Response InputHandler::DispatchTouchEvent( | 534 host_->GetRenderWidgetHost()->QueueSyntheticGesture( |
475 const std::string& type, | 535 SyntheticGesture::Create(gesture_params), |
476 const std::vector<std::unique_ptr<base::DictionaryValue>>& touch_points, | 536 base::Bind(&TapGestureResponse::OnGestureResult, |
477 const int* modifiers, | 537 base::Unretained(response))); |
478 const double* timestamp) { | |
479 return Response::FallThrough(); | |
480 } | |
481 | |
482 void InputHandler::SendSynthesizePinchGestureResponse( | |
483 DevToolsCommandId command_id, | |
484 SyntheticGesture::Result result) { | |
485 if (result == SyntheticGesture::Result::GESTURE_FINISHED) { | |
486 client_->SendSynthesizePinchGestureResponse( | |
487 command_id, SynthesizePinchGestureResponse::Create()); | |
488 } else { | |
489 client_->SendError(command_id, | |
490 Response::InternalError(base::StringPrintf( | |
491 "Synthetic pinch failed, result was %d", result))); | |
492 } | 538 } |
493 } | 539 } |
494 | 540 |
495 void InputHandler::SendSynthesizeScrollGestureResponse( | 541 } // namespace protocol |
496 DevToolsCommandId command_id, | |
497 SyntheticGesture::Result result) { | |
498 if (result == SyntheticGesture::Result::GESTURE_FINISHED) { | |
499 client_->SendSynthesizeScrollGestureResponse( | |
500 command_id, SynthesizeScrollGestureResponse::Create()); | |
501 } else { | |
502 client_->SendError(command_id, | |
503 Response::InternalError(base::StringPrintf( | |
504 "Synthetic scroll failed, result was %d", result))); | |
505 } | |
506 } | |
507 | |
508 void InputHandler::SendSynthesizeTapGestureResponse( | |
509 DevToolsCommandId command_id, | |
510 bool send_success, | |
511 SyntheticGesture::Result result) { | |
512 if (result == SyntheticGesture::Result::GESTURE_FINISHED) { | |
513 if (send_success) { | |
514 client_->SendSynthesizeTapGestureResponse( | |
515 command_id, SynthesizeTapGestureResponse::Create()); | |
516 } | |
517 } else { | |
518 client_->SendError(command_id, | |
519 Response::InternalError(base::StringPrintf( | |
520 "Synthetic tap failed, result was %d", result))); | |
521 } | |
522 } | |
523 | |
524 } // namespace input | |
525 } // namespace devtools | |
526 } // namespace content | 542 } // namespace content |
OLD | NEW |