Home | History | Annotate | Download | only in webui
      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