Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / android_webview / browser / icon_helper.cc
1 // Copyright (c) 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 "android_webview/browser/icon_helper.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/hash.h"
10 #include "base/logging.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/common/favicon_url.h"
14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "ui/gfx/size.h"
16
17 using content::BrowserThread;
18 using content::WebContents;
19
20 namespace android_webview {
21
22 IconHelper::IconHelper(WebContents* web_contents)
23     : WebContentsObserver(web_contents),
24       listener_(NULL),
25       missing_favicon_urls_() {
26 }
27
28 IconHelper::~IconHelper() {
29 }
30
31 void IconHelper::SetListener(Listener* listener) {
32   listener_ = listener;
33 }
34
35 void IconHelper::DownloadFaviconCallback(
36     int id,
37     int http_status_code,
38     const GURL& image_url,
39     const std::vector<SkBitmap>& bitmaps,
40     const std::vector<gfx::Size>& original_bitmap_sizes) {
41   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
42   if (http_status_code == 404) {
43     MarkUnableToDownloadFavicon(image_url);
44     return;
45   }
46
47   if (bitmaps.size() == 0) {
48     return;
49   }
50
51   // We can protentially have multiple frames of the icon
52   // in different sizes. We need more fine grain API spec
53   // to let clients pick out the frame they want.
54
55   // TODO(acleung): Pick the best icon to return based on size.
56   if (listener_)
57     listener_->OnReceivedIcon(image_url, bitmaps[0]);
58 }
59
60 void IconHelper::DidUpdateFaviconURL(
61     const std::vector<content::FaviconURL>& candidates) {
62   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63   for (std::vector<content::FaviconURL>::const_iterator i = candidates.begin();
64        i != candidates.end(); ++i) {
65     if (!i->icon_url.is_valid())
66       continue;
67
68     switch(i->icon_type) {
69       case content::FaviconURL::FAVICON:
70         if ((listener_ && !listener_->ShouldDownloadFavicon(i->icon_url)) ||
71             WasUnableToDownloadFavicon(i->icon_url)) {
72           break;
73         }
74         web_contents()->DownloadImage(i->icon_url,
75             true,  // Is a favicon
76             0,  // No maximum size
77             base::Bind(
78                 &IconHelper::DownloadFaviconCallback, base::Unretained(this)));
79         break;
80       case content::FaviconURL::TOUCH_ICON:
81         if (listener_)
82           listener_->OnReceivedTouchIconUrl(i->icon_url.spec(), false);
83         break;
84       case content::FaviconURL::TOUCH_PRECOMPOSED_ICON:
85         if (listener_)
86           listener_->OnReceivedTouchIconUrl(i->icon_url.spec(), true);
87         break;
88       case content::FaviconURL::INVALID_ICON:
89         // Silently ignore it. Only trigger a callback on valid icons.
90         break;
91       default:
92         NOTREACHED();
93         break;
94     }
95   }
96 }
97
98 void IconHelper::DidStartNavigationToPendingEntry(
99     const GURL& url,
100     content::NavigationController::ReloadType reload_type) {
101   if (reload_type == content::NavigationController::RELOAD_IGNORING_CACHE)
102     ClearUnableToDownloadFavicons();
103 }
104
105 void IconHelper::MarkUnableToDownloadFavicon(const GURL& icon_url) {
106   MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
107   missing_favicon_urls_.insert(url_hash);
108 }
109
110 bool IconHelper::WasUnableToDownloadFavicon(const GURL& icon_url) const {
111   MissingFaviconURLHash url_hash = base::Hash(icon_url.spec());
112   return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end();
113 }
114
115 void IconHelper::ClearUnableToDownloadFavicons() {
116   missing_favicon_urls_.clear();
117 }
118
119 }  // namespace android_webview