Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: chrome/browser/favicon/favicon_service.cc

Issue 983043003: Componentize FaviconService and FaviconHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@favicon_service
Patch Set: Fix android_aosp (reverted the change by mistake by switching computer) Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "chrome/browser/favicon/favicon_service.h"
6
7 #include <cmath>
8
9 #include "base/hash.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "components/favicon/core/browser/favicon_client.h"
13 #include "components/favicon_base/favicon_util.h"
14 #include "components/favicon_base/select_favicon_frames.h"
15 #include "components/history/core/browser/history_service.h"
16 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "ui/gfx/codec/png_codec.h"
18 #include "ui/gfx/favicon_size.h"
19 #include "ui/gfx/image/image_skia.h"
20 #include "url/gurl.h"
21
22 using base::Bind;
23
24 namespace {
25
26 // Helper to run callback with empty results if we cannot get the history
27 // service.
28 base::CancelableTaskTracker::TaskId RunWithEmptyResultAsync(
29 const favicon_base::FaviconResultsCallback& callback,
30 base::CancelableTaskTracker* tracker) {
31 scoped_refptr<base::SingleThreadTaskRunner> thread_runner(
32 base::ThreadTaskRunnerHandle::Get());
33 return tracker->PostTask(
34 thread_runner.get(), FROM_HERE,
35 Bind(callback, std::vector<favicon_base::FaviconRawBitmapResult>()));
36 }
37
38 // Returns a vector of pixel edge sizes from |size_in_dip| and
39 // favicon_base::GetFaviconScales().
40 std::vector<int> GetPixelSizesForFaviconScales(int size_in_dip) {
41 std::vector<float> scales = favicon_base::GetFaviconScales();
42 std::vector<int> sizes_in_pixel;
43 for (size_t i = 0; i < scales.size(); ++i) {
44 sizes_in_pixel.push_back(std::ceil(size_in_dip * scales[i]));
45 }
46 return sizes_in_pixel;
47 }
48
49 } // namespace
50
51 FaviconService::FaviconService(FaviconClient* favicon_client,
52 history::HistoryService* history_service)
53 : history_service_(history_service), favicon_client_(favicon_client) {
54 }
55
56 FaviconService::~FaviconService() {
57 }
58
59 // static
60 void FaviconService::FaviconResultsCallbackRunner(
61 const favicon_base::FaviconResultsCallback& callback,
62 const std::vector<favicon_base::FaviconRawBitmapResult>* results) {
63 callback.Run(*results);
64 }
65
66 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage(
67 const GURL& icon_url,
68 const favicon_base::FaviconImageCallback& callback,
69 base::CancelableTaskTracker* tracker) {
70 favicon_base::FaviconResultsCallback callback_runner =
71 Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
72 base::Unretained(this), callback, gfx::kFaviconSize);
73 if (history_service_) {
74 std::vector<GURL> icon_urls;
75 icon_urls.push_back(icon_url);
76 return history_service_->GetFavicons(
77 icon_urls,
78 favicon_base::FAVICON,
79 GetPixelSizesForFaviconScales(gfx::kFaviconSize),
80 callback_runner,
81 tracker);
82 }
83 return RunWithEmptyResultAsync(callback_runner, tracker);
84 }
85
86 base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon(
87 const GURL& icon_url,
88 favicon_base::IconType icon_type,
89 int desired_size_in_pixel,
90 const favicon_base::FaviconRawBitmapCallback& callback,
91 base::CancelableTaskTracker* tracker) {
92 favicon_base::FaviconResultsCallback callback_runner =
93 Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
94 base::Unretained(this),
95 callback,
96 desired_size_in_pixel);
97
98 if (history_service_) {
99 std::vector<GURL> icon_urls;
100 icon_urls.push_back(icon_url);
101 std::vector<int> desired_sizes_in_pixel;
102 desired_sizes_in_pixel.push_back(desired_size_in_pixel);
103
104 return history_service_->GetFavicons(
105 icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker);
106 }
107 return RunWithEmptyResultAsync(callback_runner, tracker);
108 }
109
110 base::CancelableTaskTracker::TaskId FaviconService::GetFavicon(
111 const GURL& icon_url,
112 favicon_base::IconType icon_type,
113 int desired_size_in_dip,
114 const favicon_base::FaviconResultsCallback& callback,
115 base::CancelableTaskTracker* tracker) {
116 if (history_service_) {
117 std::vector<GURL> icon_urls;
118 icon_urls.push_back(icon_url);
119 return history_service_->GetFavicons(
120 icon_urls,
121 icon_type,
122 GetPixelSizesForFaviconScales(desired_size_in_dip),
123 callback,
124 tracker);
125 }
126 return RunWithEmptyResultAsync(callback, tracker);
127 }
128
129 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForPageURL(
130 const GURL& page_url,
131 const favicon_base::FaviconImageCallback& callback,
132 base::CancelableTaskTracker* tracker) {
133 return GetFaviconForPageURLImpl(
134 page_url,
135 favicon_base::FAVICON,
136 GetPixelSizesForFaviconScales(gfx::kFaviconSize),
137 Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
138 base::Unretained(this),
139 callback,
140 gfx::kFaviconSize),
141 tracker);
142 }
143
144 base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForPageURL(
145 const GURL& page_url,
146 int icon_types,
147 int desired_size_in_pixel,
148 const favicon_base::FaviconRawBitmapCallback& callback,
149 base::CancelableTaskTracker* tracker) {
150 std::vector<int> desired_sizes_in_pixel;
151 desired_sizes_in_pixel.push_back(desired_size_in_pixel);
152 return GetFaviconForPageURLImpl(
153 page_url,
154 icon_types,
155 desired_sizes_in_pixel,
156 Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
157 base::Unretained(this),
158 callback,
159 desired_size_in_pixel),
160 tracker);
161 }
162
163 base::CancelableTaskTracker::TaskId
164 FaviconService::GetLargestRawFaviconForPageURL(
165 const GURL& page_url,
166 const std::vector<int>& icon_types,
167 int minimum_size_in_pixels,
168 const favicon_base::FaviconRawBitmapCallback& callback,
169 base::CancelableTaskTracker* tracker) {
170 favicon_base::FaviconResultsCallback favicon_results_callback =
171 Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
172 base::Unretained(this),
173 callback,
174 0);
175 if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) {
176 std::vector<int> desired_sizes_in_pixel;
177 desired_sizes_in_pixel.push_back(0);
178 return favicon_client_->GetFaviconForNativeApplicationURL(
179 page_url, desired_sizes_in_pixel, favicon_results_callback, tracker);
180 }
181 if (history_service_) {
182 return history_service_->GetLargestFaviconForURL(page_url, icon_types,
183 minimum_size_in_pixels, callback, tracker);
184 }
185 return RunWithEmptyResultAsync(favicon_results_callback, tracker);
186 }
187
188 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL(
189 const GURL& page_url,
190 int icon_types,
191 int desired_size_in_dip,
192 const favicon_base::FaviconResultsCallback& callback,
193 base::CancelableTaskTracker* tracker) {
194 return GetFaviconForPageURLImpl(
195 page_url,
196 icon_types,
197 GetPixelSizesForFaviconScales(desired_size_in_dip),
198 callback,
199 tracker);
200 }
201
202 base::CancelableTaskTracker::TaskId
203 FaviconService::UpdateFaviconMappingsAndFetch(
204 const GURL& page_url,
205 const std::vector<GURL>& icon_urls,
206 int icon_types,
207 int desired_size_in_dip,
208 const favicon_base::FaviconResultsCallback& callback,
209 base::CancelableTaskTracker* tracker) {
210 if (history_service_) {
211 return history_service_->UpdateFaviconMappingsAndFetch(
212 page_url,
213 icon_urls,
214 icon_types,
215 GetPixelSizesForFaviconScales(desired_size_in_dip),
216 callback,
217 tracker);
218 }
219 return RunWithEmptyResultAsync(callback, tracker);
220 }
221
222 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID(
223 favicon_base::FaviconID favicon_id,
224 const favicon_base::FaviconRawBitmapCallback& callback,
225 base::CancelableTaskTracker* tracker) {
226 // Use 0 as |desired_size| to get the largest bitmap for |favicon_id| without
227 // any resizing.
228 int desired_size = 0;
229 favicon_base::FaviconResultsCallback callback_runner =
230 Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
231 base::Unretained(this),
232 callback,
233 desired_size);
234
235 if (history_service_) {
236 return history_service_->GetFaviconForID(
237 favicon_id, desired_size, callback_runner, tracker);
238 }
239 return RunWithEmptyResultAsync(callback_runner, tracker);
240 }
241
242 void FaviconService::SetFaviconOutOfDateForPage(const GURL& page_url) {
243 if (history_service_)
244 history_service_->SetFaviconsOutOfDateForPage(page_url);
245 }
246
247 void FaviconService::CloneFavicon(const GURL& old_page_url,
248 const GURL& new_page_url) {
249 if (history_service_)
250 history_service_->CloneFavicons(old_page_url, new_page_url);
251 }
252
253 void FaviconService::SetImportedFavicons(
254 const favicon_base::FaviconUsageDataList& favicon_usage) {
255 if (history_service_)
256 history_service_->SetImportedFavicons(favicon_usage);
257 }
258
259 void FaviconService::MergeFavicon(
260 const GURL& page_url,
261 const GURL& icon_url,
262 favicon_base::IconType icon_type,
263 scoped_refptr<base::RefCountedMemory> bitmap_data,
264 const gfx::Size& pixel_size) {
265 if (history_service_) {
266 history_service_->MergeFavicon(page_url, icon_url, icon_type, bitmap_data,
267 pixel_size);
268 }
269 }
270
271 void FaviconService::SetFavicons(const GURL& page_url,
272 const GURL& icon_url,
273 favicon_base::IconType icon_type,
274 const gfx::Image& image) {
275 if (!history_service_)
276 return;
277
278 gfx::ImageSkia image_skia = image.AsImageSkia();
279 image_skia.EnsureRepsForSupportedScales();
280 const std::vector<gfx::ImageSkiaRep>& image_reps = image_skia.image_reps();
281 std::vector<SkBitmap> bitmaps;
282 const std::vector<float> favicon_scales = favicon_base::GetFaviconScales();
283 for (size_t i = 0; i < image_reps.size(); ++i) {
284 // Don't save if the scale isn't one of supported favicon scales.
285 if (std::find(favicon_scales.begin(),
286 favicon_scales.end(),
287 image_reps[i].scale()) == favicon_scales.end()) {
288 continue;
289 }
290 bitmaps.push_back(image_reps[i].sk_bitmap());
291 }
292 history_service_->SetFavicons(page_url, icon_type, icon_url, bitmaps);
293 }
294
295 void FaviconService::UnableToDownloadFavicon(const GURL& icon_url) {
296 MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
297 missing_favicon_urls_.insert(url_hash);
298 }
299
300 bool FaviconService::WasUnableToDownloadFavicon(const GURL& icon_url) const {
301 MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
302 return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end();
303 }
304
305 void FaviconService::ClearUnableToDownloadFavicons() {
306 missing_favicon_urls_.clear();
307 }
308
309 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURLImpl(
310 const GURL& page_url,
311 int icon_types,
312 const std::vector<int>& desired_sizes_in_pixel,
313 const favicon_base::FaviconResultsCallback& callback,
314 base::CancelableTaskTracker* tracker) {
315 if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) {
316 return favicon_client_->GetFaviconForNativeApplicationURL(
317 page_url, desired_sizes_in_pixel, callback, tracker);
318 }
319 if (history_service_) {
320 return history_service_->GetFaviconsForURL(page_url,
321 icon_types,
322 desired_sizes_in_pixel,
323 callback,
324 tracker);
325 }
326 return RunWithEmptyResultAsync(callback, tracker);
327 }
328
329 void FaviconService::RunFaviconImageCallbackWithBitmapResults(
330 const favicon_base::FaviconImageCallback& callback,
331 int desired_size_in_dip,
332 const std::vector<favicon_base::FaviconRawBitmapResult>&
333 favicon_bitmap_results) {
334 favicon_base::FaviconImageResult image_result;
335 image_result.image = favicon_base::SelectFaviconFramesFromPNGs(
336 favicon_bitmap_results,
337 favicon_base::GetFaviconScales(),
338 desired_size_in_dip);
339 favicon_base::SetFaviconColorSpace(&image_result.image);
340
341 image_result.icon_url = image_result.image.IsEmpty() ?
342 GURL() : favicon_bitmap_results[0].icon_url;
343 callback.Run(image_result);
344 }
345
346 void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults(
347 const favicon_base::FaviconRawBitmapCallback& callback,
348 int desired_size_in_pixel,
349 const std::vector<favicon_base::FaviconRawBitmapResult>&
350 favicon_bitmap_results) {
351 if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) {
352 callback.Run(favicon_base::FaviconRawBitmapResult());
353 return;
354 }
355
356 favicon_base::FaviconRawBitmapResult bitmap_result =
357 favicon_bitmap_results[0];
358
359 // If the desired size is 0, SelectFaviconFrames() will return the largest
360 // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap
361 // data for a single bitmap, return it and avoid an unnecessary decode.
362 if (desired_size_in_pixel == 0) {
363 callback.Run(bitmap_result);
364 return;
365 }
366
367 // If history bitmap is already desired pixel size, return early.
368 if (bitmap_result.pixel_size.width() == desired_size_in_pixel &&
369 bitmap_result.pixel_size.height() == desired_size_in_pixel) {
370 callback.Run(bitmap_result);
371 return;
372 }
373
374 // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then
375 // convert back.
376 std::vector<float> desired_favicon_scales;
377 desired_favicon_scales.push_back(1.0f);
378 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
379 favicon_bitmap_results, desired_favicon_scales, desired_size_in_pixel);
380
381 std::vector<unsigned char> resized_bitmap_data;
382 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false,
383 &resized_bitmap_data)) {
384 callback.Run(favicon_base::FaviconRawBitmapResult());
385 return;
386 }
387
388 bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector(
389 &resized_bitmap_data);
390 callback.Run(bitmap_result);
391 }
OLDNEW
« no previous file with comments | « chrome/browser/favicon/favicon_service.h ('k') | chrome/browser/favicon/favicon_service_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698