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