Home | History | Annotate | Download | only in favicon
      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_SERVICE_H_
      6 #define CHROME_BROWSER_FAVICON_FAVICON_SERVICE_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/callback.h"
     11 #include "base/containers/hash_tables.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "chrome/browser/common/cancelable_request.h"
     14 #include "chrome/common/cancelable_task_tracker.h"
     15 #include "chrome/common/favicon/favicon_types.h"
     16 #include "chrome/common/ref_counted_util.h"
     17 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     18 #include "ui/base/layout.h"
     19 
     20 class GURL;
     21 class HistoryService;
     22 struct ImportedFaviconUsage;
     23 class Profile;
     24 
     25 namespace chrome {
     26 struct FaviconImageResult;
     27 }
     28 
     29 // The favicon service provides methods to access favicons. It calls the history
     30 // backend behind the scenes.
     31 //
     32 // This service is thread safe. Each request callback is invoked in the
     33 // thread that made the request.
     34 class FaviconService : public CancelableRequestProvider,
     35                        public BrowserContextKeyedService {
     36  public:
     37   explicit FaviconService(Profile* profile);
     38 
     39   virtual ~FaviconService();
     40 
     41   // Auxiliary argument structure for requesting favicons for URLs.
     42   struct FaviconForURLParams {
     43     FaviconForURLParams(const GURL& page_url,
     44                         int icon_types,
     45                         int desired_size_in_dip)
     46         : page_url(page_url),
     47           icon_types(icon_types),
     48           desired_size_in_dip(desired_size_in_dip) {}
     49 
     50     GURL page_url;
     51     int icon_types;
     52     int desired_size_in_dip;
     53   };
     54 
     55   // Callback for GetFaviconImage() and GetFaviconImageForURL().
     56   // |FaviconImageResult::image| is constructed from the bitmaps for the
     57   // passed in URL and icon types which most which closely match the passed in
     58   // |desired_size_in_dip| at the scale factors supported by the current
     59   // platform (eg MacOS) in addition to 1x.
     60   // |FaviconImageResult::icon_url| is the favicon that the favicon bitmaps in
     61   // |image| originate from.
     62   // TODO(pkotwicz): Enable constructing |image| from bitmaps from several
     63   // icon URLs.
     64   typedef base::Callback<void(const chrome::FaviconImageResult&)>
     65       FaviconImageCallback;
     66 
     67   // Callback for GetRawFavicon(), GetRawFaviconForURL() and
     68   // GetLargestRawFavicon().
     69   // See function for details on value.
     70   typedef base::Callback<void(const chrome::FaviconBitmapResult&)>
     71       FaviconRawCallback;
     72 
     73   // Callback for GetFavicon() and GetFaviconForURL().
     74   //
     75   // The first argument is the set of bitmaps for the passed in URL and
     76   // icon types whose pixel sizes best match the passed in
     77   // |desired_size_in_dip| at the scale factors supported by the current
     78   // platform (eg MacOS) in addition to 1x. The vector has at most one result
     79   // for each of the scale factors. There are less entries if a single result
     80   // is the best bitmap to use for several scale factors.
     81   typedef base::Callback<void(const std::vector<chrome::FaviconBitmapResult>&)>
     82       FaviconResultsCallback;
     83 
     84   // We usually pass parameters with pointer to avoid copy. This function is a
     85   // helper to run FaviconResultsCallback with pointer parameters.
     86   static void FaviconResultsCallbackRunner(
     87       const FaviconResultsCallback& callback,
     88       const std::vector<chrome::FaviconBitmapResult>* results);
     89 
     90   // Requests the favicon at |icon_url| of |icon_type| whose size most closely
     91   // matches |desired_size_in_dip|. If |desired_size_in_dip| is 0, the largest
     92   // favicon bitmap at |icon_url| is returned. |consumer| is notified when the
     93   // bits have been fetched. |icon_url| is the URL of the icon itself, e.g.
     94   // <http://www.google.com/favicon.ico>.
     95   // Each of the three methods below differs in the format of the callback and
     96   // the requested scale factors. All of the scale factors supported by the
     97   // current platform (eg MacOS) are requested for GetFaviconImage().
     98   CancelableTaskTracker::TaskId GetFaviconImage(
     99       const GURL& icon_url,
    100       chrome::IconType icon_type,
    101       int desired_size_in_dip,
    102       const FaviconImageCallback& callback,
    103       CancelableTaskTracker* tracker);
    104 
    105   CancelableTaskTracker::TaskId GetRawFavicon(
    106       const GURL& icon_url,
    107       chrome::IconType icon_type,
    108       int desired_size_in_dip,
    109       ui::ScaleFactor desired_scale_factor,
    110       const FaviconRawCallback& callback,
    111       CancelableTaskTracker* tracker);
    112 
    113   CancelableTaskTracker::TaskId GetFavicon(
    114       const GURL& icon_url,
    115       chrome::IconType icon_type,
    116       int desired_size_in_dip,
    117       const FaviconResultsCallback& callback,
    118       CancelableTaskTracker* tracker);
    119 
    120   // Set the favicon mappings to |page_url| for |icon_types| in the history
    121   // database.
    122   // Sample |icon_urls|:
    123   //  { ICON_URL1 -> TOUCH_ICON, known to the database,
    124   //    ICON_URL2 -> TOUCH_ICON, not known to the database,
    125   //    ICON_URL3 -> TOUCH_PRECOMPOSED_ICON, known to the database }
    126   // The new mappings are computed from |icon_urls| with these rules:
    127   // 1) Any urls in |icon_urls| which are not already known to the database are
    128   //    rejected.
    129   //    Sample new mappings to |page_url|: { ICON_URL1, ICON_URL3 }
    130   // 2) If |icon_types| has multiple types, the mappings are only set for the
    131   //    largest icon type.
    132   //    Sample new mappings to |page_url|: { ICON_URL3 }
    133   // |icon_types| can only have multiple IconTypes if
    134   // |icon_types| == TOUCH_ICON | TOUCH_PRECOMPOSED_ICON.
    135   // The favicon bitmaps which most closely match |desired_size_in_dip|
    136   // at the scale factors supported by the current platform (eg MacOS) in
    137   // addition to 1x from the favicons which were just mapped to |page_url| are
    138   // returned. If |desired_size_in_dip| is 0, the largest favicon bitmap is
    139   // returned.
    140   CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch(
    141       const GURL& page_url,
    142       const std::vector<GURL>& icon_urls,
    143       int icon_types,
    144       int desired_size_in_dip,
    145       const FaviconResultsCallback& callback,
    146       CancelableTaskTracker* tracker);
    147 
    148   // Requests the favicons of any of |icon_types| whose pixel sizes most
    149   // closely match |desired_size_in_dip| and desired scale factors for a web
    150   // page URL. If |desired_size_in_dip| is 0, the largest favicon for the web
    151   // page URL is returned. |callback| is run when the bits have been fetched.
    152   // |icon_types| can be any combination of IconType value, but only one icon
    153   // will be returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON and
    154   // FAVICON. Each of the three methods below differs in the format of the
    155   // callback and the requested scale factors. All of the scale factors
    156   // supported by the current platform (eg MacOS) are requested for
    157   // GetFaviconImageForURL().
    158   // Note. |callback| is always run asynchronously.
    159   CancelableTaskTracker::TaskId GetFaviconImageForURL(
    160       const FaviconForURLParams& params,
    161       const FaviconImageCallback& callback,
    162       CancelableTaskTracker* tracker);
    163 
    164   CancelableTaskTracker::TaskId GetRawFaviconForURL(
    165       const FaviconForURLParams& params,
    166       ui::ScaleFactor desired_scale_factor,
    167       const FaviconRawCallback& callback,
    168       CancelableTaskTracker* tracker);
    169 
    170   // See HistoryService::GetLargestFaviconForURL().
    171   CancelableTaskTracker::TaskId GetLargestRawFaviconForURL(
    172       Profile* profile,
    173       const GURL& page_url,
    174       const std::vector<int>& icon_types,
    175       int minimum_size_in_pixels,
    176       const FaviconRawCallback& callback,
    177       CancelableTaskTracker* tracker);
    178 
    179   CancelableTaskTracker::TaskId GetFaviconForURL(
    180       const FaviconForURLParams& params,
    181       const FaviconResultsCallback& callback,
    182       CancelableTaskTracker* tracker);
    183 
    184   // Used to request a bitmap for the favicon with |favicon_id| which is not
    185   // resized from the size it is stored at in the database. If there are
    186   // multiple favicon bitmaps for |favicon_id|, the largest favicon bitmap is
    187   // returned.
    188   CancelableTaskTracker::TaskId GetLargestRawFaviconForID(
    189       chrome::FaviconID favicon_id,
    190       const FaviconRawCallback& callback,
    191       CancelableTaskTracker* tracker);
    192 
    193   // Marks all types of favicon for the page as being out of date.
    194   void SetFaviconOutOfDateForPage(const GURL& page_url);
    195 
    196   // Clones all icons from an existing page. This associates the icons from
    197   // |old_page_url| with |new_page_url|, provided |new_page_url| has no
    198   // recorded associations to any other icons.
    199   // Needed if you want to declare favicons (tentatively) in advance, before a
    200   // page is ever visited.
    201   void CloneFavicon(const GURL& old_page_url, const GURL& new_page_url);
    202 
    203   // Allows the importer to set many favicons for many pages at once. The pages
    204   // must exist, any favicon sets for unknown pages will be discarded. Existing
    205   // favicons will not be overwritten.
    206   void SetImportedFavicons(
    207       const std::vector<ImportedFaviconUsage>& favicon_usage);
    208 
    209   // Set the favicon for |page_url| for |icon_type| in the thumbnail database.
    210   // Unlike SetFavicons(), this method will not delete preexisting bitmap data
    211   // which is associated to |page_url| if at all possible. Use this method if
    212   // the favicon bitmaps for any of ui::GetSupportedScaleFactors() are not
    213   // known.
    214   void MergeFavicon(const GURL& page_url,
    215                     const GURL& icon_url,
    216                     chrome::IconType icon_type,
    217                     scoped_refptr<base::RefCountedMemory> bitmap_data,
    218                     const gfx::Size& pixel_size);
    219 
    220   // Set the favicon for |page_url| for |icon_type| in the thumbnail database.
    221   // |icon_url| is the single favicon to map to |page_url|. Mappings from
    222   // |page_url| to favicons at different icon URLs will be deleted.
    223   // A favicon bitmap is added for each image rep in |image|. Any preexisting
    224   // bitmap data for |icon_url| is deleted. It is important that |image|
    225   // contains image reps for all of ui::GetSupportedScaleFactors(). Use
    226   // MergeFavicon() if it does not.
    227   // TODO(pkotwicz): Save unresized favicon bitmaps to the database.
    228   // TODO(pkotwicz): Support adding favicons for multiple icon URLs to the
    229   // thumbnail database.
    230   void SetFavicons(const GURL& page_url,
    231                    const GURL& icon_url,
    232                    chrome::IconType icon_type,
    233                    const gfx::Image& image);
    234 
    235   // Avoid repeated requests to download missing favicon.
    236   void UnableToDownloadFavicon(const GURL& icon_url);
    237   bool WasUnableToDownloadFavicon(const GURL& icon_url) const;
    238   void ClearUnableToDownloadFavicons();
    239 
    240  private:
    241   typedef uint32 MissingFaviconURLHash;
    242   base::hash_set<MissingFaviconURLHash> missing_favicon_urls_;
    243   HistoryService* history_service_;
    244   Profile* profile_;
    245 
    246   // Helper function for GetFaviconImageForURL(), GetRawFaviconForURL() and
    247   // GetFaviconForURL().
    248   CancelableTaskTracker::TaskId GetFaviconForURLImpl(
    249       const FaviconForURLParams& params,
    250       const std::vector<ui::ScaleFactor>& desired_scale_factors,
    251       const FaviconResultsCallback& callback,
    252       CancelableTaskTracker* tracker);
    253 
    254   // Intermediate callback for GetFaviconImage() and GetFaviconImageForURL()
    255   // so that history service can deal solely with FaviconResultsCallback.
    256   // Builds chrome::FaviconImageResult from |favicon_bitmap_results| and runs
    257   // |callback|.
    258   void RunFaviconImageCallbackWithBitmapResults(
    259       const FaviconImageCallback& callback,
    260       int desired_size_in_dip,
    261       const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results);
    262 
    263   // Intermediate callback for GetRawFavicon() and GetRawFaviconForURL()
    264   // so that history service can deal solely with FaviconResultsCallback.
    265   // Resizes chrome::FaviconBitmapResult if necessary and runs |callback|.
    266   void RunFaviconRawCallbackWithBitmapResults(
    267       const FaviconRawCallback& callback,
    268       int desired_size_in_dip,
    269       ui::ScaleFactor desired_scale_factor,
    270       const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results);
    271 
    272   DISALLOW_COPY_AND_ASSIGN(FaviconService);
    273 };
    274 
    275 #endif  // CHROME_BROWSER_FAVICON_FAVICON_SERVICE_H_
    276