| Index: chrome/renderer/automation/automation_renderer_helper.cc
|
| diff --git a/chrome/renderer/automation/automation_renderer_helper.cc b/chrome/renderer/automation/automation_renderer_helper.cc
|
| index 28a8b180a66d1148d286314aeaf61dbaa764f001..7d09dc10f27c17aa37ea46e1d9147abb7792ce28 100644
|
| --- a/chrome/renderer/automation/automation_renderer_helper.cc
|
| +++ b/chrome/renderer/automation/automation_renderer_helper.cc
|
| @@ -4,13 +4,24 @@
|
|
|
| #include "chrome/renderer/automation/automation_renderer_helper.h"
|
|
|
| +#include <algorithm>
|
| +
|
| #include "base/basictypes.h"
|
| #include "chrome/common/automation_messages.h"
|
| +#include "content/public/renderer/render_view.h"
|
| +#include "skia/ext/platform_canvas.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
| +#include "ui/gfx/codec/png_codec.h"
|
| +#include "ui/gfx/rect.h"
|
| +#include "webkit/glue/webkit_glue.h"
|
|
|
| using WebKit::WebFrame;
|
| +using WebKit::WebSize;
|
| using WebKit::WebURL;
|
| +using WebKit::WebView;
|
|
|
| AutomationRendererHelper::AutomationRendererHelper(
|
| content::RenderView* render_view)
|
| @@ -19,6 +30,92 @@ AutomationRendererHelper::AutomationRendererHelper(
|
|
|
| AutomationRendererHelper::~AutomationRendererHelper() { }
|
|
|
| +bool AutomationRendererHelper::SnapshotEntirePage(
|
| + WebView* view,
|
| + std::vector<unsigned char>* png_data,
|
| + std::string* error_msg) {
|
| + WebFrame* frame = view->mainFrame();
|
| + WebSize old_size = view->size();
|
| + WebSize new_size = frame->contentsSize();
|
| + // For RTL, the minimum scroll offset may be negative.
|
| + WebSize min_scroll = frame->minimumScrollOffset();
|
| + WebSize old_scroll = frame->scrollOffset();
|
| + bool fixed_layout_enabled = view->isFixedLayoutModeEnabled();
|
| + WebSize fixed_size = view->fixedLayoutSize();
|
| +
|
| + frame->setCanHaveScrollbars(false);
|
| + view->setFixedLayoutSize(old_size);
|
| + view->enableFixedLayoutMode(true);
|
| + view->resize(new_size);
|
| + view->layout();
|
| + frame->setScrollOffset(WebSize(0, 0));
|
| +
|
| + skia::PlatformCanvas canvas(
|
| + new_size.width, new_size.height, true /* is_opaque */);
|
| + view->paint(webkit_glue::ToWebCanvas(&canvas),
|
| + gfx::Rect(0, 0, new_size.width, new_size.height));
|
| +
|
| + frame->setCanHaveScrollbars(true);
|
| + view->setFixedLayoutSize(fixed_size);
|
| + view->enableFixedLayoutMode(fixed_layout_enabled);
|
| + view->resize(old_size);
|
| + view->layout();
|
| + frame->setScrollOffset(WebSize(old_scroll.width - min_scroll.width,
|
| + old_scroll.height - min_scroll.height));
|
| +
|
| + const SkBitmap& bmp = skia::GetTopDevice(canvas)->accessBitmap(false);
|
| + SkAutoLockPixels lock_pixels(bmp);
|
| + // EncodeBGRA uses FORMAT_SkBitmap, which doesn't work on windows for some
|
| + // cases dealing with transparency. See crbug.com/96317. Use FORMAT_BGRA.
|
| + bool encode_success = gfx::PNGCodec::Encode(
|
| + reinterpret_cast<unsigned char*>(bmp.getPixels()),
|
| + gfx::PNGCodec::FORMAT_BGRA,
|
| + gfx::Size(bmp.width(), bmp.height()),
|
| + bmp.rowBytes(),
|
| + true, // discard_transparency
|
| + std::vector<gfx::PNGCodec::Comment>(),
|
| + png_data);
|
| + if (!encode_success)
|
| + *error_msg = "failed to encode image as png";
|
| + return encode_success;
|
| +}
|
| +
|
| +void AutomationRendererHelper::OnSnapshotEntirePage() {
|
| + std::vector<unsigned char> png_data;
|
| + std::string error_msg;
|
| + bool success = false;
|
| + if (render_view()->GetWebView()) {
|
| + success = SnapshotEntirePage(
|
| + render_view()->GetWebView(), &png_data, &error_msg);
|
| + } else {
|
| + error_msg = "cannot snapshot page because webview is null";
|
| + }
|
| +
|
| + // Check that the image is not too large, allowing a 1kb buffer for other
|
| + // message data.
|
| + if (success && png_data.size() > IPC::Channel::kMaximumMessageSize - 1024) {
|
| + png_data.clear();
|
| + success = false;
|
| + error_msg = "image is too large to be transferred over ipc";
|
| + }
|
| + Send(new AutomationMsg_SnapshotEntirePageACK(
|
| + routing_id(), success, png_data, error_msg));
|
| +}
|
| +
|
| +bool AutomationRendererHelper::OnMessageReceived(const IPC::Message& message) {
|
| + bool handled = true;
|
| + bool deserialize_success = true;
|
| + IPC_BEGIN_MESSAGE_MAP_EX(AutomationRendererHelper, message,
|
| + deserialize_success)
|
| + IPC_MESSAGE_HANDLER(AutomationMsg_SnapshotEntirePage, OnSnapshotEntirePage)
|
| + IPC_MESSAGE_UNHANDLED(handled = false)
|
| + IPC_END_MESSAGE_MAP_EX()
|
| + if (!deserialize_success) {
|
| + LOG(ERROR) << "Failed to deserialize an IPC message";
|
| + }
|
| + return handled;
|
| +}
|
| +
|
| void AutomationRendererHelper::WillPerformClientRedirect(
|
| WebFrame* frame, const WebURL& from, const WebURL& to, double interval,
|
| double fire_time) {
|
|
|