blob: beba7b1c45969b73572d42c234d49d084f2e7434 [file] [log] [blame]
[email protected]ebbbb9f2011-03-09 13:16:141// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]67a46b7f2009-06-16 21:41:022// 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_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
[email protected]67a46b7f2009-06-16 21:41:028
[email protected]d65adb12010-04-28 17:26:499#include <map>
10#include <utility>
[email protected]038d52e12009-10-14 16:53:4111#include <vector>
12
[email protected]67a46b7f2009-06-16 21:41:0213#include "base/basictypes.h"
[email protected]d65adb12010-04-28 17:26:4914#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1515#include "base/memory/linked_ptr.h"
[email protected]67a46b7f2009-06-16 21:41:0216#include "base/timer.h"
[email protected]5de634712011-03-02 00:20:1917#include "content/browser/renderer_host/backing_store.h"
[email protected]ebbbb9f2011-03-09 13:16:1418#include "content/common/notification_observer.h"
19#include "content/common/notification_registrar.h"
[email protected]67a46b7f2009-06-16 21:41:0220
[email protected]d54169e92011-01-21 09:19:5221class GURL;
[email protected]754e33822011-01-27 05:57:4522class Profile;
[email protected]67a46b7f2009-06-16 21:41:0223class RenderWidgetHost;
24class SkBitmap;
[email protected]d65adb12010-04-28 17:26:4925class TabContents;
[email protected]67a46b7f2009-06-16 21:41:0226
[email protected]754e33822011-01-27 05:57:4527namespace history {
28class TopSites;
29}
30
[email protected]89d8a8f22011-01-12 21:12:1031class ThumbnailGenerator : NotificationObserver {
[email protected]67a46b7f2009-06-16 21:41:0232 public:
[email protected]d65adb12010-04-28 17:26:4933 typedef Callback1<const SkBitmap&>::Type ThumbnailReadyCallback;
[email protected]d54169e92011-01-21 09:19:5234 // 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
[email protected]58dca552009-06-17 00:35:0255 // This class will do nothing until you call StartThumbnailing.
[email protected]67a46b7f2009-06-16 21:41:0256 ThumbnailGenerator();
57 ~ThumbnailGenerator();
58
[email protected]58dca552009-06-17 00:35:0259 // 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
[email protected]d65adb12010-04-28 17:26:4963 // This registers a callback that can receive the resulting SkBitmap
64 // from the renderer when it is done rendering it. This differs
[email protected]948f7ab72010-05-28 23:48:0865 // from GetThumbnailForRenderer in that it may be asynchronous, and
[email protected]d65adb12010-04-28 17:26:4966 // 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
[email protected]948f7ab72010-05-28 23:48:0868 // 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);
[email protected]d65adb12010-04-28 17:26:4985
[email protected]948f7ab72010-05-28 23:48:0886 // This returns a thumbnail of a fixed, small size for the given
87 // renderer.
[email protected]67a46b7f2009-06-16 21:41:0288 SkBitmap GetThumbnailForRenderer(RenderWidgetHost* renderer) const;
89
[email protected]d54169e92011-01-21 09:19:5290 // 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
[email protected]89d8a8f22011-01-12 21:12:1097 // Start or stop monitoring notifications for |renderer| based on the value
98 // of |monitor|.
99 void MonitorRenderer(RenderWidgetHost* renderer, bool monitor);
100
[email protected]67a46b7f2009-06-16 21:41:02101#ifdef UNIT_TEST
102 // When true, the class will not use a timeout to do the expiration. This
103 // will cause expiration to happen on the next run of the message loop.
104 // Unit tests case use this to test expiration by choosing when the message
105 // loop runs.
106 void set_no_timeout(bool no_timeout) { no_timeout_ = no_timeout; }
107#endif
108
[email protected]d54169e92011-01-21 09:19:52109 // Calculates how "boring" a thumbnail is. The boring score is the
110 // 0,1 ranged percentage of pixels that are the most common
111 // luma. Higher boring scores indicate that a higher percentage of a
112 // bitmap are all the same brightness.
113 static double CalculateBoringScore(SkBitmap* bitmap);
114
115 // Gets the clipped bitmap from |bitmap| per the aspect ratio of the
116 // desired width and the desired height. For instance, if the input
117 // bitmap is vertically long (ex. 400x900) and the desired size is
118 // square (ex. 100x100), the clipped bitmap will be the top half of the
119 // input bitmap (400x400).
120 static SkBitmap GetClippedBitmap(const SkBitmap& bitmap,
121 int desired_width,
122 int desired_height,
123 ClipResult* clip_result);
124
125 // Update the thumbnail of the given URL if necessary.
126 static void UpdateThumbnailIfNecessary(TabContents* tab_contents,
127 const GURL& url);
128
[email protected]754e33822011-01-27 05:57:45129 // Returns true if we should update the thumbnail of the given URL.
130 static bool ShouldUpdateThumbnail(Profile* profile,
131 history::TopSites* top_sites,
132 const GURL& url);
133
[email protected]67a46b7f2009-06-16 21:41:02134 private:
135 // RenderWidgetHostPaintingObserver implementation.
136 virtual void WidgetWillDestroyBackingStore(RenderWidgetHost* widget,
137 BackingStore* backing_store);
138 virtual void WidgetDidUpdateBackingStore(RenderWidgetHost* widget);
139
[email protected]d65adb12010-04-28 17:26:49140 virtual void WidgetDidReceivePaintAtSizeAck(
141 RenderWidgetHost* widget,
[email protected]c88c9442010-07-19 18:55:09142 int tag,
[email protected]d65adb12010-04-28 17:26:49143 const gfx::Size& size);
144
[email protected]67a46b7f2009-06-16 21:41:02145 // NotificationObserver interface.
146 virtual void Observe(NotificationType type,
147 const NotificationSource& source,
148 const NotificationDetails& details);
149
150 // Indicates that the given widget has changed is visibility.
151 void WidgetShown(RenderWidgetHost* widget);
152 void WidgetHidden(RenderWidgetHost* widget);
153
154 // Called when the given widget is destroyed.
155 void WidgetDestroyed(RenderWidgetHost* widget);
156
[email protected]d65adb12010-04-28 17:26:49157 // Called when the given tab contents are disconnected (either
158 // through being closed, or because the renderer is no longer there).
159 void TabContentsDisconnected(TabContents* contents);
160
[email protected]67a46b7f2009-06-16 21:41:02161 // Timer function called on a delay after a tab has been shown. It will
162 // invalidate the thumbnail for hosts with expired thumbnails in shown_hosts_.
163 void ShownDelayHandler();
164
165 // Removes the given host from the shown_hosts_ list, if it is there.
166 void EraseHostFromShownList(RenderWidgetHost* host);
167
168 NotificationRegistrar registrar_;
169
170 base::OneShotTimer<ThumbnailGenerator> timer_;
171
172 // A list of all RWHs that have been shown and need to have their thumbnail
173 // expired at some time in the future with the "slop" time has elapsed. This
174 // list will normally have 0 or 1 items in it.
175 std::vector<RenderWidgetHost*> shown_hosts_;
176
177 // See the setter above.
178 bool no_timeout_;
179
[email protected]c88c9442010-07-19 18:55:09180 // Map of callback objects by sequence number.
[email protected]d65adb12010-04-28 17:26:49181 struct AsyncRequestInfo;
[email protected]c88c9442010-07-19 18:55:09182 typedef std::map<int,
[email protected]d65adb12010-04-28 17:26:49183 linked_ptr<AsyncRequestInfo> > ThumbnailCallbackMap;
184 ThumbnailCallbackMap callback_map_;
185
[email protected]67a46b7f2009-06-16 21:41:02186 DISALLOW_COPY_AND_ASSIGN(ThumbnailGenerator);
187};
188
189#endif // CHROME_BROWSER_TAB_CONTENTS_THUMBNAIL_GENERATOR_H_