OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "components/favicon/core/favicon_handler.h" | 5 #include "components/favicon/core/favicon_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 } | 188 } |
189 | 189 |
190 void FaviconHandler::FetchFavicon(const GURL& url) { | 190 void FaviconHandler::FetchFavicon(const GURL& url) { |
191 cancelable_task_tracker_.TryCancelAll(); | 191 cancelable_task_tracker_.TryCancelAll(); |
192 | 192 |
193 url_ = url; | 193 url_ = url; |
194 | 194 |
195 initial_history_result_expired_or_incomplete_ = false; | 195 initial_history_result_expired_or_incomplete_ = false; |
196 redownload_icons_ = false; | 196 redownload_icons_ = false; |
197 got_favicon_from_history_ = false; | 197 got_favicon_from_history_ = false; |
198 download_request_.Cancel(); | 198 manifest_download_request_.Cancel(); |
199 image_download_request_.Cancel(); | |
200 manifest_url_.reset(); | |
199 candidates_.clear(); | 201 candidates_.clear(); |
200 notification_icon_url_ = GURL(); | 202 notification_icon_url_ = GURL(); |
201 notification_icon_type_ = favicon_base::INVALID_ICON; | 203 notification_icon_type_ = favicon_base::INVALID_ICON; |
202 current_candidate_index_ = 0u; | 204 current_candidate_index_ = 0u; |
203 best_favicon_ = DownloadedFavicon(); | 205 best_favicon_ = DownloadedFavicon(); |
204 | 206 |
205 // Request the favicon from the history service. In parallel to this the | 207 // Request the favicon from the history service. In parallel to this the |
206 // renderer is going to notify us (well WebContents) when the favicon url is | 208 // renderer is going to notify us (well WebContents) when the favicon url is |
207 // available. | 209 // available. |
208 if (service_) { | 210 if (service_) { |
(...skipping 28 matching lines...) Expand all Loading... | |
237 best_favicon_.candidate.score; | 239 best_favicon_.candidate.score; |
238 } else { | 240 } else { |
239 return best_favicon_.candidate.score == 1; | 241 return best_favicon_.candidate.score == 1; |
240 } | 242 } |
241 } | 243 } |
242 | 244 |
243 void FaviconHandler::SetFavicon(const GURL& icon_url, | 245 void FaviconHandler::SetFavicon(const GURL& icon_url, |
244 const gfx::Image& image, | 246 const gfx::Image& image, |
245 favicon_base::IconType icon_type) { | 247 favicon_base::IconType icon_type) { |
246 if (service_ && ShouldSaveFavicon()) | 248 if (service_ && ShouldSaveFavicon()) |
247 service_->SetFavicons(url_, icon_url, icon_type, image); | 249 service_->SetFavicons(url_, manifest_url_.value_or(icon_url), icon_type, |
250 image); | |
248 | 251 |
249 NotifyFaviconUpdated(icon_url, icon_type, image); | 252 NotifyFaviconUpdated(icon_url, icon_type, image); |
250 } | 253 } |
251 | 254 |
252 void FaviconHandler::NotifyFaviconUpdated( | 255 void FaviconHandler::NotifyFaviconUpdated( |
253 const std::vector<favicon_base::FaviconRawBitmapResult>& | 256 const std::vector<favicon_base::FaviconRawBitmapResult>& |
254 favicon_bitmap_results) { | 257 favicon_bitmap_results) { |
255 if (favicon_bitmap_results.empty()) | 258 if (favicon_bitmap_results.empty()) |
256 return; | 259 return; |
257 | 260 |
258 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( | 261 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( |
259 favicon_bitmap_results, | 262 favicon_bitmap_results, |
260 favicon_base::GetFaviconScales(), | 263 favicon_base::GetFaviconScales(), |
261 preferred_icon_size()); | 264 preferred_icon_size()); |
262 // The history service sends back results for a single icon URL and icon | 265 // The history service sends back results for a single icon URL and icon |
263 // type, so it does not matter which result we get |icon_url| and |icon_type| | 266 // type, so it does not matter which result we get |icon_url| and |icon_type| |
264 // from. | 267 // from. |
265 const GURL icon_url = favicon_bitmap_results[0].icon_url; | 268 const GURL icon_url = favicon_bitmap_results[0].icon_url; |
266 favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type; | 269 favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type; |
267 NotifyFaviconUpdated(icon_url, icon_type, resized_image); | 270 NotifyFaviconUpdated(icon_url, icon_type, resized_image); |
268 } | 271 } |
269 | 272 |
270 void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url, | 273 void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url, |
271 favicon_base::IconType icon_type, | 274 favicon_base::IconType icon_type, |
272 const gfx::Image& image) { | 275 const gfx::Image& image) { |
273 if (image.IsEmpty()) | 276 if (image.IsEmpty()) |
274 return; | 277 return; |
275 | 278 |
279 // If a manifest is being processed, it's URL overrides the icon URL. | |
280 const GURL& notification_icon_url = manifest_url_.value_or(icon_url); | |
281 | |
276 gfx::Image image_with_adjusted_colorspace = image; | 282 gfx::Image image_with_adjusted_colorspace = image; |
277 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); | 283 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); |
278 | 284 |
279 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, | 285 delegate_->OnFaviconUpdated(url_, handler_type_, notification_icon_url, |
280 icon_url != notification_icon_url_, | 286 notification_icon_url != notification_icon_url_, |
281 image_with_adjusted_colorspace); | 287 image_with_adjusted_colorspace); |
282 | 288 |
283 notification_icon_url_ = icon_url; | 289 notification_icon_url_ = notification_icon_url; |
284 notification_icon_type_ = icon_type; | 290 notification_icon_type_ = icon_type; |
285 } | 291 } |
286 | 292 |
287 void FaviconHandler::OnUpdateFaviconURL( | 293 void FaviconHandler::OnUpdateCandidates( |
288 const GURL& page_url, | 294 const GURL& page_url, |
289 const std::vector<FaviconURL>& candidates) { | 295 const std::vector<FaviconURL>& candidates, |
296 const base::Optional<GURL>& manifest_url) { | |
297 DCHECK_EQ(page_url, url_); | |
290 if (page_url != url_) | 298 if (page_url != url_) |
291 return; | 299 return; |
292 | 300 |
301 // TODO/DONOTSUBMIT(mastiz): Not sure if this is reachable at all: perhaps | |
302 // manifest URL can be specified via Javascript? | |
pkotwicz
2017/04/11 03:47:07
Yes, the manifest URL can be changed via JavaScrip
mastiz
2017/04/11 13:31:01
Ack, thanks. Added a new test.
| |
303 if (manifest_url_ && manifest_url_ == manifest_url) | |
304 return; | |
305 | |
306 manifest_url_ = manifest_url; | |
307 | |
308 // If no manifest available, proceed with the regular candidates only. | |
309 if (!manifest_url.has_value()) { | |
310 OnGotFinalIconURLCandidates(candidates); | |
311 return; | |
312 } | |
313 | |
314 if (redownload_icons_) { | |
pkotwicz
2017/04/11 03:47:07
Do we need to wait till OnFaviconDataForInitialURL
mastiz
2017/04/11 13:31:01
redownload_icons_ can only be true only after OnFa
pkotwicz
2017/04/12 22:10:06
I'd recommend getting rid of this if() statement a
mastiz
2017/04/20 18:06:33
Done.
| |
315 ScheduleManifestDownload(); | |
316 } else { | |
317 // See if there is a cached favicon for the manifest. | |
318 GetFaviconAndUpdateMappingsUnlessIncognito( | |
319 /*icon_url=*/*manifest_url, favicon_base::FAVICON, | |
320 base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService, | |
321 base::Unretained(this))); | |
322 } | |
323 } | |
324 | |
325 void FaviconHandler::OnFaviconDataForManifestFromFaviconService( | |
326 const std::vector<favicon_base::FaviconRawBitmapResult>& | |
327 favicon_bitmap_results) { | |
328 bool has_valid_result = HasValidResult(favicon_bitmap_results); | |
329 bool has_expired_or_incomplete_result = | |
330 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | |
331 favicon_bitmap_results); | |
332 | |
333 if (has_valid_result) { | |
334 // There is a valid favicon. Notify any observers. It is useful to notify | |
335 // the observers even if the favicon is expired or incomplete (incorrect | |
336 // size) because temporarily showing the user an expired favicon or | |
337 // streched favicon is preferable to showing the user the default favicon. | |
338 NotifyFaviconUpdated(favicon_bitmap_results); | |
339 } | |
340 | |
341 if (has_expired_or_incomplete_result) | |
342 ScheduleManifestDownload(); | |
343 } | |
344 | |
345 void FaviconHandler::ScheduleManifestDownload() { | |
346 manifest_download_request_.Reset(base::Bind( | |
347 &FaviconHandler::OnGotFinalIconURLCandidates, base::Unretained(this))); | |
348 // If we download a manifest, make need to bypass the lookups in the favicon | |
349 // cache because the manifest's URL is used as icon URL anyway. | |
350 redownload_icons_ = true; | |
351 delegate_->DownloadManifest(*manifest_url_, | |
352 manifest_download_request_.callback()); | |
pkotwicz
2017/04/11 03:47:07
We need to take into account that the Web Manifest
mastiz
2017/04/11 13:31:01
Done, implemented one proposal for this.
Unless y
pkotwicz
2017/04/12 22:10:06
This is OK for now
| |
353 } | |
354 | |
355 void FaviconHandler::OnGotFinalIconURLCandidates( | |
356 const std::vector<FaviconURL>& candidates) { | |
357 // Mark manifest download as finished, if there was one. | |
358 manifest_download_request_.Cancel(); | |
359 | |
293 std::vector<FaviconCandidate> sorted_candidates; | 360 std::vector<FaviconCandidate> sorted_candidates; |
294 const std::vector<int> desired_pixel_sizes = | 361 const std::vector<int> desired_pixel_sizes = |
295 GetDesiredPixelSizes(handler_type_); | 362 GetDesiredPixelSizes(handler_type_); |
296 for (const FaviconURL& candidate : candidates) { | 363 for (const FaviconURL& candidate : candidates) { |
297 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { | 364 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { |
298 sorted_candidates.push_back( | 365 sorted_candidates.push_back( |
299 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); | 366 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); |
300 } | 367 } |
301 } | 368 } |
302 | 369 |
303 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), | 370 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), |
304 &FaviconCandidate::CompareScore); | 371 &FaviconCandidate::CompareScore); |
305 | 372 |
306 if (candidates_.size() == sorted_candidates.size() && | 373 if (candidates_.size() == sorted_candidates.size() && |
307 std::equal(sorted_candidates.begin(), sorted_candidates.end(), | 374 std::equal(sorted_candidates.begin(), sorted_candidates.end(), |
308 candidates_.begin())) { | 375 candidates_.begin())) { |
309 return; | 376 return; |
310 } | 377 } |
311 | 378 |
312 download_request_.Cancel(); | 379 image_download_request_.Cancel(); |
313 candidates_ = std::move(sorted_candidates); | 380 candidates_ = std::move(sorted_candidates); |
314 current_candidate_index_ = 0u; | 381 current_candidate_index_ = 0u; |
315 best_favicon_ = DownloadedFavicon(); | 382 best_favicon_ = DownloadedFavicon(); |
316 | 383 |
317 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 384 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
318 // This appears to be what FF does as well. | 385 // This appears to be what FF does as well. |
319 if (current_candidate() && got_favicon_from_history_) | 386 if (current_candidate() && got_favicon_from_history_) |
320 OnGotInitialHistoryDataAndIconURLCandidates(); | 387 OnGotInitialHistoryDataAndIconURLCandidates(); |
321 } | 388 } |
322 | 389 |
(...skipping 25 matching lines...) Expand all Loading... | |
348 } | 415 } |
349 | 416 |
350 void FaviconHandler::OnDidDownloadFavicon( | 417 void FaviconHandler::OnDidDownloadFavicon( |
351 favicon_base::IconType icon_type, | 418 favicon_base::IconType icon_type, |
352 int id, | 419 int id, |
353 int http_status_code, | 420 int http_status_code, |
354 const GURL& image_url, | 421 const GURL& image_url, |
355 const std::vector<SkBitmap>& bitmaps, | 422 const std::vector<SkBitmap>& bitmaps, |
356 const std::vector<gfx::Size>& original_bitmap_sizes) { | 423 const std::vector<gfx::Size>& original_bitmap_sizes) { |
357 // Mark download as finished. | 424 // Mark download as finished. |
358 download_request_.Cancel(); | 425 image_download_request_.Cancel(); |
359 | 426 |
360 if (bitmaps.empty() && http_status_code == 404) { | 427 if (bitmaps.empty() && http_status_code == 404) { |
361 DVLOG(1) << "Failed to Download Favicon:" << image_url; | 428 DVLOG(1) << "Failed to Download Favicon:" << image_url; |
362 if (service_) | 429 if (service_) |
363 service_->UnableToDownloadFavicon(image_url); | 430 service_->UnableToDownloadFavicon(image_url); |
364 } | 431 } |
365 | 432 |
366 bool request_next_icon = true; | 433 bool request_next_icon = true; |
367 if (!bitmaps.empty()) { | 434 if (!bitmaps.empty()) { |
368 float score = 0.0f; | 435 float score = 0.0f; |
(...skipping 27 matching lines...) Expand all Loading... | |
396 | 463 |
397 if (request_next_icon && current_candidate_index_ + 1 < candidates_.size()) { | 464 if (request_next_icon && current_candidate_index_ + 1 < candidates_.size()) { |
398 // Process the next candidate. | 465 // Process the next candidate. |
399 ++current_candidate_index_; | 466 ++current_candidate_index_; |
400 DownloadCurrentCandidateOrAskFaviconService(); | 467 DownloadCurrentCandidateOrAskFaviconService(); |
401 } else { | 468 } else { |
402 // We have either found the ideal candidate or run out of candidates. | 469 // We have either found the ideal candidate or run out of candidates. |
403 if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { | 470 if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { |
404 // No more icons to request, set the favicon from the candidate. | 471 // No more icons to request, set the favicon from the candidate. |
405 SetFavicon(best_favicon_.candidate.icon_url, best_favicon_.image, | 472 SetFavicon(best_favicon_.candidate.icon_url, best_favicon_.image, |
406 best_favicon_.candidate.icon_type); | 473 best_favicon_.candidate.icon_type); |
pkotwicz
2017/04/11 03:47:07
If the |icon_url| is from the Web Manifest, we hav
mastiz
2017/04/11 13:31:01
This is implemented inside SetFavicon and NotifyFa
pkotwicz
2017/04/12 22:10:06
I think that it is clearer if you pass the correct
mastiz
2017/04/20 18:06:33
Done.
pkotwicz
2017/04/24 14:42:14
It looks like there is still the manifest_url_.val
mastiz
2017/04/27 13:54:50
There's at least one codepath (via OnFaviconDataFo
pkotwicz
2017/05/01 04:56:53
When NotifyFaviconUpdated() is called as a result
mastiz
2017/05/04 10:57:53
You're right, thanks. Done.
| |
407 } | 474 } |
408 // Clear download related state. | 475 // Clear download related state. |
409 current_candidate_index_ = candidates_.size(); | 476 current_candidate_index_ = candidates_.size(); |
410 best_favicon_ = DownloadedFavicon(); | 477 best_favicon_ = DownloadedFavicon(); |
411 } | 478 } |
412 } | 479 } |
413 | 480 |
414 const std::vector<GURL> FaviconHandler::GetIconURLs() const { | 481 const std::vector<GURL> FaviconHandler::GetIconURLs() const { |
415 std::vector<GURL> icon_urls; | 482 std::vector<GURL> icon_urls; |
416 for (const FaviconCandidate& candidate : candidates_) | 483 for (const FaviconCandidate& candidate : candidates_) |
417 icon_urls.push_back(candidate.icon_url); | 484 icon_urls.push_back(candidate.icon_url); |
418 return icon_urls; | 485 return icon_urls; |
419 } | 486 } |
420 | 487 |
421 bool FaviconHandler::HasPendingTasksForTest() { | 488 bool FaviconHandler::HasPendingTasksForTest() { |
422 return !download_request_.IsCancelled() || | 489 return !manifest_download_request_.IsCancelled() || |
490 !image_download_request_.IsCancelled() || | |
423 cancelable_task_tracker_.HasTrackedTasks(); | 491 cancelable_task_tracker_.HasTrackedTasks(); |
424 } | 492 } |
425 | 493 |
426 bool FaviconHandler::ShouldSaveFavicon() { | 494 bool FaviconHandler::ShouldSaveFavicon() { |
427 if (!delegate_->IsOffTheRecord()) | 495 if (!delegate_->IsOffTheRecord()) |
428 return true; | 496 return true; |
429 | 497 |
430 // Always save favicon if the page is bookmarked. | 498 // Always save favicon if the page is bookmarked. |
431 return delegate_->IsBookmarked(url_); | 499 return delegate_->IsBookmarked(url_); |
432 } | 500 } |
433 | 501 |
434 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 502 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
435 const std::vector<favicon_base::FaviconRawBitmapResult>& | 503 const std::vector<favicon_base::FaviconRawBitmapResult>& |
436 favicon_bitmap_results) { | 504 favicon_bitmap_results) { |
437 got_favicon_from_history_ = true; | 505 got_favicon_from_history_ = true; |
438 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 506 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
439 initial_history_result_expired_or_incomplete_ = | 507 initial_history_result_expired_or_incomplete_ = |
440 !has_valid_result || | 508 !has_valid_result || |
441 HasExpiredOrIncompleteResult(preferred_icon_size(), | 509 HasExpiredOrIncompleteResult(preferred_icon_size(), |
442 favicon_bitmap_results); | 510 favicon_bitmap_results); |
443 redownload_icons_ = initial_history_result_expired_or_incomplete_ && | 511 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
444 !favicon_bitmap_results.empty(); | 512 !favicon_bitmap_results.empty(); |
445 | 513 |
446 if (has_valid_result && (!current_candidate() || | 514 if (has_valid_result && (!current_candidate() || |
447 DoUrlsAndIconsMatch(current_candidate()->icon_url, | 515 DoUrlsAndIconsMatch(current_candidate()->icon_url, |
448 current_candidate()->icon_type, | 516 current_candidate()->icon_type, |
449 favicon_bitmap_results))) { | 517 favicon_bitmap_results))) { |
pkotwicz
2017/04/11 03:47:07
We should trigger this if() statement if the "data
mastiz
2017/04/11 13:31:01
This situation would cause current_candidate() ==
| |
450 // The db knows the favicon (although it may be out of date) and the entry | 518 // The db knows the favicon (although it may be out of date) and the entry |
451 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 519 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
452 // to be expired (or the wrong url) we'll fetch later on. This way the | 520 // to be expired (or the wrong url) we'll fetch later on. This way the |
453 // user doesn't see a flash of the default favicon. | 521 // user doesn't see a flash of the default favicon. |
454 NotifyFaviconUpdated(favicon_bitmap_results); | 522 NotifyFaviconUpdated(favicon_bitmap_results); |
455 } | 523 } |
456 | 524 |
457 if (current_candidate()) | 525 if (current_candidate()) |
458 OnGotInitialHistoryDataAndIconURLCandidates(); | 526 OnGotInitialHistoryDataAndIconURLCandidates(); |
459 } | 527 } |
460 | 528 |
461 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 529 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
462 GURL icon_url = current_candidate()->icon_url; | 530 const GURL icon_url = current_candidate()->icon_url; |
463 favicon_base::IconType icon_type = current_candidate()->icon_type; | 531 const favicon_base::IconType icon_type = current_candidate()->icon_type; |
464 | |
465 if (redownload_icons_) { | 532 if (redownload_icons_) { |
466 // We have the mapping, but the favicon is out of date. Download it now. | 533 // We have the mapping, but the favicon is out of date. Download it now. |
467 ScheduleDownload(icon_url, icon_type); | 534 ScheduleFaviconDownload(icon_url, icon_type); |
468 } else if (service_) { | 535 } else { |
469 // We don't know the favicon, but we may have previously downloaded the | 536 GetFaviconAndUpdateMappingsUnlessIncognito( |
470 // favicon for another page that shares the same favicon. Ask for the | 537 icon_url, icon_type, |
471 // favicon given the favicon URL. | 538 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this))); |
472 if (delegate_->IsOffTheRecord()) { | |
473 service_->GetFavicon( | |
474 icon_url, icon_type, preferred_icon_size(), | |
475 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | |
476 &cancelable_task_tracker_); | |
477 } else { | |
478 // Ask the history service for the icon. This does two things: | |
479 // 1. Attempts to fetch the favicon data from the database. | |
480 // 2. If the favicon exists in the database, this updates the database to | |
481 // include the mapping between the page url and the favicon url. | |
482 // This is asynchronous. The history service will call back when done. | |
483 // TODO(pkotwicz): pass in all of |image_urls_| to | |
484 // UpdateFaviconMappingsAndFetch(). | |
485 service_->UpdateFaviconMappingsAndFetch( | |
486 url_, {icon_url}, icon_type, preferred_icon_size(), | |
487 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | |
488 &cancelable_task_tracker_); | |
489 } | |
490 } | 539 } |
491 } | 540 } |
492 | 541 |
542 void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito( | |
543 const GURL& icon_url, | |
544 favicon_base::IconType icon_type, | |
545 const favicon_base::FaviconResultsCallback& callback) { | |
546 if (!service_) | |
547 return; | |
548 | |
549 // We don't know the favicon, but we may have previously downloaded the | |
550 // favicon for another page that shares the same favicon. Ask for the | |
551 // favicon given the favicon URL. | |
552 if (delegate_->IsOffTheRecord()) { | |
553 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback, | |
554 &cancelable_task_tracker_); | |
555 } else { | |
556 // Ask the history service for the icon. This does two things: | |
557 // 1. Attempts to fetch the favicon data from the database. | |
558 // 2. If the favicon exists in the database, this updates the database to | |
559 // include the mapping between the page url and the favicon url. | |
560 // This is asynchronous. The history service will call back when done. | |
561 // TODO(pkotwicz): pass in all of |image_urls_| to | |
562 // UpdateFaviconMappingsAndFetch(). | |
563 service_->UpdateFaviconMappingsAndFetch(url_, {icon_url}, icon_type, | |
564 preferred_icon_size(), callback, | |
565 &cancelable_task_tracker_); | |
566 } | |
567 } | |
568 | |
493 void FaviconHandler::OnFaviconData(const std::vector< | 569 void FaviconHandler::OnFaviconData(const std::vector< |
494 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 570 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
495 bool has_results = !favicon_bitmap_results.empty(); | 571 bool has_results = !favicon_bitmap_results.empty(); |
496 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 572 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
497 bool has_expired_or_incomplete_result = | 573 bool has_expired_or_incomplete_result = |
498 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | 574 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
499 favicon_bitmap_results); | 575 favicon_bitmap_results); |
500 | 576 |
501 if (has_valid_result) { | 577 if (has_valid_result) { |
502 // There is a valid favicon. Notify any observers. It is useful to notify | 578 // There is a valid favicon. Notify any observers. It is useful to notify |
503 // the observers even if the favicon is expired or incomplete (incorrect | 579 // the observers even if the favicon is expired or incomplete (incorrect |
504 // size) because temporarily showing the user an expired favicon or | 580 // size) because temporarily showing the user an expired favicon or |
505 // streched favicon is preferable to showing the user the default favicon. | 581 // streched favicon is preferable to showing the user the default favicon. |
506 NotifyFaviconUpdated(favicon_bitmap_results); | 582 NotifyFaviconUpdated(favicon_bitmap_results); |
507 } | 583 } |
508 | 584 |
509 if (!current_candidate() || | 585 if (!current_candidate() || |
510 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, | 586 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, |
511 current_candidate()->icon_type, | 587 current_candidate()->icon_type, |
512 favicon_bitmap_results))) { | 588 favicon_bitmap_results))) { |
513 // The icon URLs have been updated since the favicon data was requested. | 589 // The icon URLs have been updated since the favicon data was requested. |
590 NOTREACHED(); // DONOTSUBMIT | |
514 return; | 591 return; |
515 } | 592 } |
516 | 593 |
517 if (has_expired_or_incomplete_result) { | 594 if (has_expired_or_incomplete_result) { |
518 ScheduleDownload(current_candidate()->icon_url, | 595 ScheduleFaviconDownload(current_candidate()->icon_url, |
519 current_candidate()->icon_type); | 596 current_candidate()->icon_type); |
520 } | 597 } |
521 } | 598 } |
522 | 599 |
523 void FaviconHandler::ScheduleDownload(const GURL& image_url, | 600 void FaviconHandler::ScheduleFaviconDownload(const GURL& image_url, |
524 favicon_base::IconType icon_type) { | 601 favicon_base::IconType icon_type) { |
525 DCHECK(image_url.is_valid()); | 602 DCHECK(image_url.is_valid()); |
526 // Note that CancelableCallback starts cancelled. | 603 // Note that CancelableCallback starts cancelled. |
527 DCHECK(download_request_.IsCancelled()) << "More than one ongoing download"; | 604 DCHECK(image_download_request_.IsCancelled()) |
605 << "More than one ongoing download"; | |
528 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { | 606 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { |
529 DVLOG(1) << "Skip Failed FavIcon: " << image_url; | 607 DVLOG(1) << "Skip Failed FavIcon: " << image_url; |
530 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), | 608 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), |
531 std::vector<gfx::Size>()); | 609 std::vector<gfx::Size>()); |
532 return; | 610 return; |
533 } | 611 } |
534 download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, | 612 image_download_request_.Reset( |
535 base::Unretained(this), icon_type)); | 613 base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), |
614 icon_type)); | |
536 // A max bitmap size is specified to avoid receiving huge bitmaps in | 615 // A max bitmap size is specified to avoid receiving huge bitmaps in |
537 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 616 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
538 // for more details about the max bitmap size. | 617 // for more details about the max bitmap size. |
539 const int download_id = | 618 const int download_id = |
540 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), | 619 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), |
541 download_request_.callback()); | 620 image_download_request_.callback()); |
542 DCHECK_NE(download_id, 0); | 621 DCHECK_NE(download_id, 0); |
543 } | 622 } |
544 | 623 |
545 } // namespace favicon | 624 } // namespace favicon |
OLD | NEW |