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 |
pkotwicz
2017/04/12 22:10:06
Shouldn't the TOUCH_LARGEST FaviconHandler complet
mastiz
2017/04/20 18:06:33
This happens in upper layers: the manifest URL is
pkotwicz
2017/04/24 14:42:14
I see. This is done in FaviconDriverImpl
| |
301 // |candidates| or |manifest_url| could have been modified via Javascript. | |
302 if (manifest_url_ && manifest_url_ == manifest_url) | |
303 return; | |
304 | |
305 manifest_url_ = manifest_url; | |
306 non_manifest_original_candidates_ = candidates; | |
307 | |
308 // Check if the manifest previously returned a 404 (or a 200 but contained no | |
309 // icons), and ignore the manifest URL if that's the case. | |
310 if (manifest_url_ && service_ && | |
311 service_->WasUnableToDownloadFavicon(*manifest_url_)) { | |
312 DVLOG(1) << "Skip failed Manifest: " << *manifest_url_; | |
313 manifest_url_.reset(); | |
314 } | |
315 | |
316 // If no manifest available, proceed with the regular candidates only. | |
317 if (!manifest_url_) { | |
318 OnGotFinalIconURLCandidates(candidates); | |
319 return; | |
320 } | |
321 | |
322 if (redownload_icons_) { | |
323 // Note that |redownload_icons_| can only be true after the database lookup | |
324 // for the page URL is completed. | |
325 ScheduleManifestDownload(); | |
326 } else { | |
327 // See if there is a cached favicon for the manifest. | |
328 GetFaviconAndUpdateMappingsUnlessIncognito( | |
329 /*icon_url=*/*manifest_url_, favicon_base::FAVICON, | |
330 base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService, | |
331 base::Unretained(this))); | |
332 } | |
333 } | |
334 | |
335 void FaviconHandler::OnFaviconDataForManifestFromFaviconService( | |
336 const std::vector<favicon_base::FaviconRawBitmapResult>& | |
337 favicon_bitmap_results) { | |
338 bool has_valid_result = HasValidResult(favicon_bitmap_results); | |
339 bool has_expired_or_incomplete_result = | |
340 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | |
341 favicon_bitmap_results); | |
342 | |
343 if (has_valid_result) { | |
344 // There is a valid favicon. Notify any observers. It is useful to notify | |
345 // the observers even if the favicon is expired or incomplete (incorrect | |
346 // size) because temporarily showing the user an expired favicon or | |
347 // streched favicon is preferable to showing the user the default favicon. | |
348 NotifyFaviconUpdated(favicon_bitmap_results); | |
349 } | |
350 | |
351 if (has_expired_or_incomplete_result) | |
352 ScheduleManifestDownload(); | |
353 } | |
354 | |
355 void FaviconHandler::ScheduleManifestDownload() { | |
356 manifest_download_request_.Reset(base::Bind( | |
357 &FaviconHandler::OnDidDownloadManifest, base::Unretained(this))); | |
358 delegate_->DownloadManifest(*manifest_url_, | |
359 manifest_download_request_.callback()); | |
360 } | |
361 | |
362 void FaviconHandler::OnDidDownloadManifest( | |
363 int status_code, | |
364 const std::vector<FaviconURL>& candidates) { | |
365 // Mark manifest download as finished. | |
366 manifest_download_request_.Cancel(); | |
367 | |
368 if (!candidates.empty()) { | |
369 DCHECK(status_code == 200); | |
pkotwicz
2017/04/12 22:10:06
Why the DCHECK() ?
mastiz
2017/04/20 18:06:33
To add clarity, but I realize you're not a big fan
| |
370 OnGotFinalIconURLCandidates(candidates); | |
pkotwicz
2017/04/12 22:10:07
You want to return here?
mastiz
2017/04/20 18:06:33
Correct, done (btw tests were failing due to this)
| |
371 } | |
372 | |
373 // If either the downloading of the manifest failed, OR the manifest contains | |
374 // no icons, proceed with the list of icons listed in the HTML. | |
375 DVLOG(1) << "Could not fetch Manifest icons from " << *manifest_url_ | |
376 << ", falling back to inlined ones, which are " | |
377 << non_manifest_original_candidates_.size(); | |
378 | |
379 if (service_ && (status_code == 404 || status_code == 200)) | |
pkotwicz
2017/04/12 22:10:07
Why is this if() checking the status code?
mastiz
2017/04/20 18:06:33
We shouldn't call UnableToDownloadFavicon() for al
pkotwicz
2017/04/24 14:42:15
Perhaps FaviconHandler::OnDidDownloadManifest() sh
mastiz
2017/04/27 13:54:50
How would that distinguish a 404 from 503?
pkotwicz
2017/05/01 04:56:53
I suggest doing this:
if (status_code == 404 || (
mastiz
2017/05/04 10:57:53
Would that work for a manifest that returns a 200
pkotwicz
2017/05/04 17:28:24
Black listing anything other than 5xx sounds reaso
mastiz
2017/05/10 10:03:51
Done.
pkotwicz
2017/05/12 06:13:28
Did you forget to upload a patch set. There does n
mastiz
2017/05/12 13:31:32
This was done previously but I've reverted it (in
pkotwicz
2017/05/12 15:37:41
Fair enough. You will need to delete the tests whi
mastiz
2017/05/15 14:06:59
404 behavior hasn't changed, only 5xx. That is, an
pkotwicz
2017/05/16 06:36:34
Ok, I see now
| |
380 service_->UnableToDownloadFavicon(*manifest_url_); | |
pkotwicz
2017/04/12 22:10:07
If we end up download the Web Manifest on each pag
mastiz
2017/04/20 18:06:33
If we were to always load and parse manifests, thi
pkotwicz
2017/04/24 14:42:15
It might not be that nice because:
- Web Manifest
mastiz
2017/04/27 13:54:50
Acknowledged, makes sense. We'd need to see how th
| |
381 | |
382 manifest_url_.reset(); | |
383 OnGotFinalIconURLCandidates(non_manifest_original_candidates_); | |
384 } | |
385 | |
386 void FaviconHandler::OnGotFinalIconURLCandidates( | |
387 const std::vector<FaviconURL>& candidates) { | |
293 std::vector<FaviconCandidate> sorted_candidates; | 388 std::vector<FaviconCandidate> sorted_candidates; |
294 const std::vector<int> desired_pixel_sizes = | 389 const std::vector<int> desired_pixel_sizes = |
295 GetDesiredPixelSizes(handler_type_); | 390 GetDesiredPixelSizes(handler_type_); |
296 for (const FaviconURL& candidate : candidates) { | 391 for (const FaviconURL& candidate : candidates) { |
297 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { | 392 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { |
298 sorted_candidates.push_back( | 393 sorted_candidates.push_back( |
299 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); | 394 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); |
300 } | 395 } |
301 } | 396 } |
302 | 397 |
303 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), | 398 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), |
304 &FaviconCandidate::CompareScore); | 399 &FaviconCandidate::CompareScore); |
305 | 400 |
306 if (candidates_.size() == sorted_candidates.size() && | 401 if (candidates_.size() == sorted_candidates.size() && |
307 std::equal(sorted_candidates.begin(), sorted_candidates.end(), | 402 std::equal(sorted_candidates.begin(), sorted_candidates.end(), |
308 candidates_.begin())) { | 403 candidates_.begin())) { |
309 return; | 404 return; |
310 } | 405 } |
311 | 406 |
312 download_request_.Cancel(); | 407 image_download_request_.Cancel(); |
313 candidates_ = std::move(sorted_candidates); | 408 candidates_ = std::move(sorted_candidates); |
314 current_candidate_index_ = 0u; | 409 current_candidate_index_ = 0u; |
315 best_favicon_ = DownloadedFavicon(); | 410 best_favicon_ = DownloadedFavicon(); |
316 | 411 |
317 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 412 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
318 // This appears to be what FF does as well. | 413 // This appears to be what FF does as well. |
319 if (current_candidate() && got_favicon_from_history_) | 414 if (current_candidate() && got_favicon_from_history_) |
320 OnGotInitialHistoryDataAndIconURLCandidates(); | 415 OnGotInitialHistoryDataAndIconURLCandidates(); |
321 } | 416 } |
322 | 417 |
(...skipping 25 matching lines...) Expand all Loading... | |
348 } | 443 } |
349 | 444 |
350 void FaviconHandler::OnDidDownloadFavicon( | 445 void FaviconHandler::OnDidDownloadFavicon( |
351 favicon_base::IconType icon_type, | 446 favicon_base::IconType icon_type, |
352 int id, | 447 int id, |
353 int http_status_code, | 448 int http_status_code, |
354 const GURL& image_url, | 449 const GURL& image_url, |
355 const std::vector<SkBitmap>& bitmaps, | 450 const std::vector<SkBitmap>& bitmaps, |
356 const std::vector<gfx::Size>& original_bitmap_sizes) { | 451 const std::vector<gfx::Size>& original_bitmap_sizes) { |
357 // Mark download as finished. | 452 // Mark download as finished. |
358 download_request_.Cancel(); | 453 image_download_request_.Cancel(); |
359 | 454 |
360 if (bitmaps.empty() && http_status_code == 404) { | 455 if (bitmaps.empty() && http_status_code == 404) { |
361 DVLOG(1) << "Failed to Download Favicon:" << image_url; | 456 DVLOG(1) << "Failed to Download Favicon:" << image_url; |
362 if (service_) | 457 if (service_) |
363 service_->UnableToDownloadFavicon(image_url); | 458 service_->UnableToDownloadFavicon(image_url); |
364 } | 459 } |
365 | 460 |
366 bool request_next_icon = true; | 461 bool request_next_icon = true; |
367 if (!bitmaps.empty()) { | 462 if (!bitmaps.empty()) { |
368 float score = 0.0f; | 463 float score = 0.0f; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 } | 507 } |
413 | 508 |
414 const std::vector<GURL> FaviconHandler::GetIconURLs() const { | 509 const std::vector<GURL> FaviconHandler::GetIconURLs() const { |
415 std::vector<GURL> icon_urls; | 510 std::vector<GURL> icon_urls; |
416 for (const FaviconCandidate& candidate : candidates_) | 511 for (const FaviconCandidate& candidate : candidates_) |
417 icon_urls.push_back(candidate.icon_url); | 512 icon_urls.push_back(candidate.icon_url); |
418 return icon_urls; | 513 return icon_urls; |
419 } | 514 } |
420 | 515 |
421 bool FaviconHandler::HasPendingTasksForTest() { | 516 bool FaviconHandler::HasPendingTasksForTest() { |
422 return !download_request_.IsCancelled() || | 517 return !manifest_download_request_.IsCancelled() || |
518 !image_download_request_.IsCancelled() || | |
423 cancelable_task_tracker_.HasTrackedTasks(); | 519 cancelable_task_tracker_.HasTrackedTasks(); |
424 } | 520 } |
425 | 521 |
426 bool FaviconHandler::ShouldSaveFavicon() { | 522 bool FaviconHandler::ShouldSaveFavicon() { |
427 if (!delegate_->IsOffTheRecord()) | 523 if (!delegate_->IsOffTheRecord()) |
428 return true; | 524 return true; |
429 | 525 |
430 // Always save favicon if the page is bookmarked. | 526 // Always save favicon if the page is bookmarked. |
431 return delegate_->IsBookmarked(url_); | 527 return delegate_->IsBookmarked(url_); |
432 } | 528 } |
433 | 529 |
434 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 530 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
435 const std::vector<favicon_base::FaviconRawBitmapResult>& | 531 const std::vector<favicon_base::FaviconRawBitmapResult>& |
436 favicon_bitmap_results) { | 532 favicon_bitmap_results) { |
437 got_favicon_from_history_ = true; | 533 got_favicon_from_history_ = true; |
438 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 534 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
439 initial_history_result_expired_or_incomplete_ = | 535 initial_history_result_expired_or_incomplete_ = |
440 !has_valid_result || | 536 !has_valid_result || |
441 HasExpiredOrIncompleteResult(preferred_icon_size(), | 537 HasExpiredOrIncompleteResult(preferred_icon_size(), |
442 favicon_bitmap_results); | 538 favicon_bitmap_results); |
443 redownload_icons_ = initial_history_result_expired_or_incomplete_ && | 539 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
444 !favicon_bitmap_results.empty(); | 540 !favicon_bitmap_results.empty(); |
445 | 541 |
446 if (has_valid_result && (!current_candidate() || | 542 if (has_valid_result && (!current_candidate() || |
447 DoUrlsAndIconsMatch(current_candidate()->icon_url, | 543 DoUrlsAndIconsMatch(current_candidate()->icon_url, |
448 current_candidate()->icon_type, | 544 current_candidate()->icon_type, |
449 favicon_bitmap_results))) { | 545 favicon_bitmap_results))) { |
pkotwicz
2017/04/12 22:10:06
I think that this should be changed to:
if (has_v
mastiz
2017/04/20 18:06:33
Done.
| |
450 // The db knows the favicon (although it may be out of date) and the entry | 546 // 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 | 547 // 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 | 548 // 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. | 549 // user doesn't see a flash of the default favicon. |
454 NotifyFaviconUpdated(favicon_bitmap_results); | 550 NotifyFaviconUpdated(favicon_bitmap_results); |
455 } | 551 } |
456 | 552 |
457 if (current_candidate()) | 553 if (current_candidate()) |
458 OnGotInitialHistoryDataAndIconURLCandidates(); | 554 OnGotInitialHistoryDataAndIconURLCandidates(); |
459 } | 555 } |
460 | 556 |
461 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 557 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
462 GURL icon_url = current_candidate()->icon_url; | 558 const GURL icon_url = current_candidate()->icon_url; |
463 favicon_base::IconType icon_type = current_candidate()->icon_type; | 559 const favicon_base::IconType icon_type = current_candidate()->icon_type; |
464 | 560 // If the icons listed in a manifest are being processed, skip the cache |
465 if (redownload_icons_) { | 561 // lookup for |icon_url| since the manifest's URL is used for caching anyway, |
562 // and this lookup has happened earlier. | |
563 if (redownload_icons_ || manifest_url_) { | |
466 // We have the mapping, but the favicon is out of date. Download it now. | 564 // We have the mapping, but the favicon is out of date. Download it now. |
467 ScheduleDownload(icon_url, icon_type); | 565 ScheduleFaviconDownload(icon_url, icon_type); |
468 } else if (service_) { | 566 } else { |
469 // We don't know the favicon, but we may have previously downloaded the | 567 GetFaviconAndUpdateMappingsUnlessIncognito( |
470 // favicon for another page that shares the same favicon. Ask for the | 568 icon_url, icon_type, |
471 // favicon given the favicon URL. | 569 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 } | 570 } |
491 } | 571 } |
492 | 572 |
573 void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito( | |
574 const GURL& icon_url, | |
575 favicon_base::IconType icon_type, | |
576 const favicon_base::FaviconResultsCallback& callback) { | |
577 if (!service_) | |
578 return; | |
579 | |
580 // We don't know the favicon, but we may have previously downloaded the | |
581 // favicon for another page that shares the same favicon. Ask for the | |
582 // favicon given the favicon URL. | |
583 if (delegate_->IsOffTheRecord()) { | |
584 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback, | |
585 &cancelable_task_tracker_); | |
586 } else { | |
587 // Ask the history service for the icon. This does two things: | |
588 // 1. Attempts to fetch the favicon data from the database. | |
589 // 2. If the favicon exists in the database, this updates the database to | |
590 // include the mapping between the page url and the favicon url. | |
591 // This is asynchronous. The history service will call back when done. | |
592 // TODO(pkotwicz): pass in all of |image_urls_| to | |
593 // UpdateFaviconMappingsAndFetch(). | |
594 service_->UpdateFaviconMappingsAndFetch(url_, {icon_url}, icon_type, | |
595 preferred_icon_size(), callback, | |
596 &cancelable_task_tracker_); | |
597 } | |
598 } | |
599 | |
493 void FaviconHandler::OnFaviconData(const std::vector< | 600 void FaviconHandler::OnFaviconData(const std::vector< |
494 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 601 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
495 bool has_results = !favicon_bitmap_results.empty(); | 602 bool has_results = !favicon_bitmap_results.empty(); |
496 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 603 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
497 bool has_expired_or_incomplete_result = | 604 bool has_expired_or_incomplete_result = |
498 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | 605 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
499 favicon_bitmap_results); | 606 favicon_bitmap_results); |
500 | 607 |
501 if (has_valid_result) { | 608 if (has_valid_result) { |
502 // There is a valid favicon. Notify any observers. It is useful to notify | 609 // 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 | 610 // the observers even if the favicon is expired or incomplete (incorrect |
504 // size) because temporarily showing the user an expired favicon or | 611 // size) because temporarily showing the user an expired favicon or |
505 // streched favicon is preferable to showing the user the default favicon. | 612 // streched favicon is preferable to showing the user the default favicon. |
506 NotifyFaviconUpdated(favicon_bitmap_results); | 613 NotifyFaviconUpdated(favicon_bitmap_results); |
507 } | 614 } |
508 | 615 |
509 if (!current_candidate() || | 616 if (!current_candidate() || |
510 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, | 617 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, |
511 current_candidate()->icon_type, | 618 current_candidate()->icon_type, |
512 favicon_bitmap_results))) { | 619 favicon_bitmap_results))) { |
513 // The icon URLs have been updated since the favicon data was requested. | 620 // The icon URLs have been updated since the favicon data was requested. |
621 NOTREACHED(); // DONOTSUBMIT | |
514 return; | 622 return; |
515 } | 623 } |
516 | 624 |
517 if (has_expired_or_incomplete_result) { | 625 if (has_expired_or_incomplete_result) { |
518 ScheduleDownload(current_candidate()->icon_url, | 626 ScheduleFaviconDownload(current_candidate()->icon_url, |
519 current_candidate()->icon_type); | 627 current_candidate()->icon_type); |
520 } | 628 } |
521 } | 629 } |
522 | 630 |
523 void FaviconHandler::ScheduleDownload(const GURL& image_url, | 631 void FaviconHandler::ScheduleFaviconDownload(const GURL& image_url, |
524 favicon_base::IconType icon_type) { | 632 favicon_base::IconType icon_type) { |
525 DCHECK(image_url.is_valid()); | 633 DCHECK(image_url.is_valid()); |
526 // Note that CancelableCallback starts cancelled. | 634 // Note that CancelableCallback starts cancelled. |
527 DCHECK(download_request_.IsCancelled()) << "More than one ongoing download"; | 635 DCHECK(image_download_request_.IsCancelled()) |
636 << "More than one ongoing download"; | |
528 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { | 637 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { |
529 DVLOG(1) << "Skip Failed FavIcon: " << image_url; | 638 DVLOG(1) << "Skip Failed FavIcon: " << image_url; |
530 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), | 639 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), |
531 std::vector<gfx::Size>()); | 640 std::vector<gfx::Size>()); |
532 return; | 641 return; |
533 } | 642 } |
534 download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, | 643 image_download_request_.Reset( |
535 base::Unretained(this), icon_type)); | 644 base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), |
645 icon_type)); | |
536 // A max bitmap size is specified to avoid receiving huge bitmaps in | 646 // A max bitmap size is specified to avoid receiving huge bitmaps in |
537 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 647 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
538 // for more details about the max bitmap size. | 648 // for more details about the max bitmap size. |
539 const int download_id = | 649 const int download_id = |
540 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), | 650 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), |
541 download_request_.callback()); | 651 image_download_request_.callback()); |
542 DCHECK_NE(download_id, 0); | 652 DCHECK_NE(download_id, 0); |
543 } | 653 } |
544 | 654 |
545 } // namespace favicon | 655 } // namespace favicon |
OLD | NEW |