favicon_source.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/ui/webui/favicon_source.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service_factory.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/instant_io_context.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/instant_service.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/instant_service_factory.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/locale_settings.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/webui/web_ui_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parameters which can be used in chrome://favicon path. See .h file for a 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// description of what each does. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kIconURLParameter[] = "iconurl/"; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLargestParameter[] = "largest/"; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOriginParameter[] = "origin/"; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kSizeParameter[] = "size/"; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if |search| is a substring of |path| which starts at 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |start_index|. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasSubstringAt(const std::string& path, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t start_index, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& search) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (search.empty()) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (start_index + search.size() >= path.size()) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (path.compare(start_index, search.size(), search) == 0); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FaviconSource::IconRequest::IconRequest() 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : size_in_dip(gfx::kFaviconSize), 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_factor(ui::SCALE_FACTOR_NONE) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FaviconSource::IconRequest::IconRequest( 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::URLDataSource::GotDataCallback& cb, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& path, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScaleFactor scale) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : callback(cb), 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_path(path), 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_dip(size), 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_factor(scale) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FaviconSource::IconRequest::~IconRequest() { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FaviconSource::FaviconSource(Profile* profile, IconType type) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : profile_(profile->GetOriginalProfile()), 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_types_(type == FAVICON ? history::FAVICON : 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) history::TOUCH_PRECOMPOSED_ICON | history::TOUCH_ICON | 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) history::FAVICON) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FaviconSource::~FaviconSource() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FaviconSource::GetSource() { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return icon_types_ == history::FAVICON ? 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::kChromeUIFaviconHost : chrome::kChromeUITouchIconHost; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconSource::StartDataRequest( 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& raw_path, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::URLDataSource::GotDataCallback& callback) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconService* favicon_service = 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!favicon_service || raw_path.empty()) { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDefaultResponse(callback); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Translate to regular path if |raw_path| is of the form 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // chrome-search://favicon/<most_visited_item_id>, where 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // "most_visited_item_id" is a uint64. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string path = InstantService::MaybeTranslateInstantPathOnUI(profile_, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_path); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(16, gfx::kFaviconSize); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size_in_dip = 16; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t parsed_index = 0; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasSubstringAt(path, parsed_index, kLargestParameter)) { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_index += strlen(kLargestParameter); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_dip = 0; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (HasSubstringAt(path, parsed_index, kSizeParameter)) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_index += strlen(kSizeParameter); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t scale_delimiter = path.find("@", parsed_index); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scale_delimiter == std::string::npos) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDefaultResponse(callback); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string size = path.substr(parsed_index, 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_delimiter - parsed_index); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::StringToInt(size, &size_in_dip)) { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDefaultResponse(callback); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size_in_dip != 64 && size_in_dip != 32) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only 64x64, 32x32 and 16x16 icons are supported. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_dip = 16; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t slash = path.find("/", scale_delimiter); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (slash == std::string::npos) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDefaultResponse(callback); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string scale_str = path.substr(scale_delimiter + 1, 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) slash - scale_delimiter - 1); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webui::ParseScaleFactor(scale_str, &scale_factor); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Return the default favicon (as opposed to a resized favicon) for 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // favicon sizes which are not cached by the favicon service. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Currently the favicon service caches: 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - favicons of sizes "16 * scale factor" px of type FAVICON 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // where scale factor is one of FaviconUtil::GetFaviconScaleFactors(). 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - the largest TOUCH_ICON / TOUCH_PRECOMPOSED_ICON 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size_in_dip != 16 && icon_types_ == history::FAVICON) { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDefaultResponse(callback); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_index = slash + 1; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasSubstringAt(path, parsed_index, kIconURLParameter)) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_index += strlen(kIconURLParameter); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(michaelbai): Change GetRawFavicon to support combination of 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IconType. 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_service->GetRawFavicon( 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(path.substr(parsed_index)), 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::FAVICON, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_in_dip, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scale_factor, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FaviconSource::OnFaviconDataAvailable, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconRequest(callback, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path.substr(parsed_index), 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_dip, 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_factor)), 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelable_task_tracker_); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string url; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // URL requests prefixed with "origin/" are converted to a form with an 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // empty path and a valid scheme. (e.g., example.com --> 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://example.com/ or http://example.com/a --> http://example.com/) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasSubstringAt(path, parsed_index, kOriginParameter)) { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_index += strlen(kOriginParameter); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url = path.substr(parsed_index); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the URL does not specify a scheme (e.g., example.com instead of 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://example.com), add "http://" as a default. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GURL(url).has_scheme()) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url = "http://" + url; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Strip the path beyond the top-level domain. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url = GURL(url).GetOrigin().spec(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url = path.substr(parsed_index); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intercept requests for prepopulated pages. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(history::kPrepopulatedPages); i++) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (url == 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF8(history::kPrepopulatedPages[i].url_id)) { 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::kPrepopulatedPages[i].favicon_id, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scale_factor)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_service->GetRawFaviconForURL( 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconService::FaviconForURLParams( 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_, GURL(url), icon_types_, size_in_dip), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scale_factor, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FaviconSource::OnFaviconDataAvailable, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconRequest(callback, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_dip, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scale_factor)), 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelable_task_tracker_); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string FaviconSource::GetMimeType(const std::string&) const { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to explicitly return a mime type, otherwise if the user tries to 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // drag the image they get no extension. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "image/png"; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FaviconSource::ShouldReplaceExistingSource() const { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Leave the existing DataSource in place, otherwise we'll drop any pending 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests on the floor. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FaviconSource::ShouldServiceRequest(const net::URLRequest* request) const { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return InstantService::IsInstantPath(request->url()) && 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InstantIOContext::ShouldServiceRequest(request); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return URLDataSource::ShouldServiceRequest(request); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FaviconSource::HandleMissingResource(const IconRequest& request) { 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No additional checks to locate the favicon resource in the base 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // implementation. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconSource::OnFaviconDataAvailable( 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IconRequest& request, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const history::FaviconBitmapResult& bitmap_result) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bitmap_result.is_valid()) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Forward the data along to the networking system. 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.callback.Run(bitmap_result.bitmap_data); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (!HandleMissingResource(request)) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDefaultResponse(request); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FaviconSource::SendDefaultResponse( 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::URLDataSource::GotDataCallback& callback) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendDefaultResponse(IconRequest(callback, 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "", 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SCALE_FACTOR_100P)); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FaviconSource::SendDefaultResponse(const IconRequest& icon_request) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int favicon_index; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_id; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (icon_request.size_in_dip) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 64: 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_index = SIZE_64; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_id = IDR_DEFAULT_FAVICON_64; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 32: 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_index = SIZE_32; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_id = IDR_DEFAULT_FAVICON_32; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_index = SIZE_16; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_id = IDR_DEFAULT_FAVICON; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RefCountedMemory* default_favicon = default_favicons_[favicon_index]; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!default_favicon) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor = icon_request.scale_factor; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_favicon = ResourceBundle::GetSharedInstance() 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .LoadDataResourceBytesForScale(resource_id, scale_factor); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_favicons_[favicon_index] = default_favicon; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_request.callback.Run(default_favicon); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 290