Home | History | Annotate | Download | only in tab_contents
      1 // Copyright (c) 2011 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.
      4 
      5 #ifndef CHROME_BROWSER_TAB_CONTENTS_THUMBNAIL_GENERATOR_H_
      6 #define CHROME_BROWSER_TAB_CONTENTS_THUMBNAIL_GENERATOR_H_
      7 #pragma once
      8 
      9 #include <map>
     10 #include <utility>
     11 #include <vector>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/callback.h"
     15 #include "base/memory/linked_ptr.h"
     16 #include "base/timer.h"
     17 #include "content/browser/renderer_host/backing_store.h"
     18 #include "content/common/notification_observer.h"
     19 #include "content/common/notification_registrar.h"
     20 
     21 class GURL;
     22 class Profile;
     23 class RenderWidgetHost;
     24 class SkBitmap;
     25 class TabContents;
     26 
     27 namespace history {
     28 class TopSites;
     29 }
     30 
     31 class ThumbnailGenerator : NotificationObserver {
     32  public:
     33   typedef Callback1<const SkBitmap&>::Type ThumbnailReadyCallback;
     34   // The result of clipping. This can be used to determine if the
     35   // generated thumbnail is good or not.
     36   enum ClipResult {
     37     // The source image is smaller.
     38     kSourceIsSmaller,
     39     // Wider than tall, clip horizontally.
     40     kWiderThanTall,
     41     // Taller than wide, clip vertically.
     42     kTallerThanWide,
     43     // The source and destination aspect ratios are identical.
     44     kNotClipped,
     45   };
     46 
     47   // Bitmasks of options for generating a thumbnail.
     48   enum ThumbnailOptions {
     49     // No options.
     50     kNoOptions = 0,
     51     // Request a clipped thumbnail with the aspect ratio preserved.
     52     kClippedThumbnail = 1 << 0,
     53   };
     54 
     55   // This class will do nothing until you call StartThumbnailing.
     56   ThumbnailGenerator();
     57   ~ThumbnailGenerator();
     58 
     59   // Ensures that we're properly hooked in to generated thumbnails. This can
     60   // be called repeatedly and with wild abandon to no ill effect.
     61   void StartThumbnailing();
     62 
     63   // This registers a callback that can receive the resulting SkBitmap
     64   // from the renderer when it is done rendering it.  This differs
     65   // from GetThumbnailForRenderer in that it may be asynchronous, and
     66   // because it will also fetch the bitmap even if the tab is hidden.
     67   // In addition, if the renderer has to be invoked, the scaling of
     68   // the thumbnail happens on the rendering thread.
     69   //
     70   // Takes ownership of the callback object.
     71   //
     72   // If |prefer_backing_store| is set, then the function will try and
     73   // use the backing store for the page if it exists.  |page_size| is
     74   // the size to render the page, and |desired_size| is the size to
     75   // scale the resulting rendered page to (which is done efficiently
     76   // if done in the rendering thread).  If |prefer_backing_store| is
     77   // set, and the backing store is used, then the resulting image will
     78   // be less then twice the size of the |desired_size| in both
     79   // dimensions, but might not be the exact size requested.
     80   void AskForSnapshot(RenderWidgetHost* renderer,
     81                       bool prefer_backing_store,
     82                       ThumbnailReadyCallback* callback,
     83                       gfx::Size page_size,
     84                       gfx::Size desired_size);
     85 
     86   // This returns a thumbnail of a fixed, small size for the given
     87   // renderer.
     88   SkBitmap GetThumbnailForRenderer(RenderWidgetHost* renderer) const;
     89 
     90   // This returns a thumbnail of a fixed, small size for the given
     91   // renderer. |options| is a bitmask of ThumbnailOptions. If
     92   // |clip_result| is non-NULL, the result of clipping will be written.
     93   SkBitmap GetThumbnailForRendererWithOptions(RenderWidgetHost* renderer,
     94                                               int options,
     95                                               ClipResult* clip_result) const;
     96 
     97   // Start or stop monitoring notifications for |renderer| based on the value
     98   // of |monitor|.
     99   void MonitorRenderer(RenderWidgetHost* renderer, bool monitor);
    100 
    101   // Calculates how "boring" a thumbnail is. The boring score is the
    102   // 0,1 ranged percentage of pixels that are the most common
    103   // luma. Higher boring scores indicate that a higher percentage of a
    104   // bitmap are all the same brightness.
    105   static double CalculateBoringScore(SkBitmap* bitmap);
    106 
    107   // Gets the clipped bitmap from |bitmap| per the aspect ratio of the
    108   // desired width and the desired height. For instance, if the input
    109   // bitmap is vertically long (ex. 400x900) and the desired size is
    110   // square (ex. 100x100), the clipped bitmap will be the top half of the
    111   // input bitmap (400x400).
    112   static SkBitmap GetClippedBitmap(const SkBitmap& bitmap,
    113                                    int desired_width,
    114                                    int desired_height,
    115                                    ClipResult* clip_result);
    116 
    117   // Update the thumbnail of the given tab contents if necessary.
    118   void UpdateThumbnailIfNecessary(TabContents* tab_contents);
    119 
    120   // Returns true if we should update the thumbnail of the given URL.
    121   static bool ShouldUpdateThumbnail(Profile* profile,
    122                                     history::TopSites* top_sites,
    123                                     const GURL& url);
    124 
    125  private:
    126   virtual void WidgetDidReceivePaintAtSizeAck(
    127       RenderWidgetHost* widget,
    128       int tag,
    129       const gfx::Size& size);
    130 
    131   // NotificationObserver interface.
    132   virtual void Observe(NotificationType type,
    133                        const NotificationSource& source,
    134                        const NotificationDetails& details);
    135 
    136   // Indicates that the given widget has changed is visibility.
    137   void WidgetHidden(RenderWidgetHost* widget);
    138 
    139   // Called when the given tab contents are disconnected (either
    140   // through being closed, or because the renderer is no longer there).
    141   void TabContentsDisconnected(TabContents* contents);
    142 
    143   NotificationRegistrar registrar_;
    144 
    145   // Map of callback objects by sequence number.
    146   struct AsyncRequestInfo;
    147   typedef std::map<int,
    148                    linked_ptr<AsyncRequestInfo> > ThumbnailCallbackMap;
    149   ThumbnailCallbackMap callback_map_;
    150 
    151   DISALLOW_COPY_AND_ASSIGN(ThumbnailGenerator);
    152 };
    153 
    154 #endif  // CHROME_BROWSER_TAB_CONTENTS_THUMBNAIL_GENERATOR_H_
    155