Home | History | Annotate | Download | only in search
      1 // Copyright 2013 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/app_list/search/webstore_result_icon_source.h"
      6 
      7 #include <string>
      8 
      9 #include "content/public/browser/browser_thread.h"
     10 #include "grit/theme_resources.h"
     11 #include "net/base/load_flags.h"
     12 #include "net/url_request/url_fetcher.h"
     13 #include "net/url_request/url_request_status.h"
     14 #include "ui/base/resource/resource_bundle.h"
     15 #include "ui/gfx/canvas.h"
     16 #include "ui/gfx/image/image_skia_operations.h"
     17 
     18 using content::BrowserThread;
     19 
     20 namespace app_list {
     21 
     22 WebstoreResultIconSource::WebstoreResultIconSource(
     23     const IconLoadedCallback& icon_loaded_callback,
     24     net::URLRequestContextGetter* context_getter,
     25     const GURL& icon_url,
     26     int icon_size)
     27     : icon_loaded_callback_(icon_loaded_callback),
     28       context_getter_(context_getter),
     29       icon_url_(icon_url),
     30       icon_size_(icon_size),
     31       icon_fetch_attempted_(false) {
     32   DCHECK(!icon_loaded_callback_.is_null());
     33 }
     34 
     35 WebstoreResultIconSource::~WebstoreResultIconSource() {
     36   if (image_decoder_.get())
     37     image_decoder_->set_delegate(NULL);
     38 }
     39 
     40 void WebstoreResultIconSource::StartIconFetch() {
     41   icon_fetch_attempted_ = true;
     42 
     43   icon_fetcher_.reset(
     44       net::URLFetcher::Create(icon_url_, net::URLFetcher::GET, this));
     45   icon_fetcher_->SetRequestContext(context_getter_);
     46   icon_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
     47   icon_fetcher_->Start();
     48 }
     49 
     50 gfx::ImageSkiaRep WebstoreResultIconSource::CreateBadgedIcon(
     51     ui::ScaleFactor scale_factor) {
     52   gfx::Canvas canvas(gfx::Size(icon_size_, icon_size_), scale_factor, false);
     53 
     54   canvas.DrawImageInt(icon_, 0, 0);
     55 
     56   const gfx::ImageSkia& badge = *ui::ResourceBundle::GetSharedInstance().
     57        GetImageSkiaNamed(IDR_WEBSTORE_ICON_16);
     58   canvas.DrawImageInt(
     59       badge, icon_.width() - badge.width(), icon_.height() - badge.height());
     60 
     61   return canvas.ExtractImageRep();
     62 }
     63 
     64 gfx::ImageSkiaRep WebstoreResultIconSource::GetImageForScale(
     65     ui::ScaleFactor scale_factor) {
     66   if (!icon_fetch_attempted_)
     67     StartIconFetch();
     68 
     69   if (!icon_.isNull())
     70     return CreateBadgedIcon(scale_factor);
     71 
     72   return ui::ResourceBundle::GetSharedInstance()
     73       .GetImageSkiaNamed(IDR_WEBSTORE_ICON_32)->GetRepresentation(scale_factor);
     74 }
     75 
     76 void WebstoreResultIconSource::OnURLFetchComplete(
     77     const net::URLFetcher* source) {
     78   CHECK_EQ(icon_fetcher_.get(), source);
     79 
     80   scoped_ptr<net::URLFetcher> fetcher(icon_fetcher_.Pass());
     81 
     82   if (!fetcher->GetStatus().is_success() ||
     83       fetcher->GetResponseCode() != 200) {
     84     return;
     85   }
     86 
     87   std::string unsafe_icon_data;
     88   fetcher->GetResponseAsString(&unsafe_icon_data);
     89 
     90   image_decoder_ =
     91       new ImageDecoder(this, unsafe_icon_data, ImageDecoder::DEFAULT_CODEC);
     92   image_decoder_->Start(
     93       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI));
     94 }
     95 
     96 void WebstoreResultIconSource::OnImageDecoded(const ImageDecoder* decoder,
     97                                               const SkBitmap& decoded_image) {
     98   icon_ = gfx::ImageSkiaOperations::CreateResizedImage(
     99       gfx::ImageSkia::CreateFrom1xBitmap(decoded_image),
    100       skia::ImageOperations::RESIZE_BEST,
    101       gfx::Size(icon_size_, icon_size_));
    102   icon_loaded_callback_.Run();
    103 }
    104 
    105 void WebstoreResultIconSource::OnDecodeImageFailed(
    106     const ImageDecoder* decoder) {
    107   // Failed to decode image. Do nothing and just use web store icon.
    108 }
    109 
    110 }  // namespace app_list
    111