1// Copyright 2014 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// This class holds the URL to an image and the bitmap for the fetched image,
6// and has code to fetch the bitmap from the URL.
7
8#include "chrome/browser/image_holder.h"
9
10#include "chrome/browser/profiles/profile.h"
11#include "net/base/load_flags.h"
12
13namespace chrome {
14
15ImageHolder::ImageHolder(const GURL& low_dpi_url,
16                         const GURL& high_dpi_url,
17                         Profile* profile,
18                         ImageHolderDelegate* delegate)
19    : low_dpi_url_(low_dpi_url),
20      high_dpi_url_(high_dpi_url),
21      low_dpi_fetched_(false),
22      high_dpi_fetched_(false),
23      delegate_(delegate),
24      profile_(profile) {
25
26  // If a URL is invalid, clear it so we don't try to fetch it.
27  if (!low_dpi_url_.is_valid()) {
28    low_dpi_url_ = GURL();
29  }
30  if (!high_dpi_url_.is_valid()) {
31    high_dpi_url_ = GURL();
32  }
33
34  // Create a featcher for each URL that is set.
35  if (!low_dpi_url_.is_empty()) {
36    CreateBitmapFetcher(low_dpi_url_);
37  }
38  if (!high_dpi_url_.is_empty()) {
39    CreateBitmapFetcher(high_dpi_url_);
40  }
41}
42
43ImageHolder::~ImageHolder() {}
44
45// This will let us know if we have tried to fetch once and the try completed.
46// Currently there is no logic for retries.
47bool ImageHolder::IsFetchingDone() const {
48  return ((low_dpi_url_.is_empty() || low_dpi_fetched_) &&
49           (high_dpi_url_.is_empty() || high_dpi_fetched_));
50}
51
52// If this bitmap has a valid GURL, create a fetcher for it.
53void ImageHolder::CreateBitmapFetcher(const GURL& url) {
54  // Check for dups, ignore any request for a dup.
55  ScopedVector<chrome::BitmapFetcher>::iterator iter;
56  for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
57    if ((*iter)->url() == url)
58      return;
59  }
60
61  if (url.is_valid()) {
62    fetchers_.push_back(new chrome::BitmapFetcher(url, this));
63    DVLOG(2) << __FUNCTION__ << "Pushing bitmap " << url;
64  }
65}
66
67void ImageHolder::StartFetch() {
68  // Now that we have queued them all, start the fetching.
69  ScopedVector<chrome::BitmapFetcher>::iterator iter;
70  for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
71    (*iter)->Start(
72        profile_->GetRequestContext(),
73        std::string(),
74        net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
75        net::LOAD_NORMAL);
76  }
77}
78
79// Method inherited from BitmapFetcher delegate.
80void ImageHolder::OnFetchComplete(const GURL url, const SkBitmap* bitmap) {
81  // TODO(petewil): Should I retry if a fetch fails?
82  // Match the bitmap to the URL to put it into the image with the correct scale
83  // factor.
84  if (url == low_dpi_url_) {
85    low_dpi_fetched_ = true;
86    if (bitmap != NULL)
87      image_.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 1.0));
88  } else if (url == high_dpi_url_) {
89    high_dpi_fetched_ = true;
90    if (bitmap != NULL)
91      image_.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 2.0));
92  } else {
93    DVLOG(2) << __FUNCTION__ << "Unmatched bitmap arrived " << url;
94  }
95
96  // Notify callback of bitmap arrival.
97  delegate_->OnFetchComplete();
98}
99
100}  // namespace chrome.
101