15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/thumbnails/thumbnail_tab_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/thumbnails/thumbnail_service.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/thumbnails/thumbnail_service_factory.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/thumbnails/thumbnailing_algorithm.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/thumbnails/thumbnailing_context.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size_conversions.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/scrollbar_size.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skbitmap_operations.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(ThumbnailTabHelper); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SkBitmap; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Overview 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------- 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides a service for updating thumbnails to be used in 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Most visited" section of the new tab page. The service can be started 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by StartThumbnailing(). The current algorithm of the service is as 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// simple as follows: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When a renderer is about to be hidden (this usually occurs when the 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current tab is closed or another tab is clicked), update the 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thumbnail for the tab rendered by the renderer, if needed. The 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// heuristics to judge whether or not to update the thumbnail is 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implemented in ShouldUpdateThumbnail(). 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using thumbnails::ClipResult; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using thumbnails::ThumbnailingContext; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using thumbnails::ThumbnailingAlgorithm; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Feed the constructed thumbnail to the thumbnail service. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UpdateThumbnail(const ThumbnailingContext& context, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap& thumbnail) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image image = gfx::Image::CreateFrom1xBitmap(thumbnail); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context.service->SetPageThumbnail(context, image); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Thumbnail taken for " << context.url << ": " 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << context.score.ToString(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ProcessCapturedBitmap(scoped_refptr<ThumbnailingContext> context, 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<ThumbnailingAlgorithm> algorithm, 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool succeeded, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap& bitmap) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!succeeded) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // On success, we must be on the UI thread (on failure because of shutdown we 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // are not on the UI thread). 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) algorithm->ProcessBitmap(context, base::Bind(&UpdateThumbnail), bitmap); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncProcessThumbnail(content::WebContents* web_contents, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ThumbnailingContext> context, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ThumbnailingAlgorithm> algorithm) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderWidgetHost* render_widget_host = web_contents->GetRenderViewHost(); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RenderWidgetHostView* view = render_widget_host->GetView(); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!view) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!view->IsSurfaceAvailableForCopy()) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size()); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clip the pixels that will commonly hold a scrollbar, which looks bad in 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // thumbnails. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int scrollbar_size = gfx::scrollbar_size(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size copy_size; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy_rect.Inset(0, 0, scrollbar_size, scrollbar_size); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (copy_rect.IsEmpty()) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::ScaleFactor scale_factor = 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::GetSupportedScaleFactor( 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::GetScaleFactorForNativeView(view->GetNativeView())); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->clip_result = algorithm->GetCanvasCopyInfo( 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy_rect.size(), 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scale_factor, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ©_rect, 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &context->requested_copy_size); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_widget_host->CopyFromBackingStore( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy_rect, 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) context->requested_copy_size, 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ProcessCapturedBitmap, context, algorithm), 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kN32_SkColorType); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThumbnailTabHelper::ThumbnailTabHelper(content::WebContents* contents) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : content::WebContentsObserver(contents), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enabled_(true), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_interrupted_(false) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Even though we deal in RenderWidgetHosts, we only care about its 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subclass, RenderViewHost when it is in a tab. We don't make thumbnails 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for RenderViewHosts that aren't in tabs, or RenderWidgetHosts that 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // aren't views like select popups. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<WebContents>(contents)); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThumbnailTabHelper::~ThumbnailTabHelper() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThumbnailTabHelper::Observe(int type, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHostCreated(content::Details<RenderViewHost>(details).ptr()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!*content::Details<bool>(details).ptr()) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WidgetHidden(content::Source<RenderWidgetHost>(source).ptr()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unexpected notification type: " << type; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThumbnailTabHelper::RenderViewDeleted( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RenderViewHost* render_view_host) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool registered = registrar_.IsRegistered( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<RenderWidgetHost>(render_view_host)); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (registered) { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Remove( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<RenderWidgetHost>(render_view_host)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThumbnailTabHelper::DidStartLoading( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RenderViewHost* render_view_host) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) load_interrupted_ = false; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThumbnailTabHelper::NavigationStopped() { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This function gets called when the page loading is interrupted by the 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stop button. 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) load_interrupted_ = true; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThumbnailTabHelper::UpdateThumbnailIfNecessary( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroying a WebContents may trigger it to be hidden, prompting a snapshot 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which would be unwise to attempt <http://crbug.com/130097>. If the 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebContents is in the middle of destruction, do not risk it. 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!web_contents || web_contents->IsBeingDestroyed()) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip if a pending entry exists. WidgetHidden can be called while navigating 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pages and this is not a time when thumbnails should be generated. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (web_contents->GetController().GetPendingEntry()) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url = web_contents->GetURL(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<thumbnails::ThumbnailService> thumbnail_service = 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThumbnailServiceFactory::GetForProfile(profile); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip if we don't need to update the thumbnail. 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (thumbnail_service.get() == NULL || 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !thumbnail_service->ShouldAcquirePageThumbnail(url)) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<thumbnails::ThumbnailingAlgorithm> algorithm( 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_service->GetThumbnailingAlgorithm()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<ThumbnailingContext> context(new ThumbnailingContext( 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) web_contents, thumbnail_service.get(), load_interrupted_)); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsyncProcessThumbnail(web_contents, context, algorithm); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThumbnailTabHelper::RenderViewHostCreated( 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RenderViewHost* renderer) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED is really a new 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // RenderView, not RenderViewHost, and there is no good way to get 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // notifications of RenderViewHosts. So just be tolerant of re-registrations. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool registered = registrar_.IsRegistered( 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<RenderWidgetHost>(renderer)); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!registered) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add( 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<RenderWidgetHost>(renderer)); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThumbnailTabHelper::WidgetHidden(RenderWidgetHost* widget) { 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!enabled_) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateThumbnailIfNecessary(web_contents()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 229