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
3 // found in the LICENSE file.
5 #include "base/memory/scoped_ptr.h"
6 #include "chrome/browser/favicon/favicon_handler.h"
7 #include "chrome/browser/favicon/favicon_service_factory.h"
8 #include "chrome/browser/history/history_service_factory.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
11 #include "content/public/browser/favicon_status.h"
12 #include "content/public/browser/invalidate_type.h"
13 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/web_contents.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "ui/gfx/codec/png_codec.h"
17 #include "ui/gfx/favicon_size.h"
18 #include "ui/gfx/image/image.h"
20 class TestFaviconHandler
;
22 using content::FaviconURL
;
23 using content::NavigationEntry
;
24 using content::WebContents
;
28 // Fill the given bmp with valid png data.
29 void FillDataToBitmap(int w
, int h
, SkBitmap
* bmp
) {
30 bmp
->setConfig(SkBitmap::kARGB_8888_Config
, w
, h
);
33 unsigned char* src_data
=
34 reinterpret_cast<unsigned char*>(bmp
->getAddr32(0, 0));
35 for (int i
= 0; i
< w
* h
; i
++) {
36 src_data
[i
* 4 + 0] = static_cast<unsigned char>(i
% 255);
37 src_data
[i
* 4 + 1] = static_cast<unsigned char>(i
% 255);
38 src_data
[i
* 4 + 2] = static_cast<unsigned char>(i
% 255);
39 src_data
[i
* 4 + 3] = static_cast<unsigned char>(i
% 255);
43 // Fill the given data buffer with valid png data.
44 void FillBitmap(int w
, int h
, std::vector
<unsigned char>* output
) {
46 FillDataToBitmap(w
, h
, &bitmap
);
47 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap
, false, output
);
50 void SetFaviconBitmapResult(
52 chrome::IconType icon_type
,
54 std::vector
<chrome::FaviconBitmapResult
>* favicon_bitmap_results
) {
55 scoped_refptr
<base::RefCountedBytes
> data(new base::RefCountedBytes());
56 FillBitmap(gfx::kFaviconSize
, gfx::kFaviconSize
, &data
->data());
57 chrome::FaviconBitmapResult bitmap_result
;
58 bitmap_result
.expired
= expired
;
59 bitmap_result
.bitmap_data
= data
;
60 // Use a pixel size other than (0,0) as (0,0) has a special meaning.
61 bitmap_result
.pixel_size
= gfx::Size(gfx::kFaviconSize
, gfx::kFaviconSize
);
62 bitmap_result
.icon_type
= icon_type
;
63 bitmap_result
.icon_url
= icon_url
;
65 favicon_bitmap_results
->push_back(bitmap_result
);
68 void SetFaviconBitmapResult(
70 std::vector
<chrome::FaviconBitmapResult
>* favicon_bitmap_results
) {
71 SetFaviconBitmapResult(icon_url
, chrome::FAVICON
, false /* expired */,
72 favicon_bitmap_results
);
75 // This class is used to save the download request for verifying with test case.
76 // It also will be used to invoke the onDidDownload callback.
77 class DownloadHandler
{
79 explicit DownloadHandler(TestFaviconHandler
* favicon_helper
)
80 : favicon_helper_(favicon_helper
),
84 virtual ~DownloadHandler() {
88 download_
.reset(NULL
);
94 const GURL
& image_url
,
97 download_
.reset(new Download(
98 download_id
, image_url
, image_size
, max_image_size
, false));
101 void InvokeCallback();
103 void set_failed(bool failed
) { failed_
= failed
; }
105 bool HasDownload() const { return download_
.get() != NULL
; }
106 const GURL
& GetImageUrl() const { return download_
->image_url
; }
107 void SetImageSize(int size
) { download_
->image_size
= size
; }
111 Download(int id
, GURL url
, int size
, int max_size
, bool failed
)
115 max_image_size(max_size
) {}
123 TestFaviconHandler
* favicon_helper_
;
124 scoped_ptr
<Download
> download_
;
127 DISALLOW_COPY_AND_ASSIGN(DownloadHandler
);
130 // This class is used to save the history request for verifying with test case.
131 // It also will be used to simulate the history response.
132 class HistoryRequestHandler
{
134 HistoryRequestHandler(const GURL
& page_url
,
135 const GURL
& icon_url
,
137 const FaviconService::FaviconResultsCallback
& callback
)
138 : page_url_(page_url
),
140 icon_type_(icon_type
),
141 callback_(callback
) {
144 HistoryRequestHandler(const GURL
& page_url
,
145 const GURL
& icon_url
,
147 const std::vector
<unsigned char>& bitmap_data
)
148 : page_url_(page_url
),
150 icon_type_(icon_type
),
151 bitmap_data_(bitmap_data
) {
154 virtual ~HistoryRequestHandler() {}
155 void InvokeCallback();
157 const GURL page_url_
;
158 const GURL icon_url_
;
159 const int icon_type_
;
160 const std::vector
<unsigned char> bitmap_data_
;
161 std::vector
<chrome::FaviconBitmapResult
> history_results_
;
162 FaviconService::FaviconResultsCallback callback_
;
165 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler
);
171 class TestFaviconHandlerDelegate
: public FaviconHandlerDelegate
{
173 TestFaviconHandlerDelegate() {
176 virtual ~TestFaviconHandlerDelegate() {
179 virtual NavigationEntry
* GetActiveEntry() OVERRIDE
{
180 ADD_FAILURE() << "TestFaviconHandlerDelegate::GetActiveEntry() "
181 << "should never be called in tests.";
185 virtual int StartDownload(const GURL
& url
,
186 int max_bitmap_size
) OVERRIDE
{
187 ADD_FAILURE() << "TestFaviconHandlerDelegate::StartDownload() "
188 << "should never be called in tests.";
192 virtual void NotifyFaviconUpdated(bool icon_url_changed
) OVERRIDE
{
193 ADD_FAILURE() << "TestFaviconHandlerDelegate::NotifyFaviconUpdated() "
194 << "should never be called in tests.";
198 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandlerDelegate
);
201 // This class is used to catch the FaviconHandler's download and history
202 // request, and also provide the methods to access the FaviconHandler
204 class TestFaviconHandler
: public FaviconHandler
{
206 TestFaviconHandler(const GURL
& page_url
,
208 FaviconHandlerDelegate
* delegate
,
210 : FaviconHandler(profile
, delegate
, type
),
211 entry_(NavigationEntry::Create()),
213 num_favicon_updates_(0) {
214 entry_
->SetURL(page_url
);
215 download_handler_
.reset(new DownloadHandler(this));
218 virtual ~TestFaviconHandler() {
221 HistoryRequestHandler
* history_handler() {
222 return history_handler_
.get();
225 // This method will take the ownership of the given handler.
226 void set_history_handler(HistoryRequestHandler
* handler
) {
227 history_handler_
.reset(handler
);
230 DownloadHandler
* download_handler() {
231 return download_handler_
.get();
234 size_t num_favicon_update_notifications() const {
235 return num_favicon_updates_
;
238 void ResetNumFaviconUpdateNotifications() {
239 num_favicon_updates_
= 0;
242 // Methods to access favicon internals.
243 virtual NavigationEntry
* GetEntry() OVERRIDE
{
247 const std::deque
<FaviconURL
>& urls() {
251 FaviconURL
* current_candidate() {
252 return FaviconHandler::current_candidate();
256 virtual void UpdateFaviconMappingAndFetch(
257 const GURL
& page_url
,
258 const GURL
& icon_url
,
259 chrome::IconType icon_type
,
260 const FaviconService::FaviconResultsCallback
& callback
,
261 CancelableTaskTracker
* tracker
) OVERRIDE
{
262 history_handler_
.reset(new HistoryRequestHandler(page_url
, icon_url
,
263 icon_type
, callback
));
266 virtual void GetFavicon(
267 const GURL
& icon_url
,
268 chrome::IconType icon_type
,
269 const FaviconService::FaviconResultsCallback
& callback
,
270 CancelableTaskTracker
* tracker
) OVERRIDE
{
271 history_handler_
.reset(new HistoryRequestHandler(GURL(), icon_url
,
272 icon_type
, callback
));
275 virtual void GetFaviconForURL(
276 const GURL
& page_url
,
278 const FaviconService::FaviconResultsCallback
& callback
,
279 CancelableTaskTracker
* tracker
) OVERRIDE
{
280 history_handler_
.reset(new HistoryRequestHandler(page_url
, GURL(),
281 icon_types
, callback
));
284 virtual int DownloadFavicon(const GURL
& image_url
,
285 int max_bitmap_size
) OVERRIDE
{
287 download_handler_
->AddDownload(
288 download_id_
, image_url
, 0, max_bitmap_size
);
292 virtual void SetHistoryFavicons(const GURL
& page_url
,
293 const GURL
& icon_url
,
294 chrome::IconType icon_type
,
295 const gfx::Image
& image
) OVERRIDE
{
296 scoped_refptr
<base::RefCountedMemory
> bytes
= image
.As1xPNGBytes();
297 std::vector
<unsigned char> bitmap_data(bytes
->front(),
298 bytes
->front() + bytes
->size());
299 history_handler_
.reset(new HistoryRequestHandler(
300 page_url
, icon_url
, icon_type
, bitmap_data
));
303 virtual FaviconService
* GetFaviconService() OVERRIDE
{
304 // Just give none NULL value, so overridden methods can be hit.
305 return (FaviconService
*)(1);
308 virtual bool ShouldSaveFavicon(const GURL
& url
) OVERRIDE
{
312 virtual void NotifyFaviconUpdated(bool icon_url_changed
) OVERRIDE
{
313 ++num_favicon_updates_
;
319 scoped_ptr
<NavigationEntry
> entry_
;
321 // The unique id of a download request. It will be returned to a
325 scoped_ptr
<DownloadHandler
> download_handler_
;
326 scoped_ptr
<HistoryRequestHandler
> history_handler_
;
328 // The number of times that NotifyFaviconUpdated() has been called.
329 size_t num_favicon_updates_
;
331 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler
);
336 void HistoryRequestHandler::InvokeCallback() {
337 if (!callback_
.is_null()) {
338 callback_
.Run(history_results_
);
342 void DownloadHandler::InvokeCallback() {
343 int original_size
= (download_
->image_size
> 0) ?
344 download_
->image_size
: gfx::kFaviconSize
;
345 int downloaded_size
= original_size
;
346 if (download_
->max_image_size
!= 0 &&
347 downloaded_size
> download_
->max_image_size
) {
348 downloaded_size
= download_
->max_image_size
;
350 std::vector
<SkBitmap
> bitmaps
;
351 std::vector
<gfx::Size
> original_bitmap_sizes
;
354 FillDataToBitmap(downloaded_size
, downloaded_size
, &bitmap
);
355 bitmaps
.push_back(bitmap
);
356 original_bitmap_sizes
.push_back(gfx::Size(original_size
, original_size
));
358 favicon_helper_
->OnDidDownloadFavicon(download_
->download_id
,
359 download_
->image_url
,
361 original_bitmap_sizes
);
364 class FaviconHandlerTest
: public ChromeRenderViewHostTestHarness
{
366 FaviconHandlerTest() {
369 virtual ~FaviconHandlerTest() {
372 // Simulates requesting a favicon for |page_url| given:
373 // - We have not previously cached anything in history for |page_url| or for
374 // any of |candidates|.
375 // - The page provides favicons at |candidate_icons|.
376 // - The favicons at |candidate_icons| have edge pixel sizes of
377 // |candidate_icon_sizes|.
378 void DownloadTillDoneIgnoringHistory(
379 TestFaviconHandler
* favicon_handler
,
380 const GURL
& page_url
,
381 const std::vector
<FaviconURL
>& candidate_icons
,
382 const int* candidate_icon_sizes
) {
383 favicon_handler
->ResetNumFaviconUpdateNotifications();
385 favicon_handler
->FetchFavicon(page_url
);
386 favicon_handler
->history_handler()->InvokeCallback();
388 favicon_handler
->OnUpdateFaviconURL(0, candidate_icons
);
389 EXPECT_EQ(candidate_icons
.size(), favicon_handler
->image_urls().size());
391 DownloadHandler
* download_handler
= favicon_handler
->download_handler();
392 for (size_t i
= 0; i
< candidate_icons
.size(); ++i
) {
393 favicon_handler
->history_handler()->history_results_
.clear();
394 favicon_handler
->history_handler()->InvokeCallback();
395 ASSERT_TRUE(download_handler
->HasDownload());
396 EXPECT_EQ(download_handler
->GetImageUrl(),
397 candidate_icons
[i
].icon_url
);
398 download_handler
->SetImageSize(candidate_icon_sizes
[i
]);
399 download_handler
->InvokeCallback();
401 if (favicon_handler
->num_favicon_update_notifications())
406 virtual void SetUp() {
407 // The score computed by SelectFaviconFrames() is dependent on the supported
408 // scale factors of the platform. It is used for determining the goodness of
409 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon().
410 // Force the values of the scale factors so that the tests produce the same
411 // results on all platforms.
412 std::vector
<ui::ScaleFactor
> scale_factors
;
413 scale_factors
.push_back(ui::SCALE_FACTOR_100P
);
414 scoped_set_supported_scale_factors_
.reset(
415 new ui::test::ScopedSetSupportedScaleFactors(scale_factors
));
417 ChromeRenderViewHostTestHarness::SetUp();
420 virtual void TearDown() OVERRIDE
{
421 Profile
* profile
= Profile::FromBrowserContext(
422 web_contents()->GetBrowserContext());
423 FaviconServiceFactory::GetInstance()->SetTestingFactory(
425 ChromeRenderViewHostTestHarness::TearDown();
429 typedef scoped_ptr
<ui::test::ScopedSetSupportedScaleFactors
>
430 ScopedSetSupportedScaleFactors
;
431 ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_
;
432 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerTest
);
435 TEST_F(FaviconHandlerTest
, GetFaviconFromHistory
) {
436 const GURL
page_url("http://www.google.com");
437 const GURL
icon_url("http://www.google.com/favicon");
439 TestFaviconHandlerDelegate delegate
;
440 Profile
* profile
= Profile::FromBrowserContext(
441 web_contents()->GetBrowserContext());
442 TestFaviconHandler
helper(page_url
, profile
,
443 &delegate
, FaviconHandler::FAVICON
);
445 helper
.FetchFavicon(page_url
);
446 HistoryRequestHandler
* history_handler
= helper
.history_handler();
447 // Ensure the data given to history is correct.
448 ASSERT_TRUE(history_handler
);
449 EXPECT_EQ(page_url
, history_handler
->page_url_
);
450 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
451 EXPECT_EQ(chrome::FAVICON
, history_handler
->icon_type_
);
453 SetFaviconBitmapResult(icon_url
, &history_handler
->history_results_
);
455 // Send history response.
456 history_handler
->InvokeCallback();
457 // Verify FaviconHandler status
458 EXPECT_TRUE(helper
.GetEntry()->GetFavicon().valid
);
459 EXPECT_EQ(icon_url
, helper
.GetEntry()->GetFavicon().url
);
461 // Simulates update favicon url.
462 std::vector
<FaviconURL
> urls
;
463 urls
.push_back(FaviconURL(icon_url
, FaviconURL::FAVICON
));
464 helper
.OnUpdateFaviconURL(0, urls
);
466 // Verify FaviconHandler status
467 EXPECT_EQ(1U, helper
.urls().size());
468 ASSERT_TRUE(helper
.current_candidate());
469 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
470 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
472 // Favicon shouldn't request to download icon.
473 EXPECT_FALSE(helper
.download_handler()->HasDownload());
476 TEST_F(FaviconHandlerTest
, DownloadFavicon
) {
477 const GURL
page_url("http://www.google.com");
478 const GURL
icon_url("http://www.google.com/favicon");
480 TestFaviconHandlerDelegate delegate
;
481 Profile
* profile
= Profile::FromBrowserContext(
482 web_contents()->GetBrowserContext());
483 TestFaviconHandler
helper(page_url
, profile
,
484 &delegate
, FaviconHandler::FAVICON
);
486 helper
.FetchFavicon(page_url
);
487 HistoryRequestHandler
* history_handler
= helper
.history_handler();
488 // Ensure the data given to history is correct.
489 ASSERT_TRUE(history_handler
);
490 EXPECT_EQ(page_url
, history_handler
->page_url_
);
491 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
492 EXPECT_EQ(chrome::FAVICON
, history_handler
->icon_type_
);
494 // Set icon data expired
495 SetFaviconBitmapResult(icon_url
, chrome::FAVICON
, true /* expired */,
496 &history_handler
->history_results_
);
497 // Send history response.
498 history_handler
->InvokeCallback();
499 // Verify FaviconHandler status
500 EXPECT_TRUE(helper
.GetEntry()->GetFavicon().valid
);
501 EXPECT_EQ(icon_url
, helper
.GetEntry()->GetFavicon().url
);
503 // Simulates update favicon url.
504 std::vector
<FaviconURL
> urls
;
505 urls
.push_back(FaviconURL(icon_url
, FaviconURL::FAVICON
));
506 helper
.OnUpdateFaviconURL(0, urls
);
508 // Verify FaviconHandler status
509 EXPECT_EQ(1U, helper
.urls().size());
510 ASSERT_TRUE(helper
.current_candidate());
511 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
512 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
514 // Favicon should request to download icon now.
515 DownloadHandler
* download_handler
= helper
.download_handler();
516 EXPECT_TRUE(helper
.download_handler()->HasDownload());
518 // Verify the download request.
519 EXPECT_EQ(icon_url
, download_handler
->GetImageUrl());
521 // Reset the history_handler to verify whether favicon is set.
522 helper
.set_history_handler(NULL
);
524 // Smulates download done.
525 download_handler
->InvokeCallback();
527 // New icon should be saved to history backend and navigation entry.
528 history_handler
= helper
.history_handler();
529 ASSERT_TRUE(history_handler
);
530 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
531 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
532 EXPECT_LT(0U, history_handler
->bitmap_data_
.size());
533 EXPECT_EQ(page_url
, history_handler
->page_url_
);
535 // Verify NavigationEntry.
536 content::FaviconStatus favicon_status
= helper
.GetEntry()->GetFavicon();
537 EXPECT_EQ(icon_url
, favicon_status
.url
);
538 EXPECT_TRUE(favicon_status
.valid
);
539 EXPECT_FALSE(favicon_status
.image
.IsEmpty());
540 EXPECT_EQ(gfx::kFaviconSize
, favicon_status
.image
.Width());
543 TEST_F(FaviconHandlerTest
, UpdateAndDownloadFavicon
) {
544 const GURL
page_url("http://www.google.com");
545 const GURL
icon_url("http://www.google.com/favicon");
546 const GURL
new_icon_url("http://www.google.com/new_favicon");
548 TestFaviconHandlerDelegate delegate
;
549 Profile
* profile
= Profile::FromBrowserContext(
550 web_contents()->GetBrowserContext());
551 TestFaviconHandler
helper(page_url
, profile
,
552 &delegate
, FaviconHandler::FAVICON
);
554 helper
.FetchFavicon(page_url
);
555 HistoryRequestHandler
* history_handler
= helper
.history_handler();
556 // Ensure the data given to history is correct.
557 ASSERT_TRUE(history_handler
);
558 EXPECT_EQ(page_url
, history_handler
->page_url_
);
559 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
560 EXPECT_EQ(chrome::FAVICON
, history_handler
->icon_type_
);
562 // Set valid icon data.
563 SetFaviconBitmapResult(icon_url
, &history_handler
->history_results_
);
565 // Send history response.
566 history_handler
->InvokeCallback();
567 // Verify FaviconHandler status.
568 EXPECT_TRUE(helper
.GetEntry()->GetFavicon().valid
);
569 EXPECT_EQ(icon_url
, helper
.GetEntry()->GetFavicon().url
);
571 // Reset the history_handler to verify whether new icon is requested from
573 helper
.set_history_handler(NULL
);
575 // Simulates update with the different favicon url.
576 std::vector
<FaviconURL
> urls
;
577 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
578 helper
.OnUpdateFaviconURL(0, urls
);
580 // Verify FaviconHandler status.
581 EXPECT_EQ(1U, helper
.urls().size());
582 ASSERT_TRUE(helper
.current_candidate());
583 ASSERT_EQ(new_icon_url
, helper
.current_candidate()->icon_url
);
584 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
586 // Favicon should be requested from history.
587 history_handler
= helper
.history_handler();
588 ASSERT_TRUE(history_handler
);
589 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
590 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
591 EXPECT_EQ(page_url
, history_handler
->page_url_
);
593 // Simulate not find icon.
594 history_handler
->history_results_
.clear();
595 history_handler
->InvokeCallback();
597 // Favicon should request to download icon now.
598 DownloadHandler
* download_handler
= helper
.download_handler();
599 EXPECT_TRUE(helper
.download_handler()->HasDownload());
601 // Verify the download request.
602 EXPECT_EQ(new_icon_url
, download_handler
->GetImageUrl());
604 // Reset the history_handler to verify whether favicon is set.
605 helper
.set_history_handler(NULL
);
607 // Smulates download done.
608 download_handler
->InvokeCallback();
610 // New icon should be saved to history backend and navigation entry.
611 history_handler
= helper
.history_handler();
612 ASSERT_TRUE(history_handler
);
613 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
614 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
615 EXPECT_LT(0U, history_handler
->bitmap_data_
.size());
616 EXPECT_EQ(page_url
, history_handler
->page_url_
);
618 // Verify NavigationEntry.
619 content::FaviconStatus favicon_status
= helper
.GetEntry()->GetFavicon();
620 EXPECT_EQ(new_icon_url
, favicon_status
.url
);
621 EXPECT_TRUE(favicon_status
.valid
);
622 EXPECT_FALSE(favicon_status
.image
.IsEmpty());
623 EXPECT_EQ(gfx::kFaviconSize
, favicon_status
.image
.Width());
626 TEST_F(FaviconHandlerTest
, FaviconInHistoryInvalid
) {
627 const GURL
page_url("http://www.google.com");
628 const GURL
icon_url("http://www.google.com/favicon");
630 TestFaviconHandlerDelegate delegate
;
631 Profile
* profile
= Profile::FromBrowserContext(
632 web_contents()->GetBrowserContext());
633 TestFaviconHandler
helper(page_url
, profile
,
634 &delegate
, FaviconHandler::FAVICON
);
636 helper
.FetchFavicon(page_url
);
637 HistoryRequestHandler
* history_handler
= helper
.history_handler();
638 // Ensure the data given to history is correct.
639 ASSERT_TRUE(history_handler
);
640 EXPECT_EQ(page_url
, history_handler
->page_url_
);
641 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
642 EXPECT_EQ(chrome::FAVICON
, history_handler
->icon_type_
);
644 // Set non empty but invalid data.
645 chrome::FaviconBitmapResult bitmap_result
;
646 bitmap_result
.expired
= false;
647 // Empty bitmap data is invalid.
648 bitmap_result
.bitmap_data
= new base::RefCountedBytes();
649 bitmap_result
.pixel_size
= gfx::Size(gfx::kFaviconSize
, gfx::kFaviconSize
);
650 bitmap_result
.icon_type
= chrome::FAVICON
;
651 bitmap_result
.icon_url
= icon_url
;
652 history_handler
->history_results_
.clear();
653 history_handler
->history_results_
.push_back(bitmap_result
);
655 // Send history response.
656 history_handler
->InvokeCallback();
657 // The NavigationEntry should not be set yet as the history data is invalid.
658 EXPECT_FALSE(helper
.GetEntry()->GetFavicon().valid
);
659 EXPECT_EQ(GURL(), helper
.GetEntry()->GetFavicon().url
);
661 // Reset the history_handler to verify whether new icon is requested from
663 helper
.set_history_handler(NULL
);
665 // Simulates update with matching favicon URL.
666 std::vector
<FaviconURL
> urls
;
667 urls
.push_back(FaviconURL(icon_url
, FaviconURL::FAVICON
));
668 helper
.OnUpdateFaviconURL(0, urls
);
670 // A download for the favicon should be requested, and we should not do
671 // another history request.
672 DownloadHandler
* download_handler
= helper
.download_handler();
673 EXPECT_TRUE(helper
.download_handler()->HasDownload());
674 EXPECT_EQ(NULL
, helper
.history_handler());
676 // Verify the download request.
677 EXPECT_EQ(icon_url
, download_handler
->GetImageUrl());
679 // Simulates download done.
680 download_handler
->InvokeCallback();
682 // New icon should be saved to history backend and navigation entry.
683 history_handler
= helper
.history_handler();
684 ASSERT_TRUE(history_handler
);
685 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
686 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
687 EXPECT_LT(0U, history_handler
->bitmap_data_
.size());
688 EXPECT_EQ(page_url
, history_handler
->page_url_
);
690 // Verify NavigationEntry.
691 content::FaviconStatus favicon_status
= helper
.GetEntry()->GetFavicon();
692 EXPECT_EQ(icon_url
, favicon_status
.url
);
693 EXPECT_TRUE(favicon_status
.valid
);
694 EXPECT_FALSE(favicon_status
.image
.IsEmpty());
695 EXPECT_EQ(gfx::kFaviconSize
, favicon_status
.image
.Width());
698 TEST_F(FaviconHandlerTest
, UpdateFavicon
) {
699 const GURL
page_url("http://www.google.com");
700 const GURL
icon_url("http://www.google.com/favicon");
701 const GURL
new_icon_url("http://www.google.com/new_favicon");
703 TestFaviconHandlerDelegate delegate
;
704 Profile
* profile
= Profile::FromBrowserContext(
705 web_contents()->GetBrowserContext());
706 TestFaviconHandler
helper(page_url
, profile
,
707 &delegate
, FaviconHandler::FAVICON
);
709 helper
.FetchFavicon(page_url
);
710 HistoryRequestHandler
* history_handler
= helper
.history_handler();
711 // Ensure the data given to history is correct.
712 ASSERT_TRUE(history_handler
);
713 EXPECT_EQ(page_url
, history_handler
->page_url_
);
714 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
715 EXPECT_EQ(chrome::FAVICON
, history_handler
->icon_type_
);
717 SetFaviconBitmapResult(icon_url
, &history_handler
->history_results_
);
719 // Send history response.
720 history_handler
->InvokeCallback();
721 // Verify FaviconHandler status.
722 EXPECT_TRUE(helper
.GetEntry()->GetFavicon().valid
);
723 EXPECT_EQ(icon_url
, helper
.GetEntry()->GetFavicon().url
);
725 // Reset the history_handler to verify whether new icon is requested from
727 helper
.set_history_handler(NULL
);
729 // Simulates update with the different favicon url.
730 std::vector
<FaviconURL
> urls
;
731 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
732 helper
.OnUpdateFaviconURL(0, urls
);
734 // Verify FaviconHandler status.
735 EXPECT_EQ(1U, helper
.urls().size());
736 ASSERT_TRUE(helper
.current_candidate());
737 ASSERT_EQ(new_icon_url
, helper
.current_candidate()->icon_url
);
738 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
740 // Favicon should be requested from history.
741 history_handler
= helper
.history_handler();
742 ASSERT_TRUE(history_handler
);
743 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
744 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
745 EXPECT_EQ(page_url
, history_handler
->page_url_
);
747 // Simulate find icon.
748 SetFaviconBitmapResult(new_icon_url
, &history_handler
->history_results_
);
749 history_handler
->InvokeCallback();
751 // Shouldn't request download favicon
752 EXPECT_FALSE(helper
.download_handler()->HasDownload());
754 // Verify the favicon status.
755 EXPECT_EQ(new_icon_url
, helper
.GetEntry()->GetFavicon().url
);
756 EXPECT_TRUE(helper
.GetEntry()->GetFavicon().valid
);
757 EXPECT_FALSE(helper
.GetEntry()->GetFavicon().image
.IsEmpty());
760 TEST_F(FaviconHandlerTest
, Download2ndFaviconURLCandidate
) {
761 const GURL
page_url("http://www.google.com");
762 const GURL
icon_url("http://www.google.com/favicon");
763 const GURL
new_icon_url("http://www.google.com/new_favicon");
765 TestFaviconHandlerDelegate delegate
;
766 Profile
* profile
= Profile::FromBrowserContext(
767 web_contents()->GetBrowserContext());
768 TestFaviconHandler
helper(page_url
, profile
,
769 &delegate
, FaviconHandler::TOUCH
);
771 helper
.FetchFavicon(page_url
);
772 HistoryRequestHandler
* history_handler
= helper
.history_handler();
773 // Ensure the data given to history is correct.
774 ASSERT_TRUE(history_handler
);
775 EXPECT_EQ(page_url
, history_handler
->page_url_
);
776 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
777 EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON
| chrome::TOUCH_ICON
,
778 history_handler
->icon_type_
);
781 history_handler
->history_results_
.clear();
782 // Send history response.
783 history_handler
->InvokeCallback();
784 // Verify FaviconHandler status.
785 EXPECT_FALSE(helper
.GetEntry()->GetFavicon().valid
);
786 EXPECT_EQ(GURL(), helper
.GetEntry()->GetFavicon().url
);
788 // Reset the history_handler to verify whether new icon is requested from
790 helper
.set_history_handler(NULL
);
792 // Simulates update with the different favicon url.
793 std::vector
<FaviconURL
> urls
;
794 urls
.push_back(FaviconURL(icon_url
, FaviconURL::TOUCH_PRECOMPOSED_ICON
));
795 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::TOUCH_ICON
));
796 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
797 helper
.OnUpdateFaviconURL(0, urls
);
799 // Verify FaviconHandler status.
800 EXPECT_EQ(2U, helper
.urls().size());
801 ASSERT_TRUE(helper
.current_candidate());
802 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
803 ASSERT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
,
804 helper
.current_candidate()->icon_type
);
806 // Favicon should be requested from history.
807 history_handler
= helper
.history_handler();
808 ASSERT_TRUE(history_handler
);
809 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
810 EXPECT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
, history_handler
->icon_type_
);
811 EXPECT_EQ(page_url
, history_handler
->page_url_
);
813 // Simulate not find icon.
814 history_handler
->history_results_
.clear();
815 history_handler
->InvokeCallback();
817 // Should request download favicon.
818 DownloadHandler
* download_handler
= helper
.download_handler();
819 EXPECT_TRUE(helper
.download_handler()->HasDownload());
821 // Verify the download request.
822 EXPECT_EQ(icon_url
, download_handler
->GetImageUrl());
824 // Reset the history_handler to verify whether favicon is request from
826 helper
.set_history_handler(NULL
);
827 // Smulates download failed.
828 download_handler
->set_failed(true);
829 download_handler
->InvokeCallback();
832 EXPECT_EQ(1U, helper
.urls().size());
833 ASSERT_TRUE(helper
.current_candidate());
834 EXPECT_EQ(new_icon_url
, helper
.current_candidate()->icon_url
);
835 EXPECT_EQ(FaviconURL::TOUCH_ICON
, helper
.current_candidate()->icon_type
);
837 // Favicon should be requested from history.
838 history_handler
= helper
.history_handler();
839 ASSERT_TRUE(history_handler
);
840 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
841 EXPECT_EQ(FaviconURL::TOUCH_ICON
, history_handler
->icon_type_
);
842 EXPECT_EQ(page_url
, history_handler
->page_url_
);
844 // Reset download handler
845 download_handler
->Reset();
847 // Simulates getting a expired icon from history.
848 SetFaviconBitmapResult(new_icon_url
, chrome::TOUCH_ICON
,
849 true /* expired */, &history_handler
->history_results_
);
850 history_handler
->InvokeCallback();
852 // Verify the download request.
853 EXPECT_TRUE(helper
.download_handler()->HasDownload());
854 EXPECT_EQ(new_icon_url
, download_handler
->GetImageUrl());
856 helper
.set_history_handler(NULL
);
858 // Simulates icon being downloaded.
859 download_handler
->InvokeCallback();
861 // New icon should be saved to history backend.
862 history_handler
= helper
.history_handler();
863 ASSERT_TRUE(history_handler
);
864 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
865 EXPECT_EQ(FaviconURL::TOUCH_ICON
, history_handler
->icon_type_
);
866 EXPECT_LT(0U, history_handler
->bitmap_data_
.size());
867 EXPECT_EQ(page_url
, history_handler
->page_url_
);
870 TEST_F(FaviconHandlerTest
, UpdateDuringDownloading
) {
871 const GURL
page_url("http://www.google.com");
872 const GURL
icon_url("http://www.google.com/favicon");
873 const GURL
new_icon_url("http://www.google.com/new_favicon");
875 TestFaviconHandlerDelegate delegate
;
876 Profile
* profile
= Profile::FromBrowserContext(
877 web_contents()->GetBrowserContext());
878 TestFaviconHandler
helper(page_url
, profile
,
879 &delegate
, FaviconHandler::TOUCH
);
881 helper
.FetchFavicon(page_url
);
882 HistoryRequestHandler
* history_handler
= helper
.history_handler();
883 // Ensure the data given to history is correct.
884 ASSERT_TRUE(history_handler
);
885 EXPECT_EQ(page_url
, history_handler
->page_url_
);
886 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
887 EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON
| chrome::TOUCH_ICON
,
888 history_handler
->icon_type_
);
891 history_handler
->history_results_
.clear();
892 // Send history response.
893 history_handler
->InvokeCallback();
894 // Verify FaviconHandler status.
895 EXPECT_FALSE(helper
.GetEntry()->GetFavicon().valid
);
896 EXPECT_EQ(GURL(), helper
.GetEntry()->GetFavicon().url
);
898 // Reset the history_handler to verify whether new icon is requested from
900 helper
.set_history_handler(NULL
);
902 // Simulates update with the different favicon url.
903 std::vector
<FaviconURL
> urls
;
904 urls
.push_back(FaviconURL(icon_url
, FaviconURL::TOUCH_PRECOMPOSED_ICON
));
905 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::TOUCH_ICON
));
906 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
907 helper
.OnUpdateFaviconURL(0, urls
);
909 // Verify FaviconHandler status.
910 EXPECT_EQ(2U, helper
.urls().size());
911 ASSERT_TRUE(helper
.current_candidate());
912 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
913 ASSERT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
,
914 helper
.current_candidate()->icon_type
);
916 // Favicon should be requested from history.
917 history_handler
= helper
.history_handler();
918 ASSERT_TRUE(history_handler
);
919 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
920 EXPECT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
, history_handler
->icon_type_
);
921 EXPECT_EQ(page_url
, history_handler
->page_url_
);
923 // Simulate not find icon.
924 history_handler
->history_results_
.clear();
925 history_handler
->InvokeCallback();
927 // Should request download favicon.
928 DownloadHandler
* download_handler
= helper
.download_handler();
929 EXPECT_TRUE(helper
.download_handler()->HasDownload());
931 // Verify the download request.
932 EXPECT_EQ(icon_url
, download_handler
->GetImageUrl());
934 // Reset the history_handler to verify whether favicon is request from
936 helper
.set_history_handler(NULL
);
937 const GURL
latest_icon_url("http://www.google.com/latest_favicon");
938 std::vector
<FaviconURL
> latest_urls
;
939 latest_urls
.push_back(FaviconURL(latest_icon_url
, FaviconURL::TOUCH_ICON
));
940 helper
.OnUpdateFaviconURL(0, latest_urls
);
942 EXPECT_EQ(1U, helper
.urls().size());
943 EXPECT_EQ(latest_icon_url
, helper
.current_candidate()->icon_url
);
944 EXPECT_EQ(FaviconURL::TOUCH_ICON
, helper
.current_candidate()->icon_type
);
946 // Whether new icon is requested from history
947 history_handler
= helper
.history_handler();
948 ASSERT_TRUE(history_handler
);
949 EXPECT_EQ(latest_icon_url
, history_handler
->icon_url_
);
950 EXPECT_EQ(FaviconURL::TOUCH_ICON
, history_handler
->icon_type_
);
951 EXPECT_EQ(page_url
, history_handler
->page_url_
);
953 // Reset the history_handler to verify whether favicon is request from
955 // Save the callback for late use.
956 FaviconService::FaviconResultsCallback callback
= history_handler
->callback_
;
957 helper
.set_history_handler(NULL
);
959 // Simulates download succeed.
960 download_handler
->InvokeCallback();
961 // The downloaded icon should be thrown away as there is favicon update.
962 EXPECT_FALSE(helper
.history_handler());
964 download_handler
->Reset();
966 // Simulates getting the icon from history.
967 scoped_ptr
<HistoryRequestHandler
> handler
;
968 handler
.reset(new HistoryRequestHandler(page_url
, latest_icon_url
,
969 chrome::TOUCH_ICON
, callback
));
970 SetFaviconBitmapResult(latest_icon_url
, chrome::TOUCH_ICON
,
971 false /* expired */, &handler
->history_results_
);
972 handler
->InvokeCallback();
974 // No download request.
975 EXPECT_FALSE(download_handler
->HasDownload());
978 #if !defined(OS_ANDROID)
980 // Test the favicon which is selected when the web page provides several
981 // favicons and none of the favicons are cached in history.
982 // The goal of this test is to be more of an integration test than
983 // SelectFaviconFramesTest.*.
984 TEST_F(FaviconHandlerTest
, MultipleFavicons
) {
985 const GURL
kPageURL("http://www.google.com");
986 const FaviconURL kSourceIconURLs
[] = {
987 FaviconURL(GURL("http://www.google.com/a"), FaviconURL::FAVICON
),
988 FaviconURL(GURL("http://www.google.com/b"), FaviconURL::FAVICON
),
989 FaviconURL(GURL("http://www.google.com/c"), FaviconURL::FAVICON
),
990 FaviconURL(GURL("http://www.google.com/d"), FaviconURL::FAVICON
),
991 FaviconURL(GURL("http://www.google.com/e"), FaviconURL::FAVICON
)
994 // Set the supported scale factors to 1x and 2x. This affects the behavior of
995 // SelectFaviconFrames().
996 std::vector
<ui::ScaleFactor
> scale_factors
;
997 scale_factors
.push_back(ui::SCALE_FACTOR_100P
);
998 scale_factors
.push_back(ui::SCALE_FACTOR_200P
);
999 ui::test::ScopedSetSupportedScaleFactors
scoped_supported(scale_factors
);
1001 Profile
* profile
= Profile::FromBrowserContext(
1002 web_contents()->GetBrowserContext());
1004 // 1) Test that if there are several single resolution favicons to choose from
1005 // that the largest exact match is chosen.
1006 TestFaviconHandlerDelegate delegate1
;
1007 TestFaviconHandler
handler1(kPageURL
, profile
,
1008 &delegate1
, FaviconHandler::FAVICON
);
1009 const int kSizes1
[] = { 16, 24, 32, 48, 256 };
1010 std::vector
<FaviconURL
> urls1(kSourceIconURLs
,
1011 kSourceIconURLs
+ arraysize(kSizes1
));
1012 DownloadTillDoneIgnoringHistory(&handler1
, kPageURL
, urls1
, kSizes1
);
1014 content::FaviconStatus
favicon_status1(handler1
.GetEntry()->GetFavicon());
1015 EXPECT_EQ(0u, handler1
.image_urls().size());
1016 EXPECT_TRUE(favicon_status1
.valid
);
1017 EXPECT_FALSE(favicon_status1
.image
.IsEmpty());
1018 EXPECT_EQ(gfx::kFaviconSize
, favicon_status1
.image
.Width());
1020 size_t expected_index
= 2u;
1021 EXPECT_EQ(32, kSizes1
[expected_index
]);
1022 EXPECT_EQ(kSourceIconURLs
[expected_index
].icon_url
,
1023 handler1
.GetEntry()->GetFavicon().url
);
1025 // 2) Test that if there are several single resolution favicons to choose
1026 // from, the exact match is preferred even if it results in upsampling.
1027 TestFaviconHandlerDelegate delegate2
;
1028 TestFaviconHandler
handler2(kPageURL
, profile
,
1029 &delegate2
, FaviconHandler::FAVICON
);
1030 const int kSizes2
[] = { 16, 24, 48, 256 };
1031 std::vector
<FaviconURL
> urls2(kSourceIconURLs
,
1032 kSourceIconURLs
+ arraysize(kSizes2
));
1033 DownloadTillDoneIgnoringHistory(&handler2
, kPageURL
, urls2
, kSizes2
);
1034 EXPECT_TRUE(handler2
.GetEntry()->GetFavicon().valid
);
1035 expected_index
= 0u;
1036 EXPECT_EQ(16, kSizes2
[expected_index
]);
1037 EXPECT_EQ(kSourceIconURLs
[expected_index
].icon_url
,
1038 handler2
.GetEntry()->GetFavicon().url
);
1040 // 3) Test that favicons which need to be upsampled a little or downsampled
1041 // a little are preferred over huge favicons.
1042 TestFaviconHandlerDelegate delegate3
;
1043 TestFaviconHandler
handler3(kPageURL
, profile
,
1044 &delegate3
, FaviconHandler::FAVICON
);
1045 const int kSizes3
[] = { 256, 48 };
1046 std::vector
<FaviconURL
> urls3(kSourceIconURLs
,
1047 kSourceIconURLs
+ arraysize(kSizes3
));
1048 DownloadTillDoneIgnoringHistory(&handler3
, kPageURL
, urls3
, kSizes3
);
1049 EXPECT_TRUE(handler3
.GetEntry()->GetFavicon().valid
);
1050 expected_index
= 1u;
1051 EXPECT_EQ(48, kSizes3
[expected_index
]);
1052 EXPECT_EQ(kSourceIconURLs
[expected_index
].icon_url
,
1053 handler3
.GetEntry()->GetFavicon().url
);
1055 TestFaviconHandlerDelegate delegate4
;
1056 TestFaviconHandler
handler4(kPageURL
, profile
,
1057 &delegate4
, FaviconHandler::FAVICON
);
1058 const int kSizes4
[] = { 17, 256 };
1059 std::vector
<FaviconURL
> urls4(kSourceIconURLs
,
1060 kSourceIconURLs
+ arraysize(kSizes4
));
1061 DownloadTillDoneIgnoringHistory(&handler4
, kPageURL
, urls4
, kSizes4
);
1062 EXPECT_TRUE(handler4
.GetEntry()->GetFavicon().valid
);
1063 expected_index
= 0u;
1064 EXPECT_EQ(17, kSizes4
[expected_index
]);
1065 EXPECT_EQ(kSourceIconURLs
[expected_index
].icon_url
,
1066 handler4
.GetEntry()->GetFavicon().url
);
1071 static BrowserContextKeyedService
* BuildFaviconService(
1072 content::BrowserContext
* profile
) {
1073 return new FaviconService(static_cast<Profile
*>(profile
));
1076 static BrowserContextKeyedService
* BuildHistoryService(
1077 content::BrowserContext
* profile
) {
1081 // Test that Favicon is not requested repeatedly during the same session if
1082 // server returns HTTP 404 status.
1083 TEST_F(FaviconHandlerTest
, UnableToDownloadFavicon
) {
1084 const GURL
missing_icon_url("http://www.google.com/favicon.ico");
1085 const GURL
another_icon_url("http://www.youtube.com/favicon.ico");
1087 Profile
* profile
= Profile::FromBrowserContext(
1088 web_contents()->GetBrowserContext());
1090 FaviconServiceFactory::GetInstance()->SetTestingFactory(
1091 profile
, BuildFaviconService
);
1093 HistoryServiceFactory::GetInstance()->SetTestingFactory(
1094 profile
, BuildHistoryService
);
1096 FaviconService
* favicon_service
= FaviconServiceFactory::GetForProfile(
1097 profile
, Profile::IMPLICIT_ACCESS
);
1099 FaviconTabHelper::CreateForWebContents(web_contents());
1100 FaviconTabHelper
* favicon_tab_helper
=
1101 FaviconTabHelper::FromWebContents(web_contents());
1103 std::vector
<SkBitmap
> empty_icons
;
1104 std::vector
<gfx::Size
> empty_icon_sizes
;
1105 int download_id
= 0;
1107 // Try to download missing icon.
1108 download_id
= favicon_tab_helper
->StartDownload(missing_icon_url
, 0);
1109 EXPECT_NE(0, download_id
);
1110 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));
1112 // Report download failure with HTTP 503 status.
1113 favicon_tab_helper
->DidDownloadFavicon(download_id
, 503, missing_icon_url
,
1114 empty_icons
, empty_icon_sizes
);
1115 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1116 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));
1118 // Try to download again.
1119 download_id
= favicon_tab_helper
->StartDownload(missing_icon_url
, 0);
1120 EXPECT_NE(0, download_id
);
1121 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));
1123 // Report download failure with HTTP 404 status.
1124 favicon_tab_helper
->DidDownloadFavicon(download_id
, 404, missing_icon_url
,
1125 empty_icons
, empty_icon_sizes
);
1126 // Icon is marked as UnableToDownload.
1127 EXPECT_TRUE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));
1129 // Try to download again.
1130 download_id
= favicon_tab_helper
->StartDownload(missing_icon_url
, 0);
1131 // Download is not started and Icon is still marked as UnableToDownload.
1132 EXPECT_EQ(0, download_id
);
1133 EXPECT_TRUE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));
1135 // Try to download another icon.
1136 download_id
= favicon_tab_helper
->StartDownload(another_icon_url
, 0);
1137 // Download is started as another icon URL is not same as missing_icon_url.
1138 EXPECT_NE(0, download_id
);
1139 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(another_icon_url
));
1141 // Clear the list of missing icons.
1142 favicon_service
->ClearUnableToDownloadFavicons();
1143 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));
1144 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(another_icon_url
));
1146 // Try to download again.
1147 download_id
= favicon_tab_helper
->StartDownload(missing_icon_url
, 0);
1148 EXPECT_NE(0, download_id
);
1149 // Report download success with HTTP 200 status.
1150 favicon_tab_helper
->DidDownloadFavicon(download_id
, 200, missing_icon_url
,
1151 empty_icons
, empty_icon_sizes
);
1152 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1153 EXPECT_FALSE(favicon_service
->WasUnableToDownloadFavicon(missing_icon_url
));