ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / favicon / favicon_handler_unittest.cc
blob9f30374a41eb2050d403c8ca7f555f01d21ef424
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 "chrome/browser/favicon/favicon_handler.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "chrome/browser/favicon/chrome_favicon_client.h"
9 #include "chrome/browser/favicon/chrome_favicon_client_factory.h"
10 #include "chrome/browser/favicon/favicon_service.h"
11 #include "chrome/browser/favicon/favicon_service_factory.h"
12 #include "chrome/browser/favicon/favicon_tab_helper.h"
13 #include "chrome/browser/history/history_service_factory.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
16 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "ui/gfx/codec/png_codec.h"
18 #include "ui/gfx/favicon_size.h"
19 #include "ui/gfx/image/image.h"
21 class TestFaviconHandler;
23 using favicon::FaviconURL;
25 namespace {
27 // Fill the given bmp with valid png data.
28 void FillDataToBitmap(int w, int h, SkBitmap* bmp) {
29 bmp->allocN32Pixels(w, h);
31 unsigned char* src_data =
32 reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0));
33 for (int i = 0; i < w * h; i++) {
34 src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255);
35 src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255);
36 src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255);
37 src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255);
41 // Fill the given data buffer with valid png data.
42 void FillBitmap(int w, int h, std::vector<unsigned char>* output) {
43 SkBitmap bitmap;
44 FillDataToBitmap(w, h, &bitmap);
45 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output);
48 void SetFaviconRawBitmapResult(
49 const GURL& icon_url,
50 favicon_base::IconType icon_type,
51 bool expired,
52 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
53 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
54 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data());
55 favicon_base::FaviconRawBitmapResult bitmap_result;
56 bitmap_result.expired = expired;
57 bitmap_result.bitmap_data = data;
58 // Use a pixel size other than (0,0) as (0,0) has a special meaning.
59 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
60 bitmap_result.icon_type = icon_type;
61 bitmap_result.icon_url = icon_url;
63 favicon_bitmap_results->push_back(bitmap_result);
66 void SetFaviconRawBitmapResult(
67 const GURL& icon_url,
68 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
69 SetFaviconRawBitmapResult(icon_url,
70 favicon_base::FAVICON,
71 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 {
78 public:
79 explicit DownloadHandler(TestFaviconHandler* favicon_helper)
80 : favicon_helper_(favicon_helper),
81 failed_(false) {
84 virtual ~DownloadHandler() {
87 void Reset() {
88 download_.reset(NULL);
89 failed_ = false;
92 void AddDownload(
93 int download_id,
94 const GURL& image_url,
95 const std::vector<int>& image_sizes,
96 int max_image_size) {
97 download_.reset(new Download(
98 download_id, image_url, image_sizes, 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 SetImageSizes(const std::vector<int>& sizes) {
108 download_->image_sizes = sizes; }
110 private:
111 struct Download {
112 Download(int id,
113 GURL url,
114 const std::vector<int>& sizes,
115 int max_size,
116 bool failed)
117 : download_id(id),
118 image_url(url),
119 image_sizes(sizes),
120 max_image_size(max_size) {}
121 ~Download() {}
122 int download_id;
123 GURL image_url;
124 std::vector<int> image_sizes;
125 int max_image_size;
128 TestFaviconHandler* favicon_helper_;
129 scoped_ptr<Download> download_;
130 bool failed_;
132 DISALLOW_COPY_AND_ASSIGN(DownloadHandler);
135 // This class is used to save the history request for verifying with test case.
136 // It also will be used to simulate the history response.
137 class HistoryRequestHandler {
138 public:
139 HistoryRequestHandler(const GURL& page_url,
140 const GURL& icon_url,
141 int icon_type,
142 const favicon_base::FaviconResultsCallback& callback)
143 : page_url_(page_url),
144 icon_url_(icon_url),
145 icon_type_(icon_type),
146 callback_(callback) {
149 HistoryRequestHandler(const GURL& page_url,
150 const GURL& icon_url,
151 int icon_type,
152 const std::vector<unsigned char>& bitmap_data,
153 const gfx::Size& size)
154 : page_url_(page_url),
155 icon_url_(icon_url),
156 icon_type_(icon_type),
157 bitmap_data_(bitmap_data),
158 size_(size) {
161 virtual ~HistoryRequestHandler() {}
162 void InvokeCallback();
164 const GURL page_url_;
165 const GURL icon_url_;
166 const int icon_type_;
167 const std::vector<unsigned char> bitmap_data_;
168 const gfx::Size size_;
169 std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
170 favicon_base::FaviconResultsCallback callback_;
172 private:
173 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler);
176 } // namespace
178 class TestFaviconClient : public FaviconClient {
179 public:
180 ~TestFaviconClient() override{};
182 FaviconService* GetFaviconService() override {
183 // Just give none NULL value, so overridden methods can be hit.
184 return (FaviconService*)(1);
187 bool IsBookmarked(const GURL& url) override { return false; }
190 class TestFaviconDriver : public FaviconDriver {
191 public:
192 TestFaviconDriver()
193 : favicon_validity_(false),
194 num_active_favicon_(0),
195 num_favicon_available_(0),
196 update_active_favicon_(false) {}
198 virtual ~TestFaviconDriver() {
201 bool IsOffTheRecord() override { return false; }
203 const gfx::Image GetActiveFaviconImage() override { return image_; }
205 const GURL GetActiveFaviconURL() override { return favicon_url_; }
207 bool GetActiveFaviconValidity() override { return favicon_validity_; }
209 const GURL GetActiveURL() override { return url_; }
211 void SetActiveFaviconImage(gfx::Image image) { image_ = image; }
213 void SetActiveFaviconURL(GURL favicon_url) { favicon_url_ = favicon_url; }
215 void SetActiveFaviconValidity(bool favicon_validity) {
216 favicon_validity_ = favicon_validity;
219 int StartDownload(const GURL& url, int max_bitmap_size) override {
220 ADD_FAILURE() << "TestFaviconDriver::StartDownload() "
221 << "should never be called in tests.";
222 return -1;
225 void OnFaviconAvailable(const gfx::Image& image,
226 const GURL& icon_url,
227 bool update_active_favicon) override {
228 ++num_favicon_available_;
229 available_image_ = image;
230 available_icon_url_ = icon_url;
231 update_active_favicon_ = update_active_favicon;
232 if (!update_active_favicon)
233 return;
235 ++num_active_favicon_;
236 SetActiveFaviconURL(icon_url);
237 SetActiveFaviconValidity(true);
238 SetActiveFaviconImage(image);
241 size_t num_active_favicon() const { return num_active_favicon_; }
242 size_t num_favicon_available() const { return num_favicon_available_; }
243 void ResetNumActiveFavicon() { num_active_favicon_ = 0; }
244 void ResetNumFaviconAvailable() { num_favicon_available_ = 0; }
246 void SetActiveURL(GURL url) { url_ = url; }
248 const gfx::Image available_favicon() { return available_image_; }
250 const GURL available_icon_url() { return available_icon_url_; }
252 bool update_active_favicon() { return update_active_favicon_; }
254 private:
255 GURL favicon_url_;
256 GURL url_;
257 gfx::Image image_;
258 bool favicon_validity_;
260 // The number of times that NotifyFaviconAvailable() has been called with
261 // |is_active_favicon| is true.
262 size_t num_active_favicon_;
263 // The number of times that NotifyFaviconAvailable() has been called.
264 size_t num_favicon_available_;
265 gfx::Image available_image_;
266 GURL available_icon_url_;
267 bool update_active_favicon_;
269 DISALLOW_COPY_AND_ASSIGN(TestFaviconDriver);
272 // This class is used to catch the FaviconHandler's download and history
273 // request, and also provide the methods to access the FaviconHandler
274 // internals.
275 class TestFaviconHandler : public FaviconHandler {
276 public:
277 static int GetMaximalIconSize(favicon_base::IconType icon_type) {
278 return FaviconHandler::GetMaximalIconSize(icon_type);
281 TestFaviconHandler(const GURL& page_url,
282 FaviconClient* client,
283 TestFaviconDriver* driver,
284 Type type,
285 bool download_largest_icon)
286 : FaviconHandler(client, driver, type, download_largest_icon),
287 download_id_(0) {
288 driver->SetActiveURL(page_url);
289 download_handler_.reset(new DownloadHandler(this));
292 ~TestFaviconHandler() override {}
294 HistoryRequestHandler* history_handler() {
295 return history_handler_.get();
298 // This method will take the ownership of the given handler.
299 void set_history_handler(HistoryRequestHandler* handler) {
300 history_handler_.reset(handler);
303 DownloadHandler* download_handler() {
304 return download_handler_.get();
307 // Methods to access favicon internals.
308 const std::vector<FaviconURL>& urls() {
309 return image_urls_;
312 FaviconURL* current_candidate() {
313 return FaviconHandler::current_candidate();
316 const FaviconCandidate& best_favicon_candidate() {
317 return best_favicon_candidate_;
320 protected:
321 void UpdateFaviconMappingAndFetch(
322 const GURL& page_url,
323 const GURL& icon_url,
324 favicon_base::IconType icon_type,
325 const favicon_base::FaviconResultsCallback& callback,
326 base::CancelableTaskTracker* tracker) override {
327 history_handler_.reset(new HistoryRequestHandler(page_url, icon_url,
328 icon_type, callback));
331 void GetFaviconFromFaviconService(
332 const GURL& icon_url,
333 favicon_base::IconType icon_type,
334 const favicon_base::FaviconResultsCallback& callback,
335 base::CancelableTaskTracker* tracker) override {
336 history_handler_.reset(new HistoryRequestHandler(GURL(), icon_url,
337 icon_type, callback));
340 void GetFaviconForURLFromFaviconService(
341 const GURL& page_url,
342 int icon_types,
343 const favicon_base::FaviconResultsCallback& callback,
344 base::CancelableTaskTracker* tracker) override {
345 history_handler_.reset(new HistoryRequestHandler(page_url, GURL(),
346 icon_types, callback));
349 int DownloadFavicon(const GURL& image_url, int max_bitmap_size) override {
350 download_id_++;
351 std::vector<int> sizes;
352 sizes.push_back(0);
353 download_handler_->AddDownload(
354 download_id_, image_url, sizes, max_bitmap_size);
355 return download_id_;
358 void SetHistoryFavicons(const GURL& page_url,
359 const GURL& icon_url,
360 favicon_base::IconType icon_type,
361 const gfx::Image& image) override {
362 scoped_refptr<base::RefCountedMemory> bytes = image.As1xPNGBytes();
363 std::vector<unsigned char> bitmap_data(bytes->front(),
364 bytes->front() + bytes->size());
365 history_handler_.reset(new HistoryRequestHandler(
366 page_url, icon_url, icon_type, bitmap_data, image.Size()));
369 bool ShouldSaveFavicon(const GURL& url) override { return true; }
371 GURL page_url_;
373 private:
375 // The unique id of a download request. It will be returned to a
376 // FaviconHandler.
377 int download_id_;
379 scoped_ptr<DownloadHandler> download_handler_;
380 scoped_ptr<HistoryRequestHandler> history_handler_;
382 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler);
385 namespace {
387 void HistoryRequestHandler::InvokeCallback() {
388 if (!callback_.is_null()) {
389 callback_.Run(history_results_);
393 void DownloadHandler::InvokeCallback() {
394 std::vector<gfx::Size> original_bitmap_sizes;
395 std::vector<SkBitmap> bitmaps;
396 if (!failed_) {
397 for (std::vector<int>::const_iterator i = download_->image_sizes.begin();
398 i != download_->image_sizes.end(); ++i) {
399 int original_size = (*i > 0) ? *i : gfx::kFaviconSize;
400 int downloaded_size = original_size;
401 if (download_->max_image_size != 0 &&
402 downloaded_size > download_->max_image_size) {
403 downloaded_size = download_->max_image_size;
405 SkBitmap bitmap;
406 FillDataToBitmap(downloaded_size, downloaded_size, &bitmap);
407 bitmaps.push_back(bitmap);
408 original_bitmap_sizes.push_back(gfx::Size(original_size, original_size));
411 favicon_helper_->OnDidDownloadFavicon(download_->download_id,
412 download_->image_url,
413 bitmaps,
414 original_bitmap_sizes);
417 class FaviconHandlerTest : public ChromeRenderViewHostTestHarness {
418 public:
419 FaviconHandlerTest() {
422 ~FaviconHandlerTest() override {}
424 // Simulates requesting a favicon for |page_url| given:
425 // - We have not previously cached anything in history for |page_url| or for
426 // any of |candidates|.
427 // - The page provides favicons at |candidate_icons|.
428 // - The favicons at |candidate_icons| have edge pixel sizes of
429 // |candidate_icon_sizes|.
430 void DownloadTillDoneIgnoringHistory(
431 TestFaviconDriver* favicon_driver,
432 TestFaviconHandler* favicon_handler,
433 const GURL& page_url,
434 const std::vector<FaviconURL>& candidate_icons,
435 const int* candidate_icon_sizes) {
436 UpdateFaviconURL(
437 favicon_driver, favicon_handler, page_url, candidate_icons);
438 EXPECT_EQ(candidate_icons.size(), favicon_handler->image_urls().size());
440 DownloadHandler* download_handler = favicon_handler->download_handler();
441 for (size_t i = 0; i < candidate_icons.size(); ++i) {
442 favicon_handler->history_handler()->history_results_.clear();
443 favicon_handler->history_handler()->InvokeCallback();
444 ASSERT_TRUE(download_handler->HasDownload());
445 EXPECT_EQ(download_handler->GetImageUrl(),
446 candidate_icons[i].icon_url);
447 std::vector<int> sizes;
448 sizes.push_back(candidate_icon_sizes[i]);
449 download_handler->SetImageSizes(sizes);
450 download_handler->InvokeCallback();
452 if (favicon_driver->num_active_favicon())
453 return;
457 void UpdateFaviconURL(TestFaviconDriver* favicon_driver,
458 TestFaviconHandler* favicon_handler,
459 const GURL& page_url,
460 const std::vector<FaviconURL>& candidate_icons) {
461 favicon_driver->ResetNumActiveFavicon();
463 favicon_handler->FetchFavicon(page_url);
464 favicon_handler->history_handler()->InvokeCallback();
466 favicon_handler->OnUpdateFaviconURL(candidate_icons);
469 void SetUp() override {
470 // The score computed by SelectFaviconFrames() is dependent on the supported
471 // scale factors of the platform. It is used for determining the goodness of
472 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon().
473 // Force the values of the scale factors so that the tests produce the same
474 // results on all platforms.
475 std::vector<ui::ScaleFactor> scale_factors;
476 scale_factors.push_back(ui::SCALE_FACTOR_100P);
477 scoped_set_supported_scale_factors_.reset(
478 new ui::test::ScopedSetSupportedScaleFactors(scale_factors));
480 ChromeRenderViewHostTestHarness::SetUp();
483 void TearDown() override {
484 Profile* profile = Profile::FromBrowserContext(
485 web_contents()->GetBrowserContext());
486 FaviconServiceFactory::GetInstance()->SetTestingFactory(
487 profile, NULL);
488 ChromeRenderViewHostTestHarness::TearDown();
491 private:
492 typedef scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
493 ScopedSetSupportedScaleFactors;
494 ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_;
495 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerTest);
498 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
499 const GURL page_url("http://www.google.com");
500 const GURL icon_url("http://www.google.com/favicon");
502 TestFaviconDriver driver;
503 TestFaviconClient client;
504 TestFaviconHandler helper(
505 page_url, &client, &driver, FaviconHandler::FAVICON, false);
507 helper.FetchFavicon(page_url);
508 HistoryRequestHandler* history_handler = helper.history_handler();
509 // Ensure the data given to history is correct.
510 ASSERT_TRUE(history_handler);
511 EXPECT_EQ(page_url, history_handler->page_url_);
512 EXPECT_EQ(GURL(), history_handler->icon_url_);
513 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
515 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
517 // Send history response.
518 history_handler->InvokeCallback();
519 // Verify FaviconHandler status
520 EXPECT_TRUE(driver.GetActiveFaviconValidity());
521 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
523 // Simulates update favicon url.
524 std::vector<FaviconURL> urls;
525 urls.push_back(
526 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
527 helper.OnUpdateFaviconURL(urls);
529 // Verify FaviconHandler status
530 EXPECT_EQ(1U, helper.urls().size());
531 ASSERT_TRUE(helper.current_candidate());
532 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
533 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
535 // Favicon shouldn't request to download icon.
536 EXPECT_FALSE(helper.download_handler()->HasDownload());
539 TEST_F(FaviconHandlerTest, DownloadFavicon) {
540 const GURL page_url("http://www.google.com");
541 const GURL icon_url("http://www.google.com/favicon");
543 TestFaviconDriver driver;
544 TestFaviconClient client;
545 TestFaviconHandler helper(
546 page_url, &client, &driver, FaviconHandler::FAVICON, false);
548 helper.FetchFavicon(page_url);
549 HistoryRequestHandler* history_handler = helper.history_handler();
550 // Ensure the data given to history is correct.
551 ASSERT_TRUE(history_handler);
552 EXPECT_EQ(page_url, history_handler->page_url_);
553 EXPECT_EQ(GURL(), history_handler->icon_url_);
554 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
556 // Set icon data expired
557 SetFaviconRawBitmapResult(icon_url,
558 favicon_base::FAVICON,
559 true /* expired */,
560 &history_handler->history_results_);
561 // Send history response.
562 history_handler->InvokeCallback();
563 // Verify FaviconHandler status
564 EXPECT_TRUE(driver.GetActiveFaviconValidity());
565 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
567 // Simulates update favicon url.
568 std::vector<FaviconURL> urls;
569 urls.push_back(
570 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
571 helper.OnUpdateFaviconURL(urls);
573 // Verify FaviconHandler status
574 EXPECT_EQ(1U, helper.urls().size());
575 ASSERT_TRUE(helper.current_candidate());
576 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
577 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
579 // Favicon should request to download icon now.
580 DownloadHandler* download_handler = helper.download_handler();
581 EXPECT_TRUE(helper.download_handler()->HasDownload());
583 // Verify the download request.
584 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
586 // Reset the history_handler to verify whether favicon is set.
587 helper.set_history_handler(NULL);
589 // Smulates download done.
590 download_handler->InvokeCallback();
592 // New icon should be saved to history backend and navigation entry.
593 history_handler = helper.history_handler();
594 ASSERT_TRUE(history_handler);
595 EXPECT_EQ(icon_url, history_handler->icon_url_);
596 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
597 EXPECT_LT(0U, history_handler->bitmap_data_.size());
598 EXPECT_EQ(page_url, history_handler->page_url_);
600 // Verify NavigationEntry.
601 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
602 EXPECT_TRUE(driver.GetActiveFaviconValidity());
603 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
604 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
607 TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) {
608 const GURL page_url("http://www.google.com");
609 const GURL icon_url("http://www.google.com/favicon");
610 const GURL new_icon_url("http://www.google.com/new_favicon");
612 TestFaviconDriver driver;
613 TestFaviconClient client;
614 TestFaviconHandler helper(
615 page_url, &client, &driver, FaviconHandler::FAVICON, false);
617 helper.FetchFavicon(page_url);
618 HistoryRequestHandler* history_handler = helper.history_handler();
619 // Ensure the data given to history is correct.
620 ASSERT_TRUE(history_handler);
621 EXPECT_EQ(page_url, history_handler->page_url_);
622 EXPECT_EQ(GURL(), history_handler->icon_url_);
623 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
625 // Set valid icon data.
626 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
628 // Send history response.
629 history_handler->InvokeCallback();
630 // Verify FaviconHandler status.
631 EXPECT_TRUE(driver.GetActiveFaviconValidity());
632 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
634 // Reset the history_handler to verify whether new icon is requested from
635 // history.
636 helper.set_history_handler(NULL);
638 // Simulates update with the different favicon url.
639 std::vector<FaviconURL> urls;
640 urls.push_back(FaviconURL(
641 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
642 helper.OnUpdateFaviconURL(urls);
644 // Verify FaviconHandler status.
645 EXPECT_EQ(1U, helper.urls().size());
646 ASSERT_TRUE(helper.current_candidate());
647 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
648 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
650 // Favicon should be requested from history.
651 history_handler = helper.history_handler();
652 ASSERT_TRUE(history_handler);
653 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
654 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
655 EXPECT_EQ(page_url, history_handler->page_url_);
657 // Simulate not find icon.
658 history_handler->history_results_.clear();
659 history_handler->InvokeCallback();
661 // Favicon should request to download icon now.
662 DownloadHandler* download_handler = helper.download_handler();
663 EXPECT_TRUE(helper.download_handler()->HasDownload());
665 // Verify the download request.
666 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
668 // Reset the history_handler to verify whether favicon is set.
669 helper.set_history_handler(NULL);
671 // Smulates download done.
672 download_handler->InvokeCallback();
674 // New icon should be saved to history backend and navigation entry.
675 history_handler = helper.history_handler();
676 ASSERT_TRUE(history_handler);
677 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
678 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
679 EXPECT_LT(0U, history_handler->bitmap_data_.size());
680 EXPECT_EQ(page_url, history_handler->page_url_);
682 // Verify NavigationEntry.
683 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
684 EXPECT_TRUE(driver.GetActiveFaviconValidity());
685 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
686 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
689 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
690 const GURL page_url("http://www.google.com");
691 const GURL icon_url("http://www.google.com/favicon");
693 TestFaviconDriver driver;
694 TestFaviconClient client;
695 TestFaviconHandler helper(
696 page_url, &client, &driver, FaviconHandler::FAVICON, false);
698 helper.FetchFavicon(page_url);
699 HistoryRequestHandler* history_handler = helper.history_handler();
700 // Ensure the data given to history is correct.
701 ASSERT_TRUE(history_handler);
702 EXPECT_EQ(page_url, history_handler->page_url_);
703 EXPECT_EQ(GURL(), history_handler->icon_url_);
704 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
706 // Set non empty but invalid data.
707 favicon_base::FaviconRawBitmapResult bitmap_result;
708 bitmap_result.expired = false;
709 // Empty bitmap data is invalid.
710 bitmap_result.bitmap_data = new base::RefCountedBytes();
711 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
712 bitmap_result.icon_type = favicon_base::FAVICON;
713 bitmap_result.icon_url = icon_url;
714 history_handler->history_results_.clear();
715 history_handler->history_results_.push_back(bitmap_result);
717 // Send history response.
718 history_handler->InvokeCallback();
719 // The NavigationEntry should not be set yet as the history data is invalid.
720 EXPECT_FALSE(driver.GetActiveFaviconValidity());
721 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
723 // Reset the history_handler to verify whether new icon is requested from
724 // history.
725 helper.set_history_handler(NULL);
727 // Simulates update with matching favicon URL.
728 std::vector<FaviconURL> urls;
729 urls.push_back(
730 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
731 helper.OnUpdateFaviconURL(urls);
733 // A download for the favicon should be requested, and we should not do
734 // another history request.
735 DownloadHandler* download_handler = helper.download_handler();
736 EXPECT_TRUE(helper.download_handler()->HasDownload());
737 EXPECT_EQ(NULL, helper.history_handler());
739 // Verify the download request.
740 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
742 // Simulates download done.
743 download_handler->InvokeCallback();
745 // New icon should be saved to history backend and navigation entry.
746 history_handler = helper.history_handler();
747 ASSERT_TRUE(history_handler);
748 EXPECT_EQ(icon_url, history_handler->icon_url_);
749 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
750 EXPECT_LT(0U, history_handler->bitmap_data_.size());
751 EXPECT_EQ(page_url, history_handler->page_url_);
753 // Verify NavigationEntry.
754 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
755 EXPECT_TRUE(driver.GetActiveFaviconValidity());
756 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
757 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
760 TEST_F(FaviconHandlerTest, UpdateFavicon) {
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 TestFaviconDriver driver;
766 TestFaviconClient client;
767 TestFaviconHandler helper(
768 page_url, &client, &driver, FaviconHandler::FAVICON, false);
770 helper.FetchFavicon(page_url);
771 HistoryRequestHandler* history_handler = helper.history_handler();
772 // Ensure the data given to history is correct.
773 ASSERT_TRUE(history_handler);
774 EXPECT_EQ(page_url, history_handler->page_url_);
775 EXPECT_EQ(GURL(), history_handler->icon_url_);
776 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
778 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
780 // Send history response.
781 history_handler->InvokeCallback();
782 // Verify FaviconHandler status.
783 EXPECT_TRUE(driver.GetActiveFaviconValidity());
784 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
786 // Reset the history_handler to verify whether new icon is requested from
787 // history.
788 helper.set_history_handler(NULL);
790 // Simulates update with the different favicon url.
791 std::vector<FaviconURL> urls;
792 urls.push_back(FaviconURL(
793 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
794 helper.OnUpdateFaviconURL(urls);
796 // Verify FaviconHandler status.
797 EXPECT_EQ(1U, helper.urls().size());
798 ASSERT_TRUE(helper.current_candidate());
799 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
800 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
802 // Favicon should be requested from history.
803 history_handler = helper.history_handler();
804 ASSERT_TRUE(history_handler);
805 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
806 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
807 EXPECT_EQ(page_url, history_handler->page_url_);
809 // Simulate find icon.
810 SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_);
811 history_handler->InvokeCallback();
813 // Shouldn't request download favicon
814 EXPECT_FALSE(helper.download_handler()->HasDownload());
816 // Verify the favicon status.
817 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
818 EXPECT_TRUE(driver.GetActiveFaviconValidity());
819 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
822 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
823 const GURL page_url("http://www.google.com");
824 const GURL icon_url("http://www.google.com/favicon");
825 const GURL new_icon_url("http://www.google.com/new_favicon");
827 TestFaviconDriver driver;
828 TestFaviconClient client;
829 TestFaviconHandler helper(
830 page_url, &client, &driver, FaviconHandler::TOUCH, false);
832 helper.FetchFavicon(page_url);
833 HistoryRequestHandler* history_handler = helper.history_handler();
834 // Ensure the data given to history is correct.
835 ASSERT_TRUE(history_handler);
836 EXPECT_EQ(page_url, history_handler->page_url_);
837 EXPECT_EQ(GURL(), history_handler->icon_url_);
838 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
839 history_handler->icon_type_);
841 // Icon not found.
842 history_handler->history_results_.clear();
843 // Send history response.
844 history_handler->InvokeCallback();
845 // Verify FaviconHandler status.
846 EXPECT_FALSE(driver.GetActiveFaviconValidity());
847 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
849 // Reset the history_handler to verify whether new icon is requested from
850 // history.
851 helper.set_history_handler(NULL);
853 // Simulates update with the different favicon url.
854 std::vector<FaviconURL> urls;
855 urls.push_back(FaviconURL(icon_url,
856 favicon_base::TOUCH_PRECOMPOSED_ICON,
857 std::vector<gfx::Size>()));
858 urls.push_back(FaviconURL(
859 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
860 urls.push_back(FaviconURL(
861 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
862 helper.OnUpdateFaviconURL(urls);
864 // Verify FaviconHandler status.
865 EXPECT_EQ(2U, helper.urls().size());
866 ASSERT_TRUE(helper.current_candidate());
867 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
868 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
869 helper.current_candidate()->icon_type);
871 // Favicon should be requested from history.
872 history_handler = helper.history_handler();
873 ASSERT_TRUE(history_handler);
874 EXPECT_EQ(icon_url, history_handler->icon_url_);
875 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
876 EXPECT_EQ(page_url, history_handler->page_url_);
878 // Simulate not find icon.
879 history_handler->history_results_.clear();
880 history_handler->InvokeCallback();
882 // Should request download favicon.
883 DownloadHandler* download_handler = helper.download_handler();
884 EXPECT_TRUE(helper.download_handler()->HasDownload());
886 // Verify the download request.
887 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
889 // Reset the history_handler to verify whether favicon is request from
890 // history.
891 helper.set_history_handler(NULL);
892 // Smulates download failed.
893 download_handler->set_failed(true);
894 download_handler->InvokeCallback();
896 // Left 1 url.
897 EXPECT_EQ(1U, helper.urls().size());
898 ASSERT_TRUE(helper.current_candidate());
899 EXPECT_EQ(new_icon_url, helper.current_candidate()->icon_url);
900 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
902 // Favicon should be requested from history.
903 history_handler = helper.history_handler();
904 ASSERT_TRUE(history_handler);
905 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
906 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
907 EXPECT_EQ(page_url, history_handler->page_url_);
909 // Reset download handler
910 download_handler->Reset();
912 // Simulates getting a expired icon from history.
913 SetFaviconRawBitmapResult(new_icon_url,
914 favicon_base::TOUCH_ICON,
915 true /* expired */,
916 &history_handler->history_results_);
917 history_handler->InvokeCallback();
919 // Verify the download request.
920 EXPECT_TRUE(helper.download_handler()->HasDownload());
921 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
923 helper.set_history_handler(NULL);
925 // Simulates icon being downloaded.
926 download_handler->InvokeCallback();
928 // New icon should be saved to history backend.
929 history_handler = helper.history_handler();
930 ASSERT_TRUE(history_handler);
931 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
932 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
933 EXPECT_LT(0U, history_handler->bitmap_data_.size());
934 EXPECT_EQ(page_url, history_handler->page_url_);
937 TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
938 const GURL page_url("http://www.google.com");
939 const GURL icon_url("http://www.google.com/favicon");
940 const GURL new_icon_url("http://www.google.com/new_favicon");
942 TestFaviconDriver driver;
943 TestFaviconClient client;
944 TestFaviconHandler helper(
945 page_url, &client, &driver, FaviconHandler::TOUCH, false);
947 helper.FetchFavicon(page_url);
948 HistoryRequestHandler* history_handler = helper.history_handler();
949 // Ensure the data given to history is correct.
950 ASSERT_TRUE(history_handler);
951 EXPECT_EQ(page_url, history_handler->page_url_);
952 EXPECT_EQ(GURL(), history_handler->icon_url_);
953 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
954 history_handler->icon_type_);
956 // Icon not found.
957 history_handler->history_results_.clear();
958 // Send history response.
959 history_handler->InvokeCallback();
960 // Verify FaviconHandler status.
961 EXPECT_FALSE(driver.GetActiveFaviconValidity());
962 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
964 // Reset the history_handler to verify whether new icon is requested from
965 // history.
966 helper.set_history_handler(NULL);
968 // Simulates update with the different favicon url.
969 std::vector<FaviconURL> urls;
970 urls.push_back(FaviconURL(icon_url,
971 favicon_base::TOUCH_PRECOMPOSED_ICON,
972 std::vector<gfx::Size>()));
973 urls.push_back(FaviconURL(
974 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
975 urls.push_back(FaviconURL(
976 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
977 helper.OnUpdateFaviconURL(urls);
979 // Verify FaviconHandler status.
980 EXPECT_EQ(2U, helper.urls().size());
981 ASSERT_TRUE(helper.current_candidate());
982 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
983 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
984 helper.current_candidate()->icon_type);
986 // Favicon should be requested from history.
987 history_handler = helper.history_handler();
988 ASSERT_TRUE(history_handler);
989 EXPECT_EQ(icon_url, history_handler->icon_url_);
990 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
991 EXPECT_EQ(page_url, history_handler->page_url_);
993 // Simulate not find icon.
994 history_handler->history_results_.clear();
995 history_handler->InvokeCallback();
997 // Should request download favicon.
998 DownloadHandler* download_handler = helper.download_handler();
999 EXPECT_TRUE(helper.download_handler()->HasDownload());
1001 // Verify the download request.
1002 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
1004 // Reset the history_handler to verify whether favicon is request from
1005 // history.
1006 helper.set_history_handler(NULL);
1007 const GURL latest_icon_url("http://www.google.com/latest_favicon");
1008 std::vector<FaviconURL> latest_urls;
1009 latest_urls.push_back(FaviconURL(
1010 latest_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
1011 helper.OnUpdateFaviconURL(latest_urls);
1013 EXPECT_EQ(1U, helper.urls().size());
1014 EXPECT_EQ(latest_icon_url, helper.current_candidate()->icon_url);
1015 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
1017 // Whether new icon is requested from history
1018 history_handler = helper.history_handler();
1019 ASSERT_TRUE(history_handler);
1020 EXPECT_EQ(latest_icon_url, history_handler->icon_url_);
1021 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
1022 EXPECT_EQ(page_url, history_handler->page_url_);
1024 // Reset the history_handler to verify whether favicon is request from
1025 // history.
1026 // Save the callback for late use.
1027 favicon_base::FaviconResultsCallback callback = history_handler->callback_;
1028 helper.set_history_handler(NULL);
1030 // Simulates download succeed.
1031 download_handler->InvokeCallback();
1032 // The downloaded icon should be thrown away as there is favicon update.
1033 EXPECT_FALSE(helper.history_handler());
1035 download_handler->Reset();
1037 // Simulates getting the icon from history.
1038 scoped_ptr<HistoryRequestHandler> handler;
1039 handler.reset(new HistoryRequestHandler(
1040 page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback));
1041 SetFaviconRawBitmapResult(latest_icon_url,
1042 favicon_base::TOUCH_ICON,
1043 false /* expired */,
1044 &handler->history_results_);
1045 handler->InvokeCallback();
1047 // No download request.
1048 EXPECT_FALSE(download_handler->HasDownload());
1051 #if !defined(OS_ANDROID)
1053 // Test the favicon which is selected when the web page provides several
1054 // favicons and none of the favicons are cached in history.
1055 // The goal of this test is to be more of an integration test than
1056 // SelectFaviconFramesTest.*.
1057 TEST_F(FaviconHandlerTest, MultipleFavicons) {
1058 const GURL kPageURL("http://www.google.com");
1059 const FaviconURL kSourceIconURLs[] = {
1060 FaviconURL(GURL("http://www.google.com/a"),
1061 favicon_base::FAVICON,
1062 std::vector<gfx::Size>()),
1063 FaviconURL(GURL("http://www.google.com/b"),
1064 favicon_base::FAVICON,
1065 std::vector<gfx::Size>()),
1066 FaviconURL(GURL("http://www.google.com/c"),
1067 favicon_base::FAVICON,
1068 std::vector<gfx::Size>()),
1069 FaviconURL(GURL("http://www.google.com/d"),
1070 favicon_base::FAVICON,
1071 std::vector<gfx::Size>()),
1072 FaviconURL(GURL("http://www.google.com/e"),
1073 favicon_base::FAVICON,
1074 std::vector<gfx::Size>())};
1076 // Set the supported scale factors to 1x and 2x. This affects the behavior of
1077 // SelectFaviconFrames().
1078 std::vector<ui::ScaleFactor> scale_factors;
1079 scale_factors.push_back(ui::SCALE_FACTOR_100P);
1080 scale_factors.push_back(ui::SCALE_FACTOR_200P);
1081 ui::test::ScopedSetSupportedScaleFactors scoped_supported(scale_factors);
1083 // 1) Test that if there are several single resolution favicons to choose from
1084 // that the largest exact match is chosen.
1085 TestFaviconDriver driver1;
1086 TestFaviconClient client;
1087 TestFaviconHandler handler1(
1088 kPageURL, &client, &driver1, FaviconHandler::FAVICON, false);
1090 const int kSizes1[] = { 16, 24, 32, 48, 256 };
1091 std::vector<FaviconURL> urls1(kSourceIconURLs,
1092 kSourceIconURLs + arraysize(kSizes1));
1093 DownloadTillDoneIgnoringHistory(
1094 &driver1, &handler1, kPageURL, urls1, kSizes1);
1096 EXPECT_EQ(0u, handler1.image_urls().size());
1097 EXPECT_TRUE(driver1.GetActiveFaviconValidity());
1098 EXPECT_FALSE(driver1.GetActiveFaviconImage().IsEmpty());
1099 EXPECT_EQ(gfx::kFaviconSize, driver1.GetActiveFaviconImage().Width());
1101 size_t expected_index = 2u;
1102 EXPECT_EQ(32, kSizes1[expected_index]);
1103 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1104 driver1.GetActiveFaviconURL());
1106 // 2) Test that if there are several single resolution favicons to choose
1107 // from, the exact match is preferred even if it results in upsampling.
1108 TestFaviconDriver driver2;
1109 TestFaviconHandler handler2(
1110 kPageURL, &client, &driver2, FaviconHandler::FAVICON, false);
1112 const int kSizes2[] = { 16, 24, 48, 256 };
1113 std::vector<FaviconURL> urls2(kSourceIconURLs,
1114 kSourceIconURLs + arraysize(kSizes2));
1115 DownloadTillDoneIgnoringHistory(
1116 &driver2, &handler2, kPageURL, urls2, kSizes2);
1117 EXPECT_TRUE(driver2.GetActiveFaviconValidity());
1118 expected_index = 0u;
1119 EXPECT_EQ(16, kSizes2[expected_index]);
1120 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1121 driver2.GetActiveFaviconURL());
1123 // 3) Test that favicons which need to be upsampled a little or downsampled
1124 // a little are preferred over huge favicons.
1125 TestFaviconDriver driver3;
1126 TestFaviconHandler handler3(
1127 kPageURL, &client, &driver3, FaviconHandler::FAVICON, false);
1129 const int kSizes3[] = { 256, 48 };
1130 std::vector<FaviconURL> urls3(kSourceIconURLs,
1131 kSourceIconURLs + arraysize(kSizes3));
1132 DownloadTillDoneIgnoringHistory(
1133 &driver3, &handler3, kPageURL, urls3, kSizes3);
1134 EXPECT_TRUE(driver3.GetActiveFaviconValidity());
1135 expected_index = 1u;
1136 EXPECT_EQ(48, kSizes3[expected_index]);
1137 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1138 driver3.GetActiveFaviconURL());
1140 TestFaviconDriver driver4;
1141 TestFaviconHandler handler4(
1142 kPageURL, &client, &driver4, FaviconHandler::FAVICON, false);
1144 const int kSizes4[] = { 17, 256 };
1145 std::vector<FaviconURL> urls4(kSourceIconURLs,
1146 kSourceIconURLs + arraysize(kSizes4));
1147 DownloadTillDoneIgnoringHistory(
1148 &driver4, &handler4, kPageURL, urls4, kSizes4);
1149 EXPECT_TRUE(driver4.GetActiveFaviconValidity());
1150 expected_index = 0u;
1151 EXPECT_EQ(17, kSizes4[expected_index]);
1152 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1153 driver4.GetActiveFaviconURL());
1156 #endif
1158 TEST_F(FaviconHandlerTest, TestSortFavicon) {
1159 const GURL kPageURL("http://www.google.com");
1160 std::vector<gfx::Size> icon1;
1161 icon1.push_back(gfx::Size(1024, 1024));
1162 icon1.push_back(gfx::Size(512, 512));
1164 std::vector<gfx::Size> icon2;
1165 icon2.push_back(gfx::Size(15, 15));
1166 icon2.push_back(gfx::Size(16, 16));
1168 std::vector<gfx::Size> icon3;
1169 icon3.push_back(gfx::Size(16, 16));
1170 icon3.push_back(gfx::Size(14, 14));
1172 const FaviconURL kSourceIconURLs[] = {
1173 FaviconURL(GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
1174 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
1175 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
1176 FaviconURL(GURL("http://www.google.com/d"),
1177 favicon_base::FAVICON,
1178 std::vector<gfx::Size>()),
1179 FaviconURL(GURL("http://www.google.com/e"),
1180 favicon_base::FAVICON,
1181 std::vector<gfx::Size>())};
1183 TestFaviconClient client;
1184 TestFaviconDriver driver1;
1185 TestFaviconHandler handler1(
1186 kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
1187 std::vector<FaviconURL> urls1(kSourceIconURLs,
1188 kSourceIconURLs + arraysize(kSourceIconURLs));
1189 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1191 struct ExpectedResult {
1192 // The favicon's index in kSourceIconURLs.
1193 size_t favicon_index;
1194 // Width of largest bitmap.
1195 int width;
1196 } results[] = {
1197 // First is icon1, though its size larger than maximal.
1198 {0, 1024},
1199 // Second is icon2
1200 // The 16x16 is largest.
1201 {1, 16},
1202 // Third is icon3 though it has same size as icon2.
1203 // The 16x16 is largest.
1204 {2, 16},
1205 // The rest of bitmaps come in order, there is no sizes attribute.
1206 {3, -1},
1207 {4, -1},
1209 const std::vector<FaviconURL>& icons = handler1.image_urls();
1210 ASSERT_EQ(5u, icons.size());
1211 for (size_t i = 0; i < icons.size(); ++i) {
1212 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1213 icons[i].icon_url);
1214 if (results[i].width != -1)
1215 EXPECT_EQ(results[i].width, icons[i].icon_sizes[0].width());
1219 TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {
1220 const GURL kPageURL("http://www.google.com");
1221 std::vector<gfx::Size> icon1;
1222 icon1.push_back(gfx::Size(1024, 1024));
1223 icon1.push_back(gfx::Size(512, 512));
1225 std::vector<gfx::Size> icon2;
1226 icon2.push_back(gfx::Size(15, 15));
1227 icon2.push_back(gfx::Size(14, 14));
1229 std::vector<gfx::Size> icon3;
1230 icon3.push_back(gfx::Size(16, 16));
1231 icon3.push_back(gfx::Size(512, 512));
1233 const FaviconURL kSourceIconURLs[] = {
1234 FaviconURL(
1235 GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
1236 FaviconURL(
1237 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
1238 FaviconURL(
1239 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
1240 FaviconURL(GURL("http://www.google.com/d"),
1241 favicon_base::FAVICON,
1242 std::vector<gfx::Size>()),
1243 FaviconURL(GURL("http://www.google.com/e"),
1244 favicon_base::FAVICON,
1245 std::vector<gfx::Size>())};
1247 TestFaviconClient client;
1248 TestFaviconDriver driver1;
1249 TestFaviconHandler handler1(
1250 kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
1251 std::vector<FaviconURL> urls1(kSourceIconURLs,
1252 kSourceIconURLs + arraysize(kSourceIconURLs));
1253 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1255 // Simulate the download failed, to check whether the icons were requested
1256 // to download according their size.
1257 struct ExpectedResult {
1258 // The size of image_urls_.
1259 size_t image_urls_size;
1260 // The favicon's index in kSourceIconURLs.
1261 size_t favicon_index;
1262 // Width of largest bitmap.
1263 int width;
1264 } results[] = {
1265 {5, 0, 1024},
1266 {4, 2, 512},
1267 {3, 1, 15},
1268 // The rest of bitmaps come in order.
1269 {2, 3, -1},
1270 {1, 4, -1},
1273 for (int i = 0; i < 5; ++i) {
1274 ASSERT_EQ(results[i].image_urls_size, handler1.image_urls().size());
1275 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1276 handler1.current_candidate()->icon_url);
1277 if (results[i].width != -1) {
1278 EXPECT_EQ(results[i].width, handler1.current_candidate()->
1279 icon_sizes[0].width());
1282 // Simulate no favicon from history.
1283 handler1.history_handler()->history_results_.clear();
1284 handler1.history_handler()->InvokeCallback();
1286 // Verify download request
1287 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1288 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1289 handler1.download_handler()->GetImageUrl());
1291 // Simulate the download failed.
1292 handler1.download_handler()->set_failed(true);
1293 handler1.download_handler()->InvokeCallback();
1297 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
1298 const GURL kPageURL("http://www.google.com");
1300 std::vector<gfx::Size> one_icon;
1301 one_icon.push_back(gfx::Size(15, 15));
1303 std::vector<gfx::Size> two_icons;
1304 two_icons.push_back(gfx::Size(14, 14));
1305 two_icons.push_back(gfx::Size(16, 16));
1307 const FaviconURL kSourceIconURLs[] = {
1308 FaviconURL(
1309 GURL("http://www.google.com/b"), favicon_base::FAVICON, one_icon),
1310 FaviconURL(
1311 GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons)};
1313 TestFaviconClient client;
1314 TestFaviconDriver driver1;
1315 TestFaviconHandler handler1(
1316 kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
1317 std::vector<FaviconURL> urls1(kSourceIconURLs,
1318 kSourceIconURLs + arraysize(kSourceIconURLs));
1319 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1321 ASSERT_EQ(2u, handler1.urls().size());
1323 // Index of largest favicon in kSourceIconURLs.
1324 size_t i = 1;
1325 // The largest bitmap's index in Favicon .
1326 int b = 1;
1328 // Verify the icon_bitmaps_ was initialized correctly.
1329 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1330 handler1.current_candidate()->icon_url);
1331 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1332 handler1.current_candidate()->icon_sizes[0]);
1334 // Simulate no favicon from history.
1335 handler1.history_handler()->history_results_.clear();
1336 handler1.history_handler()->InvokeCallback();
1338 // Verify download request
1339 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1340 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1341 handler1.download_handler()->GetImageUrl());
1343 // Give the correct download result.
1344 std::vector<int> sizes;
1345 for (std::vector<gfx::Size>::const_iterator j =
1346 kSourceIconURLs[i].icon_sizes.begin();
1347 j != kSourceIconURLs[i].icon_sizes.end(); ++j)
1348 sizes.push_back(j->width());
1350 handler1.download_handler()->SetImageSizes(sizes);
1351 handler1.download_handler()->InvokeCallback();
1353 // Verify the largest bitmap has been saved into history.
1354 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
1355 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1356 handler1.history_handler()->size_);
1357 // Verify NotifyFaviconAvailable().
1358 EXPECT_FALSE(driver1.update_active_favicon());
1359 EXPECT_EQ(kSourceIconURLs[i].icon_url, driver1.available_icon_url());
1360 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1361 driver1.available_favicon().Size());
1364 TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {
1365 const GURL kPageURL("http://www.google.com");
1366 const int kMaximalSize =
1367 TestFaviconHandler::GetMaximalIconSize(favicon_base::FAVICON);
1369 std::vector<gfx::Size> icon1;
1370 icon1.push_back(gfx::Size(kMaximalSize + 1, kMaximalSize + 1));
1372 std::vector<gfx::Size> icon2;
1373 icon2.push_back(gfx::Size(kMaximalSize + 2, kMaximalSize + 2));
1375 const FaviconURL kSourceIconURLs[] = {
1376 FaviconURL(
1377 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
1378 FaviconURL(
1379 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2)};
1381 TestFaviconClient client;
1382 TestFaviconDriver driver1;
1383 TestFaviconHandler handler1(
1384 kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
1385 std::vector<FaviconURL> urls1(kSourceIconURLs,
1386 kSourceIconURLs + arraysize(kSourceIconURLs));
1387 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1389 ASSERT_EQ(2u, handler1.urls().size());
1391 // Index of largest favicon in kSourceIconURLs.
1392 size_t i = 1;
1393 // The largest bitmap's index in Favicon .
1394 int b = 0;
1396 // Verify the icon_bitmaps_ was initialized correctly.
1397 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1398 handler1.current_candidate()->icon_url);
1399 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1400 handler1.current_candidate()->icon_sizes[0]);
1402 // Simulate no favicon from history.
1403 handler1.history_handler()->history_results_.clear();
1404 handler1.history_handler()->InvokeCallback();
1406 // Verify download request
1407 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1408 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1409 handler1.download_handler()->GetImageUrl());
1411 // Give the scaled download bitmap.
1412 std::vector<int> sizes;
1413 sizes.push_back(kMaximalSize);
1415 handler1.download_handler()->SetImageSizes(sizes);
1416 handler1.download_handler()->InvokeCallback();
1418 // Verify the largest bitmap has been saved into history though it was
1419 // scaled down to maximal size and smaller than icon1 now.
1420 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
1421 EXPECT_EQ(gfx::Size(kMaximalSize, kMaximalSize),
1422 handler1.history_handler()->size_);
1425 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
1426 const GURL kPageURL("http://www.google.com");
1428 std::vector<gfx::Size> icon1;
1429 icon1.push_back(gfx::Size(16, 16));
1430 const int actual_size1 = 10;
1432 std::vector<gfx::Size> icon2;
1433 icon2.push_back(gfx::Size(15, 15));
1434 const int actual_size2 = 12;
1436 const FaviconURL kSourceIconURLs[] = {
1437 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
1438 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2),
1439 FaviconURL(GURL("http://www.google.com/d"),
1440 favicon_base::FAVICON,
1441 std::vector<gfx::Size>())};
1443 TestFaviconClient client;
1444 TestFaviconDriver driver1;
1445 TestFaviconHandler handler1(
1446 kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
1447 std::vector<FaviconURL> urls1(kSourceIconURLs,
1448 kSourceIconURLs + arraysize(kSourceIconURLs));
1449 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1450 ASSERT_EQ(3u, handler1.urls().size());
1452 // Simulate no favicon from history.
1453 handler1.history_handler()->history_results_.clear();
1454 handler1.history_handler()->InvokeCallback();
1456 // Verify the first icon was request to download
1457 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1458 EXPECT_EQ(kSourceIconURLs[0].icon_url,
1459 handler1.download_handler()->GetImageUrl());
1461 // Give the incorrect size.
1462 std::vector<int> sizes;
1463 sizes.push_back(actual_size1);
1464 handler1.download_handler()->SetImageSizes(sizes);
1465 handler1.download_handler()->InvokeCallback();
1467 // Simulate no favicon from history.
1468 handler1.history_handler()->history_results_.clear();
1469 handler1.history_handler()->InvokeCallback();
1471 // Verify the 2nd icon was request to download
1472 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1473 EXPECT_EQ(kSourceIconURLs[1].icon_url,
1474 handler1.download_handler()->GetImageUrl());
1476 // Very the best candidate is icon1
1477 EXPECT_EQ(kSourceIconURLs[0].icon_url,
1478 handler1.best_favicon_candidate().image_url);
1479 EXPECT_EQ(gfx::Size(actual_size1, actual_size1),
1480 handler1.best_favicon_candidate().image.Size());
1482 // Give the incorrect size.
1483 sizes.clear();
1484 sizes.push_back(actual_size2);
1485 handler1.download_handler()->SetImageSizes(sizes);
1486 handler1.download_handler()->InvokeCallback();
1488 // Verify icon2 has been saved into history.
1489 EXPECT_EQ(kSourceIconURLs[1].icon_url, handler1.history_handler()->icon_url_);
1490 EXPECT_EQ(gfx::Size(actual_size2, actual_size2),
1491 handler1.history_handler()->size_);
1494 static KeyedService* BuildFaviconService(content::BrowserContext* profile) {
1495 FaviconClient* favicon_client =
1496 ChromeFaviconClientFactory::GetForProfile(static_cast<Profile*>(profile));
1497 return new FaviconService(static_cast<Profile*>(profile), favicon_client);
1500 static KeyedService* BuildHistoryService(content::BrowserContext* profile) {
1501 return NULL;
1504 // Test that Favicon is not requested repeatedly during the same session if
1505 // server returns HTTP 404 status.
1506 TEST_F(FaviconHandlerTest, UnableToDownloadFavicon) {
1507 const GURL missing_icon_url("http://www.google.com/favicon.ico");
1508 const GURL another_icon_url("http://www.youtube.com/favicon.ico");
1510 Profile* profile = Profile::FromBrowserContext(
1511 web_contents()->GetBrowserContext());
1513 FaviconServiceFactory::GetInstance()->SetTestingFactory(
1514 profile, BuildFaviconService);
1516 HistoryServiceFactory::GetInstance()->SetTestingFactory(
1517 profile, BuildHistoryService);
1519 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
1520 profile, ServiceAccessType::IMPLICIT_ACCESS);
1522 FaviconTabHelper::CreateForWebContents(web_contents());
1523 FaviconTabHelper* favicon_tab_helper =
1524 FaviconTabHelper::FromWebContents(web_contents());
1526 std::vector<SkBitmap> empty_icons;
1527 std::vector<gfx::Size> empty_icon_sizes;
1528 int download_id = 0;
1530 // Try to download missing icon.
1531 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1532 EXPECT_NE(0, download_id);
1533 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1535 // Report download failure with HTTP 503 status.
1536 favicon_tab_helper->DidDownloadFavicon(download_id, 503, missing_icon_url,
1537 empty_icons, empty_icon_sizes);
1538 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1539 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1541 // Try to download again.
1542 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1543 EXPECT_NE(0, download_id);
1544 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1546 // Report download failure with HTTP 404 status.
1547 favicon_tab_helper->DidDownloadFavicon(download_id, 404, missing_icon_url,
1548 empty_icons, empty_icon_sizes);
1549 // Icon is marked as UnableToDownload.
1550 EXPECT_TRUE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1552 // Try to download again.
1553 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1554 // Download is not started and Icon is still marked as UnableToDownload.
1555 EXPECT_EQ(0, download_id);
1556 EXPECT_TRUE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1558 // Try to download another icon.
1559 download_id = favicon_tab_helper->StartDownload(another_icon_url, 0);
1560 // Download is started as another icon URL is not same as missing_icon_url.
1561 EXPECT_NE(0, download_id);
1562 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(another_icon_url));
1564 // Clear the list of missing icons.
1565 favicon_service->ClearUnableToDownloadFavicons();
1566 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1567 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(another_icon_url));
1569 // Try to download again.
1570 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1571 EXPECT_NE(0, download_id);
1572 // Report download success with HTTP 200 status.
1573 favicon_tab_helper->DidDownloadFavicon(download_id, 200, missing_icon_url,
1574 empty_icons, empty_icon_sizes);
1575 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1576 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1579 class FaviconHandlerActiveFaviconValidityParamTest :
1580 public FaviconHandlerTest,
1581 public ::testing::WithParamInterface<bool> {
1582 public:
1583 FaviconHandlerActiveFaviconValidityParamTest() {}
1585 ~FaviconHandlerActiveFaviconValidityParamTest() override {}
1587 bool GetActiveFaviconValiditySetting() {
1588 return GetParam();
1591 private:
1592 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerActiveFaviconValidityParamTest);
1595 TEST_P(FaviconHandlerActiveFaviconValidityParamTest,
1596 TestDownloadLargestIconDoesNotImpactActiveFaviconValidity) {
1597 const GURL page_url("http://www.google.com");
1599 std::vector<gfx::Size> one_icon;
1600 one_icon.push_back(gfx::Size(15, 15));
1602 const GURL old_favicon_url("http://www.google.com/old");
1603 const GURL new_favicon_url("http://www.google.com/b");
1604 const FaviconURL source_icon_urls[] = {
1605 FaviconURL(new_favicon_url, favicon_base::FAVICON, one_icon)};
1606 TestFaviconClient client;
1607 TestFaviconDriver driver1;
1608 TestFaviconHandler handler1(
1609 page_url, &client, &driver1, FaviconHandler::FAVICON, true);
1610 std::vector<FaviconURL> urls1(source_icon_urls,
1611 source_icon_urls + arraysize(source_icon_urls));
1612 UpdateFaviconURL(&driver1, &handler1, page_url, urls1);
1614 HistoryRequestHandler* history_handler = handler1.history_handler();
1616 // Simulate the active favicon is updated, this shouldn't happen in real
1617 // use case, but we want to verify the behavior below is not impacted by
1618 // accident.
1619 driver1.SetActiveFaviconValidity(GetActiveFaviconValiditySetting());
1620 // Simulate the get favicon from history, but favicon URL didn't match.
1621 SetFaviconRawBitmapResult(old_favicon_url,
1622 &history_handler->history_results_);
1623 history_handler->InvokeCallback();
1624 // Since we downloaded largest icon, and don't want to set active favicon
1625 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1626 EXPECT_EQ(old_favicon_url, driver1.available_icon_url());
1627 EXPECT_FALSE(driver1.update_active_favicon());
1628 EXPECT_EQ(1u, driver1.num_favicon_available());
1630 // We are trying to get favicon from history again.
1631 history_handler = handler1.history_handler();
1632 EXPECT_EQ(new_favicon_url, history_handler->icon_url_);
1633 // Simulate the get expired favicon from history.
1634 history_handler->history_results_.clear();
1635 SetFaviconRawBitmapResult(new_favicon_url, favicon_base::FAVICON, true,
1636 &history_handler->history_results_);
1637 history_handler->InvokeCallback();
1638 // Since we downloaded largest icon, and don't want to set active favicon
1639 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1640 EXPECT_EQ(new_favicon_url, driver1.available_icon_url());
1641 EXPECT_FALSE(driver1.update_active_favicon());
1642 EXPECT_EQ(2u, driver1.num_favicon_available());
1644 // We are trying to download favicon.
1645 DownloadHandler* download_handler = handler1.download_handler();
1646 EXPECT_TRUE(download_handler->HasDownload());
1647 EXPECT_EQ(new_favicon_url, download_handler->GetImageUrl());
1648 // Simulate the download succeed.
1649 download_handler->InvokeCallback();
1650 // Since we downloaded largest icon, and don't want to set active favicon
1651 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1652 EXPECT_EQ(new_favicon_url, driver1.available_icon_url());
1653 EXPECT_FALSE(driver1.update_active_favicon());
1654 EXPECT_EQ(3u, driver1.num_favicon_available());
1657 INSTANTIATE_TEST_CASE_P(FaviconHandlerTestActiveFaviconValidityTrueOrFalse,
1658 FaviconHandlerActiveFaviconValidityParamTest,
1659 ::testing::Bool());
1661 } // namespace.