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