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/common/url_icon_source.h"
6
7#include <string>
8
9#include "content/public/browser/browser_thread.h"
10#include "net/base/load_flags.h"
11#include "net/url_request/url_fetcher.h"
12#include "net/url_request/url_request_status.h"
13#include "ui/base/resource/resource_bundle.h"
14#include "ui/gfx/image/image_skia_operations.h"
15
16using content::BrowserThread;
17
18namespace app_list {
19
20UrlIconSource::UrlIconSource(
21    const IconLoadedCallback& icon_loaded_callback,
22    net::URLRequestContextGetter* context_getter,
23    const GURL& icon_url,
24    int icon_size,
25    int default_icon_resource_id)
26    : icon_loaded_callback_(icon_loaded_callback),
27      context_getter_(context_getter),
28      icon_url_(icon_url),
29      icon_size_(icon_size),
30      default_icon_resource_id_(default_icon_resource_id),
31      icon_fetch_attempted_(false) {
32  DCHECK(!icon_loaded_callback_.is_null());
33}
34
35UrlIconSource::~UrlIconSource() {
36  if (image_decoder_.get())
37    image_decoder_->set_delegate(NULL);
38}
39
40void UrlIconSource::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
50gfx::ImageSkiaRep UrlIconSource::GetImageForScale(float scale) {
51  if (!icon_fetch_attempted_)
52    StartIconFetch();
53
54  if (!icon_.isNull())
55    return icon_.GetRepresentation(scale);
56
57  return ui::ResourceBundle::GetSharedInstance()
58      .GetImageSkiaNamed(default_icon_resource_id_)->GetRepresentation(scale);
59}
60
61void UrlIconSource::OnURLFetchComplete(
62    const net::URLFetcher* source) {
63  CHECK_EQ(icon_fetcher_.get(), source);
64
65  scoped_ptr<net::URLFetcher> fetcher(icon_fetcher_.Pass());
66
67  if (!fetcher->GetStatus().is_success() ||
68      fetcher->GetResponseCode() != 200) {
69    return;
70  }
71
72  std::string unsafe_icon_data;
73  fetcher->GetResponseAsString(&unsafe_icon_data);
74
75  image_decoder_ =
76      new ImageDecoder(this, unsafe_icon_data, ImageDecoder::DEFAULT_CODEC);
77  image_decoder_->Start(
78      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI));
79}
80
81void UrlIconSource::OnImageDecoded(const ImageDecoder* decoder,
82                                   const SkBitmap& decoded_image) {
83  icon_ = gfx::ImageSkiaOperations::CreateResizedImage(
84      gfx::ImageSkia::CreateFrom1xBitmap(decoded_image),
85      skia::ImageOperations::RESIZE_BEST,
86      gfx::Size(icon_size_, icon_size_));
87
88  icon_loaded_callback_.Run();
89}
90
91void UrlIconSource::OnDecodeImageFailed(
92    const ImageDecoder* decoder) {
93  // Failed to decode image. Do nothing and just use the default icon.
94}
95
96}  // namespace app_list
97