Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / favicon / favicon_service.cc
blobbca611ae32ddbced93267c26bdc02e4431d4f1c3
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.
5 #include "chrome/browser/favicon/favicon_service.h"
7 #include "base/hash.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "chrome/browser/favicon/favicon_util.h"
10 #include "chrome/browser/history/history_backend.h"
11 #include "chrome/browser/history/history_service.h"
12 #include "chrome/browser/history/history_service_factory.h"
13 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
14 #include "chrome/common/importer/imported_favicon_usage.h"
15 #include "chrome/common/url_constants.h"
16 #include "components/favicon_base/favicon_types.h"
17 #include "components/favicon_base/select_favicon_frames.h"
18 #include "extensions/common/constants.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/gfx/codec/png_codec.h"
21 #include "ui/gfx/favicon_size.h"
22 #include "ui/gfx/image/image_skia.h"
24 using base::Bind;
26 namespace {
28 void CancelOrRunFaviconResultsCallback(
29 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled,
30 const FaviconService::FaviconResultsCallback& callback,
31 const std::vector<favicon_base::FaviconBitmapResult>& results) {
32 if (is_canceled.Run())
33 return;
34 callback.Run(results);
37 // Helper to run callback with empty results if we cannot get the history
38 // service.
39 base::CancelableTaskTracker::TaskId RunWithEmptyResultAsync(
40 const FaviconService::FaviconResultsCallback& callback,
41 base::CancelableTaskTracker* tracker) {
42 return tracker->PostTask(
43 base::MessageLoopProxy::current().get(),
44 FROM_HERE,
45 Bind(callback, std::vector<favicon_base::FaviconBitmapResult>()));
48 // Return the TaskId to retreive the favicon from chrome specific URL.
49 base::CancelableTaskTracker::TaskId GetFaviconForChromeURL(
50 Profile* profile,
51 const GURL& page_url,
52 const std::vector<ui::ScaleFactor>& desired_scale_factors,
53 const FaviconService::FaviconResultsCallback& callback,
54 base::CancelableTaskTracker* tracker) {
55 base::CancelableTaskTracker::IsCanceledCallback is_canceled_cb;
56 base::CancelableTaskTracker::TaskId id =
57 tracker->NewTrackedTaskId(&is_canceled_cb);
58 FaviconService::FaviconResultsCallback cancelable_cb =
59 Bind(&CancelOrRunFaviconResultsCallback, is_canceled_cb, callback);
60 ChromeWebUIControllerFactory::GetInstance()->GetFaviconForURL(profile,
61 page_url, desired_scale_factors, cancelable_cb);
62 return id;
65 } // namespace
67 FaviconService::FaviconService(Profile* profile)
68 : history_service_(HistoryServiceFactory::GetForProfile(
69 profile, Profile::EXPLICIT_ACCESS)),
70 profile_(profile) {
73 // static
74 void FaviconService::FaviconResultsCallbackRunner(
75 const FaviconResultsCallback& callback,
76 const std::vector<favicon_base::FaviconBitmapResult>* results) {
77 callback.Run(*results);
80 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage(
81 const GURL& icon_url,
82 favicon_base::IconType icon_type,
83 int desired_size_in_dip,
84 const FaviconImageCallback& callback,
85 base::CancelableTaskTracker* tracker) {
86 FaviconResultsCallback callback_runner =
87 Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
88 base::Unretained(this), callback, desired_size_in_dip);
89 if (history_service_) {
90 std::vector<GURL> icon_urls;
91 icon_urls.push_back(icon_url);
92 return history_service_->GetFavicons(
93 icon_urls, icon_type, desired_size_in_dip,
94 FaviconUtil::GetFaviconScaleFactors(), callback_runner, tracker);
95 } else {
96 return RunWithEmptyResultAsync(callback_runner, tracker);
100 base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon(
101 const GURL& icon_url,
102 favicon_base::IconType icon_type,
103 int desired_size_in_dip,
104 ui::ScaleFactor desired_scale_factor,
105 const FaviconRawCallback& callback,
106 base::CancelableTaskTracker* tracker) {
107 FaviconResultsCallback callback_runner =
108 Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
109 base::Unretained(this),
110 callback, desired_size_in_dip, desired_scale_factor);
112 if (history_service_) {
113 std::vector<GURL> icon_urls;
114 icon_urls.push_back(icon_url);
115 std::vector<ui::ScaleFactor> desired_scale_factors;
116 desired_scale_factors.push_back(desired_scale_factor);
118 return history_service_->GetFavicons(
119 icon_urls, icon_type, desired_size_in_dip, desired_scale_factors,
120 callback_runner, tracker);
121 } else {
122 return RunWithEmptyResultAsync(callback_runner, tracker);
126 base::CancelableTaskTracker::TaskId FaviconService::GetFavicon(
127 const GURL& icon_url,
128 favicon_base::IconType icon_type,
129 int desired_size_in_dip,
130 const FaviconResultsCallback& callback,
131 base::CancelableTaskTracker* tracker) {
132 if (history_service_) {
133 std::vector<GURL> icon_urls;
134 icon_urls.push_back(icon_url);
135 return history_service_->GetFavicons(
136 icon_urls, icon_type, desired_size_in_dip,
137 FaviconUtil::GetFaviconScaleFactors(), callback, tracker);
138 } else {
139 return RunWithEmptyResultAsync(callback, tracker);
143 base::CancelableTaskTracker::TaskId
144 FaviconService::UpdateFaviconMappingsAndFetch(
145 const GURL& page_url,
146 const std::vector<GURL>& icon_urls,
147 int icon_types,
148 int desired_size_in_dip,
149 const FaviconResultsCallback& callback,
150 base::CancelableTaskTracker* tracker) {
151 if (history_service_) {
152 return history_service_->UpdateFaviconMappingsAndFetch(
153 page_url, icon_urls, icon_types, desired_size_in_dip,
154 FaviconUtil::GetFaviconScaleFactors(), callback, tracker);
155 } else {
156 return RunWithEmptyResultAsync(callback, tracker);
160 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForURL(
161 const FaviconForURLParams& params,
162 const FaviconImageCallback& callback,
163 base::CancelableTaskTracker* tracker) {
164 return GetFaviconForURLImpl(
165 params,
166 FaviconUtil::GetFaviconScaleFactors(),
167 Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
168 base::Unretained(this),
169 callback,
170 params.desired_size_in_dip),
171 tracker);
174 base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForURL(
175 const FaviconForURLParams& params,
176 ui::ScaleFactor desired_scale_factor,
177 const FaviconRawCallback& callback,
178 base::CancelableTaskTracker* tracker) {
179 std::vector<ui::ScaleFactor> desired_scale_factors;
180 desired_scale_factors.push_back(desired_scale_factor);
181 return GetFaviconForURLImpl(
182 params,
183 desired_scale_factors,
184 Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
185 base::Unretained(this),
186 callback,
187 params.desired_size_in_dip,
188 desired_scale_factor),
189 tracker);
192 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForURL(
193 Profile* profile,
194 const GURL& page_url,
195 const std::vector<int>& icon_types,
196 int minimum_size_in_pixels,
197 const FaviconRawCallback& callback,
198 base::CancelableTaskTracker* tracker) {
199 FaviconResultsCallback favicon_results_callback =
200 Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
201 base::Unretained(this), callback, 0, ui::ScaleFactor());
202 if (page_url.SchemeIs(content::kChromeUIScheme) ||
203 page_url.SchemeIs(extensions::kExtensionScheme)) {
204 std::vector<ui::ScaleFactor> scale_factor;
205 scale_factor.push_back(ui::SCALE_FACTOR_100P);
206 return GetFaviconForChromeURL(profile, page_url, scale_factor,
207 favicon_results_callback, tracker);
208 } else if (history_service_) {
209 return history_service_->GetLargestFaviconForURL(page_url, icon_types,
210 minimum_size_in_pixels, callback, tracker);
212 return RunWithEmptyResultAsync(favicon_results_callback, tracker);
215 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForURL(
216 const FaviconForURLParams& params,
217 const FaviconResultsCallback& callback,
218 base::CancelableTaskTracker* tracker) {
219 return GetFaviconForURLImpl(params,
220 FaviconUtil::GetFaviconScaleFactors(),
221 callback,
222 tracker);
225 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID(
226 favicon_base::FaviconID favicon_id,
227 const FaviconRawCallback& callback,
228 base::CancelableTaskTracker* tracker) {
229 // Use 0 as |desired_size_in_dip| to get the largest bitmap for |favicon_id|
230 // without any resizing.
231 int desired_size_in_dip = 0;
232 ui::ScaleFactor desired_scale_factor = ui::SCALE_FACTOR_100P;
233 FaviconResultsCallback callback_runner =
234 Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
235 base::Unretained(this),
236 callback, desired_size_in_dip, desired_scale_factor);
238 if (history_service_) {
239 return history_service_->GetFaviconForID(
240 favicon_id, desired_size_in_dip, desired_scale_factor,
241 callback_runner, tracker);
242 } else {
243 return RunWithEmptyResultAsync(callback_runner, tracker);
247 void FaviconService::SetFaviconOutOfDateForPage(const GURL& page_url) {
248 if (history_service_)
249 history_service_->SetFaviconsOutOfDateForPage(page_url);
252 void FaviconService::CloneFavicon(const GURL& old_page_url,
253 const GURL& new_page_url) {
254 if (history_service_)
255 history_service_->CloneFavicons(old_page_url, new_page_url);
258 void FaviconService::SetImportedFavicons(
259 const std::vector<ImportedFaviconUsage>& favicon_usage) {
260 if (history_service_)
261 history_service_->SetImportedFavicons(favicon_usage);
264 void FaviconService::MergeFavicon(
265 const GURL& page_url,
266 const GURL& icon_url,
267 favicon_base::IconType icon_type,
268 scoped_refptr<base::RefCountedMemory> bitmap_data,
269 const gfx::Size& pixel_size) {
270 if (history_service_) {
271 history_service_->MergeFavicon(page_url, icon_url, icon_type, bitmap_data,
272 pixel_size);
276 void FaviconService::SetFavicons(const GURL& page_url,
277 const GURL& icon_url,
278 favicon_base::IconType icon_type,
279 const gfx::Image& image) {
280 if (!history_service_)
281 return;
283 gfx::ImageSkia image_skia = image.AsImageSkia();
284 image_skia.EnsureRepsForSupportedScales();
285 const std::vector<gfx::ImageSkiaRep>& image_reps = image_skia.image_reps();
286 std::vector<favicon_base::FaviconBitmapData> favicon_bitmap_data;
287 for (size_t i = 0; i < image_reps.size(); ++i) {
288 scoped_refptr<base::RefCountedBytes> bitmap_data(
289 new base::RefCountedBytes());
290 if (gfx::PNGCodec::EncodeBGRASkBitmap(image_reps[i].sk_bitmap(),
291 false,
292 &bitmap_data->data())) {
293 gfx::Size pixel_size(image_reps[i].pixel_width(),
294 image_reps[i].pixel_height());
295 favicon_base::FaviconBitmapData bitmap_data_element;
296 bitmap_data_element.bitmap_data = bitmap_data;
297 bitmap_data_element.pixel_size = pixel_size;
298 bitmap_data_element.icon_url = icon_url;
300 favicon_bitmap_data.push_back(bitmap_data_element);
304 history_service_->SetFavicons(page_url, icon_type, favicon_bitmap_data);
307 void FaviconService::UnableToDownloadFavicon(const GURL& icon_url) {
308 MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
309 missing_favicon_urls_.insert(url_hash);
312 bool FaviconService::WasUnableToDownloadFavicon(const GURL& icon_url) const {
313 MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
314 return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end();
317 void FaviconService::ClearUnableToDownloadFavicons() {
318 missing_favicon_urls_.clear();
321 FaviconService::~FaviconService() {}
323 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForURLImpl(
324 const FaviconForURLParams& params,
325 const std::vector<ui::ScaleFactor>& desired_scale_factors,
326 const FaviconResultsCallback& callback,
327 base::CancelableTaskTracker* tracker) {
328 if (params.page_url.SchemeIs(content::kChromeUIScheme) ||
329 params.page_url.SchemeIs(extensions::kExtensionScheme)) {
330 return GetFaviconForChromeURL(profile_, params.page_url,
331 desired_scale_factors, callback, tracker);
332 } else if (history_service_) {
333 return history_service_->GetFaviconsForURL(params.page_url,
334 params.icon_types,
335 params.desired_size_in_dip,
336 desired_scale_factors,
337 callback,
338 tracker);
340 return RunWithEmptyResultAsync(callback, tracker);
343 void FaviconService::RunFaviconImageCallbackWithBitmapResults(
344 const FaviconImageCallback& callback,
345 int desired_size_in_dip,
346 const std::vector<favicon_base::FaviconBitmapResult>&
347 favicon_bitmap_results) {
348 favicon_base::FaviconImageResult image_result;
349 image_result.image = FaviconUtil::SelectFaviconFramesFromPNGs(
350 favicon_bitmap_results,
351 FaviconUtil::GetFaviconScaleFactors(),
352 desired_size_in_dip);
353 FaviconUtil::SetFaviconColorSpace(&image_result.image);
355 image_result.icon_url = image_result.image.IsEmpty() ?
356 GURL() : favicon_bitmap_results[0].icon_url;
357 callback.Run(image_result);
360 void FaviconService::RunFaviconRawCallbackWithBitmapResults(
361 const FaviconRawCallback& callback,
362 int desired_size_in_dip,
363 ui::ScaleFactor desired_scale_factor,
364 const std::vector<favicon_base::FaviconBitmapResult>&
365 favicon_bitmap_results) {
366 if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) {
367 callback.Run(favicon_base::FaviconBitmapResult());
368 return;
371 DCHECK_EQ(1u, favicon_bitmap_results.size());
372 favicon_base::FaviconBitmapResult bitmap_result = favicon_bitmap_results[0];
374 // If the desired size is 0, SelectFaviconFrames() will return the largest
375 // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap
376 // data for a single bitmap, return it and avoid an unnecessary decode.
377 if (desired_size_in_dip == 0) {
378 callback.Run(bitmap_result);
379 return;
382 // If history bitmap is already desired pixel size, return early.
383 float desired_scale = ui::GetImageScale(desired_scale_factor);
384 int desired_edge_width_in_pixel = static_cast<int>(
385 desired_size_in_dip * desired_scale + 0.5f);
386 gfx::Size desired_size_in_pixel(desired_edge_width_in_pixel,
387 desired_edge_width_in_pixel);
388 if (bitmap_result.pixel_size == desired_size_in_pixel) {
389 callback.Run(bitmap_result);
390 return;
393 // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then
394 // convert back.
395 std::vector<ui::ScaleFactor> desired_scale_factors;
396 desired_scale_factors.push_back(desired_scale_factor);
397 gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs(
398 favicon_bitmap_results, desired_scale_factors, desired_size_in_dip);
400 std::vector<unsigned char> resized_bitmap_data;
401 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false,
402 &resized_bitmap_data)) {
403 callback.Run(favicon_base::FaviconBitmapResult());
404 return;
407 bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector(
408 &resized_bitmap_data);
409 callback.Run(bitmap_result);