Chromium Code Reviews| Index: content/browser/devtools/renderer_overrides_handler.cc |
| diff --git a/content/browser/devtools/renderer_overrides_handler.cc b/content/browser/devtools/renderer_overrides_handler.cc |
| index 69fe055fd90a790ef8d459727041a60e9105a77a..448c1e76107215e937559045a53b79ee0ca0fd44 100644 |
| --- a/content/browser/devtools/renderer_overrides_handler.cc |
| +++ b/content/browser/devtools/renderer_overrides_handler.cc |
| @@ -11,11 +11,14 @@ |
| #include "base/bind_helpers.h" |
| #include "base/files/file_path.h" |
| #include "base/strings/string16.h" |
| +#include "base/time/time.h" |
| #include "base/values.h" |
| #include "content/browser/child_process_security_policy_impl.h" |
| #include "content/browser/devtools/devtools_protocol_constants.h" |
| #include "content/browser/devtools/devtools_tracing_handler.h" |
| #include "content/browser/renderer_host/render_view_host_delegate.h" |
| +#include "content/port/browser/render_view_host_delegate_view.h" |
| +#include "content/port/browser/render_widget_host_view_port.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/devtools_agent_host.h" |
| #include "content/public/browser/javascript_dialog_manager.h" |
| @@ -27,9 +30,20 @@ |
| #include "content/public/browser/web_contents_delegate.h" |
| #include "content/public/common/page_transition_types.h" |
| #include "content/public/common/referrer.h" |
| -#include "ui/snapshot/snapshot.h" |
| +#include "ui/gfx/codec/jpeg_codec.h" |
| +#include "ui/gfx/codec/png_codec.h" |
| #include "url/gurl.h" |
| +using base::TimeTicks; |
| + |
| +namespace { |
| + |
| +static const char kPng[] = "png"; |
| +static const char kJpeg[] = "jpeg"; |
| +static int kDefaultQuality = 90; |
|
Sami
2013/08/08 11:35:00
nit: kDefaultScreenshotQuality?
pfeldman
2013/08/09 13:59:02
Done.
|
| + |
| +} // namespace |
| + |
| namespace content { |
| RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) |
| @@ -141,44 +155,101 @@ RendererOverridesHandler::PageNavigate( |
| scoped_refptr<DevToolsProtocol::Response> |
| RendererOverridesHandler::PageCaptureScreenshot( |
| scoped_refptr<DevToolsProtocol::Command> command) { |
| - // Emulate async processing. |
| - BrowserThread::PostTask( |
| - BrowserThread::UI, FROM_HERE, |
| + RenderViewHost* host = agent_->GetRenderViewHost(); |
| + RenderWidgetHostViewPort* view_port = |
| + RenderWidgetHostViewPort::FromRWHV(host->GetView()); |
| + |
| + gfx::Rect view_bounds = host->GetView()->GetViewBounds(); |
| + gfx::Rect snapshot_bounds(view_bounds.size()); |
| + gfx::Size snapshot_size = snapshot_bounds.size(); |
| + |
| + view_port->CopyFromCompositingSurface( |
| + snapshot_bounds, snapshot_size, |
| base::Bind(&RendererOverridesHandler::CaptureScreenshot, |
| - weak_factory_.GetWeakPtr(), |
| - command)); |
| + weak_factory_.GetWeakPtr(), command)); |
| return command->AsyncResponsePromise(); |
| } |
| void RendererOverridesHandler::CaptureScreenshot( |
| - scoped_refptr<DevToolsProtocol::Command> command) { |
| + scoped_refptr<DevToolsProtocol::Command> command, |
| + bool success, |
| + const SkBitmap& bitmap) { |
| + if (!success) { |
| + SendRawMessage( |
| + command->InternalErrorResponse("Unable to capture screenshot")-> |
| + Serialize()); |
| + return; |
| + } |
| - RenderViewHost* host = agent_->GetRenderViewHost(); |
| - gfx::Rect view_bounds = host->GetView()->GetViewBounds(); |
| - gfx::Rect snapshot_bounds(view_bounds.size()); |
| - gfx::Size snapshot_size = snapshot_bounds.size(); |
| + std::string format; |
| + int quality = kDefaultQuality; |
| + double scale = 0; |
| - std::vector<unsigned char> png; |
| - if (ui::GrabViewSnapshot(host->GetView()->GetNativeView(), |
| - &png, |
| - snapshot_bounds)) { |
| - std::string base_64_data; |
| - bool success = base::Base64Encode( |
| - base::StringPiece(reinterpret_cast<char*>(&*png.begin()), png.size()), |
| - &base_64_data); |
| - if (success) { |
| - base::DictionaryValue* result = new base::DictionaryValue(); |
| - result->SetString( |
| - devtools::Page::captureScreenshot::kResponseData, base_64_data); |
| - scoped_refptr<DevToolsProtocol::Response> response = |
| - command->SuccessResponse(result); |
| - SendRawMessage(response->Serialize()); |
| - return; |
| - } |
| + base::DictionaryValue* params = command->params(); |
| + if (params) { |
| + params->GetString(devtools::Page::captureScreenshot::kParamFormat, |
| + &format); |
| + params->GetInteger(devtools::Page::captureScreenshot::kParamQuality, |
| + &quality); |
| + params->GetDouble(devtools::Page::captureScreenshot::kParamScale, |
| + &scale); |
| + } |
| + |
| + if (format.empty()) |
| + format = kPng; |
| + if (quality < 0 || quality > 100) |
| + quality = kDefaultQuality; |
| + if (scale <= 0 || scale > 1) |
| + scale = 1; |
| + |
| + // TODO(pfeldman): apply scale. |
| + |
| + std::vector<unsigned char> data; |
| + SkAutoLockPixels lock_image(bitmap); |
| + |
| + bool encoded; |
| + if (format == kPng) { |
| + encoded = gfx::PNGCodec::Encode( |
| + reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), |
|
Sami
2013/08/08 11:35:00
nit: should be indented by two more spaces.
pfeldman
2013/08/09 13:59:02
Done.
|
| + gfx::PNGCodec::FORMAT_SkBitmap, |
| + gfx::Size(bitmap.width(), bitmap.height()), |
| + bitmap.width() * bitmap.bytesPerPixel(), |
| + false, std::vector<gfx::PNGCodec::Comment>(), &data); |
| + } else if (format == kJpeg) { |
| + encoded = gfx::JPEGCodec::Encode( |
| + reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), |
|
Sami
2013/08/08 11:35:00
nit: ditto
pfeldman
2013/08/09 13:59:02
Done.
|
| + gfx::JPEGCodec::FORMAT_SkBitmap, |
| + bitmap.width(), |
| + bitmap.height(), |
| + bitmap.width() * bitmap.bytesPerPixel(), |
| + quality, &data); |
| + } else { |
| + encoded = false; |
| + } |
| + |
| + if (!encoded) { |
| + SendRawMessage( |
| + command->InternalErrorResponse("Unable to encode screenshot")-> |
| + Serialize()); |
| + return; |
| } |
| - SendRawMessage(command-> |
| - InternalErrorResponse("Unable to capture a screenshot")->Serialize()); |
| + |
| + std::string base_64_data; |
|
Sami
2013/08/08 11:35:00
It would be great if we could free the bitmap at t
pfeldman
2013/08/09 13:59:02
It is declared in RenderWidgetHostViewPort and cou
|
| + if (!base::Base64Encode(base::StringPiece( |
| + reinterpret_cast<char*>(&data[0]), |
| + data.size()), |
| + &base_64_data)) { |
| + SendRawMessage( |
| + command->InternalErrorResponse("Unable to base64 encode screenshot")-> |
| + Serialize()); |
| + return; |
| + } |
| + |
| + base::DictionaryValue* response = new base::DictionaryValue(); |
| + response->SetString( |
| + devtools::Page::captureScreenshot::kResponseData, base_64_data); |
| + SendRawMessage(command->SuccessResponse(response)->Serialize()); |
| } |
| } // namespace content |