Disable TabDragController tests that fail with a real compositor.
[chromium-blink-merge.git] / chrome / browser / extensions / api / capture_web_contents_function.cc
blob8e7fd7cbf1ba968278132e2dd600b12555f54115
1 // Copyright 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 "chrome/browser/extensions/api/capture_web_contents_function.h"
7 #include "base/base64.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
10 #include "chrome/common/extensions/extension_constants.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/render_widget_host_view.h"
13 #include "content/public/browser/web_contents.h"
14 #include "extensions/browser/extension_function.h"
15 #include "ui/gfx/codec/jpeg_codec.h"
16 #include "ui/gfx/codec/png_codec.h"
18 using content::RenderViewHost;
19 using content::RenderWidgetHost;
20 using content::RenderWidgetHostView;
21 using content::WebContents;
23 namespace extensions {
25 CaptureWebContentsFunction::CaptureWebContentsFunction() {
28 CaptureWebContentsFunction::~CaptureWebContentsFunction() {
31 bool CaptureWebContentsFunction::HasPermission() {
32 return true;
35 bool CaptureWebContentsFunction::RunImpl() {
36 EXTENSION_FUNCTION_VALIDATE(args_);
38 context_id_ = extension_misc::kCurrentWindowId;
39 args_->GetInteger(0, &context_id_);
41 scoped_ptr<ImageDetails> image_details;
42 if (args_->GetSize() > 1) {
43 base::Value* spec = NULL;
44 EXTENSION_FUNCTION_VALIDATE(args_->Get(1, &spec) && spec);
45 image_details = ImageDetails::FromValue(*spec);
48 if (!IsScreenshotEnabled())
49 return false;
51 WebContents* contents = GetWebContentsForID(context_id_);
52 if (!contents)
53 return false;
55 // The default format and quality setting used when encoding jpegs.
56 const ImageDetails::Format kDefaultFormat = ImageDetails::FORMAT_JPEG;
57 const int kDefaultQuality = 90;
59 image_format_ = kDefaultFormat;
60 image_quality_ = kDefaultQuality;
62 if (image_details) {
63 if (image_details->format != ImageDetails::FORMAT_NONE)
64 image_format_ = image_details->format;
65 if (image_details->quality.get())
66 image_quality_ = *image_details->quality;
69 RenderViewHost* render_view_host = contents->GetRenderViewHost();
70 RenderWidgetHostView* view = render_view_host->GetView();
71 if (!view) {
72 OnCaptureFailure(FAILURE_REASON_VIEW_INVISIBLE);
73 return false;
75 render_view_host->CopyFromBackingStore(
76 gfx::Rect(),
77 view->GetViewBounds().size(),
78 base::Bind(&CaptureWebContentsFunction::CopyFromBackingStoreComplete,
79 this));
80 return true;
83 void CaptureWebContentsFunction::CopyFromBackingStoreComplete(
84 bool succeeded,
85 const SkBitmap& bitmap) {
86 if (succeeded) {
87 OnCaptureSuccess(bitmap);
88 return;
91 WebContents* contents = GetWebContentsForID(context_id_);
92 if (!contents) {
93 OnCaptureFailure(FAILURE_REASON_CONTENT_NOT_FOUND);
94 return;
97 // Ask the renderer for a snapshot of the page.
98 RenderWidgetHost* render_widget_host = contents->GetRenderViewHost();
99 render_widget_host->GetSnapshotFromRenderer(
100 gfx::Rect(),
101 base::Bind(&CaptureWebContentsFunction::GetSnapshotFromRendererComplete,
102 this));
105 void CaptureWebContentsFunction::GetSnapshotFromRendererComplete(
106 bool succeeded,
107 const SkBitmap& bitmap) {
108 if (succeeded)
109 OnCaptureSuccess(bitmap);
110 else
111 OnCaptureFailure(FAILURE_REASON_UNKNOWN);
114 void CaptureWebContentsFunction::OnCaptureSuccess(const SkBitmap& bitmap) {
115 std::vector<unsigned char> data;
116 SkAutoLockPixels screen_capture_lock(bitmap);
117 bool encoded = false;
118 std::string mime_type;
119 switch (image_format_) {
120 case ImageDetails::FORMAT_JPEG:
121 encoded = gfx::JPEGCodec::Encode(
122 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
123 gfx::JPEGCodec::FORMAT_SkBitmap,
124 bitmap.width(),
125 bitmap.height(),
126 static_cast<int>(bitmap.rowBytes()),
127 image_quality_,
128 &data);
129 mime_type = tabs_constants::kMimeTypeJpeg;
130 break;
131 case ImageDetails::FORMAT_PNG:
132 encoded = gfx::PNGCodec::EncodeBGRASkBitmap(
133 bitmap,
134 true, // Discard transparency.
135 &data);
136 mime_type = tabs_constants::kMimeTypePng;
137 break;
138 default:
139 NOTREACHED() << "Invalid image format.";
142 if (!encoded) {
143 OnCaptureFailure(FAILURE_REASON_ENCODING_FAILED);
144 return;
147 std::string base64_result;
148 base::StringPiece stream_as_string(
149 reinterpret_cast<const char*>(vector_as_array(&data)), data.size());
151 base::Base64Encode(stream_as_string, &base64_result);
152 base64_result.insert(0, base::StringPrintf("data:%s;base64,",
153 mime_type.c_str()));
154 SetResult(new base::StringValue(base64_result));
155 SendResponse(true);
158 } // namespace extensions