Chromium Code Reviews| Index: components/favicon/core/favicon_handler.h |
| diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h |
| index f3d9d4b662c5d9c6f034cacffc7f5a8cfd67d9db..af0694b32b10a9e72a390016de281f1a3fd2ae22 100644 |
| --- a/components/favicon/core/favicon_handler.h |
| +++ b/components/favicon/core/favicon_handler.h |
| @@ -7,6 +7,7 @@ |
| #include <stddef.h> |
| +#include <list> |
| #include <map> |
| #include <vector> |
| @@ -14,16 +15,16 @@ |
| #include "base/macros.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| +#include "base/optional.h" |
| #include "base/task/cancelable_task_tracker.h" |
| #include "components/favicon/core/favicon_driver_observer.h" |
| #include "components/favicon/core/favicon_url.h" |
| #include "components/favicon_base/favicon_callback.h" |
| #include "ui/gfx/favicon_size.h" |
| #include "ui/gfx/image/image.h" |
| +#include "ui/gfx/image/image_skia.h" |
| #include "url/gurl.h" |
| -class SkBitmap; |
| - |
| namespace favicon { |
| class FaviconService; |
| @@ -68,14 +69,113 @@ class FaviconService; |
| // favicon. |
| // |
| // When the renderer downloads favicons, it considers the entire list of |
| -// favicon candidates, if |download_largest_favicon_| is true, the largest |
| -// favicon will be used, otherwise the one that best matches the preferred size |
| -// is chosen (or the first one if there is no preferred size). Once the |
| -// matching favicon has been determined, SetFavicon is called which updates |
| -// the page's favicon and notifies the database to save the favicon. |
| +// favicon candidates. Among those, the one that matches |target_spec_| |
| +// is chosen first. Once the matching favicon has been determined, SetFavicon |
| +// is called which updates the page's favicon and notifies the database to save |
| +// the favicon. |
| class FaviconHandler { |
| public: |
| + class TargetSizeSpec { |
| + public: |
| + static TargetSizeSpec ForLargest(); |
| + static std::vector<TargetSizeSpec> For16x16Dips(); |
| + |
| + TargetSizeSpec(const TargetSizeSpec&); |
| + ~TargetSizeSpec(); |
| + |
| + TargetSizeSpec(TargetSizeSpec&&); |
| + TargetSizeSpec& operator=(TargetSizeSpec&&); |
| + |
| + // Returns the target pixel size. |
| + int PixelSize() const { return pixel_size_; } |
| + |
| + // Returns the target scale factor. |
| + float ScaleFactor() const { return scale_factor_; } |
| + |
| + // Returns whether the spec is requiring the best-matching bitmap only. |
| + bool WantsBestBitmapOnly() const; |
| + |
| + // Checks if |bitmap_results| contains a bitmap satistying this spec. |
| + bool HasMatchingResult( |
| + const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) |
| + const; |
| + |
| + private: |
| + TargetSizeSpec(); |
| + |
| + int pixel_size_; |
| + float scale_factor_; |
| + |
| + // If true, FaviconHandler will resample candidates whenever needed to |
| + // ensure that bitmaps for all |pixel_sizes| are produced. |
| + bool ensure_exact_size_; |
| + }; |
| + |
| + // Used to track a candidate for the favicon. |
| + struct BitmapCandidate { |
| + // Builds a scored candidate by selecting the best bitmap size. |
| + BitmapCandidate(const TargetSizeSpec& target_size_spec, |
| + const favicon::FaviconURL& favicon_url); |
| + BitmapCandidate(const BitmapCandidate&); |
| + BitmapCandidate(BitmapCandidate&&); |
| + BitmapCandidate& operator=(BitmapCandidate&&); |
| + |
| + GURL icon_url; |
| + // Size hint provided by the page or (0, 0). |
| + gfx::Size icon_size; |
| + favicon_base::IconType icon_type; |
| + float score; |
| + }; |
| + |
| + class BitmapCandidateQueue { |
|
pkotwicz
2017/03/16 05:31:45
It is weird for a queue to have so much logic in i
|
| + public: |
| + // |candidates| must be non-empty. |
| + BitmapCandidateQueue(const TargetSizeSpec& target_size_spec, |
| + const std::vector<favicon::FaviconURL>& candidates); |
| + ~BitmapCandidateQueue(); |
| + BitmapCandidateQueue(BitmapCandidateQueue&&); |
| + BitmapCandidateQueue& operator=(BitmapCandidateQueue&&); |
| + |
| + const TargetSizeSpec& TargetSizeSpec() const { return target_size_spec_; } |
| + |
| + // Returns the next candidate to be processed, or an empty value if no |
| + // further work is demanded, although clients are allowed to feed in new |
| + // downloads via ProcessDownloadedImage(). |
| + base::Optional<BitmapCandidate> DequeueCandidate(); |
| + |
| + // Returns the current candidate without dequeueing it. |
| + const BitmapCandidate* CurrentCandidate() const; |
| + |
| + void ProcessDownloadedImage(const BitmapCandidate& candidate, |
| + const std::vector<SkBitmap>& bitmaps); |
| + |
| + // Returns the best-matching bitmap downloaded/processed so far, or null if |
| + // none available. If non-null, it's guarantee to contain a valid. |
| + // |bitmap_result|. |
| + const std::pair<BitmapCandidate, SkBitmap>* BestBitmap() const { |
| + return best_candidate_.get(); |
| + } |
| + |
| + private: |
| + // Returns whether a good enough bitmap was found (i.e. no further work |
| + // demanded by this queue, although callers are allowed to process and feed |
| + // in more processed downloads) |
| + bool IsSatisfied() const; |
| + |
| + // Desired icon size. |
| + class TargetSizeSpec target_size_spec_; |
| + |
| + // The prioritized favicon candidates from the page. There cannot be |
| + // multiple candidates for the same icon URL. |
| + std::list<BitmapCandidate> pending_candidates_; |
| + |
| + // Best bitmap we've seen so far. null if none. |
| + 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
|
| + |
| + DISALLOW_COPY_AND_ASSIGN(BitmapCandidateQueue); |
| + }; |
| + |
| class Delegate { |
| public: |
| // Mimics WebContents::ImageDownloadCallback. |
| @@ -155,26 +255,13 @@ class FaviconHandler { |
| favicon_base::IconType icon_type; |
| }; |
| - // Used to track a candidate for the favicon. |
| - struct FaviconCandidate { |
| - FaviconCandidate(); |
| - ~FaviconCandidate(); |
| - |
| - FaviconCandidate(const GURL& image_url, |
| - const gfx::Image& image, |
| - float score, |
| - favicon_base::IconType icon_type); |
| - |
| - GURL image_url; |
| - gfx::Image image; |
| - float score; |
| - favicon_base::IconType icon_type; |
| - }; |
| - |
| // Returns the bit mask of favicon_base::IconType based on the handler's type. |
| static int GetIconTypesFromHandlerType( |
| FaviconDriverObserver::NotificationIconType handler_type); |
| + std::vector<int> GetTargetPixelSizes() const; |
| + std::map<int, float> GetTargetPixelSizesAndScaleFactors() const; |
| + |
| // Called when the history request for favicon data mapped to |url_| has |
| // completed and the renderer has told us the icon URLs used by |url_| |
| void OnGotInitialHistoryDataAndIconURLCandidates(); |
| @@ -187,7 +274,7 @@ class FaviconHandler { |
| // current candidate favicon from the renderer. Otherwise requests data for |
| // the current favicon from history. If data is requested from history, |
| // OnFaviconData() is called with the history data once it has been retrieved. |
| - void DownloadCurrentCandidateOrAskFaviconService(); |
| + void DownloadNextCandidateOrAskFaviconService(); |
| // See description above class for details. |
| void OnFaviconData(const std::vector<favicon_base::FaviconRawBitmapResult>& |
| @@ -208,10 +295,10 @@ class FaviconHandler { |
| bool ShouldSaveFavicon(); |
| - // Updates |favicon_candidate_| and returns true if it is an exact match. |
| + // Updates candidate queues and returns true if no more candidates should be |
| + // processed (e.g. an exact match was found). |
| bool UpdateFaviconCandidate(const GURL& image_url, |
| const gfx::Image& image, |
| - float score, |
| favicon_base::IconType icon_type); |
| // Sets the image data for the favicon. |
| @@ -231,19 +318,6 @@ class FaviconHandler { |
| favicon_base::IconType icon_type, |
| const gfx::Image& image); |
| - // Return the current candidate if any. |
| - favicon::FaviconURL* current_candidate() { |
| - return current_candidate_index_ < image_urls_.size() |
| - ? &image_urls_[current_candidate_index_] |
| - : nullptr; |
| - } |
| - |
| - // Returns the preferred size of the image. 0 means no preference (any size |
| - // will do). |
| - int preferred_icon_size() const { |
| - return download_largest_icon_ ? 0 : gfx::kFaviconSize; |
| - } |
| - |
| // Used for FaviconService requests. |
| base::CancelableTaskTracker cancelable_task_tracker_; |
| @@ -263,8 +337,7 @@ class FaviconHandler { |
| bool initial_history_result_expired_or_incomplete_; |
| // Whether FaviconHandler should ignore history state and determine the |
| - // optimal icon URL out of |image_urls_| for |url_| by downloading |
| - // |image_urls_| one by one. |
| + // optimal icon URL out of downloading input candidates. |
| bool redownload_icons_; |
| // Requests to the renderer to download favicons. |
| @@ -274,10 +347,15 @@ class FaviconHandler { |
| // The combination of the supported icon types. |
| const int icon_types_; |
| - // Whether the largest icon should be downloaded. |
| - const bool download_largest_icon_; |
| + // The target "buckets" or requirements that the FaviconHandler will try to |
| + // fulfill. |
| + const std::vector<TargetSizeSpec> target_size_specs_; |
| + std::vector<BitmapCandidateQueue> candidate_queues_; |
| + |
| + // Current candidate being processed. |
| + base::Optional<BitmapCandidate> current_candidate_; |
| - // The prioritized favicon candidates from the page back from the renderer. |
| + // The filtered (per icon type) candidates provided by the page. |
| std::vector<favicon::FaviconURL> image_urls_; |
| // The icon URL and the icon type of the favicon in the most recent |
| @@ -292,16 +370,6 @@ class FaviconHandler { |
| // This handler's delegate. |
| Delegate* delegate_; |
| - // The index of the favicon URL in |image_urls_| which is currently being |
| - // requested from history or downloaded. |
| - size_t current_candidate_index_; |
| - |
| - // Best image we've seen so far. As images are downloaded from the page they |
| - // are stored here. When there is an exact match, or no more images are |
| - // available the favicon service and the current page are updated (assuming |
| - // the image is for a favicon). |
| - FaviconCandidate best_favicon_candidate_; |
| - |
| base::WeakPtrFactory<FaviconHandler> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN(FaviconHandler); |