Respond with QuotaExceededError when IndexedDB has no disk space on open.
[chromium-blink-merge.git] / content / browser / devtools / renderer_overrides_handler.cc
blobc25adde7619407673d7f4c202dfcede2fb20ddaf
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/devtools/renderer_overrides_handler.h"
7 #include <string>
9 #include "base/base64.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h"
13 #include "base/strings/string16.h"
14 #include "base/values.h"
15 #include "content/browser/child_process_security_policy_impl.h"
16 #include "content/browser/devtools/devtools_protocol_constants.h"
17 #include "content/browser/devtools/devtools_tracing_handler.h"
18 #include "content/browser/renderer_host/dip_util.h"
19 #include "content/browser/renderer_host/render_view_host_delegate.h"
20 #include "content/browser/renderer_host/render_view_host_impl.h"
21 #include "content/common/view_messages.h"
22 #include "content/port/browser/render_widget_host_view_port.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/devtools_agent_host.h"
25 #include "content/public/browser/javascript_dialog_manager.h"
26 #include "content/public/browser/navigation_controller.h"
27 #include "content/public/browser/navigation_entry.h"
28 #include "content/public/browser/render_process_host.h"
29 #include "content/public/browser/render_view_host.h"
30 #include "content/public/browser/render_widget_host_view.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/browser/web_contents_delegate.h"
33 #include "content/public/common/page_transition_types.h"
34 #include "content/public/common/referrer.h"
35 #include "ipc/ipc_sender.h"
36 #include "third_party/WebKit/public/web/WebInputEvent.h"
37 #include "ui/gfx/codec/jpeg_codec.h"
38 #include "ui/gfx/codec/png_codec.h"
39 #include "ui/gfx/size_conversions.h"
40 #include "ui/snapshot/snapshot.h"
41 #include "url/gurl.h"
43 using WebKit::WebGestureEvent;
44 using WebKit::WebInputEvent;
45 using WebKit::WebMouseEvent;
47 namespace content {
49 namespace {
51 static const char kPng[] = "png";
52 static const char kJpeg[] = "jpeg";
53 static int kDefaultScreenshotQuality = 80;
54 static int kFrameRateThresholdMs = 100;
56 void ParseGenericInputParams(base::DictionaryValue* params,
57 WebInputEvent* event) {
58 int modifiers = 0;
59 if (params->GetInteger(devtools::Input::kParamModifiers,
60 &modifiers)) {
61 if (modifiers & 1)
62 event->modifiers |= WebInputEvent::AltKey;
63 if (modifiers & 2)
64 event->modifiers |= WebInputEvent::ControlKey;
65 if (modifiers & 4)
66 event->modifiers |= WebInputEvent::MetaKey;
67 if (modifiers & 8)
68 event->modifiers |= WebInputEvent::ShiftKey;
71 params->GetDouble(devtools::Input::kParamTimestamp,
72 &event->timeStampSeconds);
75 } // namespace
77 RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent)
78 : agent_(agent),
79 weak_factory_(this) {
80 RegisterCommandHandler(
81 devtools::DOM::setFileInputFiles::kName,
82 base::Bind(
83 &RendererOverridesHandler::GrantPermissionsForSetFileInputFiles,
84 base::Unretained(this)));
85 RegisterCommandHandler(
86 devtools::Page::disable::kName,
87 base::Bind(
88 &RendererOverridesHandler::PageDisable, base::Unretained(this)));
89 RegisterCommandHandler(
90 devtools::Page::handleJavaScriptDialog::kName,
91 base::Bind(
92 &RendererOverridesHandler::PageHandleJavaScriptDialog,
93 base::Unretained(this)));
94 RegisterCommandHandler(
95 devtools::Page::navigate::kName,
96 base::Bind(
97 &RendererOverridesHandler::PageNavigate,
98 base::Unretained(this)));
99 RegisterCommandHandler(
100 devtools::Page::reload::kName,
101 base::Bind(
102 &RendererOverridesHandler::PageReload,
103 base::Unretained(this)));
104 RegisterCommandHandler(
105 devtools::Page::getNavigationHistory::kName,
106 base::Bind(
107 &RendererOverridesHandler::PageGetNavigationHistory,
108 base::Unretained(this)));
109 RegisterCommandHandler(
110 devtools::Page::navigateToHistoryEntry::kName,
111 base::Bind(
112 &RendererOverridesHandler::PageNavigateToHistoryEntry,
113 base::Unretained(this)));
114 RegisterCommandHandler(
115 devtools::Page::captureScreenshot::kName,
116 base::Bind(
117 &RendererOverridesHandler::PageCaptureScreenshot,
118 base::Unretained(this)));
119 RegisterCommandHandler(
120 devtools::Page::startScreencast::kName,
121 base::Bind(
122 &RendererOverridesHandler::PageStartScreencast,
123 base::Unretained(this)));
124 RegisterCommandHandler(
125 devtools::Page::stopScreencast::kName,
126 base::Bind(
127 &RendererOverridesHandler::PageStopScreencast,
128 base::Unretained(this)));
129 RegisterCommandHandler(
130 devtools::Input::dispatchMouseEvent::kName,
131 base::Bind(
132 &RendererOverridesHandler::InputDispatchMouseEvent,
133 base::Unretained(this)));
134 RegisterCommandHandler(
135 devtools::Input::dispatchGestureEvent::kName,
136 base::Bind(
137 &RendererOverridesHandler::InputDispatchGestureEvent,
138 base::Unretained(this)));
141 RendererOverridesHandler::~RendererOverridesHandler() {}
143 void RendererOverridesHandler::OnClientDetached() {
144 screencast_command_ = NULL;
147 void RendererOverridesHandler::OnSwapCompositorFrame(
148 const IPC::Message& message) {
149 ViewHostMsg_SwapCompositorFrame::Param param;
150 if (!ViewHostMsg_SwapCompositorFrame::Read(&message, &param))
151 return;
152 last_compositor_frame_metadata_ = param.b.metadata;
154 if (screencast_command_)
155 InnerSwapCompositorFrame();
158 void RendererOverridesHandler::OnVisibilityChanged(bool visible) {
159 if (!screencast_command_)
160 return;
161 NotifyScreencastVisibility(visible);
164 void RendererOverridesHandler::InnerSwapCompositorFrame() {
165 if ((base::TimeTicks::Now() - last_frame_time_).InMilliseconds() <
166 kFrameRateThresholdMs) {
167 return;
170 last_frame_time_ = base::TimeTicks::Now();
171 std::string format;
172 int quality = kDefaultScreenshotQuality;
173 double scale = 1;
174 ParseCaptureParameters(screencast_command_.get(), &format, &quality, &scale);
176 RenderViewHost* host = agent_->GetRenderViewHost();
177 RenderWidgetHostViewPort* view_port =
178 RenderWidgetHostViewPort::FromRWHV(host->GetView());
180 gfx::Rect view_bounds = host->GetView()->GetViewBounds();
181 gfx::Size snapshot_size = gfx::ToFlooredSize(
182 gfx::ScaleSize(view_bounds.size(), scale));
184 view_port->CopyFromCompositingSurface(
185 view_bounds, snapshot_size,
186 base::Bind(&RendererOverridesHandler::ScreenshotCaptured,
187 weak_factory_.GetWeakPtr(),
188 scoped_refptr<DevToolsProtocol::Command>(), format, quality,
189 last_compositor_frame_metadata_));
192 void RendererOverridesHandler::ParseCaptureParameters(
193 DevToolsProtocol::Command* command,
194 std::string* format,
195 int* quality,
196 double* scale) {
197 RenderViewHost* host = agent_->GetRenderViewHost();
198 gfx::Rect view_bounds = host->GetView()->GetViewBounds();
200 *quality = kDefaultScreenshotQuality;
201 *scale = 1;
202 double max_width = -1;
203 double max_height = -1;
204 base::DictionaryValue* params = command->params();
205 if (params) {
206 params->GetString(devtools::Page::captureScreenshot::kParamFormat,
207 format);
208 params->GetInteger(devtools::Page::captureScreenshot::kParamQuality,
209 quality);
210 params->GetDouble(devtools::Page::captureScreenshot::kParamMaxWidth,
211 &max_width);
212 params->GetDouble(devtools::Page::captureScreenshot::kParamMaxHeight,
213 &max_height);
216 float device_sf = last_compositor_frame_metadata_.device_scale_factor;
218 if (max_width > 0)
219 *scale = std::min(*scale, max_width / view_bounds.width() / device_sf);
220 if (max_height > 0)
221 *scale = std::min(*scale, max_height / view_bounds.height() / device_sf);
223 if (format->empty())
224 *format = kPng;
225 if (*quality < 0 || *quality > 100)
226 *quality = kDefaultScreenshotQuality;
227 if (*scale <= 0)
228 *scale = 0.1;
229 if (*scale > 5)
230 *scale = 5;
233 // DOM agent handlers --------------------------------------------------------
235 scoped_refptr<DevToolsProtocol::Response>
236 RendererOverridesHandler::GrantPermissionsForSetFileInputFiles(
237 scoped_refptr<DevToolsProtocol::Command> command) {
238 base::DictionaryValue* params = command->params();
239 base::ListValue* file_list = NULL;
240 const char* param =
241 devtools::DOM::setFileInputFiles::kParamFiles;
242 if (!params || !params->GetList(param, &file_list))
243 return command->InvalidParamResponse(param);
244 RenderViewHost* host = agent_->GetRenderViewHost();
245 if (!host)
246 return NULL;
248 for (size_t i = 0; i < file_list->GetSize(); ++i) {
249 base::FilePath::StringType file;
250 if (!file_list->GetString(i, &file))
251 return command->InvalidParamResponse(param);
252 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
253 host->GetProcess()->GetID(), base::FilePath(file));
255 return NULL;
259 // Page agent handlers -------------------------------------------------------
261 scoped_refptr<DevToolsProtocol::Response>
262 RendererOverridesHandler::PageDisable(
263 scoped_refptr<DevToolsProtocol::Command> command) {
264 screencast_command_ = NULL;
265 return NULL;
268 scoped_refptr<DevToolsProtocol::Response>
269 RendererOverridesHandler::PageHandleJavaScriptDialog(
270 scoped_refptr<DevToolsProtocol::Command> command) {
271 base::DictionaryValue* params = command->params();
272 const char* paramAccept =
273 devtools::Page::handleJavaScriptDialog::kParamAccept;
274 bool accept;
275 if (!params || !params->GetBoolean(paramAccept, &accept))
276 return command->InvalidParamResponse(paramAccept);
277 string16 prompt_override;
278 string16* prompt_override_ptr = &prompt_override;
279 if (!params || !params->GetString(
280 devtools::Page::handleJavaScriptDialog::kParamPromptText,
281 prompt_override_ptr)) {
282 prompt_override_ptr = NULL;
285 RenderViewHost* host = agent_->GetRenderViewHost();
286 if (host) {
287 WebContents* web_contents = host->GetDelegate()->GetAsWebContents();
288 if (web_contents) {
289 JavaScriptDialogManager* manager =
290 web_contents->GetDelegate()->GetJavaScriptDialogManager();
291 if (manager && manager->HandleJavaScriptDialog(
292 web_contents, accept, prompt_override_ptr)) {
293 return NULL;
297 return command->InternalErrorResponse("No JavaScript dialog to handle");
300 scoped_refptr<DevToolsProtocol::Response>
301 RendererOverridesHandler::PageNavigate(
302 scoped_refptr<DevToolsProtocol::Command> command) {
303 base::DictionaryValue* params = command->params();
304 std::string url;
305 const char* param = devtools::Page::navigate::kParamUrl;
306 if (!params || !params->GetString(param, &url))
307 return command->InvalidParamResponse(param);
308 GURL gurl(url);
309 if (!gurl.is_valid()) {
310 return command->InternalErrorResponse("Cannot navigate to invalid URL");
312 RenderViewHost* host = agent_->GetRenderViewHost();
313 if (host) {
314 WebContents* web_contents = host->GetDelegate()->GetAsWebContents();
315 if (web_contents) {
316 web_contents->GetController()
317 .LoadURL(gurl, Referrer(), PAGE_TRANSITION_TYPED, std::string());
318 return command->SuccessResponse(new base::DictionaryValue());
321 return command->InternalErrorResponse("No WebContents to navigate");
324 scoped_refptr<DevToolsProtocol::Response>
325 RendererOverridesHandler::PageReload(
326 scoped_refptr<DevToolsProtocol::Command> command) {
327 RenderViewHost* host = agent_->GetRenderViewHost();
328 if (host) {
329 WebContents* web_contents = host->GetDelegate()->GetAsWebContents();
330 if (web_contents) {
331 // Override only if it is crashed.
332 if (!web_contents->IsCrashed())
333 return NULL;
335 web_contents->GetController().Reload(false);
336 return command->SuccessResponse(NULL);
339 return command->InternalErrorResponse("No WebContents to reload");
342 scoped_refptr<DevToolsProtocol::Response>
343 RendererOverridesHandler::PageGetNavigationHistory(
344 scoped_refptr<DevToolsProtocol::Command> command) {
345 RenderViewHost* host = agent_->GetRenderViewHost();
346 if (host) {
347 WebContents* web_contents = host->GetDelegate()->GetAsWebContents();
348 if (web_contents) {
349 base::DictionaryValue* result = new base::DictionaryValue();
350 NavigationController& controller = web_contents->GetController();
351 result->SetInteger(
352 devtools::Page::getNavigationHistory::kResponseCurrentIndex,
353 controller.GetCurrentEntryIndex());
354 ListValue* entries = new ListValue();
355 for (int i = 0; i != controller.GetEntryCount(); ++i) {
356 const NavigationEntry* entry = controller.GetEntryAtIndex(i);
357 base::DictionaryValue* entry_value = new base::DictionaryValue();
358 entry_value->SetInteger(
359 devtools::Page::getNavigationHistory::kResponseEntryId,
360 entry->GetUniqueID());
361 entry_value->SetString(
362 devtools::Page::getNavigationHistory::kResponseEntryURL,
363 entry->GetURL().spec());
364 entry_value->SetString(
365 devtools::Page::getNavigationHistory::kResponseEntryTitle,
366 entry->GetTitle());
367 entries->Append(entry_value);
369 result->Set(
370 devtools::Page::getNavigationHistory::kResponseEntries,
371 entries);
372 return command->SuccessResponse(result);
375 return command->InternalErrorResponse("No WebContents to navigate");
378 scoped_refptr<DevToolsProtocol::Response>
379 RendererOverridesHandler::PageNavigateToHistoryEntry(
380 scoped_refptr<DevToolsProtocol::Command> command) {
381 int entry_id;
383 base::DictionaryValue* params = command->params();
384 const char* param = devtools::Page::navigateToHistoryEntry::kParamEntryId;
385 if (!params || !params->GetInteger(param, &entry_id)) {
386 return command->InvalidParamResponse(param);
389 RenderViewHost* host = agent_->GetRenderViewHost();
390 if (host) {
391 WebContents* web_contents = host->GetDelegate()->GetAsWebContents();
392 if (web_contents) {
393 NavigationController& controller = web_contents->GetController();
394 for (int i = 0; i != controller.GetEntryCount(); ++i) {
395 if (controller.GetEntryAtIndex(i)->GetUniqueID() == entry_id) {
396 controller.GoToIndex(i);
397 return command->SuccessResponse(new base::DictionaryValue());
400 return command->InvalidParamResponse(param);
403 return command->InternalErrorResponse("No WebContents to navigate");
406 scoped_refptr<DevToolsProtocol::Response>
407 RendererOverridesHandler::PageCaptureScreenshot(
408 scoped_refptr<DevToolsProtocol::Command> command) {
409 std::string format;
410 int quality = kDefaultScreenshotQuality;
411 double scale = 1;
412 ParseCaptureParameters(command.get(), &format, &quality, &scale);
414 RenderViewHost* host = agent_->GetRenderViewHost();
415 gfx::Rect view_bounds = host->GetView()->GetViewBounds();
417 // Grab screen pixels if available for current platform.
418 // TODO(pfeldman): support format, scale and quality in ui::GrabViewSnapshot.
419 std::vector<unsigned char> png;
420 bool is_unscaled_png = scale == 1 && format == kPng;
421 if (is_unscaled_png && ui::GrabViewSnapshot(host->GetView()->GetNativeView(),
422 &png, view_bounds)) {
423 std::string base64_data;
424 bool success = base::Base64Encode(
425 base::StringPiece(reinterpret_cast<char*>(&*png.begin()), png.size()),
426 &base64_data);
427 if (success) {
428 base::DictionaryValue* result = new base::DictionaryValue();
429 result->SetString(
430 devtools::Page::kData, base64_data);
431 return command->SuccessResponse(result);
433 return command->InternalErrorResponse("Unable to base64encode screenshot");
436 // Fallback to copying from compositing surface.
437 RenderWidgetHostViewPort* view_port =
438 RenderWidgetHostViewPort::FromRWHV(host->GetView());
440 gfx::Size snapshot_size = gfx::ToFlooredSize(
441 gfx::ScaleSize(view_bounds.size(), scale));
442 view_port->CopyFromCompositingSurface(
443 view_bounds, snapshot_size,
444 base::Bind(&RendererOverridesHandler::ScreenshotCaptured,
445 weak_factory_.GetWeakPtr(), command, format, quality,
446 last_compositor_frame_metadata_));
447 return command->AsyncResponsePromise();
450 scoped_refptr<DevToolsProtocol::Response>
451 RendererOverridesHandler::PageStartScreencast(
452 scoped_refptr<DevToolsProtocol::Command> command) {
453 screencast_command_ = command;
454 RenderViewHostImpl* host = static_cast<RenderViewHostImpl*>(
455 agent_->GetRenderViewHost());
456 bool visible = !host->is_hidden();
457 NotifyScreencastVisibility(visible);
458 if (visible)
459 InnerSwapCompositorFrame();
460 return command->SuccessResponse(NULL);
463 scoped_refptr<DevToolsProtocol::Response>
464 RendererOverridesHandler::PageStopScreencast(
465 scoped_refptr<DevToolsProtocol::Command> command) {
466 last_frame_time_ = base::TimeTicks();
467 screencast_command_ = NULL;
468 return command->SuccessResponse(NULL);
471 void RendererOverridesHandler::ScreenshotCaptured(
472 scoped_refptr<DevToolsProtocol::Command> command,
473 const std::string& format,
474 int quality,
475 const cc::CompositorFrameMetadata& metadata,
476 bool success,
477 const SkBitmap& bitmap) {
478 if (!success) {
479 if (command) {
480 SendAsyncResponse(
481 command->InternalErrorResponse("Unable to capture screenshot"));
483 return;
486 std::vector<unsigned char> data;
487 SkAutoLockPixels lock_image(bitmap);
488 bool encoded;
489 if (format == kPng) {
490 encoded = gfx::PNGCodec::Encode(
491 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
492 gfx::PNGCodec::FORMAT_SkBitmap,
493 gfx::Size(bitmap.width(), bitmap.height()),
494 bitmap.width() * bitmap.bytesPerPixel(),
495 false, std::vector<gfx::PNGCodec::Comment>(), &data);
496 } else if (format == kJpeg) {
497 encoded = gfx::JPEGCodec::Encode(
498 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
499 gfx::JPEGCodec::FORMAT_SkBitmap,
500 bitmap.width(),
501 bitmap.height(),
502 bitmap.width() * bitmap.bytesPerPixel(),
503 quality, &data);
504 } else {
505 encoded = false;
508 if (!encoded) {
509 if (command) {
510 SendAsyncResponse(
511 command->InternalErrorResponse("Unable to encode screenshot"));
513 return;
516 std::string base_64_data;
517 if (!base::Base64Encode(base::StringPiece(
518 reinterpret_cast<char*>(&data[0]),
519 data.size()),
520 &base_64_data)) {
521 if (command) {
522 SendAsyncResponse(
523 command->InternalErrorResponse("Unable to base64 encode"));
525 return;
528 base::DictionaryValue* response = new base::DictionaryValue();
529 response->SetString(devtools::Page::kData, base_64_data);
531 // Consider metadata empty in case it has no device scale factor.
532 if (metadata.device_scale_factor != 0) {
533 response->SetDouble(devtools::Page::kParamDeviceScaleFactor,
534 metadata.device_scale_factor);
535 response->SetDouble(devtools::Page::kParamPageScaleFactor,
536 metadata.page_scale_factor);
537 response->SetDouble(devtools::Page::kParamPageScaleFactorMin,
538 metadata.min_page_scale_factor);
539 response->SetDouble(devtools::Page::kParamPageScaleFactorMax,
540 metadata.max_page_scale_factor);
541 response->SetDouble(devtools::Page::kParamOffsetTop,
542 metadata.location_bar_content_translation.y());
543 response->SetDouble(devtools::Page::kParamOffsetBottom,
544 metadata.overdraw_bottom_height);
546 base::DictionaryValue* viewport = new base::DictionaryValue();
547 viewport->SetDouble(devtools::kParamX, metadata.root_scroll_offset.x());
548 viewport->SetDouble(devtools::kParamY, metadata.root_scroll_offset.y());
549 viewport->SetDouble(devtools::kParamWidth, metadata.viewport_size.width());
550 viewport->SetDouble(devtools::kParamHeight,
551 metadata.viewport_size.height());
552 response->Set(devtools::Page::kParamViewport, viewport);
555 if (command) {
556 SendAsyncResponse(command->SuccessResponse(response));
557 } else {
558 SendNotification(devtools::Page::screencastFrame::kName, response);
562 void RendererOverridesHandler::NotifyScreencastVisibility(bool visible) {
563 base::DictionaryValue* params = new base::DictionaryValue();
564 params->SetBoolean(
565 devtools::Page::screencastVisibilityChanged::kParamVisible, visible);
566 SendNotification(
567 devtools::Page::screencastVisibilityChanged::kName, params);
570 // Input agent handlers ------------------------------------------------------
572 scoped_refptr<DevToolsProtocol::Response>
573 RendererOverridesHandler::InputDispatchMouseEvent(
574 scoped_refptr<DevToolsProtocol::Command> command) {
575 base::DictionaryValue* params = command->params();
576 if (!params)
577 return NULL;
579 bool device_space = false;
580 if (!params->GetBoolean(devtools::Input::kParamDeviceSpace,
581 &device_space) ||
582 !device_space) {
583 return NULL;
586 RenderViewHost* host = agent_->GetRenderViewHost();
587 WebKit::WebMouseEvent mouse_event;
588 ParseGenericInputParams(params, &mouse_event);
590 std::string type;
591 if (params->GetString(devtools::Input::kParamType,
592 &type)) {
593 if (type == "mousePressed")
594 mouse_event.type = WebInputEvent::MouseDown;
595 else if (type == "mouseReleased")
596 mouse_event.type = WebInputEvent::MouseUp;
597 else if (type == "mouseMoved")
598 mouse_event.type = WebInputEvent::MouseMove;
599 else
600 return NULL;
601 } else {
602 return NULL;
605 if (!params->GetInteger(devtools::kParamX, &mouse_event.x) ||
606 !params->GetInteger(devtools::kParamY, &mouse_event.y)) {
607 return NULL;
610 mouse_event.windowX = mouse_event.x;
611 mouse_event.windowY = mouse_event.y;
612 mouse_event.globalX = mouse_event.x;
613 mouse_event.globalY = mouse_event.y;
615 params->GetInteger(devtools::Input::dispatchMouseEvent::kParamClickCount,
616 &mouse_event.clickCount);
618 std::string button;
619 if (!params->GetString(devtools::Input::dispatchMouseEvent::kParamButton,
620 &button)) {
621 return NULL;
624 if (button == "none") {
625 mouse_event.button = WebMouseEvent::ButtonNone;
626 } else if (button == "left") {
627 mouse_event.button = WebMouseEvent::ButtonLeft;
628 mouse_event.modifiers |= WebInputEvent::LeftButtonDown;
629 } else if (button == "middle") {
630 mouse_event.button = WebMouseEvent::ButtonMiddle;
631 mouse_event.modifiers |= WebInputEvent::MiddleButtonDown;
632 } else if (button == "right") {
633 mouse_event.button = WebMouseEvent::ButtonRight;
634 mouse_event.modifiers |= WebInputEvent::RightButtonDown;
635 } else {
636 return NULL;
639 host->ForwardMouseEvent(mouse_event);
640 return command->SuccessResponse(NULL);
643 scoped_refptr<DevToolsProtocol::Response>
644 RendererOverridesHandler::InputDispatchGestureEvent(
645 scoped_refptr<DevToolsProtocol::Command> command) {
646 base::DictionaryValue* params = command->params();
647 if (!params)
648 return NULL;
650 RenderViewHostImpl* host = static_cast<RenderViewHostImpl*>(
651 agent_->GetRenderViewHost());
652 WebKit::WebGestureEvent event;
653 ParseGenericInputParams(params, &event);
655 std::string type;
656 if (params->GetString(devtools::Input::kParamType,
657 &type)) {
658 if (type == "scrollBegin")
659 event.type = WebInputEvent::GestureScrollBegin;
660 else if (type == "scrollUpdate")
661 event.type = WebInputEvent::GestureScrollUpdate;
662 else if (type == "scrollEnd")
663 event.type = WebInputEvent::GestureScrollEnd;
664 else if (type == "tapDown")
665 event.type = WebInputEvent::GestureTapDown;
666 else if (type == "tap")
667 event.type = WebInputEvent::GestureTap;
668 else if (type == "pinchBegin")
669 event.type = WebInputEvent::GesturePinchBegin;
670 else if (type == "pinchUpdate")
671 event.type = WebInputEvent::GesturePinchUpdate;
672 else if (type == "pinchEnd")
673 event.type = WebInputEvent::GesturePinchEnd;
674 else
675 return NULL;
676 } else {
677 return NULL;
680 if (!params->GetInteger(devtools::kParamX, &event.x) ||
681 !params->GetInteger(devtools::kParamY, &event.y)) {
682 return NULL;
684 event.globalX = event.x;
685 event.globalY = event.y;
687 if (type == "scrollUpdate") {
688 int dx;
689 int dy;
690 if (!params->GetInteger(
691 devtools::Input::dispatchGestureEvent::kParamDeltaX, &dx) ||
692 !params->GetInteger(
693 devtools::Input::dispatchGestureEvent::kParamDeltaY, &dy)) {
694 return NULL;
696 event.data.scrollUpdate.deltaX = dx;
697 event.data.scrollUpdate.deltaY = dy;
700 if (type == "pinchUpdate") {
701 double scale;
702 if (!params->GetDouble(
703 devtools::Input::dispatchGestureEvent::kParamPinchScale,
704 &scale)) {
705 return NULL;
707 event.data.pinchUpdate.scale = static_cast<float>(scale);
710 host->ForwardGestureEvent(event);
711 return command->SuccessResponse(NULL);
714 } // namespace content