Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: chrome/browser/fav_icon_helper.cc

Issue 482003: Get web app icon via FavIconHelper and auto repair/update (Closed)
Patch Set: miranda's review 1 Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/fav_icon_helper.h ('k') | chrome/browser/tab_contents/tab_contents.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/fav_icon_helper.h" 5 #include "chrome/browser/fav_icon_helper.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include "app/gfx/codec/png_codec.h" 9 #include "app/gfx/codec/png_codec.h"
10 #include "app/gfx/favicon_size.h" 10 #include "app/gfx/favicon_size.h"
11 #include "chrome/browser/profile.h" 11 #include "chrome/browser/profile.h"
12 #include "chrome/browser/renderer_host/render_view_host.h" 12 #include "chrome/browser/renderer_host/render_view_host.h"
13 #include "chrome/browser/tab_contents/navigation_controller.h" 13 #include "chrome/browser/tab_contents/navigation_controller.h"
14 #include "chrome/browser/tab_contents/navigation_entry.h" 14 #include "chrome/browser/tab_contents/navigation_entry.h"
15 #include "chrome/browser/tab_contents/tab_contents_delegate.h" 15 #include "chrome/browser/tab_contents/tab_contents_delegate.h"
16 #include "chrome/browser/tab_contents/tab_contents.h" 16 #include "chrome/browser/tab_contents/tab_contents.h"
17 #include "skia/ext/image_operations.h" 17 #include "skia/ext/image_operations.h"
18 18
19 FavIconHelper::FavIconHelper(TabContents* tab_contents) 19 FavIconHelper::FavIconHelper(TabContents* tab_contents)
20 : tab_contents_(tab_contents), 20 : tab_contents_(tab_contents),
21 got_fav_icon_url_(false), 21 got_fav_icon_url_(false),
22 got_fav_icon_from_history_(false), 22 got_fav_icon_from_history_(false),
23 fav_icon_expired_(false) { 23 fav_icon_expired_(false) {
24 } 24 }
25 25
26 FavIconHelper::~FavIconHelper() {
27 SkBitmap empty_image;
28
29 // Call pending download callbacks with error to allow caller to clean up.
30 for (DownloadRequests::iterator i = download_requests_.begin();
31 i != download_requests_.end(); ++i) {
32 if (i->second.callback) {
33 i->second.callback->Run(i->first, true, empty_image);
34 }
35 }
36 }
37
26 void FavIconHelper::FetchFavIcon(const GURL& url) { 38 void FavIconHelper::FetchFavIcon(const GURL& url) {
27 cancelable_consumer_.CancelAllRequests(); 39 cancelable_consumer_.CancelAllRequests();
28 40
29 url_ = url; 41 url_ = url;
30 42
31 fav_icon_expired_ = got_fav_icon_from_history_ = got_fav_icon_url_ = false; 43 fav_icon_expired_ = got_fav_icon_from_history_ = got_fav_icon_url_ = false;
32 44
33 // Request the favicon from the history service. In parallel to this the 45 // Request the favicon from the history service. In parallel to this the
34 // renderer is going to notify us (well TabContents) when the favicon url is 46 // renderer is going to notify us (well TabContents) when the favicon url is
35 // available. 47 // available.
36 if (GetFaviconService()) { 48 if (GetFaviconService()) {
37 GetFaviconService()->GetFaviconForURL(url_, &cancelable_consumer_, 49 GetFaviconService()->GetFaviconForURL(url_, &cancelable_consumer_,
38 NewCallback(this, &FavIconHelper::OnFavIconDataForInitialURL)); 50 NewCallback(this, &FavIconHelper::OnFavIconDataForInitialURL));
39 } 51 }
40 } 52 }
41 53
54 int FavIconHelper::DownloadImage(const GURL& image_url,
55 int image_size,
56 ImageDownloadCallback* callback) {
57 DCHECK(callback); // Must provide a callback.
58 return ScheduleDownload(GURL(), image_url, image_size, callback);
59 }
60
42 Profile* FavIconHelper::profile() { 61 Profile* FavIconHelper::profile() {
43 return tab_contents_->profile(); 62 return tab_contents_->profile();
44 } 63 }
45 64
46 FaviconService* FavIconHelper::GetFaviconService() { 65 FaviconService* FavIconHelper::GetFaviconService() {
47 return profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); 66 return profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
48 } 67 }
49 68
50 void FavIconHelper::SetFavIcon( 69 void FavIconHelper::SetFavIcon(
51 int download_id, 70 const GURL& url,
52 const GURL& image_url, 71 const GURL& image_url,
53 const SkBitmap& image) { 72 const SkBitmap& image) {
54 DownloadRequests::iterator i = download_requests_.find(download_id);
55 if (i == download_requests_.end()) {
56 // Currently TabContents notifies us of ANY downloads so that it is
57 // possible to get here.
58 return;
59 }
60
61 const SkBitmap& sized_image = 73 const SkBitmap& sized_image =
62 (image.width() == kFavIconSize && image.height() == kFavIconSize) 74 (image.width() == kFavIconSize && image.height() == kFavIconSize)
63 ? image : ConvertToFavIconSize(image); 75 ? image : ConvertToFavIconSize(image);
64 76
65 if (GetFaviconService() && !profile()->IsOffTheRecord()) { 77 if (GetFaviconService() && !profile()->IsOffTheRecord()) {
66 std::vector<unsigned char> image_data; 78 std::vector<unsigned char> image_data;
67 gfx::PNGCodec::EncodeBGRASkBitmap(sized_image, false, &image_data); 79 gfx::PNGCodec::EncodeBGRASkBitmap(sized_image, false, &image_data);
68 GetFaviconService()->SetFavicon(i->second.url, i->second.fav_icon_url, 80 GetFaviconService()->SetFavicon(url, image_url, image_data);
69 image_data);
70 } 81 }
71 82
72 if (i->second.url == url_) { 83 if (url == url_) {
73 NavigationEntry* entry = GetEntry(); 84 NavigationEntry* entry = GetEntry();
74 if (entry) 85 if (entry)
75 UpdateFavIcon(entry, sized_image); 86 UpdateFavIcon(entry, sized_image);
76 } 87 }
77
78 download_requests_.erase(i);
79 }
80
81 void FavIconHelper::FavIconDownloadFailed(int download_id) {
82 DownloadRequests::iterator i = download_requests_.find(download_id);
83 if (i != download_requests_.end())
84 download_requests_.erase(i);
85 } 88 }
86 89
87 void FavIconHelper::UpdateFavIcon(NavigationEntry* entry, 90 void FavIconHelper::UpdateFavIcon(NavigationEntry* entry,
88 const std::vector<unsigned char>& data) { 91 const std::vector<unsigned char>& data) {
89 SkBitmap image; 92 SkBitmap image;
90 gfx::PNGCodec::Decode(&data.front(), data.size(), &image); 93 gfx::PNGCodec::Decode(&data.front(), data.size(), &image);
91 UpdateFavIcon(entry, image); 94 UpdateFavIcon(entry, image);
92 } 95 }
93 96
94 void FavIconHelper::UpdateFavIcon(NavigationEntry* entry, 97 void FavIconHelper::UpdateFavIcon(NavigationEntry* entry,
(...skipping 30 matching lines...) Expand all
125 128
126 if (got_fav_icon_from_history_) 129 if (got_fav_icon_from_history_)
127 DownloadFavIconOrAskHistory(entry); 130 DownloadFavIconOrAskHistory(entry);
128 } 131 }
129 132
130 void FavIconHelper::DidDownloadFavIcon(RenderViewHost* render_view_host, 133 void FavIconHelper::DidDownloadFavIcon(RenderViewHost* render_view_host,
131 int id, 134 int id,
132 const GURL& image_url, 135 const GURL& image_url,
133 bool errored, 136 bool errored,
134 const SkBitmap& image) { 137 const SkBitmap& image) {
135 if (errored) 138 DownloadRequests::iterator i = download_requests_.find(id);
136 FavIconDownloadFailed(id); 139 if (i == download_requests_.end()) {
137 else 140 // Currently TabContents notifies us of ANY downloads so that it is
138 SetFavIcon(id, image_url, image); 141 // possible to get here.
142 return;
143 }
144
145 if (i->second.callback) {
146 i->second.callback->Run(id, errored, image);
147 } else if (!errored) {
148 SetFavIcon(i->second.url, image_url, image);
149 }
150
151 download_requests_.erase(i);
139 } 152 }
140 153
141 NavigationEntry* FavIconHelper::GetEntry() { 154 NavigationEntry* FavIconHelper::GetEntry() {
142 NavigationEntry* entry = tab_contents_->controller().GetActiveEntry(); 155 NavigationEntry* entry = tab_contents_->controller().GetActiveEntry();
143 if (entry && entry->url() == url_ && 156 if (entry && entry->url() == url_ &&
144 tab_contents_->IsActiveEntry(entry->page_id())) { 157 tab_contents_->IsActiveEntry(entry->page_id())) {
145 return entry; 158 return entry;
146 } 159 }
147 // If the URL has changed out from under us (as will happen with redirects) 160 // If the URL has changed out from under us (as will happen with redirects)
148 // return NULL. 161 // return NULL.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 DownloadFavIconOrAskHistory(entry); 202 DownloadFavIconOrAskHistory(entry);
190 } 203 }
191 // else we haven't got the icon url. When we get it we'll ask the 204 // else we haven't got the icon url. When we get it we'll ask the
192 // renderer to download the icon. 205 // renderer to download the icon.
193 } 206 }
194 207
195 void FavIconHelper::DownloadFavIconOrAskHistory(NavigationEntry* entry) { 208 void FavIconHelper::DownloadFavIconOrAskHistory(NavigationEntry* entry) {
196 DCHECK(entry); // We should only get here if entry is valid. 209 DCHECK(entry); // We should only get here if entry is valid.
197 if (fav_icon_expired_) { 210 if (fav_icon_expired_) {
198 // We have the mapping, but the favicon is out of date. Download it now. 211 // We have the mapping, but the favicon is out of date. Download it now.
199 ScheduleDownload(entry); 212 ScheduleDownload(entry->url(), entry->favicon().url(), kFavIconSize, NULL);
200 } else if (GetFaviconService()) { 213 } else if (GetFaviconService()) {
201 // We don't know the favicon, but we may have previously downloaded the 214 // We don't know the favicon, but we may have previously downloaded the
202 // favicon for another page that shares the same favicon. Ask for the 215 // favicon for another page that shares the same favicon. Ask for the
203 // favicon given the favicon URL. 216 // favicon given the favicon URL.
204 if (profile()->IsOffTheRecord()) { 217 if (profile()->IsOffTheRecord()) {
205 GetFaviconService()->GetFavicon( 218 GetFaviconService()->GetFavicon(
206 entry->favicon().url(), 219 entry->favicon().url(),
207 &cancelable_consumer_, 220 &cancelable_consumer_,
208 NewCallback(this, &FavIconHelper::OnFavIconData)); 221 NewCallback(this, &FavIconHelper::OnFavIconData));
209 } else { 222 } else {
(...skipping 26 matching lines...) Expand all
236 249
237 if (know_favicon && data && !data->data.empty()) { 250 if (know_favicon && data && !data->data.empty()) {
238 // There is a favicon, set it now. If expired we'll download the current 251 // There is a favicon, set it now. If expired we'll download the current
239 // one again, but at least the user will get some icon instead of the 252 // one again, but at least the user will get some icon instead of the
240 // default and most likely the current one is fine anyway. 253 // default and most likely the current one is fine anyway.
241 UpdateFavIcon(entry, data->data); 254 UpdateFavIcon(entry, data->data);
242 } 255 }
243 256
244 if (!know_favicon || expired) { 257 if (!know_favicon || expired) {
245 // We don't know the favicon, or it is out of date. Request the current one. 258 // We don't know the favicon, or it is out of date. Request the current one.
246 ScheduleDownload(entry); 259 ScheduleDownload(entry->url(), entry->favicon().url(), kFavIconSize, NULL);
247 } 260 }
248 } 261 }
249 262
250 void FavIconHelper::ScheduleDownload(NavigationEntry* entry) { 263 int FavIconHelper::ScheduleDownload(const GURL& url,
264 const GURL& image_url,
265 int image_size,
266 ImageDownloadCallback* callback) {
251 const int download_id = tab_contents_->render_view_host()->DownloadFavIcon( 267 const int download_id = tab_contents_->render_view_host()->DownloadFavIcon(
252 entry->favicon().url(), kFavIconSize); 268 image_url, image_size);
253 if (!download_id)
254 return; // Download request failed.
255 269
256 // Download ids should be unique. 270 if (download_id) {
257 DCHECK(download_requests_.find(download_id) == download_requests_.end()); 271 // Download ids should be unique.
258 download_requests_[download_id] = 272 DCHECK(download_requests_.find(download_id) == download_requests_.end());
259 DownloadRequest(entry->url(), entry->favicon().url()); 273 download_requests_[download_id] = DownloadRequest(url, image_url, callback);
274 }
275
276 return download_id;
260 } 277 }
261 278
262 SkBitmap FavIconHelper::ConvertToFavIconSize(const SkBitmap& image) { 279 SkBitmap FavIconHelper::ConvertToFavIconSize(const SkBitmap& image) {
263 int width = image.width(); 280 int width = image.width();
264 int height = image.height(); 281 int height = image.height();
265 if (width > 0 && height > 0) { 282 if (width > 0 && height > 0) {
266 calc_favicon_target_size(&width, &height); 283 calc_favicon_target_size(&width, &height);
267 return skia::ImageOperations::Resize( 284 return skia::ImageOperations::Resize(
268 image, skia::ImageOperations::RESIZE_LANCZOS3, 285 image, skia::ImageOperations::RESIZE_LANCZOS3,
269 width, height); 286 width, height);
270 } 287 }
271 return image; 288 return image;
272 } 289 }
OLDNEW
« no previous file with comments | « chrome/browser/fav_icon_helper.h ('k') | chrome/browser/tab_contents/tab_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698