favicon_service.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/favicon/favicon_types.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_util.h" 11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/favicon/imported_favicon_usage.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/select_favicon_frames.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.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( 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CancelableTaskTracker::IsCanceledCallback& is_canceled, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconService::FaviconResultsCallback& callback, 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::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. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId RunWithEmptyResultAsync( 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconService::FaviconResultsCallback& callback, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tracker->PostTask( 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current(), 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Bind(callback, std::vector<chrome::FaviconBitmapResult>())); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FaviconService::FaviconService(HistoryService* history_service) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : history_service_(history_service) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconService::FaviconResultsCallbackRunner( 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconResultsCallback& callback, 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconBitmapResult>* results) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*results); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetFaviconImage( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url, 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconImageCallback& callback, 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconResultsCallback callback_runner = 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), callback, desired_size_in_dip); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> icon_urls; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_urls.push_back(icon_url); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return history_service_->GetFavicons( 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_urls, icon_type, desired_size_in_dip, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconUtil::GetFaviconScaleFactors(), callback_runner, tracker); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RunWithEmptyResultAsync(callback_runner, tracker); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetRawFavicon( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url, 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor desired_scale_factor, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconRawCallback& callback, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconResultsCallback callback_runner = 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, desired_size_in_dip, desired_scale_factor); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> icon_urls; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_urls.push_back(icon_url); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::ScaleFactor> desired_scale_factors; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_scale_factors.push_back(desired_scale_factor); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return history_service_->GetFavicons( 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_urls, icon_type, desired_size_in_dip, desired_scale_factors, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_runner, tracker); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RunWithEmptyResultAsync(callback_runner, tracker); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetFavicon( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url, 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconResultsCallback& callback, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> icon_urls; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_urls.push_back(icon_url); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return history_service_->GetFavicons( 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_urls, icon_type, desired_size_in_dip, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconUtil::GetFaviconScaleFactors(), callback, tracker); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RunWithEmptyResultAsync(callback, tracker); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::UpdateFaviconMappingsAndFetch( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<GURL>& icon_urls, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_types, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconResultsCallback& callback, 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return history_service_->UpdateFaviconMappingsAndFetch( 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) page_url, icon_urls, icon_types, desired_size_in_dip, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconUtil::GetFaviconScaleFactors(), callback, tracker); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RunWithEmptyResultAsync(callback, tracker); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForURL( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FaviconForURLParams& params, 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconImageCallback& callback, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetFaviconForURLImpl( 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconUtil::GetFaviconScaleFactors(), 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.desired_size_in_dip), 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracker); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForURL( 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FaviconForURLParams& params, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor desired_scale_factor, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconRawCallback& callback, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::ScaleFactor> desired_scale_factors; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_scale_factors.push_back(desired_scale_factor); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetFaviconForURLImpl( 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_scale_factors, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.desired_size_in_dip, 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_scale_factor), 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracker); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetFaviconForURL( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FaviconForURLParams& params, 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconResultsCallback& callback, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetFaviconForURLImpl(params, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconUtil::GetFaviconScaleFactors(), 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracker); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID( 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID favicon_id, 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconRawCallback& callback, 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use 0 as |desired_size_in_dip| to get the largest bitmap for |favicon_id| 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // without any resizing. 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int desired_size_in_dip = 0; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScaleFactor desired_scale_factor = ui::SCALE_FACTOR_100P; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconResultsCallback callback_runner = 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&FaviconService::RunFaviconRawCallbackWithBitmapResults, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, desired_size_in_dip, desired_scale_factor); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return history_service_->GetFaviconForID( 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_id, desired_size_in_dip, desired_scale_factor, 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_runner, tracker); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RunWithEmptyResultAsync(callback_runner, tracker); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::SetFaviconOutOfDateForPage(const GURL& page_url) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service_->SetFaviconsOutOfDateForPage(page_url); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::CloneFavicon(const GURL& old_page_url, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_page_url) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service_->CloneFavicons(old_page_url, new_page_url); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::SetImportedFavicons( 216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::vector<ImportedFaviconUsage>& favicon_usage) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service_->SetImportedFavicons(favicon_usage); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconService::MergeFavicon( 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& icon_url, 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedMemory> bitmap_data, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& pixel_size) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service_) { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) history_service_->MergeFavicon(page_url, icon_url, icon_type, bitmap_data, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixel_size); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FaviconService::SetFavicons(const GURL& page_url, 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GURL& icon_url, 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Image& image) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!history_service_) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia image_skia = image.AsImageSkia(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_skia.EnsureRepsForSupportedScaleFactors(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<gfx::ImageSkiaRep>& image_reps = image_skia.image_reps(); 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapData> favicon_bitmap_data; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < image_reps.size(); ++i) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedBytes> bitmap_data( 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::RefCountedBytes()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gfx::PNGCodec::EncodeBGRASkBitmap(image_reps[i].sk_bitmap(), 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bitmap_data->data())) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pixel_size(image_reps[i].pixel_width(), 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_reps[i].pixel_height()); 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconBitmapData bitmap_data_element; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_data_element.bitmap_data = bitmap_data; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_data_element.pixel_size = pixel_size; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_data_element.icon_url = icon_url; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_bitmap_data.push_back(bitmap_data_element); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) history_service_->SetFavicons(page_url, icon_type, favicon_bitmap_data); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FaviconService::UnableToDownloadFavicon(const GURL& icon_url) { 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MissingFaviconURLHash url_hash = base::Hash(icon_url.spec()); 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) missing_favicon_urls_.insert(url_hash); 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool FaviconService::WasUnableToDownloadFavicon(const GURL& icon_url) const { 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MissingFaviconURLHash url_hash = base::Hash(icon_url.spec()); 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end(); 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FaviconService::ClearUnableToDownloadFavicons() { 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) missing_favicon_urls_.clear(); 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FaviconService::~FaviconService() {} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId FaviconService::GetFaviconForURLImpl( 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FaviconForURLParams& params, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconResultsCallback& callback, 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params.page_url.SchemeIs(chrome::kChromeUIScheme) || 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.page_url.SchemeIs(extensions::kExtensionScheme)) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker::IsCanceledCallback is_canceled_cb; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker::TaskId id = 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracker->NewTrackedTaskId(&is_canceled_cb); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconResultsCallback cancelable_cb = 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bind(&CancelOrRunFaviconResultsCallback, is_canceled_cb, callback); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChromeWebUIControllerFactory::GetInstance()->GetFaviconForURL( 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.profile, params.page_url, desired_scale_factors, cancelable_cb); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (history_service_) { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return history_service_->GetFaviconsForURL(params.page_url, 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.icon_types, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.desired_size_in_dip, 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_scale_factors, 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback, 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracker); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RunWithEmptyResultAsync(callback, tracker); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconService::RunFaviconImageCallbackWithBitmapResults( 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconImageCallback& callback, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconImageResult image_result; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_result.image = FaviconUtil::SelectFaviconFramesFromPNGs( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_bitmap_results, 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconUtil::GetFaviconScaleFactors(), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_size_in_dip); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_result.icon_url = image_result.image.IsEmpty() ? 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL() : favicon_bitmap_results[0].icon_url; 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(image_result); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconService::RunFaviconRawCallbackWithBitmapResults( 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FaviconRawCallback& callback, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor desired_scale_factor, 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) { 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(chrome::FaviconBitmapResult()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(1u, favicon_bitmap_results.size()); 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconBitmapResult bitmap_result = favicon_bitmap_results[0]; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the desired size is 0, SelectFaviconFrames() will return the largest 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data for a single bitmap, return it and avoid an unnecessary decode. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (desired_size_in_dip == 0) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(bitmap_result); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If history bitmap is already desired pixel size, return early. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float desired_scale = ui::GetScaleFactorScale(desired_scale_factor); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_edge_width_in_pixel = static_cast<int>( 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_size_in_dip * desired_scale + 0.5f); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size desired_size_in_pixel(desired_edge_width_in_pixel, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_edge_width_in_pixel); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bitmap_result.pixel_size == desired_size_in_pixel) { 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(bitmap_result); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // convert back. 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::ScaleFactor> desired_scale_factors; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_scale_factors.push_back(desired_scale_factor); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs( 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_bitmap_results, desired_scale_factors, desired_size_in_dip); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char> resized_bitmap_data; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &resized_bitmap_data)) { 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(chrome::FaviconBitmapResult()); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector( 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &resized_bitmap_data); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(bitmap_result); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 373