Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / favicon / favicon_handler.h
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.
4
5 #ifndef CHROME_BROWSER_FAVICON_FAVICON_HANDLER_H_
6 #define CHROME_BROWSER_FAVICON_FAVICON_HANDLER_H_
7
8 #include <deque>
9 #include <map>
10 #include <vector>
11
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"
21
22 class FaviconClient;
23 class FaviconDriver;
24 class SkBitmap;
25
26 namespace base {
27 class RefCountedMemory;
28 }
29
30 // FaviconHandler works with FaviconDriver to fetch the specific type of
31 // favicon.
32 //
33 // FetchFavicon requests the favicon from the favicon service which in turn
34 // requests the favicon from the history database. At this point
35 // we only know the URL of the page, and not necessarily the url of the
36 // favicon. To ensure we handle reloading stale favicons as well as
37 // reloading a favicon on page reload we always request the favicon from
38 // history regardless of whether the active favicon is valid.
39 //
40 // After the navigation two types of events are delivered (which is
41 // first depends upon who is faster): notification from the history
42 // db on our request for the favicon
43 // (OnFaviconDataForInitialURLFromFaviconService), or a message from the
44 // renderer giving us the URL of the favicon for the page (SetFaviconURL).
45 // . If the history db has a valid up to date favicon for the page, we update
46 //   the current page and use the favicon.
47 // . When we receive the favicon url if it matches that of the current page
48 //   and the current page's favicon is set, we do nothing (everything is
49 //   ok).
50 // . On the other hand if the database does not know the favicon for url, or
51 //   the favicon is out date, or the URL from the renderer does not match that
52 //   of the current page we proceed to DownloadFaviconOrAskHistory. Before we
53 //   invoke DownloadFaviconOrAskHistory we wait until we've received both
54 //   the favicon url and the callback from history. We wait to ensure we
55 //   truly know both the favicon url and the state of the database.
56 //
57 // DownloadFaviconOrAskHistory does the following:
58 // . If we have a valid favicon, but it is expired we ask the renderer to
59 //   download the favicon.
60 // . Otherwise we ask the history database to update the mapping from
61 //   page url to favicon url and call us back with the favicon. Remember, it is
62 //   possible for the db to already have the favicon, just not the mapping
63 //   between page to favicon url. The callback for this is OnFaviconData.
64 //
65 // OnFaviconData either updates the favicon of the current page (if the
66 // db knew about the favicon), or requests the renderer to download the
67 // favicon.
68 //
69 // When the renderer downloads favicons, it considers the entire list of
70 // favicon candidates, if |download_largest_favicon_| is true, the largest
71 // favicon will be used, otherwise the one that best matches the preferred size
72 // is chosen (or the first one if there is no preferred  size). Once the
73 // matching favicon has been determined, SetFavicon is called which updates
74 // the page's favicon and notifies the database to save the favicon.
75
76 class FaviconHandler {
77  public:
78   enum Type {
79     FAVICON,
80     TOUCH,
81   };
82
83   FaviconHandler(FaviconClient* client,
84                  FaviconDriver* driver,
85                  Type icon_type,
86                  bool download_largest_icon);
87   virtual ~FaviconHandler();
88
89   // Initiates loading the favicon for the specified url.
90   void FetchFavicon(const GURL& url);
91
92   // Message Handler.  Must be public, because also called from
93   // PrerenderContents. Collects the |image_urls| list.
94   void OnUpdateFaviconURL(const std::vector<favicon::FaviconURL>& candidates);
95
96   // Processes the current image_irls_ entry, requesting the image from the
97   // history / download service.
98   void ProcessCurrentUrl();
99
100   // Message handler for ImageHostMsg_DidDownloadImage. Called when the image
101   // at |image_url| has been downloaded.
102   // |bitmaps| is a list of all the frames of the image at |image_url|.
103   // |original_bitmap_sizes| are the sizes of |bitmaps| before they were resized
104   // to the maximum bitmap size passed to DownloadFavicon().
105   void OnDidDownloadFavicon(
106       int id,
107       const GURL& image_url,
108       const std::vector<SkBitmap>& bitmaps,
109       const std::vector<gfx::Size>& original_bitmap_sizes);
110
111   // For testing.
112   const std::vector<favicon::FaviconURL>& image_urls() const {
113     return image_urls_;
114   }
115
116  protected:
117   // These virtual methods make FaviconHandler testable and are overridden by
118   // TestFaviconHandler.
119
120   // Asks the render to download favicon, returns the request id.
121   virtual int DownloadFavicon(const GURL& image_url, int max_bitmap_size);
122
123   // Ask the favicon from history
124   virtual void UpdateFaviconMappingAndFetch(
125       const GURL& page_url,
126       const GURL& icon_url,
127       favicon_base::IconType icon_type,
128       const favicon_base::FaviconResultsCallback& callback,
129       base::CancelableTaskTracker* tracker);
130
131   virtual void GetFaviconFromFaviconService(
132       const GURL& icon_url,
133       favicon_base::IconType icon_type,
134       const favicon_base::FaviconResultsCallback& callback,
135       base::CancelableTaskTracker* tracker);
136
137   virtual void GetFaviconForURLFromFaviconService(
138       const GURL& page_url,
139       int icon_types,
140       const favicon_base::FaviconResultsCallback& callback,
141       base::CancelableTaskTracker* tracker);
142
143   virtual void SetHistoryFavicons(const GURL& page_url,
144                                   const GURL& icon_url,
145                                   favicon_base::IconType icon_type,
146                                   const gfx::Image& image);
147
148   // Returns true if the favicon should be saved.
149   virtual bool ShouldSaveFavicon(const GURL& url);
150
151   // Notifies the driver that the favicon for the active entry was updated.
152   // |icon_url_changed| is true if a favicon with a different icon URL has been
153   // selected since the previous call to NotifyFaviconUpdated().
154   virtual void NotifyFaviconUpdated(bool icon_url_changed);
155
156  private:
157   friend class TestFaviconHandler; // For testing
158
159   // Represents an in progress download of an image from the renderer.
160   struct DownloadRequest {
161     DownloadRequest();
162     ~DownloadRequest();
163
164     DownloadRequest(const GURL& url,
165                     const GURL& image_url,
166                     favicon_base::IconType icon_type);
167
168     GURL url;
169     GURL image_url;
170     favicon_base::IconType icon_type;
171   };
172
173   // Used to track a candidate for the favicon.
174   struct FaviconCandidate {
175     FaviconCandidate();
176     ~FaviconCandidate();
177
178     FaviconCandidate(const GURL& url,
179                      const GURL& image_url,
180                      const gfx::Image& image,
181                      float score,
182                      favicon_base::IconType icon_type);
183
184     GURL url;
185     GURL image_url;
186     gfx::Image image;
187     float score;
188     favicon_base::IconType icon_type;
189   };
190
191   // See description above class for details.
192   void OnFaviconDataForInitialURLFromFaviconService(const std::vector<
193       favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results);
194
195   // If the favicon has expired, asks the renderer to download the favicon.
196   // Otherwise asks history to update the mapping between page url and icon
197   // url with a callback to OnFaviconData when done.
198   void DownloadFaviconOrAskFaviconService(const GURL& page_url,
199                                           const GURL& icon_url,
200                                           favicon_base::IconType icon_type);
201
202   // See description above class for details.
203   void OnFaviconData(const std::vector<favicon_base::FaviconRawBitmapResult>&
204                          favicon_bitmap_results);
205
206   // Schedules a download for the specified entry. This adds the request to
207   // download_requests_.
208   int ScheduleDownload(const GURL& url,
209                        const GURL& image_url,
210                        favicon_base::IconType icon_type);
211
212   // Updates |favicon_candidate_| and returns true if it is an exact match.
213   bool UpdateFaviconCandidate(const GURL& url,
214                               const GURL& image_url,
215                               const gfx::Image& image,
216                               float score,
217                               favicon_base::IconType icon_type);
218
219   // Sets the image data for the favicon.
220   void SetFavicon(const GURL& url,
221                   const GURL& icon_url,
222                   const gfx::Image& image,
223                   favicon_base::IconType icon_type);
224
225   // Sets the favicon's data.
226   void SetFaviconOnActivePage(const std::vector<
227       favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results);
228   void SetFaviconOnActivePage(const GURL& icon_url, const gfx::Image& image);
229
230   // Return the current candidate if any.
231   favicon::FaviconURL* current_candidate() {
232     return (!image_urls_.empty()) ? &image_urls_.front() : NULL;
233   }
234
235   // Returns whether the page's url changed since the favicon was requested.
236   bool PageChangedSinceFaviconWasRequested();
237
238   // Returns the preferred size of the image. 0 means no preference (any size
239   // will do).
240   int preferred_icon_size() const {
241     if (download_largest_icon_)
242       return 0;
243     return icon_types_ == favicon_base::FAVICON ? gfx::kFaviconSize : 0;
244   }
245
246   // Sorts the entries in |image_urls_| by icon size in descending order.
247   // Additionally removes any entries whose sizes are all greater than the max
248   // allowed size.
249   void SortAndPruneImageUrls();
250
251   // Used for FaviconService requests.
252   base::CancelableTaskTracker cancelable_task_tracker_;
253
254   // URL of the page we're requesting the favicon for.
255   GURL url_;
256
257   // Whether we got the initial response for the favicon back from the renderer.
258   bool got_favicon_from_history_;
259
260   // Whether the favicon is out of date or the favicon data in
261   // |history_results_| is known to be incomplete. If true, it means history
262   // knows about the favicon, but we need to download the favicon because the
263   // icon has expired or the data in the database is incomplete.
264   bool favicon_expired_or_incomplete_;
265
266   // Requests to the renderer to download favicons.
267   typedef std::map<int, DownloadRequest> DownloadRequests;
268   DownloadRequests download_requests_;
269
270   // The combination of the supported icon types.
271   const int icon_types_;
272
273   // Whether the largest icon should be downloaded.
274   const bool download_largest_icon_;
275
276   // The prioritized favicon candidates from the page back from the renderer.
277   std::vector<favicon::FaviconURL> image_urls_;
278
279   // The FaviconRawBitmapResults from history.
280   std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
281
282   // The client which implements embedder-specific Favicon operations.
283   FaviconClient* client_;  // weak
284
285   // This handler's driver.
286   FaviconDriver* driver_;  // weak
287
288   // Best image we've seen so far.  As images are downloaded from the page they
289   // are stored here. When there is an exact match, or no more images are
290   // available the favicon service and the current page are updated (assuming
291   // the image is for a favicon).
292   FaviconCandidate best_favicon_candidate_;
293
294   DISALLOW_COPY_AND_ASSIGN(FaviconHandler);
295 };
296
297 #endif  // CHROME_BROWSER_FAVICON_FAVICON_HANDLER_H_