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