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

Side by Side Diff: components/favicon/core/favicon_service.cc

Issue 2347173002: Extend FaviconService to support fetching favicons from a Google server (Closed)
Patch Set: Addressing some comments Created 4 years 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/favicon/core/favicon_service.h" 5 #include "components/favicon/core/favicon_service.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <cmath> 8 #include <cmath>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/hash.h" 11 #include "base/hash.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/stringprintf.h"
13 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
14 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
15 #include "components/favicon/core/favicon_client.h" 16 #include "components/favicon/core/favicon_client.h"
16 #include "components/favicon_base/favicon_util.h" 17 #include "components/favicon_base/favicon_util.h"
17 #include "components/favicon_base/select_favicon_frames.h" 18 #include "components/favicon_base/select_favicon_frames.h"
18 #include "components/history/core/browser/history_service.h" 19 #include "components/history/core/browser/history_service.h"
20 #include "components/image_fetcher/image_fetcher.h"
19 #include "third_party/skia/include/core/SkBitmap.h" 21 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/gfx/codec/png_codec.h" 22 #include "ui/gfx/codec/png_codec.h"
21 #include "ui/gfx/favicon_size.h" 23 #include "ui/gfx/favicon_size.h"
22 #include "ui/gfx/image/image_skia.h" 24 #include "ui/gfx/image/image_skia.h"
23 #include "url/gurl.h" 25 #include "url/gurl.h"
24 26
25 namespace favicon { 27 namespace favicon {
26 namespace { 28 namespace {
27 29
30 const char kGoogleFaviconServiceRequestFormat[] =
31 "https://s2.googleusercontent.com/s2/"
32 "favicons?domain=%s&src=%s&sz=%d&alt=404";
33
34 const int kGoogleFaviconServiceSupportedSizes[] = {16, 24, 32, 48, 64};
35
36 int GetGoogleFaviconServiceSupportedSize(int arbitrary_size) {
37 // Take the smallest size larger than arbitrary_size.
38 for (int size : kGoogleFaviconServiceSupportedSizes) {
39 if (size >= arbitrary_size)
40 return size;
41 }
42 // Or at least the largest available size.
43 return kGoogleFaviconServiceSupportedSizes
44 [arraysize(kGoogleFaviconServiceSupportedSizes) - 1];
45 }
46
47 GURL GetGoogleFaviconServiceURL(GURL page_url,
48 const std::string& client_id,
49 int supported_size) {
50 return GURL(base::StringPrintf(kGoogleFaviconServiceRequestFormat,
51 page_url.spec().c_str(),
52 client_id.c_str(),
53 supported_size));
54 }
55
28 // Helper to run callback with empty results if we cannot get the history 56 // Helper to run callback with empty results if we cannot get the history
29 // service. 57 // service.
30 base::CancelableTaskTracker::TaskId RunWithEmptyResultAsync( 58 base::CancelableTaskTracker::TaskId RunWithEmptyResultAsync(
31 const favicon_base::FaviconResultsCallback& callback, 59 const favicon_base::FaviconResultsCallback& callback,
32 base::CancelableTaskTracker* tracker) { 60 base::CancelableTaskTracker* tracker) {
33 scoped_refptr<base::SingleThreadTaskRunner> thread_runner( 61 scoped_refptr<base::SingleThreadTaskRunner> thread_runner(
34 base::ThreadTaskRunnerHandle::Get()); 62 base::ThreadTaskRunnerHandle::Get());
35 return tracker->PostTask( 63 return tracker->PostTask(
36 thread_runner.get(), FROM_HERE, 64 thread_runner.get(), FROM_HERE,
37 base::Bind(callback, 65 base::Bind(callback,
38 std::vector<favicon_base::FaviconRawBitmapResult>())); 66 std::vector<favicon_base::FaviconRawBitmapResult>()));
39 } 67 }
40 68
41 // Returns a vector of pixel edge sizes from |size_in_dip| and 69 // Returns a vector of pixel edge sizes from |size_in_dip| and
42 // favicon_base::GetFaviconScales(). 70 // favicon_base::GetFaviconScales().
43 std::vector<int> GetPixelSizesForFaviconScales(int size_in_dip) { 71 std::vector<int> GetPixelSizesForFaviconScales(int size_in_dip) {
44 std::vector<float> scales = favicon_base::GetFaviconScales(); 72 std::vector<float> scales = favicon_base::GetFaviconScales();
45 std::vector<int> sizes_in_pixel; 73 std::vector<int> sizes_in_pixel;
46 for (size_t i = 0; i < scales.size(); ++i) { 74 for (size_t i = 0; i < scales.size(); ++i) {
47 sizes_in_pixel.push_back(std::ceil(size_in_dip * scales[i])); 75 sizes_in_pixel.push_back(std::ceil(size_in_dip * scales[i]));
48 } 76 }
49 return sizes_in_pixel; 77 return sizes_in_pixel;
50 } 78 }
51 79
52 } // namespace 80 } // namespace
53 81
54 FaviconService::FaviconService(std::unique_ptr<FaviconClient> favicon_client, 82 FaviconService::FaviconService(
55 history::HistoryService* history_service) 83 std::unique_ptr<FaviconClient> favicon_client,
84 history::HistoryService* history_service,
85 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher)
56 : favicon_client_(std::move(favicon_client)), 86 : favicon_client_(std::move(favicon_client)),
57 history_service_(history_service) {} 87 history_service_(history_service),
88 image_fetcher_(std::move(image_fetcher)) {}
58 89
59 FaviconService::~FaviconService() { 90 FaviconService::~FaviconService() {
60 } 91 }
61 92
62 // static 93 // static
63 void FaviconService::FaviconResultsCallbackRunner( 94 void FaviconService::FaviconResultsCallbackRunner(
64 const favicon_base::FaviconResultsCallback& callback, 95 const favicon_base::FaviconResultsCallback& callback,
65 const std::vector<favicon_base::FaviconRawBitmapResult>* results) { 96 const std::vector<favicon_base::FaviconRawBitmapResult>* results) {
66 callback.Run(*results); 97 callback.Run(*results);
67 } 98 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 TRACE_EVENT0("browser", "FaviconService::GetFaviconForPageURL"); 223 TRACE_EVENT0("browser", "FaviconService::GetFaviconForPageURL");
193 return GetFaviconForPageURLImpl( 224 return GetFaviconForPageURLImpl(
194 page_url, 225 page_url,
195 icon_types, 226 icon_types,
196 GetPixelSizesForFaviconScales(desired_size_in_dip), 227 GetPixelSizesForFaviconScales(desired_size_in_dip),
197 callback, 228 callback,
198 tracker); 229 tracker);
199 } 230 }
200 231
201 base::CancelableTaskTracker::TaskId 232 base::CancelableTaskTracker::TaskId
233 FaviconService::GetRawFaviconForPageURLDownloadFromGoogleServerIfNeeded(
234 const GURL& page_url,
235 int minimum_size_in_pixels,
236 int desired_size_in_pixels,
237 std::string client_id,
238 data_use_measurement::DataUseUserData::ServiceName data_use_service_name,
239 const favicon_base::FaviconImageCallback& callback,
240 base::CancelableTaskTracker* tracker) {
241 TRACE_EVENT0("browser",
242 "FaviconService::"
243 "GetRawFaviconForPageURLDownloadFromGoogleServerIfNeeded");
244 std::vector<int> desired_sizes_in_pixel;
245 desired_sizes_in_pixel.push_back(desired_size_in_pixels);
246 return GetFaviconForPageURLImpl(
247 page_url, favicon_base::IconType::FAVICON, desired_sizes_in_pixel,
248 base::Bind(&FaviconService::
249 RunFaviconImageCallbackOrDownloadFromGoogleFaviconServer,
250 base::Unretained(this), page_url, minimum_size_in_pixels,
251 desired_size_in_pixels, client_id, data_use_service_name,
252 callback),
253 tracker);
254 }
255
256 base::CancelableTaskTracker::TaskId
202 FaviconService::UpdateFaviconMappingsAndFetch( 257 FaviconService::UpdateFaviconMappingsAndFetch(
203 const GURL& page_url, 258 const GURL& page_url,
204 const std::vector<GURL>& icon_urls, 259 const std::vector<GURL>& icon_urls,
205 int icon_types, 260 int icon_types,
206 int desired_size_in_dip, 261 int desired_size_in_dip,
207 const favicon_base::FaviconResultsCallback& callback, 262 const favicon_base::FaviconResultsCallback& callback,
208 base::CancelableTaskTracker* tracker) { 263 base::CancelableTaskTracker* tracker) {
209 if (history_service_) { 264 if (history_service_) {
210 return history_service_->UpdateFaviconMappingsAndFetch( 265 return history_service_->UpdateFaviconMappingsAndFetch(
211 page_url, 266 page_url,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 const favicon_base::FaviconRawBitmapCallback& callback, 396 const favicon_base::FaviconRawBitmapCallback& callback,
342 int desired_size_in_pixel, 397 int desired_size_in_pixel,
343 const std::vector<favicon_base::FaviconRawBitmapResult>& 398 const std::vector<favicon_base::FaviconRawBitmapResult>&
344 favicon_bitmap_results) { 399 favicon_bitmap_results) {
345 TRACE_EVENT0("browser", 400 TRACE_EVENT0("browser",
346 "FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults"); 401 "FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults");
347 callback.Run( 402 callback.Run(
348 ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel)); 403 ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel));
349 } 404 }
350 405
406 void FaviconService::RunFaviconImageCallbackOrDownloadFromGoogleFaviconServer(
407 const GURL& page_url,
408 int minimum_size_in_pixels,
409 int desired_size_in_pixel,
410 std::string client_id,
411 data_use_measurement::DataUseUserData::ServiceName data_use_service_name,
412 const favicon_base::FaviconImageCallback& callback,
413 const std::vector<favicon_base::FaviconRawBitmapResult>&
414 favicon_bitmap_results) {
415 TRACE_EVENT0(
416 "browser",
417 "FaviconService::DownloadFromGoogleServerFaviconImageForPageURL");
418 // TODO(jkrcal): Ensure we do not get an icon upscaled from a smaller png than
419 // |minimum_size_in_pixels|. Is extending SelectFaviconFramesFromPNGs() the
420 // simplest path? Or should I do it similarly to GetLargestRawFaviconForID()?
jkrcal 2016/12/09 13:57:44 Peter, can you help me with this, please?
pkotwicz 2016/12/09 19:46:30 Things get complicated if you want to download a f
jkrcal 2016/12/14 15:18:50 I do not want to download anything in such a case.
pkotwicz 2016/12/15 01:22:27 I recomment adding FaviconRawBitmapResult::width_i
jkrcal 2016/12/15 18:17:27 Thanks for the hint! When looking in the code, I
pkotwicz 2016/12/15 18:43:57 For the sake of clarity, I recommend adding width_
pkotwicz 2016/12/15 18:43:57 Sorry for the confusion. FaviconRawBitmapResult::
jkrcal 2016/12/16 12:53:52 Thanks for the clarification! I did not want to m
421
422 gfx::Image image = favicon_base::SelectFaviconFramesFromPNGs(
423 favicon_bitmap_results,
424 {static_cast<float>(desired_size_in_pixel) / gfx::kFaviconSize},
425 gfx::kFaviconSize);
426
427 if (!image.IsEmpty()) {
428 // Serve the favicon from the cache.
429 favicon_base::FaviconImageResult image_result;
430 image_result.image = image;
431 favicon_base::SetFaviconColorSpace(&image_result.image);
432 image_result.icon_url = favicon_bitmap_results[0].icon_url;
433 callback.Run(image_result);
434 return;
435 }
436
437 // No favicon in the cache. Download it from the server.
438
439 if (!image_fetcher_.get()) {
440 base::ThreadTaskRunnerHandle::Get()->PostTask(
441 FROM_HERE, base::Bind(callback, favicon_base::FaviconImageResult()));
442 return;
443 }
444
445 int supported_size =
446 GetGoogleFaviconServiceSupportedSize(desired_size_in_pixel);
447 GURL image_url = GetGoogleFaviconServiceURL(page_url, client_id,
448 supported_size);
449
450 image_fetcher_->SetDataUseServiceName(data_use_service_name);
451 image_fetcher_->StartOrQueueNetworkRequest(
452 image_url.spec(), image_url,
453 base::Bind(&FaviconService::
454 StoreFaviconFromGoogleServiceAndRunFaviconImageCallback,
455 base::Unretained(this), callback, page_url));
456 }
457
458 void FaviconService::StoreFaviconFromGoogleServiceAndRunFaviconImageCallback(
459 const favicon_base::FaviconImageCallback& callback,
460 const GURL& page_url,
461 const std::string& icon_url,
462 const gfx::Image& image) {
463 if (image.IsEmpty())
464 callback.Run(favicon_base::FaviconImageResult());
465
466 // TODO(jkrcal): No rescaling to desired_size_in_px. Should I fetch raw data
467 // from ImageFetcher, construct
468 // std::vector<favicon_base::FaviconRawBitmapResult> and use
469 // SelectFaviconFramesFromPNGs().
jkrcal 2016/12/09 13:57:44 Peter, can you help me with this, please?
pkotwicz 2016/12/09 19:46:30 My understanding is that you are currently not res
jkrcal 2016/12/14 15:18:50 Sorry, the comment is a bit unclear :) Yes, I woul
pkotwicz 2016/12/15 01:22:27 You are right. Similar functions in FaviconService
jkrcal 2016/12/15 18:17:27 Done, thanks!
470
471 favicon_base::FaviconImageResult image_result;
472 image_result.icon_url = GURL(icon_url);
473 image_result.image = image;
474 favicon_base::SetFaviconColorSpace(&image_result.image);
475 // Store the favicon in the cache.
476 SetFavicons(page_url, image_result.icon_url,
477 favicon_base::IconType::FAVICON, image_result.image);
478 // Mark them as out-of-date so that they are refetched when we visit the
479 // original page any time in the future.
480 SetFaviconOutOfDateForPage(page_url);
481
482 callback.Run(image_result);
483 }
484
351 } // namespace favicon 485 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698