Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / components / favicon / core / favicon_handler.h
blob960eba5136c46ac3d052f173e831aa42a318d124
1 // Copyright (c) 2012 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.
5 #ifndef COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_
6 #define COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_
8 #include <deque>
9 #include <map>
10 #include <vector>
12 #include "base/basictypes.h"
13 #include "base/callback_forward.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/task/cancelable_task_tracker.h"
16 #include "components/favicon/core/favicon_url.h"
17 #include "components/favicon_base/favicon_callback.h"
18 #include "ui/gfx/favicon_size.h"
19 #include "ui/gfx/image/image.h"
20 #include "url/gurl.h"
22 class FaviconTabHelperTest;
23 class SkBitmap;
24 class TestFaviconHandler;
26 namespace base {
27 class RefCountedMemory;
30 namespace favicon {
32 class FaviconDriver;
33 class FaviconService;
35 // FaviconHandler works with FaviconDriver to fetch the specific type of
36 // favicon.
38 // FetchFavicon requests the favicon from the favicon service which in turn
39 // requests the favicon from the history database. At this point
40 // we only know the URL of the page, and not necessarily the url of the
41 // favicon. To ensure we handle reloading stale favicons as well as
42 // reloading a favicon on page reload we always request the favicon from
43 // history regardless of whether the active favicon is valid.
45 // After the navigation two types of events are delivered (which is
46 // first depends upon who is faster): notification from the history
47 // db on our request for the favicon
48 // (OnFaviconDataForInitialURLFromFaviconService), or a message from the
49 // renderer giving us the URL of the favicon for the page (SetFaviconURL).
50 // . If the history db has a valid up to date favicon for the page, we update
51 // the current page and use the favicon.
52 // . When we receive the favicon url if it matches that of the current page
53 // and the current page's favicon is set, we do nothing (everything is
54 // ok).
55 // . On the other hand if the database does not know the favicon for url, or
56 // the favicon is out date, or the URL from the renderer does not match that
57 // of the current page we proceed to DownloadFaviconOrAskHistory. Before we
58 // invoke DownloadFaviconOrAskHistory we wait until we've received both
59 // the favicon url and the callback from history. We wait to ensure we
60 // truly know both the favicon url and the state of the database.
62 // DownloadFaviconOrAskHistory does the following:
63 // . If we have a valid favicon, but it is expired we ask the renderer to
64 // download the favicon.
65 // . Otherwise we ask the history database to update the mapping from
66 // page url to favicon url and call us back with the favicon. Remember, it is
67 // possible for the db to already have the favicon, just not the mapping
68 // between page to favicon url. The callback for this is OnFaviconData.
70 // OnFaviconData either updates the favicon of the current page (if the
71 // db knew about the favicon), or requests the renderer to download the
72 // favicon.
74 // When the renderer downloads favicons, it considers the entire list of
75 // favicon candidates, if |download_largest_favicon_| is true, the largest
76 // favicon will be used, otherwise the one that best matches the preferred size
77 // is chosen (or the first one if there is no preferred size). Once the
78 // matching favicon has been determined, SetFavicon is called which updates
79 // the page's favicon and notifies the database to save the favicon.
81 class FaviconHandler {
82 public:
83 enum Type { FAVICON, TOUCH, LARGE };
85 FaviconHandler(FaviconService* service,
86 FaviconDriver* driver,
87 Type handler_type,
88 bool download_largest_icon);
89 virtual ~FaviconHandler();
91 // Returns the bit mask of favicon_base::IconType based on the handler's type.
92 static int GetIconTypesFromHandlerType(Type icon_type);
94 // Initiates loading the favicon for the specified url.
95 void FetchFavicon(const GURL& url);
97 // Message Handler. Must be public, because also called from
98 // PrerenderContents. Collects the |image_urls| list.
99 void OnUpdateFaviconURL(const std::vector<favicon::FaviconURL>& candidates);
101 // Processes the current image_urls_ entry, requesting the image from the
102 // history / download service.
103 void ProcessCurrentUrl();
105 // Message handler for ImageHostMsg_DidDownloadImage. Called when the image
106 // at |image_url| has been downloaded.
107 // |bitmaps| is a list of all the frames of the image at |image_url|.
108 // |original_bitmap_sizes| are the sizes of |bitmaps| before they were resized
109 // to the maximum bitmap size passed to DownloadFavicon().
110 void OnDidDownloadFavicon(
111 int id,
112 const GURL& image_url,
113 const std::vector<SkBitmap>& bitmaps,
114 const std::vector<gfx::Size>& original_bitmap_sizes);
116 // For testing.
117 const std::vector<favicon::FaviconURL>& image_urls() const {
118 return image_urls_;
121 protected:
122 // These virtual methods make FaviconHandler testable and are overridden by
123 // TestFaviconHandler.
125 // Asks the render to download favicon, returns the request id.
126 virtual int DownloadFavicon(const GURL& image_url, int max_bitmap_size);
128 // Ask the favicon from history
129 virtual void UpdateFaviconMappingAndFetch(
130 const GURL& page_url,
131 const GURL& icon_url,
132 favicon_base::IconType icon_type,
133 const favicon_base::FaviconResultsCallback& callback,
134 base::CancelableTaskTracker* tracker);
136 virtual void GetFaviconFromFaviconService(
137 const GURL& icon_url,
138 favicon_base::IconType icon_type,
139 const favicon_base::FaviconResultsCallback& callback,
140 base::CancelableTaskTracker* tracker);
142 virtual void GetFaviconForURLFromFaviconService(
143 const GURL& page_url,
144 int icon_types,
145 const favicon_base::FaviconResultsCallback& callback,
146 base::CancelableTaskTracker* tracker);
148 virtual void SetHistoryFavicons(const GURL& page_url,
149 const GURL& icon_url,
150 favicon_base::IconType icon_type,
151 const gfx::Image& image);
153 // Returns true if the favicon should be saved.
154 virtual bool ShouldSaveFavicon(const GURL& url);
156 private:
157 // For testing:
158 friend class ::FaviconTabHelperTest;
159 friend class ::TestFaviconHandler;
161 // Represents an in progress download of an image from the renderer.
162 struct DownloadRequest {
163 DownloadRequest();
164 ~DownloadRequest();
166 DownloadRequest(const GURL& url,
167 const GURL& image_url,
168 favicon_base::IconType icon_type);
170 GURL url;
171 GURL image_url;
172 favicon_base::IconType icon_type;
175 // Used to track a candidate for the favicon.
176 struct FaviconCandidate {
177 FaviconCandidate();
178 ~FaviconCandidate();
180 FaviconCandidate(const GURL& url,
181 const GURL& image_url,
182 const gfx::Image& image,
183 float score,
184 favicon_base::IconType icon_type);
186 GURL url;
187 GURL image_url;
188 gfx::Image image;
189 float score;
190 favicon_base::IconType icon_type;
193 // Get the maximal icon size in pixels for a icon of type |icon_type| for the
194 // current platform.
195 static int GetMaximalIconSize(favicon_base::IconType icon_type);
197 // See description above class for details.
198 void OnFaviconDataForInitialURLFromFaviconService(const std::vector<
199 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results);
201 // If the favicon has expired, asks the renderer to download the favicon.
202 // Otherwise asks history to update the mapping between page url and icon
203 // url with a callback to OnFaviconData when done.
204 void DownloadFaviconOrAskFaviconService(const GURL& page_url,
205 const GURL& icon_url,
206 favicon_base::IconType icon_type);
208 // See description above class for details.
209 void OnFaviconData(const std::vector<favicon_base::FaviconRawBitmapResult>&
210 favicon_bitmap_results);
212 // Schedules a download for the specified entry. This adds the request to
213 // download_requests_.
214 int ScheduleDownload(const GURL& url,
215 const GURL& image_url,
216 favicon_base::IconType icon_type);
218 // Updates |favicon_candidate_| and returns true if it is an exact match.
219 bool UpdateFaviconCandidate(const GURL& url,
220 const GURL& image_url,
221 const gfx::Image& image,
222 float score,
223 favicon_base::IconType icon_type);
225 // Sets the image data for the favicon.
226 void SetFavicon(const GURL& url,
227 const GURL& icon_url,
228 const gfx::Image& image,
229 favicon_base::IconType icon_type);
231 // Notifies |driver_| favicon available. See
232 // FaviconDriver::NotifyFaviconAvailable() for |is_active_favicon| in detail.
233 void NotifyFaviconAvailable(
234 const std::vector<favicon_base::FaviconRawBitmapResult>&
235 favicon_bitmap_results,
236 bool is_active_favicon);
237 void NotifyFaviconAvailable(const GURL& icon_url,
238 const gfx::Image& image,
239 bool is_active_favicon);
241 // Return the current candidate if any.
242 favicon::FaviconURL* current_candidate() {
243 return (!image_urls_.empty()) ? &image_urls_.front() : NULL;
246 // Returns whether the page's url changed since the favicon was requested.
247 bool PageChangedSinceFaviconWasRequested();
249 // Returns the preferred size of the image. 0 means no preference (any size
250 // will do).
251 int preferred_icon_size() const {
252 if (download_largest_icon_)
253 return 0;
254 return handler_type_ == FAVICON ? gfx::kFaviconSize : 0;
257 // Sorts the entries in |image_urls_| by icon size in descending order.
258 // Additionally removes any entries whose sizes are all greater than the max
259 // allowed size.
260 void SortAndPruneImageUrls();
262 // Used for FaviconService requests.
263 base::CancelableTaskTracker cancelable_task_tracker_;
265 // URL of the page we're requesting the favicon for.
266 GURL url_;
268 // Whether we are waiting for data from the FaviconService.
269 bool waiting_for_favicon_service_data_;
271 // Whether we got data back for the initial request to the FaviconService.
272 bool got_favicon_from_history_;
274 // Whether the favicon is out of date or the favicon data in
275 // |history_results_| is known to be incomplete. If true, it means history
276 // knows about the favicon, but we need to download the favicon because the
277 // icon has expired or the data in the database is incomplete.
278 bool favicon_expired_or_incomplete_;
280 // Requests to the renderer to download favicons.
281 typedef std::map<int, DownloadRequest> DownloadRequests;
282 DownloadRequests download_requests_;
284 // The type of the current handler.
285 const Type handler_type_;
287 // The combination of the supported icon types.
288 const int icon_types_;
290 // Whether the largest icon should be downloaded.
291 const bool download_largest_icon_;
293 // The prioritized favicon candidates from the page back from the renderer.
294 std::vector<favicon::FaviconURL> image_urls_;
296 // The FaviconRawBitmapResults from history.
297 std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
299 // The FaviconService which implements favicon operations. May be null during
300 // testing.
301 FaviconService* service_;
303 // This handler's driver, owns this object.
304 FaviconDriver* driver_;
306 // Best image we've seen so far. As images are downloaded from the page they
307 // are stored here. When there is an exact match, or no more images are
308 // available the favicon service and the current page are updated (assuming
309 // the image is for a favicon).
310 FaviconCandidate best_favicon_candidate_;
312 DISALLOW_COPY_AND_ASSIGN(FaviconHandler);
315 } // namespace favicon
317 #endif // COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_