190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/app_list/search/common/url_icon_source.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <string>
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/load_flags.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_status.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using content::BrowserThread;
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace app_list {
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)UrlIconSource::UrlIconSource(
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const IconLoadedCallback& icon_loaded_callback,
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    net::URLRequestContextGetter* context_getter,
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GURL& icon_url,
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int icon_size,
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int default_icon_resource_id)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : icon_loaded_callback_(icon_loaded_callback),
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      context_getter_(context_getter),
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      icon_url_(icon_url),
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      icon_size_(icon_size),
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      default_icon_resource_id_(default_icon_resource_id),
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      icon_fetch_attempted_(false) {
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!icon_loaded_callback_.is_null());
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)UrlIconSource::~UrlIconSource() {
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (image_decoder_.get())
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_decoder_->set_delegate(NULL);
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void UrlIconSource::StartIconFetch() {
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_fetch_attempted_ = true;
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_fetcher_.reset(
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      net::URLFetcher::Create(icon_url_, net::URLFetcher::GET, this));
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_fetcher_->SetRequestContext(context_getter_);
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_fetcher_->Start();
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::ImageSkiaRep UrlIconSource::GetImageForScale(float scale) {
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!icon_fetch_attempted_)
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    StartIconFetch();
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!icon_.isNull())
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return icon_.GetRepresentation(scale);
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ui::ResourceBundle::GetSharedInstance()
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      .GetImageSkiaNamed(default_icon_resource_id_)->GetRepresentation(scale);
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void UrlIconSource::OnURLFetchComplete(
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const net::URLFetcher* source) {
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CHECK_EQ(icon_fetcher_.get(), source);
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<net::URLFetcher> fetcher(icon_fetcher_.Pass());
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!fetcher->GetStatus().is_success() ||
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fetcher->GetResponseCode() != 200) {
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string unsafe_icon_data;
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fetcher->GetResponseAsString(&unsafe_icon_data);
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  image_decoder_ =
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new ImageDecoder(this, unsafe_icon_data, ImageDecoder::DEFAULT_CODEC);
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  image_decoder_->Start(
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI));
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void UrlIconSource::OnImageDecoded(const ImageDecoder* decoder,
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                   const SkBitmap& decoded_image) {
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_ = gfx::ImageSkiaOperations::CreateResizedImage(
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::ImageSkia::CreateFrom1xBitmap(decoded_image),
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      skia::ImageOperations::RESIZE_BEST,
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Size(icon_size_, icon_size_));
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  icon_loaded_callback_.Run();
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void UrlIconSource::OnDecodeImageFailed(
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const ImageDecoder* decoder) {
93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Failed to decode image. Do nothing and just use the default icon.
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace app_list
97