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