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