favicon_service.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/hash.h"
8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/select_favicon_frames.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_favicon_usage.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/favicon_base/favicon_types.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/favicon_size.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::Bind;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CancelOrRunFaviconResultsCallback(
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::CancelableTaskTracker::IsCanceledCallback& is_canceled,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::vector<favicon_base::FaviconBitmapResult>& results) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_canceled.Run())
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(results);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Helper to run callback with empty results if we cannot get the history
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// service.
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId RunWithEmptyResultAsync(
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTask(
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::MessageLoopProxy::current().get(),
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      Bind(callback, std::vector<favicon_base::FaviconBitmapResult>()));
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Return the TaskId to retreive the favicon from chrome specific URL.
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId GetFaviconForChromeURL(
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    Profile* profile,
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const GURL& page_url,
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::CancelableTaskTracker::IsCanceledCallback is_canceled_cb;
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::CancelableTaskTracker::TaskId id =
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      tracker->NewTrackedTaskId(&is_canceled_cb);
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  FaviconService::FaviconResultsCallback cancelable_cb =
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      Bind(&CancelOrRunFaviconResultsCallback, is_canceled_cb, callback);
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ChromeWebUIControllerFactory::GetInstance()->GetFaviconForURL(profile,
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      page_url, desired_scale_factors, cancelable_cb);
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return id;
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)FaviconService::FaviconService(Profile* profile)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : history_service_(HistoryServiceFactory::GetForProfile(
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          profile, Profile::EXPLICIT_ACCESS)),
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      profile_(profile) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconService::FaviconResultsCallbackRunner(
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconResultsCallback& callback,
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::vector<favicon_base::FaviconBitmapResult>* results) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(*results);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& icon_url,
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconImageCallback& callback,
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconResultsCallback callback_runner =
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           base::Unretained(this), callback, desired_size_in_dip);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> icon_urls;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_urls.push_back(icon_url);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return history_service_->GetFavicons(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        icon_urls, icon_type, desired_size_in_dip,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FaviconUtil::GetFaviconScaleFactors(), callback_runner, tracker);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return RunWithEmptyResultAsync(callback_runner, tracker);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon(
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& icon_url,
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScaleFactor desired_scale_factor,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconRawCallback& callback,
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconResultsCallback callback_runner =
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           base::Unretained(this),
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           callback, desired_size_in_dip, desired_scale_factor);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> icon_urls;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_urls.push_back(icon_url);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<ui::ScaleFactor> desired_scale_factors;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desired_scale_factors.push_back(desired_scale_factor);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return history_service_->GetFavicons(
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        icon_urls, icon_type, desired_size_in_dip, desired_scale_factors,
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        callback_runner, tracker);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return RunWithEmptyResultAsync(callback_runner, tracker);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetFavicon(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& icon_url,
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconResultsCallback& callback,
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> icon_urls;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_urls.push_back(icon_url);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return history_service_->GetFavicons(
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        icon_urls, icon_type, desired_size_in_dip,
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FaviconUtil::GetFaviconScaleFactors(), callback, tracker);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return RunWithEmptyResultAsync(callback, tracker);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FaviconService::UpdateFaviconMappingsAndFetch(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconResultsCallback& callback,
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return history_service_->UpdateFaviconMappingsAndFetch(
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        page_url, icon_urls, icon_types, desired_size_in_dip,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FaviconUtil::GetFaviconScaleFactors(), callback, tracker);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return RunWithEmptyResultAsync(callback, tracker);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForURL(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FaviconForURLParams& params,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconImageCallback& callback,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetFaviconForURLImpl(
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params,
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FaviconUtil::GetFaviconScaleFactors(),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           base::Unretained(this),
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           callback,
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           params.desired_size_in_dip),
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tracker);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForURL(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FaviconForURLParams& params,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScaleFactor desired_scale_factor,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconRawCallback& callback,
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ui::ScaleFactor> desired_scale_factors;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desired_scale_factors.push_back(desired_scale_factor);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetFaviconForURLImpl(
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      desired_scale_factors,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           base::Unretained(this),
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           callback,
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           params.desired_size_in_dip,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           desired_scale_factor),
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tracker);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForURL(
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    Profile* profile,
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const GURL& page_url,
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::vector<int>& icon_types,
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int minimum_size_in_pixels,
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const FaviconRawCallback& callback,
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  FaviconResultsCallback favicon_results_callback =
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)           base::Unretained(this), callback, 0, ui::ScaleFactor());
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (page_url.SchemeIs(content::kChromeUIScheme) ||
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      page_url.SchemeIs(extensions::kExtensionScheme)) {
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::vector<ui::ScaleFactor> scale_factor;
2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scale_factor.push_back(ui::SCALE_FACTOR_100P);
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return GetFaviconForChromeURL(profile, page_url, scale_factor,
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                  favicon_results_callback, tracker);
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (history_service_) {
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return history_service_->GetLargestFaviconForURL(page_url, icon_types,
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        minimum_size_in_pixels, callback, tracker);
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return RunWithEmptyResultAsync(favicon_results_callback, tracker);
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForURL(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FaviconForURLParams& params,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconResultsCallback& callback,
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetFaviconForURLImpl(params,
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              FaviconUtil::GetFaviconScaleFactors(),
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              callback,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              tracker);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID(
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::FaviconID favicon_id,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconRawCallback& callback,
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use 0 as |desired_size_in_dip| to get the largest bitmap for |favicon_id|
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // without any resizing.
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int desired_size_in_dip = 0;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScaleFactor desired_scale_factor = ui::SCALE_FACTOR_100P;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconResultsCallback callback_runner =
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           base::Unretained(this),
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           callback, desired_size_in_dip, desired_scale_factor);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_) {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return history_service_->GetFaviconForID(
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        favicon_id, desired_size_in_dip, desired_scale_factor,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        callback_runner, tracker);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return RunWithEmptyResultAsync(callback_runner, tracker);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::SetFaviconOutOfDateForPage(const GURL& page_url) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_->SetFaviconsOutOfDateForPage(page_url);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::CloneFavicon(const GURL& old_page_url,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const GURL& new_page_url) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_->CloneFavicons(old_page_url, new_page_url);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::SetImportedFavicons(
259a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::vector<ImportedFaviconUsage>& favicon_usage) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_service_->SetImportedFavicons(favicon_usage);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::MergeFavicon(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& icon_url,
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedMemory> bitmap_data,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& pixel_size) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service_) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history_service_->MergeFavicon(page_url, icon_url, icon_type, bitmap_data,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   pixel_size);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FaviconService::SetFavicons(const GURL& page_url,
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 const GURL& icon_url,
2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                 favicon_base::IconType icon_type,
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 const gfx::Image& image) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_service_)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia image_skia = image.AsImageSkia();
28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  image_skia.EnsureRepsForSupportedScales();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<gfx::ImageSkiaRep>& image_reps = image_skia.image_reps();
2860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<favicon_base::FaviconBitmapData> favicon_bitmap_data;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < image_reps.size(); ++i) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedBytes> bitmap_data(
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new base::RefCountedBytes());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (gfx::PNGCodec::EncodeBGRASkBitmap(image_reps[i].sk_bitmap(),
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          false,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          &bitmap_data->data())) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Size pixel_size(image_reps[i].pixel_width(),
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           image_reps[i].pixel_height());
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      favicon_base::FaviconBitmapData bitmap_data_element;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.bitmap_data = bitmap_data;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.pixel_size = pixel_size;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bitmap_data_element.icon_url = icon_url;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_bitmap_data.push_back(bitmap_data_element);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history_service_->SetFavicons(page_url, icon_type, favicon_bitmap_data);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FaviconService::UnableToDownloadFavicon(const GURL& icon_url) {
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  missing_favicon_urls_.insert(url_hash);
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool FaviconService::WasUnableToDownloadFavicon(const GURL& icon_url) const {
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end();
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FaviconService::ClearUnableToDownloadFavicons() {
31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  missing_favicon_urls_.clear();
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FaviconService::~FaviconService() {}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForURLImpl(
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FaviconForURLParams& params,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconResultsCallback& callback,
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (params.page_url.SchemeIs(content::kChromeUIScheme) ||
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.page_url.SchemeIs(extensions::kExtensionScheme)) {
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return GetFaviconForChromeURL(profile_, params.page_url,
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                  desired_scale_factors, callback, tracker);
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (history_service_) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return history_service_->GetFaviconsForURL(params.page_url,
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               params.icon_types,
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               params.desired_size_in_dip,
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               desired_scale_factors,
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               callback,
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               tracker);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return RunWithEmptyResultAsync(callback, tracker);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconService::RunFaviconImageCallbackWithBitmapResults(
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconImageCallback& callback,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
3460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::vector<favicon_base::FaviconBitmapResult>&
3470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        favicon_bitmap_results) {
3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  favicon_base::FaviconImageResult image_result;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  image_result.image = FaviconUtil::SelectFaviconFramesFromPNGs(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_bitmap_results,
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FaviconUtil::GetFaviconScaleFactors(),
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desired_size_in_dip);
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FaviconUtil::SetFaviconColorSpace(&image_result.image);
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  image_result.icon_url = image_result.image.IsEmpty() ?
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL() : favicon_bitmap_results[0].icon_url;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(image_result);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconService::RunFaviconRawCallbackWithBitmapResults(
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconRawCallback& callback,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScaleFactor desired_scale_factor,
3640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::vector<favicon_base::FaviconBitmapResult>&
3650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        favicon_bitmap_results) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) {
3670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    callback.Run(favicon_base::FaviconBitmapResult());
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(1u, favicon_bitmap_results.size());
3720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  favicon_base::FaviconBitmapResult bitmap_result = favicon_bitmap_results[0];
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the desired size is 0, SelectFaviconFrames() will return the largest
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data for a single bitmap, return it and avoid an unnecessary decode.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (desired_size_in_dip == 0) {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(bitmap_result);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If history bitmap is already desired pixel size, return early.
38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  float desired_scale = ui::GetImageScale(desired_scale_factor);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int desired_edge_width_in_pixel = static_cast<int>(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desired_size_in_dip * desired_scale + 0.5f);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size desired_size_in_pixel(desired_edge_width_in_pixel,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  desired_edge_width_in_pixel);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bitmap_result.pixel_size == desired_size_in_pixel) {
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(bitmap_result);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // convert back.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ui::ScaleFactor> desired_scale_factors;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desired_scale_factors.push_back(desired_scale_factor);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs(
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      favicon_bitmap_results, desired_scale_factors, desired_size_in_dip);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> resized_bitmap_data;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &resized_bitmap_data)) {
4030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    callback.Run(favicon_base::FaviconBitmapResult());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector(
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &resized_bitmap_data);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(bitmap_result);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
411