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