| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 cancelable_consumer_.CancelAllRequests(); | 45 cancelable_consumer_.CancelAllRequests(); |
| 46 | 46 |
| 47 url_ = url; | 47 url_ = url; |
| 48 | 48 |
| 49 fav_icon_expired_ = got_fav_icon_from_history_ = got_fav_icon_url_ = false; | 49 fav_icon_expired_ = got_fav_icon_from_history_ = got_fav_icon_url_ = false; |
| 50 | 50 |
| 51 // Request the favicon from the history service. In parallel to this the | 51 // Request the favicon from the history service. In parallel to this the |
| 52 // renderer is going to notify us (well TabContents) when the favicon url is | 52 // renderer is going to notify us (well TabContents) when the favicon url is |
| 53 // available. | 53 // available. |
| 54 if (GetFaviconService()) { | 54 if (GetFaviconService()) { |
| 55 GetFaviconService()->GetFaviconForURL(url_, &cancelable_consumer_, | 55 GetFaviconService()->GetFaviconForURL(url_, history::FAV_ICON, |
| 56 &cancelable_consumer_, |
| 56 NewCallback(this, &FavIconHelper::OnFavIconDataForInitialURL)); | 57 NewCallback(this, &FavIconHelper::OnFavIconDataForInitialURL)); |
| 57 } | 58 } |
| 58 } | 59 } |
| 59 | 60 |
| 60 int FavIconHelper::DownloadImage(const GURL& image_url, | 61 int FavIconHelper::DownloadImage(const GURL& image_url, |
| 61 int image_size, | 62 int image_size, |
| 62 ImageDownloadCallback* callback) { | 63 ImageDownloadCallback* callback) { |
| 63 DCHECK(callback); // Must provide a callback. | 64 DCHECK(callback); // Must provide a callback. |
| 64 return ScheduleDownload(GURL(), image_url, image_size, callback); | 65 return ScheduleDownload(GURL(), image_url, image_size, callback); |
| 65 } | 66 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 76 const GURL& url, | 77 const GURL& url, |
| 77 const GURL& image_url, | 78 const GURL& image_url, |
| 78 const SkBitmap& image) { | 79 const SkBitmap& image) { |
| 79 const SkBitmap& sized_image = | 80 const SkBitmap& sized_image = |
| 80 (image.width() == kFavIconSize && image.height() == kFavIconSize) | 81 (image.width() == kFavIconSize && image.height() == kFavIconSize) |
| 81 ? image : ConvertToFavIconSize(image); | 82 ? image : ConvertToFavIconSize(image); |
| 82 | 83 |
| 83 if (GetFaviconService() && ShouldSaveFavicon(url)) { | 84 if (GetFaviconService() && ShouldSaveFavicon(url)) { |
| 84 std::vector<unsigned char> image_data; | 85 std::vector<unsigned char> image_data; |
| 85 gfx::PNGCodec::EncodeBGRASkBitmap(sized_image, false, &image_data); | 86 gfx::PNGCodec::EncodeBGRASkBitmap(sized_image, false, &image_data); |
| 86 GetFaviconService()->SetFavicon(url, image_url, image_data); | 87 GetFaviconService()->SetFavicon(url, image_url, image_data, |
| 88 history::FAV_ICON); |
| 87 } | 89 } |
| 88 | 90 |
| 89 if (url == url_) { | 91 if (url == url_) { |
| 90 NavigationEntry* entry = GetEntry(); | 92 NavigationEntry* entry = GetEntry(); |
| 91 if (entry) | 93 if (entry) |
| 92 UpdateFavIcon(entry, sized_image); | 94 UpdateFavIcon(entry, sized_image); |
| 93 } | 95 } |
| 94 } | 96 } |
| 95 | 97 |
| 96 void FavIconHelper::UpdateFavIcon(NavigationEntry* entry, | 98 void FavIconHelper::UpdateFavIcon(NavigationEntry* entry, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 tab_contents()->IsActiveEntry(entry->page_id())) { | 177 tab_contents()->IsActiveEntry(entry->page_id())) { |
| 176 return entry; | 178 return entry; |
| 177 } | 179 } |
| 178 // If the URL has changed out from under us (as will happen with redirects) | 180 // If the URL has changed out from under us (as will happen with redirects) |
| 179 // return NULL. | 181 // return NULL. |
| 180 return NULL; | 182 return NULL; |
| 181 } | 183 } |
| 182 | 184 |
| 183 void FavIconHelper::OnFavIconDataForInitialURL( | 185 void FavIconHelper::OnFavIconDataForInitialURL( |
| 184 FaviconService::Handle handle, | 186 FaviconService::Handle handle, |
| 185 bool know_favicon, | 187 FaviconService::FaviconData favicon) { |
| 186 scoped_refptr<RefCountedMemory> data, | |
| 187 bool expired, | |
| 188 GURL icon_url) { | |
| 189 NavigationEntry* entry = GetEntry(); | 188 NavigationEntry* entry = GetEntry(); |
| 190 if (!entry) | 189 if (!entry) |
| 191 return; | 190 return; |
| 192 | 191 |
| 193 got_fav_icon_from_history_ = true; | 192 got_fav_icon_from_history_ = true; |
| 194 | 193 |
| 195 fav_icon_expired_ = (know_favicon && expired); | 194 fav_icon_expired_ = (favicon.known_icon && favicon.expired); |
| 196 | 195 |
| 197 if (know_favicon && !entry->favicon().is_valid() && | 196 if (favicon.known_icon && !entry->favicon().is_valid() && |
| 198 (!got_fav_icon_url_ || entry->favicon().url() == icon_url)) { | 197 (!got_fav_icon_url_ || entry->favicon().url() == favicon.icon_url)) { |
| 199 // The db knows the favicon (although it may be out of date) and the entry | 198 // The db knows the favicon (although it may be out of date) and the entry |
| 200 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 199 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
| 201 // to be expired (or the wrong url) we'll fetch later on. This way the | 200 // to be expired (or the wrong url) we'll fetch later on. This way the |
| 202 // user doesn't see a flash of the default favicon. | 201 // user doesn't see a flash of the default favicon. |
| 203 entry->favicon().set_url(icon_url); | 202 entry->favicon().set_url(favicon.icon_url); |
| 204 if (data.get() && data->size()) | 203 if (favicon.image_data.get() && favicon.image_data->size()) |
| 205 UpdateFavIcon(entry, data); | 204 UpdateFavIcon(entry, favicon.image_data); |
| 206 entry->favicon().set_is_valid(true); | 205 entry->favicon().set_is_valid(true); |
| 207 } | 206 } |
| 208 | 207 |
| 209 if (know_favicon && !expired) { | 208 if (favicon.known_icon && !favicon.expired) { |
| 210 if (got_fav_icon_url_ && entry->favicon().url() != icon_url) { | 209 if (got_fav_icon_url_ && entry->favicon().url() != favicon.icon_url) { |
| 211 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will | 210 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will |
| 212 // update the mapping for this url and download the favicon if we don't | 211 // update the mapping for this url and download the favicon if we don't |
| 213 // already have it. | 212 // already have it. |
| 214 DownloadFavIconOrAskHistory(entry); | 213 DownloadFavIconOrAskHistory(entry); |
| 215 } | 214 } |
| 216 } else if (got_fav_icon_url_) { | 215 } else if (got_fav_icon_url_) { |
| 217 // We know the official url for the favicon, by either don't have the | 216 // We know the official url for the favicon, by either don't have the |
| 218 // favicon or its expired. Continue on to DownloadFavIconOrAskHistory to | 217 // favicon or its expired. Continue on to DownloadFavIconOrAskHistory to |
| 219 // either download or check history again. | 218 // either download or check history again. |
| 220 DownloadFavIconOrAskHistory(entry); | 219 DownloadFavIconOrAskHistory(entry); |
| 221 } | 220 } |
| 222 // else we haven't got the icon url. When we get it we'll ask the | 221 // else we haven't got the icon url. When we get it we'll ask the |
| 223 // renderer to download the icon. | 222 // renderer to download the icon. |
| 224 } | 223 } |
| 225 | 224 |
| 226 void FavIconHelper::DownloadFavIconOrAskHistory(NavigationEntry* entry) { | 225 void FavIconHelper::DownloadFavIconOrAskHistory(NavigationEntry* entry) { |
| 227 DCHECK(entry); // We should only get here if entry is valid. | 226 DCHECK(entry); // We should only get here if entry is valid. |
| 228 if (fav_icon_expired_) { | 227 if (fav_icon_expired_) { |
| 229 // We have the mapping, but the favicon is out of date. Download it now. | 228 // We have the mapping, but the favicon is out of date. Download it now. |
| 230 ScheduleDownload(entry->url(), entry->favicon().url(), kFavIconSize, NULL); | 229 ScheduleDownload(entry->url(), entry->favicon().url(), kFavIconSize, NULL); |
| 231 } else if (GetFaviconService()) { | 230 } else if (GetFaviconService()) { |
| 232 // We don't know the favicon, but we may have previously downloaded the | 231 // We don't know the favicon, but we may have previously downloaded the |
| 233 // favicon for another page that shares the same favicon. Ask for the | 232 // favicon for another page that shares the same favicon. Ask for the |
| 234 // favicon given the favicon URL. | 233 // favicon given the favicon URL. |
| 235 if (profile()->IsOffTheRecord()) { | 234 if (profile()->IsOffTheRecord()) { |
| 236 GetFaviconService()->GetFavicon( | 235 GetFaviconService()->GetFavicon( |
| 237 entry->favicon().url(), | 236 entry->favicon().url(), |
| 237 history::FAV_ICON, |
| 238 &cancelable_consumer_, | 238 &cancelable_consumer_, |
| 239 NewCallback(this, &FavIconHelper::OnFavIconData)); | 239 NewCallback(this, &FavIconHelper::OnFavIconData)); |
| 240 } else { | 240 } else { |
| 241 // Ask the history service for the icon. This does two things: | 241 // Ask the history service for the icon. This does two things: |
| 242 // 1. Attempts to fetch the favicon data from the database. | 242 // 1. Attempts to fetch the favicon data from the database. |
| 243 // 2. If the favicon exists in the database, this updates the database to | 243 // 2. If the favicon exists in the database, this updates the database to |
| 244 // include the mapping between the page url and the favicon url. | 244 // include the mapping between the page url and the favicon url. |
| 245 // This is asynchronous. The history service will call back when done. | 245 // This is asynchronous. The history service will call back when done. |
| 246 // Issue the request and associate the current page ID with it. | 246 // Issue the request and associate the current page ID with it. |
| 247 GetFaviconService()->UpdateFaviconMappingAndFetch( | 247 GetFaviconService()->UpdateFaviconMappingAndFetch( |
| 248 entry->url(), | 248 entry->url(), |
| 249 entry->favicon().url(), &cancelable_consumer_, | 249 entry->favicon().url(), |
| 250 history::FAV_ICON, |
| 251 &cancelable_consumer_, |
| 250 NewCallback(this, &FavIconHelper::OnFavIconData)); | 252 NewCallback(this, &FavIconHelper::OnFavIconData)); |
| 251 } | 253 } |
| 252 } | 254 } |
| 253 } | 255 } |
| 254 | 256 |
| 255 void FavIconHelper::OnFavIconData( | 257 void FavIconHelper::OnFavIconData( |
| 256 FaviconService::Handle handle, | 258 FaviconService::Handle handle, |
| 257 bool know_favicon, | 259 FaviconService::FaviconData favicon) { |
| 258 scoped_refptr<RefCountedMemory> data, | |
| 259 bool expired, | |
| 260 GURL icon_url) { | |
| 261 NavigationEntry* entry = GetEntry(); | 260 NavigationEntry* entry = GetEntry(); |
| 262 if (!entry) | 261 if (!entry) |
| 263 return; | 262 return; |
| 264 | 263 |
| 265 // No need to update the favicon url. By the time we get here | 264 // No need to update the favicon url. By the time we get here |
| 266 // UpdateFavIconURL will have set the favicon url. | 265 // UpdateFavIconURL will have set the favicon url. |
| 267 | 266 |
| 268 if (know_favicon && data.get() && data->size()) { | 267 if (favicon.known_icon && favicon.image_data.get() && |
| 268 favicon.image_data->size()) { |
| 269 // There is a favicon, set it now. If expired we'll download the current | 269 // There is a favicon, set it now. If expired we'll download the current |
| 270 // one again, but at least the user will get some icon instead of the | 270 // one again, but at least the user will get some icon instead of the |
| 271 // default and most likely the current one is fine anyway. | 271 // default and most likely the current one is fine anyway. |
| 272 UpdateFavIcon(entry, data); | 272 UpdateFavIcon(entry, favicon.image_data); |
| 273 } | 273 } |
| 274 | 274 |
| 275 if (!know_favicon || expired) { | 275 if (!favicon.known_icon || favicon.expired) { |
| 276 // We don't know the favicon, or it is out of date. Request the current one. | 276 // We don't know the favicon, or it is out of date. Request the current one. |
| 277 ScheduleDownload(entry->url(), entry->favicon().url(), kFavIconSize, NULL); | 277 ScheduleDownload(entry->url(), entry->favicon().url(), kFavIconSize, NULL); |
| 278 } | 278 } |
| 279 } | 279 } |
| 280 | 280 |
| 281 int FavIconHelper::ScheduleDownload(const GURL& url, | 281 int FavIconHelper::ScheduleDownload(const GURL& url, |
| 282 const GURL& image_url, | 282 const GURL& image_url, |
| 283 int image_size, | 283 int image_size, |
| 284 ImageDownloadCallback* callback) { | 284 ImageDownloadCallback* callback) { |
| 285 const int download_id = tab_contents()->render_view_host()->DownloadFavIcon( | 285 const int download_id = tab_contents()->render_view_host()->DownloadFavIcon( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 307 } | 307 } |
| 308 | 308 |
| 309 bool FavIconHelper::ShouldSaveFavicon(const GURL& url) { | 309 bool FavIconHelper::ShouldSaveFavicon(const GURL& url) { |
| 310 if (!profile()->IsOffTheRecord()) | 310 if (!profile()->IsOffTheRecord()) |
| 311 return true; | 311 return true; |
| 312 | 312 |
| 313 // Otherwise store the favicon if the page is bookmarked. | 313 // Otherwise store the favicon if the page is bookmarked. |
| 314 BookmarkModel* bookmark_model = profile()->GetBookmarkModel(); | 314 BookmarkModel* bookmark_model = profile()->GetBookmarkModel(); |
| 315 return bookmark_model && bookmark_model->IsBookmarked(url); | 315 return bookmark_model && bookmark_model->IsBookmarked(url); |
| 316 } | 316 } |
| OLD | NEW |