Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / favicon / favicon_handler_unittest.cc
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.
4
5 #include "chrome/browser/favicon/favicon_handler.h"
6
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"
20
21 class TestFaviconHandler;
22
23 using favicon::FaviconURL;
24
25 namespace {
26
27 // Fill the given bmp with valid png data.
28 void FillDataToBitmap(int w, int h, SkBitmap* bmp) {
29   bmp->allocN32Pixels(w, h);
30
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);
38   }
39 }
40
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);
46 }
47
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;
62
63   favicon_bitmap_results->push_back(bitmap_result);
64 }
65
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);
73 }
74
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) {
82   }
83
84   virtual ~DownloadHandler() {
85   }
86
87   void Reset() {
88     download_.reset(NULL);
89     failed_ = false;
90   }
91
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));
99   }
100
101   void InvokeCallback();
102
103   void set_failed(bool failed) { failed_ = failed; }
104
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; }
109
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;
126   };
127
128   TestFaviconHandler* favicon_helper_;
129   scoped_ptr<Download> download_;
130   bool failed_;
131
132   DISALLOW_COPY_AND_ASSIGN(DownloadHandler);
133 };
134
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) {
147   }
148
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) {
159   }
160
161   virtual ~HistoryRequestHandler() {}
162   void InvokeCallback();
163
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_;
171
172  private:
173   DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler);
174 };
175
176 }  // namespace
177
178 class TestFaviconClient : public FaviconClient {
179  public:
180   ~TestFaviconClient() override{};
181
182   FaviconService* GetFaviconService() override {
183     // Just give none NULL value, so overridden methods can be hit.
184     return (FaviconService*)(1);
185   }
186
187   bool IsBookmarked(const GURL& url) override { return false; }
188 };
189
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) {}
197
198   virtual ~TestFaviconDriver() {
199   }
200
201   bool IsOffTheRecord() override { return false; }
202
203   const gfx::Image GetActiveFaviconImage() override { return image_; }
204
205   const GURL GetActiveFaviconURL() override { return favicon_url_; }
206
207   bool GetActiveFaviconValidity() override { return favicon_validity_; }
208
209   const GURL GetActiveURL() override { return url_; }
210
211   void SetActiveFaviconImage(gfx::Image image) { image_ = image; }
212
213   void SetActiveFaviconURL(GURL favicon_url) { favicon_url_ = favicon_url; }
214
215   void SetActiveFaviconValidity(bool favicon_validity) {
216     favicon_validity_ = favicon_validity;
217   }
218
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;
223   }
224
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;
234
235     ++num_active_favicon_;
236     SetActiveFaviconURL(icon_url);
237     SetActiveFaviconValidity(true);
238     SetActiveFaviconImage(image);
239   }
240
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; }
245
246   void SetActiveURL(GURL url) { url_ = url; }
247
248   const gfx::Image available_favicon() { return available_image_; }
249
250   const GURL available_icon_url() { return available_icon_url_; }
251
252   bool update_active_favicon() { return update_active_favicon_; }
253
254  private:
255   GURL favicon_url_;
256   GURL url_;
257   gfx::Image image_;
258   bool favicon_validity_;
259
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_;
268
269   DISALLOW_COPY_AND_ASSIGN(TestFaviconDriver);
270 };
271
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);
279   }
280
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));
290   }
291
292   ~TestFaviconHandler() override {}
293
294   HistoryRequestHandler* history_handler() {
295     return history_handler_.get();
296   }
297
298   // This method will take the ownership of the given handler.
299   void set_history_handler(HistoryRequestHandler* handler) {
300     history_handler_.reset(handler);
301   }
302
303   DownloadHandler* download_handler() {
304     return download_handler_.get();
305   }
306
307   // Methods to access favicon internals.
308   const std::vector<FaviconURL>& urls() {
309     return image_urls_;
310   }
311
312   FaviconURL* current_candidate() {
313     return FaviconHandler::current_candidate();
314   }
315
316   const FaviconCandidate& best_favicon_candidate() {
317     return best_favicon_candidate_;
318   }
319
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));
329   }
330
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));
338   }
339
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));
347   }
348
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_;
356   }
357
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()));
367   }
368
369   bool ShouldSaveFavicon(const GURL& url) override { return true; }
370
371   GURL page_url_;
372
373  private:
374
375   // The unique id of a download request. It will be returned to a
376   // FaviconHandler.
377   int download_id_;
378
379   scoped_ptr<DownloadHandler> download_handler_;
380   scoped_ptr<HistoryRequestHandler> history_handler_;
381
382   DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler);
383 };
384
385 namespace {
386
387 void HistoryRequestHandler::InvokeCallback() {
388   if (!callback_.is_null()) {
389     callback_.Run(history_results_);
390   }
391 }
392
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;
404       }
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));
409     }
410   }
411   favicon_helper_->OnDidDownloadFavicon(download_->download_id,
412                                         download_->image_url,
413                                         bitmaps,
414                                         original_bitmap_sizes);
415 }
416
417 class FaviconHandlerTest : public ChromeRenderViewHostTestHarness {
418  public:
419   FaviconHandlerTest() {
420   }
421
422   ~FaviconHandlerTest() override {}
423
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());
439
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();
451
452       if (favicon_driver->num_active_favicon())
453         return;
454     }
455   }
456
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();
462
463     favicon_handler->FetchFavicon(page_url);
464     favicon_handler->history_handler()->InvokeCallback();
465
466     favicon_handler->OnUpdateFaviconURL(candidate_icons);
467   }
468
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));
479
480     ChromeRenderViewHostTestHarness::SetUp();
481   }
482
483   void TearDown() override {
484     Profile* profile = Profile::FromBrowserContext(
485         web_contents()->GetBrowserContext());
486     FaviconServiceFactory::GetInstance()->SetTestingFactory(
487       profile, NULL);
488     ChromeRenderViewHostTestHarness::TearDown();
489   }
490
491  private:
492   typedef scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
493       ScopedSetSupportedScaleFactors;
494   ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_;
495   DISALLOW_COPY_AND_ASSIGN(FaviconHandlerTest);
496 };
497
498 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
499   const GURL page_url("http://www.google.com");
500   const GURL icon_url("http://www.google.com/favicon");
501
502   TestFaviconDriver driver;
503   TestFaviconClient client;
504   TestFaviconHandler helper(
505       page_url, &client, &driver, FaviconHandler::FAVICON, false);
506
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_);
514
515   SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
516
517   // Send history response.
518   history_handler->InvokeCallback();
519   // Verify FaviconHandler status
520   EXPECT_TRUE(driver.GetActiveFaviconValidity());
521   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
522
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);
528
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);
534
535   // Favicon shouldn't request to download icon.
536   EXPECT_FALSE(helper.download_handler()->HasDownload());
537 }
538
539 TEST_F(FaviconHandlerTest, DownloadFavicon) {
540   const GURL page_url("http://www.google.com");
541   const GURL icon_url("http://www.google.com/favicon");
542
543   TestFaviconDriver driver;
544   TestFaviconClient client;
545   TestFaviconHandler helper(
546       page_url, &client, &driver, FaviconHandler::FAVICON, false);
547
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_);
555
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());
566
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);
572
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);
578
579   // Favicon should request to download icon now.
580   DownloadHandler* download_handler = helper.download_handler();
581   EXPECT_TRUE(helper.download_handler()->HasDownload());
582
583   // Verify the download request.
584   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
585
586   // Reset the history_handler to verify whether favicon is set.
587   helper.set_history_handler(NULL);
588
589   // Smulates download done.
590   download_handler->InvokeCallback();
591
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_);
599
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());
605 }
606
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");
611
612   TestFaviconDriver driver;
613   TestFaviconClient client;
614   TestFaviconHandler helper(
615       page_url, &client, &driver, FaviconHandler::FAVICON, false);
616
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_);
624
625   // Set valid icon data.
626   SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
627
628   // Send history response.
629   history_handler->InvokeCallback();
630   // Verify FaviconHandler status.
631   EXPECT_TRUE(driver.GetActiveFaviconValidity());
632   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
633
634   // Reset the history_handler to verify whether new icon is requested from
635   // history.
636   helper.set_history_handler(NULL);
637
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);
643
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);
649
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_);
656
657   // Simulate not find icon.
658   history_handler->history_results_.clear();
659   history_handler->InvokeCallback();
660
661   // Favicon should request to download icon now.
662   DownloadHandler* download_handler = helper.download_handler();
663   EXPECT_TRUE(helper.download_handler()->HasDownload());
664
665   // Verify the download request.
666   EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
667
668   // Reset the history_handler to verify whether favicon is set.
669   helper.set_history_handler(NULL);
670
671   // Smulates download done.
672   download_handler->InvokeCallback();
673
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_);
681
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());
687 }
688
689 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
690   const GURL page_url("http://www.google.com");
691   const GURL icon_url("http://www.google.com/favicon");
692
693   TestFaviconDriver driver;
694   TestFaviconClient client;
695   TestFaviconHandler helper(
696       page_url, &client, &driver, FaviconHandler::FAVICON, false);
697
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_);
705
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);
716
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());
722
723   // Reset the history_handler to verify whether new icon is requested from
724   // history.
725   helper.set_history_handler(NULL);
726
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);
732
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());
738
739   // Verify the download request.
740   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
741
742   // Simulates download done.
743   download_handler->InvokeCallback();
744
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_);
752
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());
758 }
759
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");
764
765   TestFaviconDriver driver;
766   TestFaviconClient client;
767   TestFaviconHandler helper(
768       page_url, &client, &driver, FaviconHandler::FAVICON, false);
769
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_);
777
778   SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
779
780   // Send history response.
781   history_handler->InvokeCallback();
782   // Verify FaviconHandler status.
783   EXPECT_TRUE(driver.GetActiveFaviconValidity());
784   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
785
786   // Reset the history_handler to verify whether new icon is requested from
787   // history.
788   helper.set_history_handler(NULL);
789
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);
795
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);
801
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_);
808
809   // Simulate find icon.
810   SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_);
811   history_handler->InvokeCallback();
812
813   // Shouldn't request download favicon
814   EXPECT_FALSE(helper.download_handler()->HasDownload());
815
816   // Verify the favicon status.
817   EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
818   EXPECT_TRUE(driver.GetActiveFaviconValidity());
819   EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
820 }
821
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");
826
827   TestFaviconDriver driver;
828   TestFaviconClient client;
829   TestFaviconHandler helper(
830       page_url, &client, &driver, FaviconHandler::TOUCH, false);
831
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_);
840
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());
848
849   // Reset the history_handler to verify whether new icon is requested from
850   // history.
851   helper.set_history_handler(NULL);
852
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);
863
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);
870
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_);
877
878   // Simulate not find icon.
879   history_handler->history_results_.clear();
880   history_handler->InvokeCallback();
881
882   // Should request download favicon.
883   DownloadHandler* download_handler = helper.download_handler();
884   EXPECT_TRUE(helper.download_handler()->HasDownload());
885
886   // Verify the download request.
887   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
888
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();
895
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);
901
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_);
908
909   // Reset download handler
910   download_handler->Reset();
911
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();
918
919   // Verify the download request.
920   EXPECT_TRUE(helper.download_handler()->HasDownload());
921   EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
922
923   helper.set_history_handler(NULL);
924
925   // Simulates icon being downloaded.
926   download_handler->InvokeCallback();
927
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_);
935 }
936
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");
941
942   TestFaviconDriver driver;
943   TestFaviconClient client;
944   TestFaviconHandler helper(
945       page_url, &client, &driver, FaviconHandler::TOUCH, false);
946
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_);
955
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());
963
964   // Reset the history_handler to verify whether new icon is requested from
965   // history.
966   helper.set_history_handler(NULL);
967
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);
978
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);
985
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_);
992
993   // Simulate not find icon.
994   history_handler->history_results_.clear();
995   history_handler->InvokeCallback();
996
997   // Should request download favicon.
998   DownloadHandler* download_handler = helper.download_handler();
999   EXPECT_TRUE(helper.download_handler()->HasDownload());
1000
1001   // Verify the download request.
1002   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
1003
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);
1012
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);
1016
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_);
1023
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);
1029
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());
1034
1035   download_handler->Reset();
1036
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();
1046
1047   // No download request.
1048   EXPECT_FALSE(download_handler->HasDownload());
1049 }
1050
1051 #if !defined(OS_ANDROID)
1052
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>())};
1075
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);
1082
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);
1089
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);
1095
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());
1100
1101   size_t expected_index = 2u;
1102   EXPECT_EQ(32, kSizes1[expected_index]);
1103   EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1104             driver1.GetActiveFaviconURL());
1105
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);
1111
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());
1122
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);
1128
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());
1139
1140   TestFaviconDriver driver4;
1141   TestFaviconHandler handler4(
1142       kPageURL, &client, &driver4, FaviconHandler::FAVICON, false);
1143
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());
1154 }
1155
1156 #endif
1157
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));
1163
1164   std::vector<gfx::Size> icon2;
1165   icon2.push_back(gfx::Size(15, 15));
1166   icon2.push_back(gfx::Size(16, 16));
1167
1168   std::vector<gfx::Size> icon3;
1169   icon3.push_back(gfx::Size(16, 16));
1170   icon3.push_back(gfx::Size(14, 14));
1171
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>())};
1182
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);
1190
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},
1208   };
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());
1216   }
1217 }
1218
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));
1224
1225   std::vector<gfx::Size> icon2;
1226   icon2.push_back(gfx::Size(15, 15));
1227   icon2.push_back(gfx::Size(14, 14));
1228
1229   std::vector<gfx::Size> icon3;
1230   icon3.push_back(gfx::Size(16, 16));
1231   icon3.push_back(gfx::Size(512, 512));
1232
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>())};
1246
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);
1254
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},
1271   };
1272
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());
1280     }
1281
1282     // Simulate no favicon from history.
1283     handler1.history_handler()->history_results_.clear();
1284     handler1.history_handler()->InvokeCallback();
1285
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());
1290
1291     // Simulate the download failed.
1292     handler1.download_handler()->set_failed(true);
1293     handler1.download_handler()->InvokeCallback();
1294   }
1295 }
1296
1297 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
1298   const GURL kPageURL("http://www.google.com");
1299
1300   std::vector<gfx::Size> one_icon;
1301   one_icon.push_back(gfx::Size(15, 15));
1302
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));
1306
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)};
1312
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);
1320
1321   ASSERT_EQ(2u, handler1.urls().size());
1322
1323   // Index of largest favicon in kSourceIconURLs.
1324   size_t i = 1;
1325   // The largest bitmap's index in Favicon .
1326   int b = 1;
1327
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]);
1333
1334   // Simulate no favicon from history.
1335   handler1.history_handler()->history_results_.clear();
1336   handler1.history_handler()->InvokeCallback();
1337
1338   // Verify download request
1339   ASSERT_TRUE(handler1.download_handler()->HasDownload());
1340   EXPECT_EQ(kSourceIconURLs[i].icon_url,
1341             handler1.download_handler()->GetImageUrl());
1342
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());
1349
1350   handler1.download_handler()->SetImageSizes(sizes);
1351   handler1.download_handler()->InvokeCallback();
1352
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());
1362 }
1363
1364 TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {
1365   const GURL kPageURL("http://www.google.com");
1366   const int kMaximalSize =
1367     TestFaviconHandler::GetMaximalIconSize(favicon_base::FAVICON);
1368
1369   std::vector<gfx::Size> icon1;
1370   icon1.push_back(gfx::Size(kMaximalSize + 1, kMaximalSize + 1));
1371
1372   std::vector<gfx::Size> icon2;
1373   icon2.push_back(gfx::Size(kMaximalSize + 2, kMaximalSize + 2));
1374
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)};
1380
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);
1388
1389   ASSERT_EQ(2u, handler1.urls().size());
1390
1391   // Index of largest favicon in kSourceIconURLs.
1392   size_t i = 1;
1393   // The largest bitmap's index in Favicon .
1394   int b = 0;
1395
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]);
1401
1402   // Simulate no favicon from history.
1403   handler1.history_handler()->history_results_.clear();
1404   handler1.history_handler()->InvokeCallback();
1405
1406   // Verify download request
1407   ASSERT_TRUE(handler1.download_handler()->HasDownload());
1408   EXPECT_EQ(kSourceIconURLs[i].icon_url,
1409             handler1.download_handler()->GetImageUrl());
1410
1411   // Give the scaled download bitmap.
1412   std::vector<int> sizes;
1413   sizes.push_back(kMaximalSize);
1414
1415   handler1.download_handler()->SetImageSizes(sizes);
1416   handler1.download_handler()->InvokeCallback();
1417
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_);
1423 }
1424
1425 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
1426   const GURL kPageURL("http://www.google.com");
1427
1428   std::vector<gfx::Size> icon1;
1429   icon1.push_back(gfx::Size(16, 16));
1430   const int actual_size1 = 10;
1431
1432   std::vector<gfx::Size> icon2;
1433   icon2.push_back(gfx::Size(15, 15));
1434   const int actual_size2 = 12;
1435
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>())};
1442
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());
1451
1452   // Simulate no favicon from history.
1453   handler1.history_handler()->history_results_.clear();
1454   handler1.history_handler()->InvokeCallback();
1455
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());
1460
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();
1466
1467   // Simulate no favicon from history.
1468   handler1.history_handler()->history_results_.clear();
1469   handler1.history_handler()->InvokeCallback();
1470
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());
1475
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());
1481
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();
1487
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_);
1492 }
1493
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);
1498 }
1499
1500 static KeyedService* BuildHistoryService(content::BrowserContext* profile) {
1501   return NULL;
1502 }
1503
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");
1509
1510   Profile* profile = Profile::FromBrowserContext(
1511       web_contents()->GetBrowserContext());
1512
1513   FaviconServiceFactory::GetInstance()->SetTestingFactory(
1514       profile, BuildFaviconService);
1515
1516   HistoryServiceFactory::GetInstance()->SetTestingFactory(
1517       profile, BuildHistoryService);
1518
1519   FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
1520       profile, Profile::IMPLICIT_ACCESS);
1521
1522   FaviconTabHelper::CreateForWebContents(web_contents());
1523   FaviconTabHelper* favicon_tab_helper =
1524       FaviconTabHelper::FromWebContents(web_contents());
1525
1526   std::vector<SkBitmap> empty_icons;
1527   std::vector<gfx::Size> empty_icon_sizes;
1528   int download_id = 0;
1529
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));
1534
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));
1540
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));
1545
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));
1551
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));
1557
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));
1563
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));
1568
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));
1577 }
1578
1579 class FaviconHandlerActiveFaviconValidityParamTest :
1580       public FaviconHandlerTest,
1581       public ::testing::WithParamInterface<bool> {
1582  public:
1583   FaviconHandlerActiveFaviconValidityParamTest() {}
1584
1585   ~FaviconHandlerActiveFaviconValidityParamTest() override {}
1586
1587   bool GetActiveFaviconValiditySetting() {
1588     return GetParam();
1589   }
1590
1591  private:
1592   DISALLOW_COPY_AND_ASSIGN(FaviconHandlerActiveFaviconValidityParamTest);
1593 };
1594
1595 TEST_P(FaviconHandlerActiveFaviconValidityParamTest,
1596        TestDownloadLargestIconDoesNotImpactActiveFaviconValidity) {
1597   const GURL page_url("http://www.google.com");
1598
1599   std::vector<gfx::Size> one_icon;
1600   one_icon.push_back(gfx::Size(15, 15));
1601
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);
1613
1614   HistoryRequestHandler* history_handler = handler1.history_handler();
1615
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());
1629
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());
1643
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());
1655 }
1656
1657 INSTANTIATE_TEST_CASE_P(FaviconHandlerTestActiveFaviconValidityTrueOrFalse,
1658                         FaviconHandlerActiveFaviconValidityParamTest,
1659                         ::testing::Bool());
1660
1661 }  // namespace.