1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/webui/favicon_source.h" 6 7 #include "base/callback.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/common/url_constants.h" 10 #include "grit/app_resources.h" 11 #include "ui/base/resource/resource_bundle.h" 12 13 FaviconSource::FaviconSource(Profile* profile) 14 : DataSource(chrome::kChromeUIFaviconHost, MessageLoop::current()), 15 profile_(profile->GetOriginalProfile()) { 16 } 17 18 FaviconSource::~FaviconSource() { 19 } 20 21 void FaviconSource::StartDataRequest(const std::string& path, 22 bool is_incognito, 23 int request_id) { 24 FaviconService* favicon_service = 25 profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); 26 if (favicon_service) { 27 FaviconService::Handle handle; 28 if (path.empty()) { 29 SendDefaultResponse(request_id); 30 return; 31 } 32 33 if (path.size() > 8 && path.substr(0, 8) == "iconurl/") { 34 handle = favicon_service->GetFavicon( 35 GURL(path.substr(8)), 36 history::FAVICON, 37 &cancelable_consumer_, 38 NewCallback(this, &FaviconSource::OnFaviconDataAvailable)); 39 } else { 40 handle = favicon_service->GetFaviconForURL( 41 GURL(path), 42 history::FAVICON, 43 &cancelable_consumer_, 44 NewCallback(this, &FaviconSource::OnFaviconDataAvailable)); 45 } 46 // Attach the ChromeURLDataManager request ID to the history request. 47 cancelable_consumer_.SetClientData(favicon_service, handle, request_id); 48 } else { 49 SendResponse(request_id, NULL); 50 } 51 } 52 53 std::string FaviconSource::GetMimeType(const std::string&) const { 54 // We need to explicitly return a mime type, otherwise if the user tries to 55 // drag the image they get no extension. 56 return "image/png"; 57 } 58 59 bool FaviconSource::ShouldReplaceExistingSource() const { 60 // Leave the existing DataSource in place, otherwise we'll drop any pending 61 // requests on the floor. 62 return false; 63 } 64 65 void FaviconSource::OnFaviconDataAvailable( 66 FaviconService::Handle request_handle, 67 history::FaviconData favicon) { 68 FaviconService* favicon_service = 69 profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); 70 int request_id = cancelable_consumer_.GetClientData(favicon_service, 71 request_handle); 72 73 if (favicon.is_valid()) { 74 // Forward the data along to the networking system. 75 SendResponse(request_id, favicon.image_data); 76 } else { 77 SendDefaultResponse(request_id); 78 } 79 } 80 81 void FaviconSource::SendDefaultResponse(int request_id) { 82 if (!default_favicon_.get()) { 83 default_favicon_ = 84 ResourceBundle::GetSharedInstance().LoadDataResourceBytes( 85 IDR_DEFAULT_FAVICON); 86 } 87 88 SendResponse(request_id, default_favicon_); 89 } 90