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)      &copy_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