OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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/renderer_overrides_handler.h" | 5 #include "content/browser/devtools/renderer_overrides_handler.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/barrier_closure.h" | 10 #include "base/barrier_closure.h" |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 194 |
195 RenderWidgetHostViewPort* view_port = | 195 RenderWidgetHostViewPort* view_port = |
196 RenderWidgetHostViewPort::FromRWHV(host->GetView()); | 196 RenderWidgetHostViewPort::FromRWHV(host->GetView()); |
197 | 197 |
198 gfx::Rect view_bounds = host->GetView()->GetViewBounds(); | 198 gfx::Rect view_bounds = host->GetView()->GetViewBounds(); |
199 gfx::Size snapshot_size = gfx::ToFlooredSize( | 199 gfx::Size snapshot_size = gfx::ToFlooredSize( |
200 gfx::ScaleSize(view_bounds.size(), scale)); | 200 gfx::ScaleSize(view_bounds.size(), scale)); |
201 | 201 |
202 view_port->CopyFromCompositingSurface( | 202 view_port->CopyFromCompositingSurface( |
203 view_bounds, snapshot_size, | 203 view_bounds, snapshot_size, |
204 base::Bind(&RendererOverridesHandler::ScreenshotCaptured, | 204 base::Bind(&RendererOverridesHandler::ScreencastFrameCaptured, |
205 weak_factory_.GetWeakPtr(), | 205 weak_factory_.GetWeakPtr(), |
206 scoped_refptr<DevToolsProtocol::Command>(), format, quality, | 206 format, quality, last_compositor_frame_metadata_), |
207 last_compositor_frame_metadata_), | |
208 SkBitmap::kARGB_8888_Config); | 207 SkBitmap::kARGB_8888_Config); |
209 } | 208 } |
210 | 209 |
211 void RendererOverridesHandler::ParseCaptureParameters( | 210 void RendererOverridesHandler::ParseCaptureParameters( |
212 DevToolsProtocol::Command* command, | 211 DevToolsProtocol::Command* command, |
213 std::string* format, | 212 std::string* format, |
214 int* quality, | 213 int* quality, |
215 double* scale) { | 214 double* scale) { |
216 *quality = kDefaultScreenshotQuality; | 215 *quality = kDefaultScreenshotQuality; |
217 *scale = 1; | 216 *scale = 1; |
218 double max_width = -1; | 217 double max_width = -1; |
219 double max_height = -1; | 218 double max_height = -1; |
220 base::DictionaryValue* params = command->params(); | 219 base::DictionaryValue* params = command->params(); |
221 if (params) { | 220 if (params) { |
222 params->GetString(devtools::Page::captureScreenshot::kParamFormat, | 221 params->GetString(devtools::Page::startScreencast::kParamFormat, |
223 format); | 222 format); |
224 params->GetInteger(devtools::Page::captureScreenshot::kParamQuality, | 223 params->GetInteger(devtools::Page::startScreencast::kParamQuality, |
225 quality); | 224 quality); |
226 params->GetDouble(devtools::Page::captureScreenshot::kParamMaxWidth, | 225 params->GetDouble(devtools::Page::startScreencast::kParamMaxWidth, |
227 &max_width); | 226 &max_width); |
228 params->GetDouble(devtools::Page::captureScreenshot::kParamMaxHeight, | 227 params->GetDouble(devtools::Page::startScreencast::kParamMaxHeight, |
229 &max_height); | 228 &max_height); |
230 } | 229 } |
231 | 230 |
232 RenderViewHost* host = agent_->GetRenderViewHost(); | 231 RenderViewHost* host = agent_->GetRenderViewHost(); |
233 CHECK(host->GetView()); | 232 CHECK(host->GetView()); |
234 gfx::Rect view_bounds = host->GetView()->GetViewBounds(); | 233 gfx::Rect view_bounds = host->GetView()->GetViewBounds(); |
235 if (max_width > 0) | 234 if (max_width > 0) |
236 *scale = std::min(*scale, max_width / view_bounds.width()); | 235 *scale = std::min(*scale, max_width / view_bounds.width()); |
237 if (max_height > 0) | 236 if (max_height > 0) |
238 *scale = std::min(*scale, max_height / view_bounds.height()); | 237 *scale = std::min(*scale, max_height / view_bounds.height()); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 } | 415 } |
417 return command->InvalidParamResponse(param); | 416 return command->InvalidParamResponse(param); |
418 } | 417 } |
419 } | 418 } |
420 return command->InternalErrorResponse("No WebContents to navigate"); | 419 return command->InternalErrorResponse("No WebContents to navigate"); |
421 } | 420 } |
422 | 421 |
423 scoped_refptr<DevToolsProtocol::Response> | 422 scoped_refptr<DevToolsProtocol::Response> |
424 RendererOverridesHandler::PageCaptureScreenshot( | 423 RendererOverridesHandler::PageCaptureScreenshot( |
425 scoped_refptr<DevToolsProtocol::Command> command) { | 424 scoped_refptr<DevToolsProtocol::Command> command) { |
426 RenderViewHost* host = agent_->GetRenderViewHost(); | 425 RenderViewHostImpl* host = static_cast<RenderViewHostImpl*>( |
| 426 agent_->GetRenderViewHost()); |
427 if (!host->GetView()) | 427 if (!host->GetView()) |
428 return command->InternalErrorResponse("Unable to access the view"); | 428 return command->InternalErrorResponse("Unable to access the view"); |
429 | 429 |
430 std::string format; | 430 host->GetSnapshotFromBrowser( |
431 int quality = kDefaultScreenshotQuality; | 431 base::Bind(&RendererOverridesHandler::ScreenshotCaptured, |
432 double scale = 1; | 432 weak_factory_.GetWeakPtr(), command)); |
433 ParseCaptureParameters(command.get(), &format, &quality, &scale); | |
434 | 433 |
435 gfx::Rect view_bounds = host->GetView()->GetViewBounds(); | |
436 gfx::Size snapshot_size = gfx::ToFlooredSize( | |
437 gfx::ScaleSize(view_bounds.size(), scale)); | |
438 | |
439 // Grab screen pixels if available for current platform. | |
440 // TODO(pfeldman): support format, scale and quality in ui::GrabViewSnapshot. | |
441 std::vector<unsigned char> png; | |
442 bool is_unscaled_png = scale == 1 && format == kPng; | |
443 if (is_unscaled_png && ui::GrabViewSnapshot(host->GetView()->GetNativeView(), | |
444 &png, | |
445 gfx::Rect(snapshot_size))) { | |
446 std::string base64_data; | |
447 base::Base64Encode( | |
448 base::StringPiece(reinterpret_cast<char*>(&*png.begin()), png.size()), | |
449 &base64_data); | |
450 base::DictionaryValue* result = new base::DictionaryValue(); | |
451 result->SetString( | |
452 devtools::Page::captureScreenshot::kResponseData, base64_data); | |
453 return command->SuccessResponse(result); | |
454 } | |
455 | |
456 // Fallback to copying from compositing surface. | |
457 RenderWidgetHostViewPort* view_port = | |
458 RenderWidgetHostViewPort::FromRWHV(host->GetView()); | |
459 | |
460 view_port->CopyFromCompositingSurface( | |
461 view_bounds, snapshot_size, | |
462 base::Bind(&RendererOverridesHandler::ScreenshotCaptured, | |
463 weak_factory_.GetWeakPtr(), command, format, quality, | |
464 last_compositor_frame_metadata_), | |
465 SkBitmap::kARGB_8888_Config); | |
466 return command->AsyncResponsePromise(); | 434 return command->AsyncResponsePromise(); |
467 } | 435 } |
468 | 436 |
| 437 void RendererOverridesHandler::ScreenshotCaptured( |
| 438 scoped_refptr<DevToolsProtocol::Command> command, |
| 439 const unsigned char* png_data, |
| 440 size_t png_size) { |
| 441 if (!png_data || !png_size) { |
| 442 SendAsyncResponse( |
| 443 command->InternalErrorResponse("Unable to capture screenshot")); |
| 444 return; |
| 445 } |
| 446 |
| 447 std::string base_64_data; |
| 448 base::Base64Encode( |
| 449 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size), |
| 450 &base_64_data); |
| 451 |
| 452 base::DictionaryValue* response = new base::DictionaryValue(); |
| 453 response->SetString(devtools::Page::screencastFrame::kParamData, |
| 454 base_64_data); |
| 455 |
| 456 SendAsyncResponse(command->SuccessResponse(response)); |
| 457 } |
| 458 |
469 scoped_refptr<DevToolsProtocol::Response> | 459 scoped_refptr<DevToolsProtocol::Response> |
470 RendererOverridesHandler::PageCanScreencast( | 460 RendererOverridesHandler::PageCanScreencast( |
471 scoped_refptr<DevToolsProtocol::Command> command) { | 461 scoped_refptr<DevToolsProtocol::Command> command) { |
472 base::DictionaryValue* result = new base::DictionaryValue(); | 462 base::DictionaryValue* result = new base::DictionaryValue(); |
473 #if defined(OS_ANDROID) | 463 #if defined(OS_ANDROID) |
474 result->SetBoolean(devtools::kResult, true); | 464 result->SetBoolean(devtools::kResult, true); |
475 #else | 465 #else |
476 result->SetBoolean(devtools::kResult, false); | 466 result->SetBoolean(devtools::kResult, false); |
477 #endif // defined(OS_ANDROID) | 467 #endif // defined(OS_ANDROID) |
478 return command->SuccessResponse(result); | 468 return command->SuccessResponse(result); |
(...skipping 13 matching lines...) Expand all Loading... |
492 } | 482 } |
493 | 483 |
494 scoped_refptr<DevToolsProtocol::Response> | 484 scoped_refptr<DevToolsProtocol::Response> |
495 RendererOverridesHandler::PageStopScreencast( | 485 RendererOverridesHandler::PageStopScreencast( |
496 scoped_refptr<DevToolsProtocol::Command> command) { | 486 scoped_refptr<DevToolsProtocol::Command> command) { |
497 last_frame_time_ = base::TimeTicks(); | 487 last_frame_time_ = base::TimeTicks(); |
498 screencast_command_ = NULL; | 488 screencast_command_ = NULL; |
499 return command->SuccessResponse(NULL); | 489 return command->SuccessResponse(NULL); |
500 } | 490 } |
501 | 491 |
502 void RendererOverridesHandler::ScreenshotCaptured( | 492 void RendererOverridesHandler::ScreencastFrameCaptured( |
503 scoped_refptr<DevToolsProtocol::Command> command, | |
504 const std::string& format, | 493 const std::string& format, |
505 int quality, | 494 int quality, |
506 const cc::CompositorFrameMetadata& metadata, | 495 const cc::CompositorFrameMetadata& metadata, |
507 bool success, | 496 bool success, |
508 const SkBitmap& bitmap) { | 497 const SkBitmap& bitmap) { |
509 if (!success) { | 498 if (!success) { |
510 if (command) { | 499 if (capture_retry_count_) { |
511 SendAsyncResponse( | |
512 command->InternalErrorResponse("Unable to capture screenshot")); | |
513 } else if (capture_retry_count_) { | |
514 --capture_retry_count_; | 500 --capture_retry_count_; |
515 base::MessageLoop::current()->PostDelayedTask( | 501 base::MessageLoop::current()->PostDelayedTask( |
516 FROM_HERE, | 502 FROM_HERE, |
517 base::Bind(&RendererOverridesHandler::InnerSwapCompositorFrame, | 503 base::Bind(&RendererOverridesHandler::InnerSwapCompositorFrame, |
518 weak_factory_.GetWeakPtr()), | 504 weak_factory_.GetWeakPtr()), |
519 base::TimeDelta::FromMilliseconds(kFrameRateThresholdMs)); | 505 base::TimeDelta::FromMilliseconds(kFrameRateThresholdMs)); |
520 } | 506 } |
521 return; | 507 return; |
522 } | 508 } |
523 | 509 |
(...skipping 12 matching lines...) Expand all Loading... |
536 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), | 522 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), |
537 gfx::JPEGCodec::FORMAT_SkBitmap, | 523 gfx::JPEGCodec::FORMAT_SkBitmap, |
538 bitmap.width(), | 524 bitmap.width(), |
539 bitmap.height(), | 525 bitmap.height(), |
540 bitmap.width() * bitmap.bytesPerPixel(), | 526 bitmap.width() * bitmap.bytesPerPixel(), |
541 quality, &data); | 527 quality, &data); |
542 } else { | 528 } else { |
543 encoded = false; | 529 encoded = false; |
544 } | 530 } |
545 | 531 |
546 if (!encoded) { | 532 if (!encoded) |
547 if (command) { | |
548 SendAsyncResponse( | |
549 command->InternalErrorResponse("Unable to encode screenshot")); | |
550 } | |
551 return; | 533 return; |
552 } | |
553 | 534 |
554 std::string base_64_data; | 535 std::string base_64_data; |
555 base::Base64Encode( | 536 base::Base64Encode( |
556 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()), | 537 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()), |
557 &base_64_data); | 538 &base_64_data); |
558 | 539 |
559 base::DictionaryValue* response = new base::DictionaryValue(); | 540 base::DictionaryValue* response = new base::DictionaryValue(); |
560 response->SetString(devtools::Page::screencastFrame::kParamData, | 541 response->SetString(devtools::Page::screencastFrame::kParamData, |
561 base_64_data); | 542 base_64_data); |
562 | 543 |
(...skipping 25 matching lines...) Expand all Loading... |
588 metadata.root_scroll_offset.x()); | 569 metadata.root_scroll_offset.x()); |
589 viewport->SetDouble(devtools::DOM::Rect::kParamY, | 570 viewport->SetDouble(devtools::DOM::Rect::kParamY, |
590 metadata.root_scroll_offset.y()); | 571 metadata.root_scroll_offset.y()); |
591 viewport->SetDouble(devtools::DOM::Rect::kParamWidth, | 572 viewport->SetDouble(devtools::DOM::Rect::kParamWidth, |
592 metadata.viewport_size.width()); | 573 metadata.viewport_size.width()); |
593 viewport->SetDouble(devtools::DOM::Rect::kParamHeight, | 574 viewport->SetDouble(devtools::DOM::Rect::kParamHeight, |
594 metadata.viewport_size.height()); | 575 metadata.viewport_size.height()); |
595 response_metadata->Set( | 576 response_metadata->Set( |
596 devtools::Page::ScreencastFrameMetadata::kParamViewport, viewport); | 577 devtools::Page::ScreencastFrameMetadata::kParamViewport, viewport); |
597 | 578 |
598 if (command) { | 579 response->Set(devtools::Page::screencastFrame::kParamMetadata, |
599 response->Set(devtools::Page::captureScreenshot::kResponseMetadata, | 580 response_metadata); |
600 response_metadata); | |
601 } else { | |
602 response->Set(devtools::Page::screencastFrame::kParamMetadata, | |
603 response_metadata); | |
604 } | |
605 } | 581 } |
606 | 582 |
607 if (command) { | 583 SendNotification(devtools::Page::screencastFrame::kName, response); |
608 SendAsyncResponse(command->SuccessResponse(response)); | |
609 } else { | |
610 SendNotification(devtools::Page::screencastFrame::kName, response); | |
611 } | |
612 } | 584 } |
613 | 585 |
614 // Quota and Usage ------------------------------------------ | 586 // Quota and Usage ------------------------------------------ |
615 | 587 |
616 namespace { | 588 namespace { |
617 | 589 |
618 typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)> | 590 typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)> |
619 ResponseCallback; | 591 ResponseCallback; |
620 | 592 |
621 void QueryUsageAndQuotaCompletedOnIOThread( | 593 void QueryUsageAndQuotaCompletedOnIOThread( |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 return NULL; | 944 return NULL; |
973 } | 945 } |
974 event.data.pinchUpdate.scale = static_cast<float>(scale); | 946 event.data.pinchUpdate.scale = static_cast<float>(scale); |
975 } | 947 } |
976 | 948 |
977 host->ForwardGestureEvent(event); | 949 host->ForwardGestureEvent(event); |
978 return command->SuccessResponse(NULL); | 950 return command->SuccessResponse(NULL); |
979 } | 951 } |
980 | 952 |
981 } // namespace content | 953 } // namespace content |
OLD | NEW |