1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/renderer/chrome_render_frame_observer.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/common/prerender_messages.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/print_messages.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/render_messages.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/renderer/prerender/prerender_helper.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/renderer/printing/print_web_view_helper.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/renderer/render_frame.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "skia/ext/image_operations.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "skia/ext/platform_canvas.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebImage.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebNode.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using blink::WebElement; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using blink::WebNode; 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// If the source image is null or occupies less area than 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// |thumbnail_min_area_pixels|, we return the image unmodified. Otherwise, we 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// scale down the image so that the width and height do not exceed 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// |thumbnail_max_size_pixels|, preserving the original aspect ratio. 29116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSkBitmap Downscale(const blink::WebImage& image, 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int thumbnail_min_area_pixels, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Size& thumbnail_max_size_pixels) { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (image.isNull()) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return SkBitmap(); 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Size image_size = image.size(); 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (image_size.GetArea() < thumbnail_min_area_pixels) 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return image.getSkBitmap(); 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (image_size.width() <= thumbnail_max_size_pixels.width() && 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) image_size.height() <= thumbnail_max_size_pixels.height()) 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return image.getSkBitmap(); 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::SizeF scaled_size = image_size; 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (scaled_size.width() > thumbnail_max_size_pixels.width()) { 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scaled_size.Scale(thumbnail_max_size_pixels.width() / scaled_size.width()); 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (scaled_size.height() > thumbnail_max_size_pixels.height()) { 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scaled_size.Scale( 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thumbnail_max_size_pixels.height() / scaled_size.height()); 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return skia::ImageOperations::Resize(image.getSkBitmap(), 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skia::ImageOperations::RESIZE_GOOD, 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<int>(scaled_size.width()), 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<int>(scaled_size.height())); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ChromeRenderFrameObserver::ChromeRenderFrameObserver( 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::RenderFrame* render_frame) 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : content::RenderFrameObserver(render_frame) { 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ChromeRenderFrameObserver::~ChromeRenderFrameObserver() { 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ChromeRenderFrameObserver::OnMessageReceived(const IPC::Message& message) { 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Filter only. 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool handled = true; 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ChromeRenderFrameObserver, message) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_MESSAGE_HANDLER(PrerenderMsg_SetIsPrerendering, OnSetIsPrerendering) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_END_MESSAGE_MAP() 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (handled) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ChromeRenderFrameObserver, message) 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_MESSAGE_HANDLER(ChromeViewMsg_RequestThumbnailForContextNode, 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnRequestThumbnailForContextNode) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_MESSAGE_HANDLER(PrintMsg_PrintNodeUnderContextMenu, 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnPrintNodeUnderContextMenu) 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IPC_END_MESSAGE_MAP() 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return handled; 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeRenderFrameObserver::OnSetIsPrerendering(bool is_prerendering) { 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (is_prerendering) { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the PrerenderHelper for this frame already exists, don't create it. It 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // can already be created for subframes during handling of 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RenderFrameCreated, if the parent frame was prerendering at time of 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // subframe creation. 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (prerender::PrerenderHelper::Get(render_frame())) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The PrerenderHelper will destroy itself either after recording histograms 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // or on destruction of the RenderView. 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new prerender::PrerenderHelper(render_frame()); 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeRenderFrameObserver::OnRequestThumbnailForContextNode( 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int thumbnail_min_area_pixels, 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Size& thumbnail_max_size_pixels) { 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WebNode context_node = render_frame()->GetContextMenuNode(); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SkBitmap thumbnail; 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Size original_size; 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!context_node.isNull() && context_node.isElementNode()) { 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebImage image = context_node.to<WebElement>().imageContents(); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) original_size = image.size(); 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thumbnail = Downscale(image, 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thumbnail_min_area_pixels, 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thumbnail_max_size_pixels); 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Send(new ChromeViewHostMsg_RequestThumbnailForContextNode_ACK( 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) routing_id(), thumbnail, original_size)); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeRenderFrameObserver::OnPrintNodeUnderContextMenu() { 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printing::PrintWebViewHelper* helper = 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printing::PrintWebViewHelper::Get(render_frame()->GetRenderView()); 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (helper) 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper->PrintNode(render_frame()->GetContextMenuNode()); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 130