Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: components/favicon/core/favicon_handler.h

Issue 2739173002: Always select best favicon bitmap (Closed)
Patch Set: WIP. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_ 5 #ifndef COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_
6 #define COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_ 6 #define COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <list>
10 #include <map> 11 #include <map>
11 #include <vector> 12 #include <vector>
12 13
13 #include "base/callback_forward.h" 14 #include "base/callback_forward.h"
14 #include "base/macros.h" 15 #include "base/macros.h"
15 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
16 #include "base/memory/weak_ptr.h" 17 #include "base/memory/weak_ptr.h"
18 #include "base/optional.h"
17 #include "base/task/cancelable_task_tracker.h" 19 #include "base/task/cancelable_task_tracker.h"
18 #include "components/favicon/core/favicon_driver_observer.h" 20 #include "components/favicon/core/favicon_driver_observer.h"
19 #include "components/favicon/core/favicon_url.h" 21 #include "components/favicon/core/favicon_url.h"
20 #include "components/favicon_base/favicon_callback.h" 22 #include "components/favicon_base/favicon_callback.h"
21 #include "ui/gfx/favicon_size.h" 23 #include "ui/gfx/favicon_size.h"
22 #include "ui/gfx/image/image.h" 24 #include "ui/gfx/image/image.h"
25 #include "ui/gfx/image/image_skia.h"
23 #include "url/gurl.h" 26 #include "url/gurl.h"
24 27
25 class SkBitmap;
26
27 namespace favicon { 28 namespace favicon {
28 29
29 class FaviconService; 30 class FaviconService;
30 31
31 // FaviconHandler works with FaviconDriver to fetch the specific type of 32 // FaviconHandler works with FaviconDriver to fetch the specific type of
32 // favicon. 33 // favicon.
33 // 34 //
34 // FetchFavicon requests the favicon from the favicon service which in turn 35 // FetchFavicon requests the favicon from the favicon service which in turn
35 // requests the favicon from the history database. At this point 36 // requests the favicon from the history database. At this point
36 // we only know the URL of the page, and not necessarily the url of the 37 // we only know the URL of the page, and not necessarily the url of the
(...skipping 24 matching lines...) Expand all
61 // . Otherwise we ask the history database to update the mapping from 62 // . Otherwise we ask the history database to update the mapping from
62 // page url to favicon url and call us back with the favicon. Remember, it is 63 // page url to favicon url and call us back with the favicon. Remember, it is
63 // possible for the db to already have the favicon, just not the mapping 64 // possible for the db to already have the favicon, just not the mapping
64 // between page to favicon url. The callback for this is OnFaviconData. 65 // between page to favicon url. The callback for this is OnFaviconData.
65 // 66 //
66 // OnFaviconData either updates the favicon of the current page (if the 67 // OnFaviconData either updates the favicon of the current page (if the
67 // db knew about the favicon), or requests the renderer to download the 68 // db knew about the favicon), or requests the renderer to download the
68 // favicon. 69 // favicon.
69 // 70 //
70 // When the renderer downloads favicons, it considers the entire list of 71 // When the renderer downloads favicons, it considers the entire list of
71 // favicon candidates, if |download_largest_favicon_| is true, the largest 72 // favicon candidates. Among those, the one that matches |target_spec_|
72 // favicon will be used, otherwise the one that best matches the preferred size 73 // is chosen first. Once the matching favicon has been determined, SetFavicon
73 // is chosen (or the first one if there is no preferred size). Once the 74 // is called which updates the page's favicon and notifies the database to save
74 // matching favicon has been determined, SetFavicon is called which updates 75 // the favicon.
75 // the page's favicon and notifies the database to save the favicon.
76 76
77 class FaviconHandler { 77 class FaviconHandler {
78 public: 78 public:
79 class TargetSizeSpec {
80 public:
81 static TargetSizeSpec ForLargest();
82 static std::vector<TargetSizeSpec> For16x16Dips();
83
84 TargetSizeSpec(const TargetSizeSpec&);
85 ~TargetSizeSpec();
86
87 TargetSizeSpec(TargetSizeSpec&&);
88 TargetSizeSpec& operator=(TargetSizeSpec&&);
89
90 // Returns the target pixel size.
91 int PixelSize() const { return pixel_size_; }
92
93 // Returns the target scale factor.
94 float ScaleFactor() const { return scale_factor_; }
95
96 // Returns whether the spec is requiring the best-matching bitmap only.
97 bool WantsBestBitmapOnly() const;
98
99 // Checks if |bitmap_results| contains a bitmap satistying this spec.
100 bool HasMatchingResult(
101 const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results)
102 const;
103
104 private:
105 TargetSizeSpec();
106
107 int pixel_size_;
108 float scale_factor_;
109
110 // If true, FaviconHandler will resample candidates whenever needed to
111 // ensure that bitmaps for all |pixel_sizes| are produced.
112 bool ensure_exact_size_;
113 };
114
115 // Used to track a candidate for the favicon.
116 struct BitmapCandidate {
117 // Builds a scored candidate by selecting the best bitmap size.
118 BitmapCandidate(const TargetSizeSpec& target_size_spec,
119 const favicon::FaviconURL& favicon_url);
120 BitmapCandidate(const BitmapCandidate&);
121 BitmapCandidate(BitmapCandidate&&);
122 BitmapCandidate& operator=(BitmapCandidate&&);
123
124 GURL icon_url;
125 // Size hint provided by the page or (0, 0).
126 gfx::Size icon_size;
127 favicon_base::IconType icon_type;
128 float score;
129 };
130
131 class BitmapCandidateQueue {
pkotwicz 2017/03/16 05:31:45 It is weird for a queue to have so much logic in i
132 public:
133 // |candidates| must be non-empty.
134 BitmapCandidateQueue(const TargetSizeSpec& target_size_spec,
135 const std::vector<favicon::FaviconURL>& candidates);
136 ~BitmapCandidateQueue();
137 BitmapCandidateQueue(BitmapCandidateQueue&&);
138 BitmapCandidateQueue& operator=(BitmapCandidateQueue&&);
139
140 const TargetSizeSpec& TargetSizeSpec() const { return target_size_spec_; }
141
142 // Returns the next candidate to be processed, or an empty value if no
143 // further work is demanded, although clients are allowed to feed in new
144 // downloads via ProcessDownloadedImage().
145 base::Optional<BitmapCandidate> DequeueCandidate();
146
147 // Returns the current candidate without dequeueing it.
148 const BitmapCandidate* CurrentCandidate() const;
149
150 void ProcessDownloadedImage(const BitmapCandidate& candidate,
151 const std::vector<SkBitmap>& bitmaps);
152
153 // Returns the best-matching bitmap downloaded/processed so far, or null if
154 // none available. If non-null, it's guarantee to contain a valid.
155 // |bitmap_result|.
156 const std::pair<BitmapCandidate, SkBitmap>* BestBitmap() const {
157 return best_candidate_.get();
158 }
159
160 private:
161 // Returns whether a good enough bitmap was found (i.e. no further work
162 // demanded by this queue, although callers are allowed to process and feed
163 // in more processed downloads)
164 bool IsSatisfied() const;
165
166 // Desired icon size.
167 class TargetSizeSpec target_size_spec_;
168
169 // The prioritized favicon candidates from the page. There cannot be
170 // multiple candidates for the same icon URL.
171 std::list<BitmapCandidate> pending_candidates_;
172
173 // Best bitmap we've seen so far. null if none.
174 std::unique_ptr<std::pair<BitmapCandidate, SkBitmap>> best_candidate_;
pkotwicz 2017/03/16 05:31:45 I think that it would be easier to have: best_cand
175
176 DISALLOW_COPY_AND_ASSIGN(BitmapCandidateQueue);
177 };
178
79 class Delegate { 179 class Delegate {
80 public: 180 public:
81 // Mimics WebContents::ImageDownloadCallback. 181 // Mimics WebContents::ImageDownloadCallback.
82 typedef base::Callback<void( 182 typedef base::Callback<void(
83 int id, 183 int id,
84 int status_code, 184 int status_code,
85 const GURL& image_url, 185 const GURL& image_url,
86 const std::vector<SkBitmap>& bitmaps, 186 const std::vector<SkBitmap>& bitmaps,
87 const std::vector<gfx::Size>& original_bitmap_sizes)> 187 const std::vector<gfx::Size>& original_bitmap_sizes)>
88 ImageDownloadCallback; 188 ImageDownloadCallback;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 struct DownloadRequest { 248 struct DownloadRequest {
149 DownloadRequest(); 249 DownloadRequest();
150 ~DownloadRequest(); 250 ~DownloadRequest();
151 251
152 DownloadRequest(const GURL& image_url, favicon_base::IconType icon_type); 252 DownloadRequest(const GURL& image_url, favicon_base::IconType icon_type);
153 253
154 GURL image_url; 254 GURL image_url;
155 favicon_base::IconType icon_type; 255 favicon_base::IconType icon_type;
156 }; 256 };
157 257
158 // Used to track a candidate for the favicon.
159 struct FaviconCandidate {
160 FaviconCandidate();
161 ~FaviconCandidate();
162
163 FaviconCandidate(const GURL& image_url,
164 const gfx::Image& image,
165 float score,
166 favicon_base::IconType icon_type);
167
168 GURL image_url;
169 gfx::Image image;
170 float score;
171 favicon_base::IconType icon_type;
172 };
173
174 // Returns the bit mask of favicon_base::IconType based on the handler's type. 258 // Returns the bit mask of favicon_base::IconType based on the handler's type.
175 static int GetIconTypesFromHandlerType( 259 static int GetIconTypesFromHandlerType(
176 FaviconDriverObserver::NotificationIconType handler_type); 260 FaviconDriverObserver::NotificationIconType handler_type);
177 261
262 std::vector<int> GetTargetPixelSizes() const;
263 std::map<int, float> GetTargetPixelSizesAndScaleFactors() const;
264
178 // Called when the history request for favicon data mapped to |url_| has 265 // Called when the history request for favicon data mapped to |url_| has
179 // completed and the renderer has told us the icon URLs used by |url_| 266 // completed and the renderer has told us the icon URLs used by |url_|
180 void OnGotInitialHistoryDataAndIconURLCandidates(); 267 void OnGotInitialHistoryDataAndIconURLCandidates();
181 268
182 // See description above class for details. 269 // See description above class for details.
183 void OnFaviconDataForInitialURLFromFaviconService(const std::vector< 270 void OnFaviconDataForInitialURLFromFaviconService(const std::vector<
184 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results); 271 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results);
185 272
186 // If the favicon currently mapped to |url_| has expired, downloads the 273 // If the favicon currently mapped to |url_| has expired, downloads the
187 // current candidate favicon from the renderer. Otherwise requests data for 274 // current candidate favicon from the renderer. Otherwise requests data for
188 // the current favicon from history. If data is requested from history, 275 // the current favicon from history. If data is requested from history,
189 // OnFaviconData() is called with the history data once it has been retrieved. 276 // OnFaviconData() is called with the history data once it has been retrieved.
190 void DownloadCurrentCandidateOrAskFaviconService(); 277 void DownloadNextCandidateOrAskFaviconService();
191 278
192 // See description above class for details. 279 // See description above class for details.
193 void OnFaviconData(const std::vector<favicon_base::FaviconRawBitmapResult>& 280 void OnFaviconData(const std::vector<favicon_base::FaviconRawBitmapResult>&
194 favicon_bitmap_results); 281 favicon_bitmap_results);
195 282
196 // Schedules a download for the specified entry. This adds the request to 283 // Schedules a download for the specified entry. This adds the request to
197 // download_requests_. 284 // download_requests_.
198 void ScheduleDownload(const GURL& image_url, 285 void ScheduleDownload(const GURL& image_url,
199 favicon_base::IconType icon_type); 286 favicon_base::IconType icon_type);
200 287
201 // Triggered when a download of an image has finished. 288 // Triggered when a download of an image has finished.
202 void OnDidDownloadFavicon( 289 void OnDidDownloadFavicon(
203 int id, 290 int id,
204 int http_status_code, 291 int http_status_code,
205 const GURL& image_url, 292 const GURL& image_url,
206 const std::vector<SkBitmap>& bitmaps, 293 const std::vector<SkBitmap>& bitmaps,
207 const std::vector<gfx::Size>& original_bitmap_sizes); 294 const std::vector<gfx::Size>& original_bitmap_sizes);
208 295
209 bool ShouldSaveFavicon(); 296 bool ShouldSaveFavicon();
210 297
211 // Updates |favicon_candidate_| and returns true if it is an exact match. 298 // Updates candidate queues and returns true if no more candidates should be
299 // processed (e.g. an exact match was found).
212 bool UpdateFaviconCandidate(const GURL& image_url, 300 bool UpdateFaviconCandidate(const GURL& image_url,
213 const gfx::Image& image, 301 const gfx::Image& image,
214 float score,
215 favicon_base::IconType icon_type); 302 favicon_base::IconType icon_type);
216 303
217 // Sets the image data for the favicon. 304 // Sets the image data for the favicon.
218 void SetFavicon(const GURL& icon_url, 305 void SetFavicon(const GURL& icon_url,
219 const gfx::Image& image, 306 const gfx::Image& image,
220 favicon_base::IconType icon_type); 307 favicon_base::IconType icon_type);
221 308
222 // Notifies |driver_| that FaviconHandler found an icon which matches the 309 // Notifies |driver_| that FaviconHandler found an icon which matches the
223 // |handler_type_| criteria. NotifyFaviconUpdated() can be called multiple 310 // |handler_type_| criteria. NotifyFaviconUpdated() can be called multiple
224 // times for the same page if: 311 // times for the same page if:
225 // - a better match is found for |handler_type_| (e.g. newer bitmap data) 312 // - a better match is found for |handler_type_| (e.g. newer bitmap data)
226 // - Javascript changes the page's icon URLs. 313 // - Javascript changes the page's icon URLs.
227 void NotifyFaviconUpdated( 314 void NotifyFaviconUpdated(
228 const std::vector<favicon_base::FaviconRawBitmapResult>& 315 const std::vector<favicon_base::FaviconRawBitmapResult>&
229 favicon_bitmap_results); 316 favicon_bitmap_results);
230 void NotifyFaviconUpdated(const GURL& icon_url, 317 void NotifyFaviconUpdated(const GURL& icon_url,
231 favicon_base::IconType icon_type, 318 favicon_base::IconType icon_type,
232 const gfx::Image& image); 319 const gfx::Image& image);
233 320
234 // Return the current candidate if any.
235 favicon::FaviconURL* current_candidate() {
236 return current_candidate_index_ < image_urls_.size()
237 ? &image_urls_[current_candidate_index_]
238 : nullptr;
239 }
240
241 // Returns the preferred size of the image. 0 means no preference (any size
242 // will do).
243 int preferred_icon_size() const {
244 return download_largest_icon_ ? 0 : gfx::kFaviconSize;
245 }
246
247 // Used for FaviconService requests. 321 // Used for FaviconService requests.
248 base::CancelableTaskTracker cancelable_task_tracker_; 322 base::CancelableTaskTracker cancelable_task_tracker_;
249 323
250 FaviconDriverObserver::NotificationIconType handler_type_; 324 FaviconDriverObserver::NotificationIconType handler_type_;
251 325
252 // URL of the page we're requesting the favicon for. 326 // URL of the page we're requesting the favicon for.
253 GURL url_; 327 GURL url_;
254 328
255 // Whether we got data back for the initial request to the FaviconService. 329 // Whether we got data back for the initial request to the FaviconService.
256 bool got_favicon_from_history_; 330 bool got_favicon_from_history_;
257 331
258 // Whether the history data returned in 332 // Whether the history data returned in
259 // OnFaviconDataForInitialURLFromFaviconService() is out of date or is known 333 // OnFaviconDataForInitialURLFromFaviconService() is out of date or is known
260 // to be incomplete. If true, it means there is a favicon mapped to |url_| in 334 // to be incomplete. If true, it means there is a favicon mapped to |url_| in
261 // history, but we need to redownload the icon URLs because the icon in the 335 // history, but we need to redownload the icon URLs because the icon in the
262 // database has expired or the data in the database is incomplete. 336 // database has expired or the data in the database is incomplete.
263 bool initial_history_result_expired_or_incomplete_; 337 bool initial_history_result_expired_or_incomplete_;
264 338
265 // Whether FaviconHandler should ignore history state and determine the 339 // Whether FaviconHandler should ignore history state and determine the
266 // optimal icon URL out of |image_urls_| for |url_| by downloading 340 // optimal icon URL out of downloading input candidates.
267 // |image_urls_| one by one.
268 bool redownload_icons_; 341 bool redownload_icons_;
269 342
270 // Requests to the renderer to download favicons. 343 // Requests to the renderer to download favicons.
271 typedef std::map<int, DownloadRequest> DownloadRequests; 344 typedef std::map<int, DownloadRequest> DownloadRequests;
272 DownloadRequests download_requests_; 345 DownloadRequests download_requests_;
273 346
274 // The combination of the supported icon types. 347 // The combination of the supported icon types.
275 const int icon_types_; 348 const int icon_types_;
276 349
277 // Whether the largest icon should be downloaded. 350 // The target "buckets" or requirements that the FaviconHandler will try to
278 const bool download_largest_icon_; 351 // fulfill.
352 const std::vector<TargetSizeSpec> target_size_specs_;
353 std::vector<BitmapCandidateQueue> candidate_queues_;
279 354
280 // The prioritized favicon candidates from the page back from the renderer. 355 // Current candidate being processed.
356 base::Optional<BitmapCandidate> current_candidate_;
357
358 // The filtered (per icon type) candidates provided by the page.
281 std::vector<favicon::FaviconURL> image_urls_; 359 std::vector<favicon::FaviconURL> image_urls_;
282 360
283 // The icon URL and the icon type of the favicon in the most recent 361 // The icon URL and the icon type of the favicon in the most recent
284 // FaviconDriver::OnFaviconAvailable() notification. 362 // FaviconDriver::OnFaviconAvailable() notification.
285 GURL notification_icon_url_; 363 GURL notification_icon_url_;
286 favicon_base::IconType notification_icon_type_; 364 favicon_base::IconType notification_icon_type_;
287 365
288 // The FaviconService which implements favicon operations. May be null during 366 // The FaviconService which implements favicon operations. May be null during
289 // testing. 367 // testing.
290 FaviconService* service_; 368 FaviconService* service_;
291 369
292 // This handler's delegate. 370 // This handler's delegate.
293 Delegate* delegate_; 371 Delegate* delegate_;
294 372
295 // The index of the favicon URL in |image_urls_| which is currently being
296 // requested from history or downloaded.
297 size_t current_candidate_index_;
298
299 // Best image we've seen so far. As images are downloaded from the page they
300 // are stored here. When there is an exact match, or no more images are
301 // available the favicon service and the current page are updated (assuming
302 // the image is for a favicon).
303 FaviconCandidate best_favicon_candidate_;
304
305 base::WeakPtrFactory<FaviconHandler> weak_ptr_factory_; 373 base::WeakPtrFactory<FaviconHandler> weak_ptr_factory_;
306 374
307 DISALLOW_COPY_AND_ASSIGN(FaviconHandler); 375 DISALLOW_COPY_AND_ASSIGN(FaviconHandler);
308 }; 376 };
309 377
310 } // namespace favicon 378 } // namespace favicon
311 379
312 #endif // COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_ 380 #endif // COMPONENTS_FAVICON_CORE_FAVICON_HANDLER_H_
OLDNEW
« no previous file with comments | « no previous file | components/favicon/core/favicon_handler.cc » ('j') | components/favicon/core/favicon_handler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698