Make castv2 performance test work.
[chromium-blink-merge.git] / chrome / browser / favicon / favicon_handler_unittest.cc
blob2e858d5ac02c21545f386a85c5b040953b0e9bd5
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 "components/favicon/core/favicon_handler.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "chrome/browser/favicon/chrome_favicon_client_factory.h"
9 #include "chrome/browser/favicon/favicon_service_factory.h"
10 #include "chrome/browser/favicon/favicon_tab_helper.h"
11 #include "chrome/browser/history/history_service_factory.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
14 #include "components/favicon/core/favicon_service.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 favicon::FaviconURL;
24 namespace {
26 // Fill the given bmp with valid png data.
27 void FillDataToBitmap(int w, int h, SkBitmap* bmp) {
28 bmp->allocN32Pixels(w, h);
30 unsigned char* src_data =
31 reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0));
32 for (int i = 0; i < w * h; i++) {
33 src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255);
34 src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255);
35 src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255);
36 src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255);
40 // Fill the given data buffer with valid png data.
41 void FillBitmap(int w, int h, std::vector<unsigned char>* output) {
42 SkBitmap bitmap;
43 FillDataToBitmap(w, h, &bitmap);
44 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output);
47 void SetFaviconRawBitmapResult(
48 const GURL& icon_url,
49 favicon_base::IconType icon_type,
50 bool expired,
51 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
52 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
53 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data());
54 favicon_base::FaviconRawBitmapResult bitmap_result;
55 bitmap_result.expired = expired;
56 bitmap_result.bitmap_data = data;
57 // Use a pixel size other than (0,0) as (0,0) has a special meaning.
58 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
59 bitmap_result.icon_type = icon_type;
60 bitmap_result.icon_url = icon_url;
62 favicon_bitmap_results->push_back(bitmap_result);
65 void SetFaviconRawBitmapResult(
66 const GURL& icon_url,
67 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
68 SetFaviconRawBitmapResult(icon_url,
69 favicon_base::FAVICON,
70 false /* expired */,
71 favicon_bitmap_results);
74 // This class is used to save the download request for verifying with test case.
75 // It also will be used to invoke the onDidDownload callback.
76 class DownloadHandler {
77 public:
78 explicit DownloadHandler(TestFaviconHandler* favicon_helper)
79 : favicon_helper_(favicon_helper),
80 failed_(false) {
83 ~DownloadHandler() {}
85 void Reset() {
86 download_.reset();
87 failed_ = false;
90 void AddDownload(
91 int download_id,
92 const GURL& image_url,
93 const std::vector<int>& image_sizes,
94 int max_image_size) {
95 download_.reset(new Download(
96 download_id, image_url, image_sizes, max_image_size, false));
99 void InvokeCallback();
101 void set_failed(bool failed) { failed_ = failed; }
103 bool HasDownload() const { return download_.get(); }
104 const GURL& GetImageUrl() const { return download_->image_url; }
105 void SetImageSizes(const std::vector<int>& sizes) {
106 download_->image_sizes = sizes; }
108 private:
109 struct Download {
110 Download(int id,
111 GURL url,
112 const std::vector<int>& sizes,
113 int max_size,
114 bool failed)
115 : download_id(id),
116 image_url(url),
117 image_sizes(sizes),
118 max_image_size(max_size) {}
119 ~Download() {}
120 int download_id;
121 GURL image_url;
122 std::vector<int> image_sizes;
123 int max_image_size;
126 TestFaviconHandler* favicon_helper_;
127 scoped_ptr<Download> download_;
128 bool failed_;
130 DISALLOW_COPY_AND_ASSIGN(DownloadHandler);
133 // This class is used to save the history request for verifying with test case.
134 // It also will be used to simulate the history response.
135 class HistoryRequestHandler {
136 public:
137 HistoryRequestHandler(const GURL& page_url,
138 const GURL& icon_url,
139 int icon_type,
140 const favicon_base::FaviconResultsCallback& callback)
141 : page_url_(page_url),
142 icon_url_(icon_url),
143 icon_type_(icon_type),
144 callback_(callback) {
147 HistoryRequestHandler(const GURL& page_url,
148 const GURL& icon_url,
149 int icon_type,
150 const std::vector<unsigned char>& bitmap_data,
151 const gfx::Size& size)
152 : page_url_(page_url),
153 icon_url_(icon_url),
154 icon_type_(icon_type),
155 bitmap_data_(bitmap_data),
156 size_(size) {
159 ~HistoryRequestHandler() {}
160 void InvokeCallback();
162 const GURL page_url_;
163 const GURL icon_url_;
164 const int icon_type_;
165 const std::vector<unsigned char> bitmap_data_;
166 const gfx::Size size_;
167 std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
168 favicon_base::FaviconResultsCallback callback_;
170 private:
171 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler);
174 } // namespace
176 class TestFaviconDriver : public favicon::FaviconDriver {
177 public:
178 TestFaviconDriver()
179 : favicon_validity_(false),
180 num_active_favicon_(0),
181 num_favicon_available_(0),
182 update_active_favicon_(false) {}
184 ~TestFaviconDriver() override {}
186 int StartDownload(const GURL& url, int max_bitmap_size) override {
187 ADD_FAILURE() << "TestFaviconDriver::StartDownload() "
188 << "should never be called in tests.";
189 return -1;
192 bool IsOffTheRecord() override { return false; }
194 bool IsBookmarked(const GURL& url) override { return false; }
196 GURL GetActiveURL() override { return url_; }
198 base::string16 GetActiveTitle() override { return base::string16(); }
200 bool GetActiveFaviconValidity() override { return favicon_validity_; }
202 void SetActiveFaviconValidity(bool favicon_validity) override {
203 favicon_validity_ = favicon_validity;
206 GURL GetActiveFaviconURL() override { return favicon_url_; }
208 void SetActiveFaviconURL(const GURL& favicon_url) override {
209 favicon_url_ = favicon_url;
212 gfx::Image GetActiveFaviconImage() override { return image_; }
214 void SetActiveFaviconImage(const gfx::Image& image) override {
215 image_ = image;
218 void OnFaviconAvailable(const gfx::Image& image,
219 const GURL& icon_url,
220 bool update_active_favicon) override {
221 ++num_favicon_available_;
222 available_image_ = image;
223 available_icon_url_ = icon_url;
224 update_active_favicon_ = update_active_favicon;
225 if (!update_active_favicon)
226 return;
228 ++num_active_favicon_;
229 SetActiveFaviconURL(icon_url);
230 SetActiveFaviconValidity(true);
231 SetActiveFaviconImage(image);
234 size_t num_active_favicon() const { return num_active_favicon_; }
235 size_t num_favicon_available() const { return num_favicon_available_; }
236 void ResetNumActiveFavicon() { num_active_favicon_ = 0; }
237 void ResetNumFaviconAvailable() { num_favicon_available_ = 0; }
239 void SetActiveURL(GURL url) { url_ = url; }
241 const gfx::Image available_favicon() { return available_image_; }
243 const GURL available_icon_url() { return available_icon_url_; }
245 bool update_active_favicon() { return update_active_favicon_; }
247 private:
248 GURL favicon_url_;
249 GURL url_;
250 gfx::Image image_;
251 bool favicon_validity_;
253 // The number of times that NotifyFaviconAvailable() has been called with
254 // |is_active_favicon| is true.
255 size_t num_active_favicon_;
256 // The number of times that NotifyFaviconAvailable() has been called.
257 size_t num_favicon_available_;
258 gfx::Image available_image_;
259 GURL available_icon_url_;
260 bool update_active_favicon_;
262 DISALLOW_COPY_AND_ASSIGN(TestFaviconDriver);
265 // This class is used to catch the FaviconHandler's download and history
266 // request, and also provide the methods to access the FaviconHandler
267 // internals.
268 class TestFaviconHandler : public favicon::FaviconHandler {
269 public:
270 static int GetMaximalIconSize(favicon_base::IconType icon_type) {
271 return FaviconHandler::GetMaximalIconSize(icon_type);
274 TestFaviconHandler(const GURL& page_url,
275 TestFaviconDriver* driver,
276 Type type,
277 bool download_largest_icon)
278 : favicon::FaviconHandler(nullptr,
279 driver,
280 type,
281 download_largest_icon),
282 download_id_(0) {
283 driver->SetActiveURL(page_url);
284 download_handler_.reset(new DownloadHandler(this));
287 ~TestFaviconHandler() override {}
289 HistoryRequestHandler* history_handler() {
290 return history_handler_.get();
293 // This method will take the ownership of the given handler.
294 void set_history_handler(HistoryRequestHandler* handler) {
295 history_handler_.reset(handler);
298 DownloadHandler* download_handler() {
299 return download_handler_.get();
302 // Methods to access favicon internals.
303 const std::vector<FaviconURL>& urls() {
304 return image_urls_;
307 FaviconURL* current_candidate() {
308 return favicon::FaviconHandler::current_candidate();
311 const FaviconCandidate& best_favicon_candidate() {
312 return best_favicon_candidate_;
315 protected:
316 void UpdateFaviconMappingAndFetch(
317 const GURL& page_url,
318 const GURL& icon_url,
319 favicon_base::IconType icon_type,
320 const favicon_base::FaviconResultsCallback& callback,
321 base::CancelableTaskTracker* tracker) override {
322 history_handler_.reset(new HistoryRequestHandler(page_url, icon_url,
323 icon_type, callback));
326 void GetFaviconFromFaviconService(
327 const GURL& icon_url,
328 favicon_base::IconType icon_type,
329 const favicon_base::FaviconResultsCallback& callback,
330 base::CancelableTaskTracker* tracker) override {
331 history_handler_.reset(new HistoryRequestHandler(GURL(), icon_url,
332 icon_type, callback));
335 void GetFaviconForURLFromFaviconService(
336 const GURL& page_url,
337 int icon_types,
338 const favicon_base::FaviconResultsCallback& callback,
339 base::CancelableTaskTracker* tracker) override {
340 history_handler_.reset(new HistoryRequestHandler(page_url, GURL(),
341 icon_types, callback));
344 int DownloadFavicon(const GURL& image_url, int max_bitmap_size) override {
345 download_id_++;
346 std::vector<int> sizes;
347 sizes.push_back(0);
348 download_handler_->AddDownload(
349 download_id_, image_url, sizes, max_bitmap_size);
350 return download_id_;
353 void SetHistoryFavicons(const GURL& page_url,
354 const GURL& icon_url,
355 favicon_base::IconType icon_type,
356 const gfx::Image& image) override {
357 scoped_refptr<base::RefCountedMemory> bytes = image.As1xPNGBytes();
358 std::vector<unsigned char> bitmap_data(bytes->front(),
359 bytes->front() + bytes->size());
360 history_handler_.reset(new HistoryRequestHandler(
361 page_url, icon_url, icon_type, bitmap_data, image.Size()));
364 bool ShouldSaveFavicon(const GURL& url) override { return true; }
366 GURL page_url_;
368 private:
370 // The unique id of a download request. It will be returned to a
371 // FaviconHandler.
372 int download_id_;
374 scoped_ptr<DownloadHandler> download_handler_;
375 scoped_ptr<HistoryRequestHandler> history_handler_;
377 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler);
380 namespace {
382 void HistoryRequestHandler::InvokeCallback() {
383 if (!callback_.is_null()) {
384 callback_.Run(history_results_);
388 void DownloadHandler::InvokeCallback() {
389 std::vector<gfx::Size> original_bitmap_sizes;
390 std::vector<SkBitmap> bitmaps;
391 if (!failed_) {
392 for (std::vector<int>::const_iterator i = download_->image_sizes.begin();
393 i != download_->image_sizes.end(); ++i) {
394 int original_size = (*i > 0) ? *i : gfx::kFaviconSize;
395 int downloaded_size = original_size;
396 if (download_->max_image_size != 0 &&
397 downloaded_size > download_->max_image_size) {
398 downloaded_size = download_->max_image_size;
400 SkBitmap bitmap;
401 FillDataToBitmap(downloaded_size, downloaded_size, &bitmap);
402 bitmaps.push_back(bitmap);
403 original_bitmap_sizes.push_back(gfx::Size(original_size, original_size));
406 favicon_helper_->OnDidDownloadFavicon(download_->download_id,
407 download_->image_url,
408 bitmaps,
409 original_bitmap_sizes);
412 class FaviconHandlerTest : public ChromeRenderViewHostTestHarness {
413 public:
414 FaviconHandlerTest() {
417 ~FaviconHandlerTest() override {}
419 // Simulates requesting a favicon for |page_url| given:
420 // - We have not previously cached anything in history for |page_url| or for
421 // any of |candidates|.
422 // - The page provides favicons at |candidate_icons|.
423 // - The favicons at |candidate_icons| have edge pixel sizes of
424 // |candidate_icon_sizes|.
425 void DownloadTillDoneIgnoringHistory(
426 TestFaviconDriver* favicon_driver,
427 TestFaviconHandler* favicon_handler,
428 const GURL& page_url,
429 const std::vector<FaviconURL>& candidate_icons,
430 const int* candidate_icon_sizes) {
431 UpdateFaviconURL(
432 favicon_driver, favicon_handler, page_url, candidate_icons);
433 EXPECT_EQ(candidate_icons.size(), favicon_handler->image_urls().size());
435 DownloadHandler* download_handler = favicon_handler->download_handler();
436 for (size_t i = 0; i < candidate_icons.size(); ++i) {
437 favicon_handler->history_handler()->history_results_.clear();
438 favicon_handler->history_handler()->InvokeCallback();
439 ASSERT_TRUE(download_handler->HasDownload());
440 EXPECT_EQ(download_handler->GetImageUrl(),
441 candidate_icons[i].icon_url);
442 std::vector<int> sizes;
443 sizes.push_back(candidate_icon_sizes[i]);
444 download_handler->SetImageSizes(sizes);
445 download_handler->InvokeCallback();
447 if (favicon_driver->num_active_favicon())
448 return;
452 void UpdateFaviconURL(TestFaviconDriver* favicon_driver,
453 TestFaviconHandler* favicon_handler,
454 const GURL& page_url,
455 const std::vector<FaviconURL>& candidate_icons) {
456 favicon_driver->ResetNumActiveFavicon();
458 favicon_handler->FetchFavicon(page_url);
459 favicon_handler->history_handler()->InvokeCallback();
461 favicon_handler->OnUpdateFaviconURL(candidate_icons);
464 void SetUp() override {
465 // The score computed by SelectFaviconFrames() is dependent on the supported
466 // scale factors of the platform. It is used for determining the goodness of
467 // a downloaded bitmap in favicon::FaviconHandler::OnDidDownloadFavicon().
468 // Force the values of the scale factors so that the tests produce the same
469 // results on all platforms.
470 std::vector<ui::ScaleFactor> scale_factors;
471 scale_factors.push_back(ui::SCALE_FACTOR_100P);
472 scoped_set_supported_scale_factors_.reset(
473 new ui::test::ScopedSetSupportedScaleFactors(scale_factors));
475 ChromeRenderViewHostTestHarness::SetUp();
478 void TearDown() override {
479 Profile* profile = Profile::FromBrowserContext(
480 web_contents()->GetBrowserContext());
481 FaviconServiceFactory::GetInstance()->SetTestingFactory(profile, nullptr);
482 ChromeRenderViewHostTestHarness::TearDown();
485 private:
486 typedef scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
487 ScopedSetSupportedScaleFactors;
488 ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_;
489 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerTest);
492 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
493 const GURL page_url("http://www.google.com");
494 const GURL icon_url("http://www.google.com/favicon");
496 TestFaviconDriver driver;
497 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::FAVICON,
498 false);
500 helper.FetchFavicon(page_url);
501 HistoryRequestHandler* history_handler = helper.history_handler();
502 // Ensure the data given to history is correct.
503 ASSERT_TRUE(history_handler);
504 EXPECT_EQ(page_url, history_handler->page_url_);
505 EXPECT_EQ(GURL(), history_handler->icon_url_);
506 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
508 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
510 // Send history response.
511 history_handler->InvokeCallback();
512 // Verify FaviconHandler status
513 EXPECT_TRUE(driver.GetActiveFaviconValidity());
514 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
516 // Simulates update favicon url.
517 std::vector<FaviconURL> urls;
518 urls.push_back(
519 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
520 helper.OnUpdateFaviconURL(urls);
522 // Verify FaviconHandler status
523 EXPECT_EQ(1U, helper.urls().size());
524 ASSERT_TRUE(helper.current_candidate());
525 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
526 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
528 // Favicon shouldn't request to download icon.
529 EXPECT_FALSE(helper.download_handler()->HasDownload());
532 TEST_F(FaviconHandlerTest, DownloadFavicon) {
533 const GURL page_url("http://www.google.com");
534 const GURL icon_url("http://www.google.com/favicon");
536 TestFaviconDriver driver;
537 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::FAVICON,
538 false);
540 helper.FetchFavicon(page_url);
541 HistoryRequestHandler* history_handler = helper.history_handler();
542 // Ensure the data given to history is correct.
543 ASSERT_TRUE(history_handler);
544 EXPECT_EQ(page_url, history_handler->page_url_);
545 EXPECT_EQ(GURL(), history_handler->icon_url_);
546 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
548 // Set icon data expired
549 SetFaviconRawBitmapResult(icon_url,
550 favicon_base::FAVICON,
551 true /* expired */,
552 &history_handler->history_results_);
553 // Send history response.
554 history_handler->InvokeCallback();
555 // Verify FaviconHandler status
556 EXPECT_TRUE(driver.GetActiveFaviconValidity());
557 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
559 // Simulates update favicon url.
560 std::vector<FaviconURL> urls;
561 urls.push_back(
562 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
563 helper.OnUpdateFaviconURL(urls);
565 // Verify FaviconHandler status
566 EXPECT_EQ(1U, helper.urls().size());
567 ASSERT_TRUE(helper.current_candidate());
568 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
569 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
571 // Favicon should request to download icon now.
572 DownloadHandler* download_handler = helper.download_handler();
573 EXPECT_TRUE(helper.download_handler()->HasDownload());
575 // Verify the download request.
576 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
578 // Reset the history_handler to verify whether favicon is set.
579 helper.set_history_handler(nullptr);
581 // Smulates download done.
582 download_handler->InvokeCallback();
584 // New icon should be saved to history backend and navigation entry.
585 history_handler = helper.history_handler();
586 ASSERT_TRUE(history_handler);
587 EXPECT_EQ(icon_url, history_handler->icon_url_);
588 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
589 EXPECT_LT(0U, history_handler->bitmap_data_.size());
590 EXPECT_EQ(page_url, history_handler->page_url_);
592 // Verify NavigationEntry.
593 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
594 EXPECT_TRUE(driver.GetActiveFaviconValidity());
595 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
596 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
599 TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) {
600 const GURL page_url("http://www.google.com");
601 const GURL icon_url("http://www.google.com/favicon");
602 const GURL new_icon_url("http://www.google.com/new_favicon");
604 TestFaviconDriver driver;
605 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::FAVICON,
606 false);
608 helper.FetchFavicon(page_url);
609 HistoryRequestHandler* history_handler = helper.history_handler();
610 // Ensure the data given to history is correct.
611 ASSERT_TRUE(history_handler);
612 EXPECT_EQ(page_url, history_handler->page_url_);
613 EXPECT_EQ(GURL(), history_handler->icon_url_);
614 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
616 // Set valid icon data.
617 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
619 // Send history response.
620 history_handler->InvokeCallback();
621 // Verify FaviconHandler status.
622 EXPECT_TRUE(driver.GetActiveFaviconValidity());
623 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
625 // Reset the history_handler to verify whether new icon is requested from
626 // history.
627 helper.set_history_handler(nullptr);
629 // Simulates update with the different favicon url.
630 std::vector<FaviconURL> urls;
631 urls.push_back(FaviconURL(
632 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
633 helper.OnUpdateFaviconURL(urls);
635 // Verify FaviconHandler status.
636 EXPECT_EQ(1U, helper.urls().size());
637 ASSERT_TRUE(helper.current_candidate());
638 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
639 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
641 // Favicon should be requested from history.
642 history_handler = helper.history_handler();
643 ASSERT_TRUE(history_handler);
644 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
645 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
646 EXPECT_EQ(page_url, history_handler->page_url_);
648 // Simulate not find icon.
649 history_handler->history_results_.clear();
650 history_handler->InvokeCallback();
652 // Favicon should request to download icon now.
653 DownloadHandler* download_handler = helper.download_handler();
654 EXPECT_TRUE(helper.download_handler()->HasDownload());
656 // Verify the download request.
657 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
659 // Reset the history_handler to verify whether favicon is set.
660 helper.set_history_handler(nullptr);
662 // Smulates download done.
663 download_handler->InvokeCallback();
665 // New icon should be saved to history backend and navigation entry.
666 history_handler = helper.history_handler();
667 ASSERT_TRUE(history_handler);
668 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
669 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
670 EXPECT_LT(0U, history_handler->bitmap_data_.size());
671 EXPECT_EQ(page_url, history_handler->page_url_);
673 // Verify NavigationEntry.
674 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
675 EXPECT_TRUE(driver.GetActiveFaviconValidity());
676 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
677 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
680 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
681 const GURL page_url("http://www.google.com");
682 const GURL icon_url("http://www.google.com/favicon");
684 TestFaviconDriver driver;
685 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::FAVICON,
686 false);
688 helper.FetchFavicon(page_url);
689 HistoryRequestHandler* history_handler = helper.history_handler();
690 // Ensure the data given to history is correct.
691 ASSERT_TRUE(history_handler);
692 EXPECT_EQ(page_url, history_handler->page_url_);
693 EXPECT_EQ(GURL(), history_handler->icon_url_);
694 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
696 // Set non empty but invalid data.
697 favicon_base::FaviconRawBitmapResult bitmap_result;
698 bitmap_result.expired = false;
699 // Empty bitmap data is invalid.
700 bitmap_result.bitmap_data = new base::RefCountedBytes();
701 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
702 bitmap_result.icon_type = favicon_base::FAVICON;
703 bitmap_result.icon_url = icon_url;
704 history_handler->history_results_.clear();
705 history_handler->history_results_.push_back(bitmap_result);
707 // Send history response.
708 history_handler->InvokeCallback();
709 // The NavigationEntry should not be set yet as the history data is invalid.
710 EXPECT_FALSE(driver.GetActiveFaviconValidity());
711 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
713 // Reset the history_handler to verify whether new icon is requested from
714 // history.
715 helper.set_history_handler(nullptr);
717 // Simulates update with matching favicon URL.
718 std::vector<FaviconURL> urls;
719 urls.push_back(
720 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
721 helper.OnUpdateFaviconURL(urls);
723 // A download for the favicon should be requested, and we should not do
724 // another history request.
725 DownloadHandler* download_handler = helper.download_handler();
726 EXPECT_TRUE(helper.download_handler()->HasDownload());
727 EXPECT_EQ(nullptr, helper.history_handler());
729 // Verify the download request.
730 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
732 // Simulates download done.
733 download_handler->InvokeCallback();
735 // New icon should be saved to history backend and navigation entry.
736 history_handler = helper.history_handler();
737 ASSERT_TRUE(history_handler);
738 EXPECT_EQ(icon_url, history_handler->icon_url_);
739 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
740 EXPECT_LT(0U, history_handler->bitmap_data_.size());
741 EXPECT_EQ(page_url, history_handler->page_url_);
743 // Verify NavigationEntry.
744 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
745 EXPECT_TRUE(driver.GetActiveFaviconValidity());
746 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
747 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
750 TEST_F(FaviconHandlerTest, UpdateFavicon) {
751 const GURL page_url("http://www.google.com");
752 const GURL icon_url("http://www.google.com/favicon");
753 const GURL new_icon_url("http://www.google.com/new_favicon");
755 TestFaviconDriver driver;
756 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::FAVICON,
757 false);
759 helper.FetchFavicon(page_url);
760 HistoryRequestHandler* history_handler = helper.history_handler();
761 // Ensure the data given to history is correct.
762 ASSERT_TRUE(history_handler);
763 EXPECT_EQ(page_url, history_handler->page_url_);
764 EXPECT_EQ(GURL(), history_handler->icon_url_);
765 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
767 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
769 // Send history response.
770 history_handler->InvokeCallback();
771 // Verify FaviconHandler status.
772 EXPECT_TRUE(driver.GetActiveFaviconValidity());
773 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
775 // Reset the history_handler to verify whether new icon is requested from
776 // history.
777 helper.set_history_handler(nullptr);
779 // Simulates update with the different favicon url.
780 std::vector<FaviconURL> urls;
781 urls.push_back(FaviconURL(
782 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
783 helper.OnUpdateFaviconURL(urls);
785 // Verify FaviconHandler status.
786 EXPECT_EQ(1U, helper.urls().size());
787 ASSERT_TRUE(helper.current_candidate());
788 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
789 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
791 // Favicon should be requested from history.
792 history_handler = helper.history_handler();
793 ASSERT_TRUE(history_handler);
794 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
795 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
796 EXPECT_EQ(page_url, history_handler->page_url_);
798 // Simulate find icon.
799 SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_);
800 history_handler->InvokeCallback();
802 // Shouldn't request download favicon
803 EXPECT_FALSE(helper.download_handler()->HasDownload());
805 // Verify the favicon status.
806 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
807 EXPECT_TRUE(driver.GetActiveFaviconValidity());
808 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
811 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
812 const GURL page_url("http://www.google.com");
813 const GURL icon_url("http://www.google.com/favicon");
814 const GURL new_icon_url("http://www.google.com/new_favicon");
816 TestFaviconDriver driver;
817 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::TOUCH,
818 false);
820 helper.FetchFavicon(page_url);
821 HistoryRequestHandler* history_handler = helper.history_handler();
822 // Ensure the data given to history is correct.
823 ASSERT_TRUE(history_handler);
824 EXPECT_EQ(page_url, history_handler->page_url_);
825 EXPECT_EQ(GURL(), history_handler->icon_url_);
826 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
827 history_handler->icon_type_);
829 // Icon not found.
830 history_handler->history_results_.clear();
831 // Send history response.
832 history_handler->InvokeCallback();
833 // Verify FaviconHandler status.
834 EXPECT_FALSE(driver.GetActiveFaviconValidity());
835 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
837 // Reset the history_handler to verify whether new icon is requested from
838 // history.
839 helper.set_history_handler(nullptr);
841 // Simulates update with the different favicon url.
842 std::vector<FaviconURL> urls;
843 urls.push_back(FaviconURL(icon_url,
844 favicon_base::TOUCH_PRECOMPOSED_ICON,
845 std::vector<gfx::Size>()));
846 urls.push_back(FaviconURL(
847 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
848 urls.push_back(FaviconURL(
849 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
850 helper.OnUpdateFaviconURL(urls);
852 // Verify FaviconHandler status.
853 EXPECT_EQ(2U, helper.urls().size());
854 ASSERT_TRUE(helper.current_candidate());
855 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
856 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
857 helper.current_candidate()->icon_type);
859 // Favicon should be requested from history.
860 history_handler = helper.history_handler();
861 ASSERT_TRUE(history_handler);
862 EXPECT_EQ(icon_url, history_handler->icon_url_);
863 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
864 EXPECT_EQ(page_url, history_handler->page_url_);
866 // Simulate not find icon.
867 history_handler->history_results_.clear();
868 history_handler->InvokeCallback();
870 // Should request download favicon.
871 DownloadHandler* download_handler = helper.download_handler();
872 EXPECT_TRUE(helper.download_handler()->HasDownload());
874 // Verify the download request.
875 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
877 // Reset the history_handler to verify whether favicon is request from
878 // history.
879 helper.set_history_handler(nullptr);
880 // Smulates download failed.
881 download_handler->set_failed(true);
882 download_handler->InvokeCallback();
884 // Left 1 url.
885 EXPECT_EQ(1U, helper.urls().size());
886 ASSERT_TRUE(helper.current_candidate());
887 EXPECT_EQ(new_icon_url, helper.current_candidate()->icon_url);
888 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
890 // Favicon should be requested from history.
891 history_handler = helper.history_handler();
892 ASSERT_TRUE(history_handler);
893 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
894 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
895 EXPECT_EQ(page_url, history_handler->page_url_);
897 // Reset download handler
898 download_handler->Reset();
900 // Simulates getting a expired icon from history.
901 SetFaviconRawBitmapResult(new_icon_url,
902 favicon_base::TOUCH_ICON,
903 true /* expired */,
904 &history_handler->history_results_);
905 history_handler->InvokeCallback();
907 // Verify the download request.
908 EXPECT_TRUE(helper.download_handler()->HasDownload());
909 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
911 helper.set_history_handler(nullptr);
913 // Simulates icon being downloaded.
914 download_handler->InvokeCallback();
916 // New icon should be saved to history backend.
917 history_handler = helper.history_handler();
918 ASSERT_TRUE(history_handler);
919 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
920 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
921 EXPECT_LT(0U, history_handler->bitmap_data_.size());
922 EXPECT_EQ(page_url, history_handler->page_url_);
925 TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
926 const GURL page_url("http://www.google.com");
927 const GURL icon_url("http://www.google.com/favicon");
928 const GURL new_icon_url("http://www.google.com/new_favicon");
930 TestFaviconDriver driver;
931 TestFaviconHandler helper(page_url, &driver, favicon::FaviconHandler::TOUCH,
932 false);
934 helper.FetchFavicon(page_url);
935 HistoryRequestHandler* history_handler = helper.history_handler();
936 // Ensure the data given to history is correct.
937 ASSERT_TRUE(history_handler);
938 EXPECT_EQ(page_url, history_handler->page_url_);
939 EXPECT_EQ(GURL(), history_handler->icon_url_);
940 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
941 history_handler->icon_type_);
943 // Icon not found.
944 history_handler->history_results_.clear();
945 // Send history response.
946 history_handler->InvokeCallback();
947 // Verify FaviconHandler status.
948 EXPECT_FALSE(driver.GetActiveFaviconValidity());
949 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
951 // Reset the history_handler to verify whether new icon is requested from
952 // history.
953 helper.set_history_handler(nullptr);
955 // Simulates update with the different favicon url.
956 std::vector<FaviconURL> urls;
957 urls.push_back(FaviconURL(icon_url,
958 favicon_base::TOUCH_PRECOMPOSED_ICON,
959 std::vector<gfx::Size>()));
960 urls.push_back(FaviconURL(
961 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
962 urls.push_back(FaviconURL(
963 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
964 helper.OnUpdateFaviconURL(urls);
966 // Verify FaviconHandler status.
967 EXPECT_EQ(2U, helper.urls().size());
968 ASSERT_TRUE(helper.current_candidate());
969 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
970 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
971 helper.current_candidate()->icon_type);
973 // Favicon should be requested from history.
974 history_handler = helper.history_handler();
975 ASSERT_TRUE(history_handler);
976 EXPECT_EQ(icon_url, history_handler->icon_url_);
977 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
978 EXPECT_EQ(page_url, history_handler->page_url_);
980 // Simulate not find icon.
981 history_handler->history_results_.clear();
982 history_handler->InvokeCallback();
984 // Should request download favicon.
985 DownloadHandler* download_handler = helper.download_handler();
986 EXPECT_TRUE(helper.download_handler()->HasDownload());
988 // Verify the download request.
989 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
991 // Reset the history_handler to verify whether favicon is request from
992 // history.
993 helper.set_history_handler(nullptr);
994 const GURL latest_icon_url("http://www.google.com/latest_favicon");
995 std::vector<FaviconURL> latest_urls;
996 latest_urls.push_back(FaviconURL(
997 latest_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
998 helper.OnUpdateFaviconURL(latest_urls);
1000 EXPECT_EQ(1U, helper.urls().size());
1001 EXPECT_EQ(latest_icon_url, helper.current_candidate()->icon_url);
1002 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
1004 // Whether new icon is requested from history
1005 history_handler = helper.history_handler();
1006 ASSERT_TRUE(history_handler);
1007 EXPECT_EQ(latest_icon_url, history_handler->icon_url_);
1008 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
1009 EXPECT_EQ(page_url, history_handler->page_url_);
1011 // Reset the history_handler to verify whether favicon is request from
1012 // history.
1013 // Save the callback for late use.
1014 favicon_base::FaviconResultsCallback callback = history_handler->callback_;
1015 helper.set_history_handler(nullptr);
1017 // Simulates download succeed.
1018 download_handler->InvokeCallback();
1019 // The downloaded icon should be thrown away as there is favicon update.
1020 EXPECT_FALSE(helper.history_handler());
1022 download_handler->Reset();
1024 // Simulates getting the icon from history.
1025 scoped_ptr<HistoryRequestHandler> handler;
1026 handler.reset(new HistoryRequestHandler(
1027 page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback));
1028 SetFaviconRawBitmapResult(latest_icon_url,
1029 favicon_base::TOUCH_ICON,
1030 false /* expired */,
1031 &handler->history_results_);
1032 handler->InvokeCallback();
1034 // No download request.
1035 EXPECT_FALSE(download_handler->HasDownload());
1038 #if !defined(OS_ANDROID)
1040 // Test the favicon which is selected when the web page provides several
1041 // favicons and none of the favicons are cached in history.
1042 // The goal of this test is to be more of an integration test than
1043 // SelectFaviconFramesTest.*.
1044 TEST_F(FaviconHandlerTest, MultipleFavicons) {
1045 const GURL kPageURL("http://www.google.com");
1046 const FaviconURL kSourceIconURLs[] = {
1047 FaviconURL(GURL("http://www.google.com/a"),
1048 favicon_base::FAVICON,
1049 std::vector<gfx::Size>()),
1050 FaviconURL(GURL("http://www.google.com/b"),
1051 favicon_base::FAVICON,
1052 std::vector<gfx::Size>()),
1053 FaviconURL(GURL("http://www.google.com/c"),
1054 favicon_base::FAVICON,
1055 std::vector<gfx::Size>()),
1056 FaviconURL(GURL("http://www.google.com/d"),
1057 favicon_base::FAVICON,
1058 std::vector<gfx::Size>()),
1059 FaviconURL(GURL("http://www.google.com/e"),
1060 favicon_base::FAVICON,
1061 std::vector<gfx::Size>())};
1063 // Set the supported scale factors to 1x and 2x. This affects the behavior of
1064 // SelectFaviconFrames().
1065 std::vector<ui::ScaleFactor> scale_factors;
1066 scale_factors.push_back(ui::SCALE_FACTOR_100P);
1067 scale_factors.push_back(ui::SCALE_FACTOR_200P);
1068 ui::test::ScopedSetSupportedScaleFactors scoped_supported(scale_factors);
1070 // 1) Test that if there are several single resolution favicons to choose from
1071 // that the largest exact match is chosen.
1072 TestFaviconDriver driver1;
1073 TestFaviconHandler handler1(kPageURL, &driver1,
1074 favicon::FaviconHandler::FAVICON, false);
1076 const int kSizes1[] = { 16, 24, 32, 48, 256 };
1077 std::vector<FaviconURL> urls1(kSourceIconURLs,
1078 kSourceIconURLs + arraysize(kSizes1));
1079 DownloadTillDoneIgnoringHistory(
1080 &driver1, &handler1, kPageURL, urls1, kSizes1);
1082 EXPECT_EQ(0u, handler1.image_urls().size());
1083 EXPECT_TRUE(driver1.GetActiveFaviconValidity());
1084 EXPECT_FALSE(driver1.GetActiveFaviconImage().IsEmpty());
1085 EXPECT_EQ(gfx::kFaviconSize, driver1.GetActiveFaviconImage().Width());
1087 size_t expected_index = 2u;
1088 EXPECT_EQ(32, kSizes1[expected_index]);
1089 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1090 driver1.GetActiveFaviconURL());
1092 // 2) Test that if there are several single resolution favicons to choose
1093 // from, the exact match is preferred even if it results in upsampling.
1094 TestFaviconDriver driver2;
1095 TestFaviconHandler handler2(kPageURL, &driver2,
1096 favicon::FaviconHandler::FAVICON, false);
1098 const int kSizes2[] = { 16, 24, 48, 256 };
1099 std::vector<FaviconURL> urls2(kSourceIconURLs,
1100 kSourceIconURLs + arraysize(kSizes2));
1101 DownloadTillDoneIgnoringHistory(
1102 &driver2, &handler2, kPageURL, urls2, kSizes2);
1103 EXPECT_TRUE(driver2.GetActiveFaviconValidity());
1104 expected_index = 0u;
1105 EXPECT_EQ(16, kSizes2[expected_index]);
1106 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1107 driver2.GetActiveFaviconURL());
1109 // 3) Test that favicons which need to be upsampled a little or downsampled
1110 // a little are preferred over huge favicons.
1111 TestFaviconDriver driver3;
1112 TestFaviconHandler handler3(kPageURL, &driver3,
1113 favicon::FaviconHandler::FAVICON, false);
1115 const int kSizes3[] = { 256, 48 };
1116 std::vector<FaviconURL> urls3(kSourceIconURLs,
1117 kSourceIconURLs + arraysize(kSizes3));
1118 DownloadTillDoneIgnoringHistory(
1119 &driver3, &handler3, kPageURL, urls3, kSizes3);
1120 EXPECT_TRUE(driver3.GetActiveFaviconValidity());
1121 expected_index = 1u;
1122 EXPECT_EQ(48, kSizes3[expected_index]);
1123 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1124 driver3.GetActiveFaviconURL());
1126 TestFaviconDriver driver4;
1127 TestFaviconHandler handler4(kPageURL, &driver4,
1128 favicon::FaviconHandler::FAVICON, false);
1130 const int kSizes4[] = { 17, 256 };
1131 std::vector<FaviconURL> urls4(kSourceIconURLs,
1132 kSourceIconURLs + arraysize(kSizes4));
1133 DownloadTillDoneIgnoringHistory(
1134 &driver4, &handler4, kPageURL, urls4, kSizes4);
1135 EXPECT_TRUE(driver4.GetActiveFaviconValidity());
1136 expected_index = 0u;
1137 EXPECT_EQ(17, kSizes4[expected_index]);
1138 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1139 driver4.GetActiveFaviconURL());
1142 #endif
1144 TEST_F(FaviconHandlerTest, TestSortFavicon) {
1145 const GURL kPageURL("http://www.google.com");
1146 std::vector<gfx::Size> icon1;
1147 icon1.push_back(gfx::Size(1024, 1024));
1148 icon1.push_back(gfx::Size(512, 512));
1150 std::vector<gfx::Size> icon2;
1151 icon2.push_back(gfx::Size(15, 15));
1152 icon2.push_back(gfx::Size(16, 16));
1154 std::vector<gfx::Size> icon3;
1155 icon3.push_back(gfx::Size(16, 16));
1156 icon3.push_back(gfx::Size(14, 14));
1158 const FaviconURL kSourceIconURLs[] = {
1159 FaviconURL(GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
1160 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
1161 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
1162 FaviconURL(GURL("http://www.google.com/d"),
1163 favicon_base::FAVICON,
1164 std::vector<gfx::Size>()),
1165 FaviconURL(GURL("http://www.google.com/e"),
1166 favicon_base::FAVICON,
1167 std::vector<gfx::Size>())};
1169 TestFaviconDriver driver1;
1170 TestFaviconHandler handler1(kPageURL, &driver1,
1171 favicon::FaviconHandler::FAVICON, true);
1172 std::vector<FaviconURL> urls1(kSourceIconURLs,
1173 kSourceIconURLs + arraysize(kSourceIconURLs));
1174 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1176 struct ExpectedResult {
1177 // The favicon's index in kSourceIconURLs.
1178 size_t favicon_index;
1179 // Width of largest bitmap.
1180 int width;
1181 } results[] = {
1182 // First is icon1, though its size larger than maximal.
1183 {0, 1024},
1184 // Second is icon2
1185 // The 16x16 is largest.
1186 {1, 16},
1187 // Third is icon3 though it has same size as icon2.
1188 // The 16x16 is largest.
1189 {2, 16},
1190 // The rest of bitmaps come in order, there is no sizes attribute.
1191 {3, -1},
1192 {4, -1},
1194 const std::vector<FaviconURL>& icons = handler1.image_urls();
1195 ASSERT_EQ(5u, icons.size());
1196 for (size_t i = 0; i < icons.size(); ++i) {
1197 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1198 icons[i].icon_url);
1199 if (results[i].width != -1)
1200 EXPECT_EQ(results[i].width, icons[i].icon_sizes[0].width());
1204 TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {
1205 const GURL kPageURL("http://www.google.com");
1206 std::vector<gfx::Size> icon1;
1207 icon1.push_back(gfx::Size(1024, 1024));
1208 icon1.push_back(gfx::Size(512, 512));
1210 std::vector<gfx::Size> icon2;
1211 icon2.push_back(gfx::Size(15, 15));
1212 icon2.push_back(gfx::Size(14, 14));
1214 std::vector<gfx::Size> icon3;
1215 icon3.push_back(gfx::Size(16, 16));
1216 icon3.push_back(gfx::Size(512, 512));
1218 const FaviconURL kSourceIconURLs[] = {
1219 FaviconURL(
1220 GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
1221 FaviconURL(
1222 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
1223 FaviconURL(
1224 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
1225 FaviconURL(GURL("http://www.google.com/d"),
1226 favicon_base::FAVICON,
1227 std::vector<gfx::Size>()),
1228 FaviconURL(GURL("http://www.google.com/e"),
1229 favicon_base::FAVICON,
1230 std::vector<gfx::Size>())};
1232 TestFaviconDriver driver1;
1233 TestFaviconHandler handler1(kPageURL, &driver1,
1234 favicon::FaviconHandler::FAVICON, true);
1235 std::vector<FaviconURL> urls1(kSourceIconURLs,
1236 kSourceIconURLs + arraysize(kSourceIconURLs));
1237 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1239 // Simulate the download failed, to check whether the icons were requested
1240 // to download according their size.
1241 struct ExpectedResult {
1242 // The size of image_urls_.
1243 size_t image_urls_size;
1244 // The favicon's index in kSourceIconURLs.
1245 size_t favicon_index;
1246 // Width of largest bitmap.
1247 int width;
1248 } results[] = {
1249 {5, 0, 1024},
1250 {4, 2, 512},
1251 {3, 1, 15},
1252 // The rest of bitmaps come in order.
1253 {2, 3, -1},
1254 {1, 4, -1},
1257 for (int i = 0; i < 5; ++i) {
1258 ASSERT_EQ(results[i].image_urls_size, handler1.image_urls().size());
1259 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1260 handler1.current_candidate()->icon_url);
1261 if (results[i].width != -1) {
1262 EXPECT_EQ(results[i].width, handler1.current_candidate()->
1263 icon_sizes[0].width());
1266 // Simulate no favicon from history.
1267 handler1.history_handler()->history_results_.clear();
1268 handler1.history_handler()->InvokeCallback();
1270 // Verify download request
1271 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1272 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1273 handler1.download_handler()->GetImageUrl());
1275 // Simulate the download failed.
1276 handler1.download_handler()->set_failed(true);
1277 handler1.download_handler()->InvokeCallback();
1281 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
1282 const GURL kPageURL("http://www.google.com");
1284 std::vector<gfx::Size> one_icon;
1285 one_icon.push_back(gfx::Size(15, 15));
1287 std::vector<gfx::Size> two_icons;
1288 two_icons.push_back(gfx::Size(14, 14));
1289 two_icons.push_back(gfx::Size(16, 16));
1291 const FaviconURL kSourceIconURLs[] = {
1292 FaviconURL(
1293 GURL("http://www.google.com/b"), favicon_base::FAVICON, one_icon),
1294 FaviconURL(
1295 GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons)};
1297 TestFaviconDriver driver1;
1298 TestFaviconHandler handler1(kPageURL, &driver1,
1299 favicon::FaviconHandler::FAVICON, true);
1300 std::vector<FaviconURL> urls1(kSourceIconURLs,
1301 kSourceIconURLs + arraysize(kSourceIconURLs));
1302 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1304 ASSERT_EQ(2u, handler1.urls().size());
1306 // Index of largest favicon in kSourceIconURLs.
1307 size_t i = 1;
1308 // The largest bitmap's index in Favicon .
1309 int b = 1;
1311 // Verify the icon_bitmaps_ was initialized correctly.
1312 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1313 handler1.current_candidate()->icon_url);
1314 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1315 handler1.current_candidate()->icon_sizes[0]);
1317 // Simulate no favicon from history.
1318 handler1.history_handler()->history_results_.clear();
1319 handler1.history_handler()->InvokeCallback();
1321 // Verify download request
1322 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1323 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1324 handler1.download_handler()->GetImageUrl());
1326 // Give the correct download result.
1327 std::vector<int> sizes;
1328 for (std::vector<gfx::Size>::const_iterator j =
1329 kSourceIconURLs[i].icon_sizes.begin();
1330 j != kSourceIconURLs[i].icon_sizes.end(); ++j)
1331 sizes.push_back(j->width());
1333 handler1.download_handler()->SetImageSizes(sizes);
1334 handler1.download_handler()->InvokeCallback();
1336 // Verify the largest bitmap has been saved into history.
1337 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
1338 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1339 handler1.history_handler()->size_);
1340 // Verify NotifyFaviconAvailable().
1341 EXPECT_FALSE(driver1.update_active_favicon());
1342 EXPECT_EQ(kSourceIconURLs[i].icon_url, driver1.available_icon_url());
1343 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1344 driver1.available_favicon().Size());
1347 TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {
1348 const GURL kPageURL("http://www.google.com");
1349 const int kMaximalSize =
1350 TestFaviconHandler::GetMaximalIconSize(favicon_base::FAVICON);
1352 std::vector<gfx::Size> icon1;
1353 icon1.push_back(gfx::Size(kMaximalSize + 1, kMaximalSize + 1));
1355 std::vector<gfx::Size> icon2;
1356 icon2.push_back(gfx::Size(kMaximalSize + 2, kMaximalSize + 2));
1358 const FaviconURL kSourceIconURLs[] = {
1359 FaviconURL(
1360 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
1361 FaviconURL(
1362 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2)};
1364 TestFaviconDriver driver1;
1365 TestFaviconHandler handler1(kPageURL, &driver1,
1366 favicon::FaviconHandler::FAVICON, true);
1367 std::vector<FaviconURL> urls1(kSourceIconURLs,
1368 kSourceIconURLs + arraysize(kSourceIconURLs));
1369 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1371 ASSERT_EQ(2u, handler1.urls().size());
1373 // Index of largest favicon in kSourceIconURLs.
1374 size_t i = 1;
1375 // The largest bitmap's index in Favicon .
1376 int b = 0;
1378 // Verify the icon_bitmaps_ was initialized correctly.
1379 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1380 handler1.current_candidate()->icon_url);
1381 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1382 handler1.current_candidate()->icon_sizes[0]);
1384 // Simulate no favicon from history.
1385 handler1.history_handler()->history_results_.clear();
1386 handler1.history_handler()->InvokeCallback();
1388 // Verify download request
1389 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1390 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1391 handler1.download_handler()->GetImageUrl());
1393 // Give the scaled download bitmap.
1394 std::vector<int> sizes;
1395 sizes.push_back(kMaximalSize);
1397 handler1.download_handler()->SetImageSizes(sizes);
1398 handler1.download_handler()->InvokeCallback();
1400 // Verify the largest bitmap has been saved into history though it was
1401 // scaled down to maximal size and smaller than icon1 now.
1402 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
1403 EXPECT_EQ(gfx::Size(kMaximalSize, kMaximalSize),
1404 handler1.history_handler()->size_);
1407 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
1408 const GURL kPageURL("http://www.google.com");
1410 std::vector<gfx::Size> icon1;
1411 icon1.push_back(gfx::Size(16, 16));
1412 const int actual_size1 = 10;
1414 std::vector<gfx::Size> icon2;
1415 icon2.push_back(gfx::Size(15, 15));
1416 const int actual_size2 = 12;
1418 const FaviconURL kSourceIconURLs[] = {
1419 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
1420 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2),
1421 FaviconURL(GURL("http://www.google.com/d"),
1422 favicon_base::FAVICON,
1423 std::vector<gfx::Size>())};
1425 TestFaviconDriver driver1;
1426 TestFaviconHandler handler1(kPageURL, &driver1,
1427 favicon::FaviconHandler::FAVICON, true);
1428 std::vector<FaviconURL> urls1(kSourceIconURLs,
1429 kSourceIconURLs + arraysize(kSourceIconURLs));
1430 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1431 ASSERT_EQ(3u, handler1.urls().size());
1433 // Simulate no favicon from history.
1434 handler1.history_handler()->history_results_.clear();
1435 handler1.history_handler()->InvokeCallback();
1437 // Verify the first icon was request to download
1438 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1439 EXPECT_EQ(kSourceIconURLs[0].icon_url,
1440 handler1.download_handler()->GetImageUrl());
1442 // Give the incorrect size.
1443 std::vector<int> sizes;
1444 sizes.push_back(actual_size1);
1445 handler1.download_handler()->SetImageSizes(sizes);
1446 handler1.download_handler()->InvokeCallback();
1448 // Simulate no favicon from history.
1449 handler1.history_handler()->history_results_.clear();
1450 handler1.history_handler()->InvokeCallback();
1452 // Verify the 2nd icon was request to download
1453 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1454 EXPECT_EQ(kSourceIconURLs[1].icon_url,
1455 handler1.download_handler()->GetImageUrl());
1457 // Very the best candidate is icon1
1458 EXPECT_EQ(kSourceIconURLs[0].icon_url,
1459 handler1.best_favicon_candidate().image_url);
1460 EXPECT_EQ(gfx::Size(actual_size1, actual_size1),
1461 handler1.best_favicon_candidate().image.Size());
1463 // Give the incorrect size.
1464 sizes.clear();
1465 sizes.push_back(actual_size2);
1466 handler1.download_handler()->SetImageSizes(sizes);
1467 handler1.download_handler()->InvokeCallback();
1469 // Verify icon2 has been saved into history.
1470 EXPECT_EQ(kSourceIconURLs[1].icon_url, handler1.history_handler()->icon_url_);
1471 EXPECT_EQ(gfx::Size(actual_size2, actual_size2),
1472 handler1.history_handler()->size_);
1475 static KeyedService* BuildFaviconService(content::BrowserContext* context) {
1476 Profile* profile = Profile::FromBrowserContext(context);
1477 return new favicon::FaviconService(
1478 ChromeFaviconClientFactory::GetForProfile(profile),
1479 HistoryServiceFactory::GetForProfile(profile,
1480 ServiceAccessType::EXPLICIT_ACCESS));
1483 static KeyedService* BuildHistoryService(content::BrowserContext* context) {
1484 return nullptr;
1487 // Test that Favicon is not requested repeatedly during the same session if
1488 // server returns HTTP 404 status.
1489 TEST_F(FaviconHandlerTest, UnableToDownloadFavicon) {
1490 const GURL missing_icon_url("http://www.google.com/favicon.ico");
1491 const GURL another_icon_url("http://www.youtube.com/favicon.ico");
1493 Profile* profile = Profile::FromBrowserContext(
1494 web_contents()->GetBrowserContext());
1496 FaviconServiceFactory::GetInstance()->SetTestingFactory(
1497 profile, BuildFaviconService);
1499 HistoryServiceFactory::GetInstance()->SetTestingFactory(
1500 profile, BuildHistoryService);
1502 favicon::FaviconService* favicon_service =
1503 FaviconServiceFactory::GetForProfile(profile,
1504 ServiceAccessType::IMPLICIT_ACCESS);
1506 FaviconTabHelper::CreateForWebContents(web_contents());
1507 FaviconTabHelper* favicon_tab_helper =
1508 FaviconTabHelper::FromWebContents(web_contents());
1510 std::vector<SkBitmap> empty_icons;
1511 std::vector<gfx::Size> empty_icon_sizes;
1512 int download_id = 0;
1514 // Try to download missing icon.
1515 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1516 EXPECT_NE(0, download_id);
1517 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1519 // Report download failure with HTTP 503 status.
1520 favicon_tab_helper->DidDownloadFavicon(download_id, 503, missing_icon_url,
1521 empty_icons, empty_icon_sizes);
1522 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1523 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1525 // Try to download again.
1526 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1527 EXPECT_NE(0, download_id);
1528 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1530 // Report download failure with HTTP 404 status.
1531 favicon_tab_helper->DidDownloadFavicon(download_id, 404, missing_icon_url,
1532 empty_icons, empty_icon_sizes);
1533 // Icon is marked as UnableToDownload.
1534 EXPECT_TRUE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1536 // Try to download again.
1537 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1538 // Download is not started and Icon is still marked as UnableToDownload.
1539 EXPECT_EQ(0, download_id);
1540 EXPECT_TRUE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1542 // Try to download another icon.
1543 download_id = favicon_tab_helper->StartDownload(another_icon_url, 0);
1544 // Download is started as another icon URL is not same as missing_icon_url.
1545 EXPECT_NE(0, download_id);
1546 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(another_icon_url));
1548 // Clear the list of missing icons.
1549 favicon_service->ClearUnableToDownloadFavicons();
1550 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1551 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(another_icon_url));
1553 // Try to download again.
1554 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1555 EXPECT_NE(0, download_id);
1556 // Report download success with HTTP 200 status.
1557 favicon_tab_helper->DidDownloadFavicon(download_id, 200, missing_icon_url,
1558 empty_icons, empty_icon_sizes);
1559 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1560 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1563 class FaviconHandlerActiveFaviconValidityParamTest :
1564 public FaviconHandlerTest,
1565 public ::testing::WithParamInterface<bool> {
1566 public:
1567 FaviconHandlerActiveFaviconValidityParamTest() {}
1569 ~FaviconHandlerActiveFaviconValidityParamTest() override {}
1571 bool GetActiveFaviconValiditySetting() {
1572 return GetParam();
1575 private:
1576 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerActiveFaviconValidityParamTest);
1579 TEST_P(FaviconHandlerActiveFaviconValidityParamTest,
1580 TestDownloadLargestIconDoesNotImpactActiveFaviconValidity) {
1581 const GURL page_url("http://www.google.com");
1583 std::vector<gfx::Size> one_icon;
1584 one_icon.push_back(gfx::Size(15, 15));
1586 const GURL old_favicon_url("http://www.google.com/old");
1587 const GURL new_favicon_url("http://www.google.com/b");
1588 const FaviconURL source_icon_urls[] = {
1589 FaviconURL(new_favicon_url, favicon_base::FAVICON, one_icon)};
1590 TestFaviconDriver driver1;
1591 TestFaviconHandler handler1(page_url, &driver1,
1592 favicon::FaviconHandler::FAVICON, true);
1593 std::vector<FaviconURL> urls1(source_icon_urls,
1594 source_icon_urls + arraysize(source_icon_urls));
1595 UpdateFaviconURL(&driver1, &handler1, page_url, urls1);
1597 HistoryRequestHandler* history_handler = handler1.history_handler();
1599 // Simulate the active favicon is updated, this shouldn't happen in real
1600 // use case, but we want to verify the behavior below is not impacted by
1601 // accident.
1602 driver1.SetActiveFaviconValidity(GetActiveFaviconValiditySetting());
1603 // Simulate the get favicon from history, but favicon URL didn't match.
1604 SetFaviconRawBitmapResult(old_favicon_url,
1605 &history_handler->history_results_);
1606 history_handler->InvokeCallback();
1607 // Since we downloaded largest icon, and don't want to set active favicon
1608 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1609 EXPECT_EQ(old_favicon_url, driver1.available_icon_url());
1610 EXPECT_FALSE(driver1.update_active_favicon());
1611 EXPECT_EQ(1u, driver1.num_favicon_available());
1613 // We are trying to get favicon from history again.
1614 history_handler = handler1.history_handler();
1615 EXPECT_EQ(new_favicon_url, history_handler->icon_url_);
1616 // Simulate the get expired favicon from history.
1617 history_handler->history_results_.clear();
1618 SetFaviconRawBitmapResult(new_favicon_url, favicon_base::FAVICON, true,
1619 &history_handler->history_results_);
1620 history_handler->InvokeCallback();
1621 // Since we downloaded largest icon, and don't want to set active favicon
1622 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1623 EXPECT_EQ(new_favicon_url, driver1.available_icon_url());
1624 EXPECT_FALSE(driver1.update_active_favicon());
1625 EXPECT_EQ(2u, driver1.num_favicon_available());
1627 // We are trying to download favicon.
1628 DownloadHandler* download_handler = handler1.download_handler();
1629 EXPECT_TRUE(download_handler->HasDownload());
1630 EXPECT_EQ(new_favicon_url, download_handler->GetImageUrl());
1631 // Simulate the download succeed.
1632 download_handler->InvokeCallback();
1633 // Since we downloaded largest icon, and don't want to set active favicon
1634 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1635 EXPECT_EQ(new_favicon_url, driver1.available_icon_url());
1636 EXPECT_FALSE(driver1.update_active_favicon());
1637 EXPECT_EQ(3u, driver1.num_favicon_available());
1640 INSTANTIATE_TEST_CASE_P(FaviconHandlerTestActiveFaviconValidityTrueOrFalse,
1641 FaviconHandlerActiveFaviconValidityParamTest,
1642 ::testing::Bool());
1644 } // namespace.