Home | History | Annotate | Download | only in favicon
      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 "base/memory/scoped_ptr.h"
      6 #include "chrome/browser/favicon/favicon_handler.h"
      7 #include "chrome/browser/favicon/favicon_service.h"
      8 #include "chrome/browser/favicon/favicon_service_factory.h"
      9 #include "chrome/browser/history/history_service_factory.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
     12 #include "third_party/skia/include/core/SkBitmap.h"
     13 #include "ui/gfx/codec/png_codec.h"
     14 #include "ui/gfx/favicon_size.h"
     15 #include "ui/gfx/image/image.h"
     16 
     17 class TestFaviconHandler;
     18 
     19 using favicon::FaviconURL;
     20 
     21 namespace {
     22 
     23 // Fill the given bmp with valid png data.
     24 void FillDataToBitmap(int w, int h, SkBitmap* bmp) {
     25   bmp->setConfig(SkBitmap::kARGB_8888_Config, w, h);
     26   bmp->allocPixels();
     27 
     28   unsigned char* src_data =
     29       reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0));
     30   for (int i = 0; i < w * h; i++) {
     31     src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255);
     32     src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255);
     33     src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255);
     34     src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255);
     35   }
     36 }
     37 
     38 // Fill the given data buffer with valid png data.
     39 void FillBitmap(int w, int h, std::vector<unsigned char>* output) {
     40   SkBitmap bitmap;
     41   FillDataToBitmap(w, h, &bitmap);
     42   gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output);
     43 }
     44 
     45 void SetFaviconRawBitmapResult(
     46     const GURL& icon_url,
     47     favicon_base::IconType icon_type,
     48     bool expired,
     49     std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
     50   scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
     51   FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data());
     52   favicon_base::FaviconRawBitmapResult bitmap_result;
     53   bitmap_result.expired = expired;
     54   bitmap_result.bitmap_data = data;
     55   // Use a pixel size other than (0,0) as (0,0) has a special meaning.
     56   bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
     57   bitmap_result.icon_type = icon_type;
     58   bitmap_result.icon_url = icon_url;
     59 
     60   favicon_bitmap_results->push_back(bitmap_result);
     61 }
     62 
     63 void SetFaviconRawBitmapResult(
     64     const GURL& icon_url,
     65     std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
     66   SetFaviconRawBitmapResult(icon_url,
     67                             favicon_base::FAVICON,
     68                             false /* expired */,
     69                             favicon_bitmap_results);
     70 }
     71 
     72 // This class is used to save the download request for verifying with test case.
     73 // It also will be used to invoke the onDidDownload callback.
     74 class DownloadHandler {
     75  public:
     76   explicit DownloadHandler(TestFaviconHandler* favicon_helper)
     77       : favicon_helper_(favicon_helper),
     78         failed_(false) {
     79   }
     80 
     81   virtual ~DownloadHandler() {
     82   }
     83 
     84   void Reset() {
     85     download_.reset(NULL);
     86     failed_ = false;
     87   }
     88 
     89   void AddDownload(
     90       int download_id,
     91       const GURL& image_url,
     92       const std::vector<int>& image_sizes,
     93       int max_image_size) {
     94     download_.reset(new Download(
     95         download_id, image_url, image_sizes, max_image_size, false));
     96   }
     97 
     98   void InvokeCallback();
     99 
    100   void set_failed(bool failed) { failed_ = failed; }
    101 
    102   bool HasDownload() const { return download_.get() != NULL; }
    103   const GURL& GetImageUrl() const { return download_->image_url; }
    104   void SetImageSizes(const std::vector<int>& sizes) {
    105     download_->image_sizes = sizes; }
    106 
    107  private:
    108   struct Download {
    109     Download(int id,
    110              GURL url,
    111              const std::vector<int>& sizes,
    112              int max_size,
    113              bool failed)
    114         : download_id(id),
    115           image_url(url),
    116           image_sizes(sizes),
    117           max_image_size(max_size) {}
    118     ~Download() {}
    119     int download_id;
    120     GURL image_url;
    121     std::vector<int> image_sizes;
    122     int max_image_size;
    123   };
    124 
    125   TestFaviconHandler* favicon_helper_;
    126   scoped_ptr<Download> download_;
    127   bool failed_;
    128 
    129   DISALLOW_COPY_AND_ASSIGN(DownloadHandler);
    130 };
    131 
    132 // This class is used to save the history request for verifying with test case.
    133 // It also will be used to simulate the history response.
    134 class HistoryRequestHandler {
    135  public:
    136   HistoryRequestHandler(const GURL& page_url,
    137                         const GURL& icon_url,
    138                         int icon_type,
    139                         const favicon_base::FaviconResultsCallback& callback)
    140       : page_url_(page_url),
    141         icon_url_(icon_url),
    142         icon_type_(icon_type),
    143         callback_(callback) {
    144   }
    145 
    146   HistoryRequestHandler(const GURL& page_url,
    147                         const GURL& icon_url,
    148                         int icon_type,
    149                         const std::vector<unsigned char>& bitmap_data,
    150                         const gfx::Size& size)
    151       : page_url_(page_url),
    152         icon_url_(icon_url),
    153         icon_type_(icon_type),
    154         bitmap_data_(bitmap_data),
    155         size_(size) {
    156   }
    157 
    158   virtual ~HistoryRequestHandler() {}
    159   void InvokeCallback();
    160 
    161   const GURL page_url_;
    162   const GURL icon_url_;
    163   const int icon_type_;
    164   const std::vector<unsigned char> bitmap_data_;
    165   const gfx::Size size_;
    166   std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
    167   favicon_base::FaviconResultsCallback callback_;
    168 
    169  private:
    170   DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler);
    171 };
    172 
    173 }  // namespace
    174 
    175 class TestFaviconClient : public FaviconClient {
    176  public:
    177   virtual ~TestFaviconClient() {};
    178 
    179   virtual FaviconService* GetFaviconService() OVERRIDE {
    180     // Just give none NULL value, so overridden methods can be hit.
    181     return (FaviconService*)(1);
    182   }
    183 
    184   virtual bool IsBookmarked(const GURL& url) OVERRIDE { return false; }
    185 };
    186 
    187 class TestFaviconDriver : public FaviconDriver {
    188  public:
    189   TestFaviconDriver() : favicon_validity_(false) {}
    190 
    191   virtual ~TestFaviconDriver() {
    192   }
    193 
    194   virtual bool IsOffTheRecord() OVERRIDE { return false; }
    195 
    196   virtual const gfx::Image GetActiveFaviconImage() OVERRIDE { return image_; }
    197 
    198   virtual const GURL GetActiveFaviconURL() OVERRIDE { return favicon_url_; }
    199 
    200   virtual bool GetActiveFaviconValidity() OVERRIDE { return favicon_validity_; }
    201 
    202   virtual const GURL GetActiveURL() OVERRIDE { return url_; }
    203 
    204   virtual void SetActiveFaviconImage(gfx::Image image) OVERRIDE {
    205     image_ = image;
    206   }
    207 
    208   virtual void SetActiveFaviconURL(GURL favicon_url) OVERRIDE {
    209     favicon_url_ = favicon_url;
    210   }
    211 
    212   virtual void SetActiveFaviconValidity(bool favicon_validity) OVERRIDE {
    213     favicon_validity_ = favicon_validity;
    214   }
    215 
    216   virtual int StartDownload(const GURL& url,
    217                             int max_bitmap_size) OVERRIDE {
    218     ADD_FAILURE() << "TestFaviconDriver::StartDownload() "
    219                   << "should never be called in tests.";
    220     return -1;
    221   }
    222 
    223   virtual void NotifyFaviconUpdated(bool icon_url_changed) OVERRIDE {
    224     ADD_FAILURE() << "TestFaviconDriver::NotifyFaviconUpdated() "
    225                   << "should never be called in tests.";
    226   }
    227 
    228   void SetActiveURL(GURL url) { url_ = url; }
    229 
    230  private:
    231   GURL favicon_url_;
    232   GURL url_;
    233   gfx::Image image_;
    234   bool favicon_validity_;
    235   DISALLOW_COPY_AND_ASSIGN(TestFaviconDriver);
    236 };
    237 
    238 // This class is used to catch the FaviconHandler's download and history
    239 // request, and also provide the methods to access the FaviconHandler
    240 // internals.
    241 class TestFaviconHandler : public FaviconHandler {
    242  public:
    243   TestFaviconHandler(const GURL& page_url,
    244                      FaviconClient* client,
    245                      TestFaviconDriver* driver,
    246                      Type type,
    247                      bool download_largest_icon)
    248       : FaviconHandler(client, driver, type, download_largest_icon),
    249         download_id_(0),
    250         num_favicon_updates_(0) {
    251     driver->SetActiveURL(page_url);
    252     download_handler_.reset(new DownloadHandler(this));
    253   }
    254 
    255   virtual ~TestFaviconHandler() {
    256   }
    257 
    258   HistoryRequestHandler* history_handler() {
    259     return history_handler_.get();
    260   }
    261 
    262   // This method will take the ownership of the given handler.
    263   void set_history_handler(HistoryRequestHandler* handler) {
    264     history_handler_.reset(handler);
    265   }
    266 
    267   DownloadHandler* download_handler() {
    268     return download_handler_.get();
    269   }
    270 
    271   size_t num_favicon_update_notifications() const {
    272     return num_favicon_updates_;
    273   }
    274 
    275   void ResetNumFaviconUpdateNotifications() {
    276     num_favicon_updates_ = 0;
    277   }
    278 
    279   // Methods to access favicon internals.
    280   const std::vector<FaviconURL>& urls() {
    281     return image_urls_;
    282   }
    283 
    284   FaviconURL* current_candidate() {
    285     return FaviconHandler::current_candidate();
    286   }
    287 
    288   const FaviconCandidate& best_favicon_candidate() {
    289     return best_favicon_candidate_;
    290   }
    291 
    292  protected:
    293   virtual void UpdateFaviconMappingAndFetch(
    294       const GURL& page_url,
    295       const GURL& icon_url,
    296       favicon_base::IconType icon_type,
    297       const favicon_base::FaviconResultsCallback& callback,
    298       base::CancelableTaskTracker* tracker) OVERRIDE {
    299     history_handler_.reset(new HistoryRequestHandler(page_url, icon_url,
    300                                                      icon_type, callback));
    301   }
    302 
    303   virtual void GetFaviconFromFaviconService(
    304       const GURL& icon_url,
    305       favicon_base::IconType icon_type,
    306       const favicon_base::FaviconResultsCallback& callback,
    307       base::CancelableTaskTracker* tracker) OVERRIDE {
    308     history_handler_.reset(new HistoryRequestHandler(GURL(), icon_url,
    309                                                      icon_type, callback));
    310   }
    311 
    312   virtual void GetFaviconForURLFromFaviconService(
    313       const GURL& page_url,
    314       int icon_types,
    315       const favicon_base::FaviconResultsCallback& callback,
    316       base::CancelableTaskTracker* tracker) OVERRIDE {
    317     history_handler_.reset(new HistoryRequestHandler(page_url, GURL(),
    318                                                      icon_types, callback));
    319   }
    320 
    321   virtual int DownloadFavicon(const GURL& image_url,
    322                               int max_bitmap_size) OVERRIDE {
    323     download_id_++;
    324     std::vector<int> sizes;
    325     sizes.push_back(0);
    326     download_handler_->AddDownload(
    327         download_id_, image_url, sizes, max_bitmap_size);
    328     return download_id_;
    329   }
    330 
    331   virtual void SetHistoryFavicons(const GURL& page_url,
    332                                   const GURL& icon_url,
    333                                   favicon_base::IconType icon_type,
    334                                   const gfx::Image& image) OVERRIDE {
    335     scoped_refptr<base::RefCountedMemory> bytes = image.As1xPNGBytes();
    336     std::vector<unsigned char> bitmap_data(bytes->front(),
    337                                            bytes->front() + bytes->size());
    338     history_handler_.reset(new HistoryRequestHandler(
    339         page_url, icon_url, icon_type, bitmap_data, image.Size()));
    340   }
    341 
    342   virtual bool ShouldSaveFavicon(const GURL& url) OVERRIDE {
    343     return true;
    344   }
    345 
    346   virtual void NotifyFaviconUpdated(bool icon_url_changed) OVERRIDE {
    347     ++num_favicon_updates_;
    348   }
    349 
    350   GURL page_url_;
    351 
    352  private:
    353 
    354   // The unique id of a download request. It will be returned to a
    355   // FaviconHandler.
    356   int download_id_;
    357 
    358   scoped_ptr<DownloadHandler> download_handler_;
    359   scoped_ptr<HistoryRequestHandler> history_handler_;
    360 
    361   // The number of times that NotifyFaviconUpdated() has been called.
    362   size_t num_favicon_updates_;
    363 
    364   DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler);
    365 };
    366 
    367 namespace {
    368 
    369 void HistoryRequestHandler::InvokeCallback() {
    370   if (!callback_.is_null()) {
    371     callback_.Run(history_results_);
    372   }
    373 }
    374 
    375 void DownloadHandler::InvokeCallback() {
    376   std::vector<gfx::Size> original_bitmap_sizes;
    377   std::vector<SkBitmap> bitmaps;
    378   if (!failed_) {
    379     for (std::vector<int>::const_iterator i = download_->image_sizes.begin();
    380          i != download_->image_sizes.end(); ++i) {
    381       int original_size = (*i > 0) ? *i : gfx::kFaviconSize;
    382       int downloaded_size = original_size;
    383       if (download_->max_image_size != 0 &&
    384           downloaded_size > download_->max_image_size) {
    385         downloaded_size = download_->max_image_size;
    386       }
    387       SkBitmap bitmap;
    388       FillDataToBitmap(downloaded_size, downloaded_size, &bitmap);
    389       bitmaps.push_back(bitmap);
    390       original_bitmap_sizes.push_back(gfx::Size(original_size, original_size));
    391     }
    392   }
    393   favicon_helper_->OnDidDownloadFavicon(download_->download_id,
    394                                         download_->image_url,
    395                                         bitmaps,
    396                                         original_bitmap_sizes);
    397 }
    398 
    399 class FaviconHandlerTest : public ChromeRenderViewHostTestHarness {
    400  public:
    401   FaviconHandlerTest() {
    402   }
    403 
    404   virtual ~FaviconHandlerTest() {
    405   }
    406 
    407   // Simulates requesting a favicon for |page_url| given:
    408   // - We have not previously cached anything in history for |page_url| or for
    409   //   any of |candidates|.
    410   // - The page provides favicons at |candidate_icons|.
    411   // - The favicons at |candidate_icons| have edge pixel sizes of
    412   //   |candidate_icon_sizes|.
    413   void DownloadTillDoneIgnoringHistory(
    414       TestFaviconHandler* favicon_handler,
    415       const GURL& page_url,
    416       const std::vector<FaviconURL>& candidate_icons,
    417       const int* candidate_icon_sizes) {
    418     UpdateFaviconURL(favicon_handler, page_url, candidate_icons);
    419     EXPECT_EQ(candidate_icons.size(), favicon_handler->image_urls().size());
    420 
    421     DownloadHandler* download_handler = favicon_handler->download_handler();
    422     for (size_t i = 0; i < candidate_icons.size(); ++i) {
    423       favicon_handler->history_handler()->history_results_.clear();
    424       favicon_handler->history_handler()->InvokeCallback();
    425       ASSERT_TRUE(download_handler->HasDownload());
    426       EXPECT_EQ(download_handler->GetImageUrl(),
    427                 candidate_icons[i].icon_url);
    428       std::vector<int> sizes;
    429       sizes.push_back(candidate_icon_sizes[i]);
    430       download_handler->SetImageSizes(sizes);
    431       download_handler->InvokeCallback();
    432 
    433       if (favicon_handler->num_favicon_update_notifications())
    434         return;
    435     }
    436   }
    437 
    438   void UpdateFaviconURL(
    439       TestFaviconHandler* favicon_handler,
    440       const GURL& page_url,
    441       const std::vector<FaviconURL>& candidate_icons) {
    442     favicon_handler->ResetNumFaviconUpdateNotifications();
    443 
    444     favicon_handler->FetchFavicon(page_url);
    445     favicon_handler->history_handler()->InvokeCallback();
    446 
    447     favicon_handler->OnUpdateFaviconURL(candidate_icons);
    448   }
    449 
    450   virtual void SetUp() {
    451     // The score computed by SelectFaviconFrames() is dependent on the supported
    452     // scale factors of the platform. It is used for determining the goodness of
    453     // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon().
    454     // Force the values of the scale factors so that the tests produce the same
    455     // results on all platforms.
    456     std::vector<ui::ScaleFactor> scale_factors;
    457     scale_factors.push_back(ui::SCALE_FACTOR_100P);
    458     scoped_set_supported_scale_factors_.reset(
    459         new ui::test::ScopedSetSupportedScaleFactors(scale_factors));
    460 
    461     ChromeRenderViewHostTestHarness::SetUp();
    462   }
    463 
    464   virtual void TearDown() OVERRIDE {
    465     Profile* profile = Profile::FromBrowserContext(
    466         web_contents()->GetBrowserContext());
    467     FaviconServiceFactory::GetInstance()->SetTestingFactory(
    468       profile, NULL);
    469     ChromeRenderViewHostTestHarness::TearDown();
    470   }
    471 
    472  private:
    473   typedef scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
    474       ScopedSetSupportedScaleFactors;
    475   ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_;
    476   DISALLOW_COPY_AND_ASSIGN(FaviconHandlerTest);
    477 };
    478 
    479 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
    480   const GURL page_url("http://www.google.com");
    481   const GURL icon_url("http://www.google.com/favicon");
    482 
    483   TestFaviconDriver driver;
    484   TestFaviconClient client;
    485   TestFaviconHandler helper(
    486       page_url, &client, &driver, FaviconHandler::FAVICON, false);
    487 
    488   helper.FetchFavicon(page_url);
    489   HistoryRequestHandler* history_handler = helper.history_handler();
    490   // Ensure the data given to history is correct.
    491   ASSERT_TRUE(history_handler);
    492   EXPECT_EQ(page_url, history_handler->page_url_);
    493   EXPECT_EQ(GURL(), history_handler->icon_url_);
    494   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    495 
    496   SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
    497 
    498   // Send history response.
    499   history_handler->InvokeCallback();
    500   // Verify FaviconHandler status
    501   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    502   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
    503 
    504   // Simulates update favicon url.
    505   std::vector<FaviconURL> urls;
    506   urls.push_back(
    507       FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    508   helper.OnUpdateFaviconURL(urls);
    509 
    510   // Verify FaviconHandler status
    511   EXPECT_EQ(1U, helper.urls().size());
    512   ASSERT_TRUE(helper.current_candidate());
    513   ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
    514   ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
    515 
    516   // Favicon shouldn't request to download icon.
    517   EXPECT_FALSE(helper.download_handler()->HasDownload());
    518 }
    519 
    520 TEST_F(FaviconHandlerTest, DownloadFavicon) {
    521   const GURL page_url("http://www.google.com");
    522   const GURL icon_url("http://www.google.com/favicon");
    523 
    524   TestFaviconDriver driver;
    525   TestFaviconClient client;
    526   TestFaviconHandler helper(
    527       page_url, &client, &driver, FaviconHandler::FAVICON, false);
    528 
    529   helper.FetchFavicon(page_url);
    530   HistoryRequestHandler* history_handler = helper.history_handler();
    531   // Ensure the data given to history is correct.
    532   ASSERT_TRUE(history_handler);
    533   EXPECT_EQ(page_url, history_handler->page_url_);
    534   EXPECT_EQ(GURL(), history_handler->icon_url_);
    535   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    536 
    537   // Set icon data expired
    538   SetFaviconRawBitmapResult(icon_url,
    539                             favicon_base::FAVICON,
    540                             true /* expired */,
    541                             &history_handler->history_results_);
    542   // Send history response.
    543   history_handler->InvokeCallback();
    544   // Verify FaviconHandler status
    545   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    546   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
    547 
    548   // Simulates update favicon url.
    549   std::vector<FaviconURL> urls;
    550   urls.push_back(
    551       FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    552   helper.OnUpdateFaviconURL(urls);
    553 
    554   // Verify FaviconHandler status
    555   EXPECT_EQ(1U, helper.urls().size());
    556   ASSERT_TRUE(helper.current_candidate());
    557   ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
    558   ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
    559 
    560   // Favicon should request to download icon now.
    561   DownloadHandler* download_handler = helper.download_handler();
    562   EXPECT_TRUE(helper.download_handler()->HasDownload());
    563 
    564   // Verify the download request.
    565   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
    566 
    567   // Reset the history_handler to verify whether favicon is set.
    568   helper.set_history_handler(NULL);
    569 
    570   // Smulates download done.
    571   download_handler->InvokeCallback();
    572 
    573   // New icon should be saved to history backend and navigation entry.
    574   history_handler = helper.history_handler();
    575   ASSERT_TRUE(history_handler);
    576   EXPECT_EQ(icon_url, history_handler->icon_url_);
    577   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    578   EXPECT_LT(0U, history_handler->bitmap_data_.size());
    579   EXPECT_EQ(page_url, history_handler->page_url_);
    580 
    581   // Verify NavigationEntry.
    582   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
    583   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    584   EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
    585   EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
    586 }
    587 
    588 TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) {
    589   const GURL page_url("http://www.google.com");
    590   const GURL icon_url("http://www.google.com/favicon");
    591   const GURL new_icon_url("http://www.google.com/new_favicon");
    592 
    593   TestFaviconDriver driver;
    594   TestFaviconClient client;
    595   TestFaviconHandler helper(
    596       page_url, &client, &driver, FaviconHandler::FAVICON, false);
    597 
    598   helper.FetchFavicon(page_url);
    599   HistoryRequestHandler* history_handler = helper.history_handler();
    600   // Ensure the data given to history is correct.
    601   ASSERT_TRUE(history_handler);
    602   EXPECT_EQ(page_url, history_handler->page_url_);
    603   EXPECT_EQ(GURL(), history_handler->icon_url_);
    604   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    605 
    606   // Set valid icon data.
    607   SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
    608 
    609   // Send history response.
    610   history_handler->InvokeCallback();
    611   // Verify FaviconHandler status.
    612   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    613   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
    614 
    615   // Reset the history_handler to verify whether new icon is requested from
    616   // history.
    617   helper.set_history_handler(NULL);
    618 
    619   // Simulates update with the different favicon url.
    620   std::vector<FaviconURL> urls;
    621   urls.push_back(FaviconURL(
    622       new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    623   helper.OnUpdateFaviconURL(urls);
    624 
    625   // Verify FaviconHandler status.
    626   EXPECT_EQ(1U, helper.urls().size());
    627   ASSERT_TRUE(helper.current_candidate());
    628   ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
    629   ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
    630 
    631   // Favicon should be requested from history.
    632   history_handler = helper.history_handler();
    633   ASSERT_TRUE(history_handler);
    634   EXPECT_EQ(new_icon_url, history_handler->icon_url_);
    635   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    636   EXPECT_EQ(page_url, history_handler->page_url_);
    637 
    638   // Simulate not find icon.
    639   history_handler->history_results_.clear();
    640   history_handler->InvokeCallback();
    641 
    642   // Favicon should request to download icon now.
    643   DownloadHandler* download_handler = helper.download_handler();
    644   EXPECT_TRUE(helper.download_handler()->HasDownload());
    645 
    646   // Verify the download request.
    647   EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
    648 
    649   // Reset the history_handler to verify whether favicon is set.
    650   helper.set_history_handler(NULL);
    651 
    652   // Smulates download done.
    653   download_handler->InvokeCallback();
    654 
    655   // New icon should be saved to history backend and navigation entry.
    656   history_handler = helper.history_handler();
    657   ASSERT_TRUE(history_handler);
    658   EXPECT_EQ(new_icon_url, history_handler->icon_url_);
    659   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    660   EXPECT_LT(0U, history_handler->bitmap_data_.size());
    661   EXPECT_EQ(page_url, history_handler->page_url_);
    662 
    663   // Verify NavigationEntry.
    664   EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
    665   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    666   EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
    667   EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
    668 }
    669 
    670 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
    671   const GURL page_url("http://www.google.com");
    672   const GURL icon_url("http://www.google.com/favicon");
    673 
    674   TestFaviconDriver driver;
    675   TestFaviconClient client;
    676   TestFaviconHandler helper(
    677       page_url, &client, &driver, FaviconHandler::FAVICON, false);
    678 
    679   helper.FetchFavicon(page_url);
    680   HistoryRequestHandler* history_handler = helper.history_handler();
    681   // Ensure the data given to history is correct.
    682   ASSERT_TRUE(history_handler);
    683   EXPECT_EQ(page_url, history_handler->page_url_);
    684   EXPECT_EQ(GURL(), history_handler->icon_url_);
    685   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    686 
    687   // Set non empty but invalid data.
    688   favicon_base::FaviconRawBitmapResult bitmap_result;
    689   bitmap_result.expired = false;
    690   // Empty bitmap data is invalid.
    691   bitmap_result.bitmap_data = new base::RefCountedBytes();
    692   bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
    693   bitmap_result.icon_type = favicon_base::FAVICON;
    694   bitmap_result.icon_url = icon_url;
    695   history_handler->history_results_.clear();
    696   history_handler->history_results_.push_back(bitmap_result);
    697 
    698   // Send history response.
    699   history_handler->InvokeCallback();
    700   // The NavigationEntry should not be set yet as the history data is invalid.
    701   EXPECT_FALSE(driver.GetActiveFaviconValidity());
    702   EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
    703 
    704   // Reset the history_handler to verify whether new icon is requested from
    705   // history.
    706   helper.set_history_handler(NULL);
    707 
    708   // Simulates update with matching favicon URL.
    709   std::vector<FaviconURL> urls;
    710   urls.push_back(
    711       FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    712   helper.OnUpdateFaviconURL(urls);
    713 
    714   // A download for the favicon should be requested, and we should not do
    715   // another history request.
    716   DownloadHandler* download_handler = helper.download_handler();
    717   EXPECT_TRUE(helper.download_handler()->HasDownload());
    718   EXPECT_EQ(NULL, helper.history_handler());
    719 
    720   // Verify the download request.
    721   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
    722 
    723   // Simulates download done.
    724   download_handler->InvokeCallback();
    725 
    726   // New icon should be saved to history backend and navigation entry.
    727   history_handler = helper.history_handler();
    728   ASSERT_TRUE(history_handler);
    729   EXPECT_EQ(icon_url, history_handler->icon_url_);
    730   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    731   EXPECT_LT(0U, history_handler->bitmap_data_.size());
    732   EXPECT_EQ(page_url, history_handler->page_url_);
    733 
    734   // Verify NavigationEntry.
    735   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
    736   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    737   EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
    738   EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
    739 }
    740 
    741 TEST_F(FaviconHandlerTest, UpdateFavicon) {
    742   const GURL page_url("http://www.google.com");
    743   const GURL icon_url("http://www.google.com/favicon");
    744   const GURL new_icon_url("http://www.google.com/new_favicon");
    745 
    746   TestFaviconDriver driver;
    747   TestFaviconClient client;
    748   TestFaviconHandler helper(
    749       page_url, &client, &driver, FaviconHandler::FAVICON, false);
    750 
    751   helper.FetchFavicon(page_url);
    752   HistoryRequestHandler* history_handler = helper.history_handler();
    753   // Ensure the data given to history is correct.
    754   ASSERT_TRUE(history_handler);
    755   EXPECT_EQ(page_url, history_handler->page_url_);
    756   EXPECT_EQ(GURL(), history_handler->icon_url_);
    757   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    758 
    759   SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
    760 
    761   // Send history response.
    762   history_handler->InvokeCallback();
    763   // Verify FaviconHandler status.
    764   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    765   EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
    766 
    767   // Reset the history_handler to verify whether new icon is requested from
    768   // history.
    769   helper.set_history_handler(NULL);
    770 
    771   // Simulates update with the different favicon url.
    772   std::vector<FaviconURL> urls;
    773   urls.push_back(FaviconURL(
    774       new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    775   helper.OnUpdateFaviconURL(urls);
    776 
    777   // Verify FaviconHandler status.
    778   EXPECT_EQ(1U, helper.urls().size());
    779   ASSERT_TRUE(helper.current_candidate());
    780   ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
    781   ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
    782 
    783   // Favicon should be requested from history.
    784   history_handler = helper.history_handler();
    785   ASSERT_TRUE(history_handler);
    786   EXPECT_EQ(new_icon_url, history_handler->icon_url_);
    787   EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
    788   EXPECT_EQ(page_url, history_handler->page_url_);
    789 
    790   // Simulate find icon.
    791   SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_);
    792   history_handler->InvokeCallback();
    793 
    794   // Shouldn't request download favicon
    795   EXPECT_FALSE(helper.download_handler()->HasDownload());
    796 
    797   // Verify the favicon status.
    798   EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
    799   EXPECT_TRUE(driver.GetActiveFaviconValidity());
    800   EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
    801 }
    802 
    803 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
    804   const GURL page_url("http://www.google.com");
    805   const GURL icon_url("http://www.google.com/favicon");
    806   const GURL new_icon_url("http://www.google.com/new_favicon");
    807 
    808   TestFaviconDriver driver;
    809   TestFaviconClient client;
    810   TestFaviconHandler helper(
    811       page_url, &client, &driver, FaviconHandler::TOUCH, false);
    812 
    813   helper.FetchFavicon(page_url);
    814   HistoryRequestHandler* history_handler = helper.history_handler();
    815   // Ensure the data given to history is correct.
    816   ASSERT_TRUE(history_handler);
    817   EXPECT_EQ(page_url, history_handler->page_url_);
    818   EXPECT_EQ(GURL(), history_handler->icon_url_);
    819   EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
    820             history_handler->icon_type_);
    821 
    822   // Icon not found.
    823   history_handler->history_results_.clear();
    824   // Send history response.
    825   history_handler->InvokeCallback();
    826   // Verify FaviconHandler status.
    827   EXPECT_FALSE(driver.GetActiveFaviconValidity());
    828   EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
    829 
    830   // Reset the history_handler to verify whether new icon is requested from
    831   // history.
    832   helper.set_history_handler(NULL);
    833 
    834   // Simulates update with the different favicon url.
    835   std::vector<FaviconURL> urls;
    836   urls.push_back(FaviconURL(icon_url,
    837                             favicon_base::TOUCH_PRECOMPOSED_ICON,
    838                             std::vector<gfx::Size>()));
    839   urls.push_back(FaviconURL(
    840       new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
    841   urls.push_back(FaviconURL(
    842       new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    843   helper.OnUpdateFaviconURL(urls);
    844 
    845   // Verify FaviconHandler status.
    846   EXPECT_EQ(2U, helper.urls().size());
    847   ASSERT_TRUE(helper.current_candidate());
    848   ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
    849   ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
    850             helper.current_candidate()->icon_type);
    851 
    852   // Favicon should be requested from history.
    853   history_handler = helper.history_handler();
    854   ASSERT_TRUE(history_handler);
    855   EXPECT_EQ(icon_url, history_handler->icon_url_);
    856   EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
    857   EXPECT_EQ(page_url, history_handler->page_url_);
    858 
    859   // Simulate not find icon.
    860   history_handler->history_results_.clear();
    861   history_handler->InvokeCallback();
    862 
    863   // Should request download favicon.
    864   DownloadHandler* download_handler = helper.download_handler();
    865   EXPECT_TRUE(helper.download_handler()->HasDownload());
    866 
    867   // Verify the download request.
    868   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
    869 
    870   // Reset the history_handler to verify whether favicon is request from
    871   // history.
    872   helper.set_history_handler(NULL);
    873   // Smulates download failed.
    874   download_handler->set_failed(true);
    875   download_handler->InvokeCallback();
    876 
    877   // Left 1 url.
    878   EXPECT_EQ(1U, helper.urls().size());
    879   ASSERT_TRUE(helper.current_candidate());
    880   EXPECT_EQ(new_icon_url, helper.current_candidate()->icon_url);
    881   EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
    882 
    883   // Favicon should be requested from history.
    884   history_handler = helper.history_handler();
    885   ASSERT_TRUE(history_handler);
    886   EXPECT_EQ(new_icon_url, history_handler->icon_url_);
    887   EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
    888   EXPECT_EQ(page_url, history_handler->page_url_);
    889 
    890   // Reset download handler
    891   download_handler->Reset();
    892 
    893   // Simulates getting a expired icon from history.
    894   SetFaviconRawBitmapResult(new_icon_url,
    895                             favicon_base::TOUCH_ICON,
    896                             true /* expired */,
    897                             &history_handler->history_results_);
    898   history_handler->InvokeCallback();
    899 
    900   // Verify the download request.
    901   EXPECT_TRUE(helper.download_handler()->HasDownload());
    902   EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
    903 
    904   helper.set_history_handler(NULL);
    905 
    906   // Simulates icon being downloaded.
    907   download_handler->InvokeCallback();
    908 
    909   // New icon should be saved to history backend.
    910   history_handler = helper.history_handler();
    911   ASSERT_TRUE(history_handler);
    912   EXPECT_EQ(new_icon_url, history_handler->icon_url_);
    913   EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
    914   EXPECT_LT(0U, history_handler->bitmap_data_.size());
    915   EXPECT_EQ(page_url, history_handler->page_url_);
    916 }
    917 
    918 TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
    919   const GURL page_url("http://www.google.com");
    920   const GURL icon_url("http://www.google.com/favicon");
    921   const GURL new_icon_url("http://www.google.com/new_favicon");
    922 
    923   TestFaviconDriver driver;
    924   TestFaviconClient client;
    925   TestFaviconHandler helper(
    926       page_url, &client, &driver, FaviconHandler::TOUCH, false);
    927 
    928   helper.FetchFavicon(page_url);
    929   HistoryRequestHandler* history_handler = helper.history_handler();
    930   // Ensure the data given to history is correct.
    931   ASSERT_TRUE(history_handler);
    932   EXPECT_EQ(page_url, history_handler->page_url_);
    933   EXPECT_EQ(GURL(), history_handler->icon_url_);
    934   EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
    935             history_handler->icon_type_);
    936 
    937   // Icon not found.
    938   history_handler->history_results_.clear();
    939   // Send history response.
    940   history_handler->InvokeCallback();
    941   // Verify FaviconHandler status.
    942   EXPECT_FALSE(driver.GetActiveFaviconValidity());
    943   EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
    944 
    945   // Reset the history_handler to verify whether new icon is requested from
    946   // history.
    947   helper.set_history_handler(NULL);
    948 
    949   // Simulates update with the different favicon url.
    950   std::vector<FaviconURL> urls;
    951   urls.push_back(FaviconURL(icon_url,
    952                             favicon_base::TOUCH_PRECOMPOSED_ICON,
    953                             std::vector<gfx::Size>()));
    954   urls.push_back(FaviconURL(
    955       new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
    956   urls.push_back(FaviconURL(
    957       new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
    958   helper.OnUpdateFaviconURL(urls);
    959 
    960   // Verify FaviconHandler status.
    961   EXPECT_EQ(2U, helper.urls().size());
    962   ASSERT_TRUE(helper.current_candidate());
    963   ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
    964   ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
    965             helper.current_candidate()->icon_type);
    966 
    967   // Favicon should be requested from history.
    968   history_handler = helper.history_handler();
    969   ASSERT_TRUE(history_handler);
    970   EXPECT_EQ(icon_url, history_handler->icon_url_);
    971   EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
    972   EXPECT_EQ(page_url, history_handler->page_url_);
    973 
    974   // Simulate not find icon.
    975   history_handler->history_results_.clear();
    976   history_handler->InvokeCallback();
    977 
    978   // Should request download favicon.
    979   DownloadHandler* download_handler = helper.download_handler();
    980   EXPECT_TRUE(helper.download_handler()->HasDownload());
    981 
    982   // Verify the download request.
    983   EXPECT_EQ(icon_url, download_handler->GetImageUrl());
    984 
    985   // Reset the history_handler to verify whether favicon is request from
    986   // history.
    987   helper.set_history_handler(NULL);
    988   const GURL latest_icon_url("http://www.google.com/latest_favicon");
    989   std::vector<FaviconURL> latest_urls;
    990   latest_urls.push_back(FaviconURL(
    991       latest_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
    992   helper.OnUpdateFaviconURL(latest_urls);
    993 
    994   EXPECT_EQ(1U, helper.urls().size());
    995   EXPECT_EQ(latest_icon_url, helper.current_candidate()->icon_url);
    996   EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
    997 
    998   // Whether new icon is requested from history
    999   history_handler = helper.history_handler();
   1000   ASSERT_TRUE(history_handler);
   1001   EXPECT_EQ(latest_icon_url, history_handler->icon_url_);
   1002   EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
   1003   EXPECT_EQ(page_url, history_handler->page_url_);
   1004 
   1005   // Reset the history_handler to verify whether favicon is request from
   1006   // history.
   1007   // Save the callback for late use.
   1008   favicon_base::FaviconResultsCallback callback = history_handler->callback_;
   1009   helper.set_history_handler(NULL);
   1010 
   1011   // Simulates download succeed.
   1012   download_handler->InvokeCallback();
   1013   // The downloaded icon should be thrown away as there is favicon update.
   1014   EXPECT_FALSE(helper.history_handler());
   1015 
   1016   download_handler->Reset();
   1017 
   1018   // Simulates getting the icon from history.
   1019   scoped_ptr<HistoryRequestHandler> handler;
   1020   handler.reset(new HistoryRequestHandler(
   1021       page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback));
   1022   SetFaviconRawBitmapResult(latest_icon_url,
   1023                             favicon_base::TOUCH_ICON,
   1024                             false /* expired */,
   1025                             &handler->history_results_);
   1026   handler->InvokeCallback();
   1027 
   1028   // No download request.
   1029   EXPECT_FALSE(download_handler->HasDownload());
   1030 }
   1031 
   1032 #if !defined(OS_ANDROID)
   1033 
   1034 // Test the favicon which is selected when the web page provides several
   1035 // favicons and none of the favicons are cached in history.
   1036 // The goal of this test is to be more of an integration test than
   1037 // SelectFaviconFramesTest.*.
   1038 TEST_F(FaviconHandlerTest, MultipleFavicons) {
   1039   const GURL kPageURL("http://www.google.com");
   1040   const FaviconURL kSourceIconURLs[] = {
   1041       FaviconURL(GURL("http://www.google.com/a"),
   1042                  favicon_base::FAVICON,
   1043                  std::vector<gfx::Size>()),
   1044       FaviconURL(GURL("http://www.google.com/b"),
   1045                  favicon_base::FAVICON,
   1046                  std::vector<gfx::Size>()),
   1047       FaviconURL(GURL("http://www.google.com/c"),
   1048                  favicon_base::FAVICON,
   1049                  std::vector<gfx::Size>()),
   1050       FaviconURL(GURL("http://www.google.com/d"),
   1051                  favicon_base::FAVICON,
   1052                  std::vector<gfx::Size>()),
   1053       FaviconURL(GURL("http://www.google.com/e"),
   1054                  favicon_base::FAVICON,
   1055                  std::vector<gfx::Size>())};
   1056 
   1057   // Set the supported scale factors to 1x and 2x. This affects the behavior of
   1058   // SelectFaviconFrames().
   1059   std::vector<ui::ScaleFactor> scale_factors;
   1060   scale_factors.push_back(ui::SCALE_FACTOR_100P);
   1061   scale_factors.push_back(ui::SCALE_FACTOR_200P);
   1062   ui::test::ScopedSetSupportedScaleFactors scoped_supported(scale_factors);
   1063 
   1064   // 1) Test that if there are several single resolution favicons to choose from
   1065   // that the largest exact match is chosen.
   1066   TestFaviconDriver driver1;
   1067   TestFaviconClient client;
   1068   TestFaviconHandler handler1(
   1069       kPageURL, &client, &driver1, FaviconHandler::FAVICON, false);
   1070 
   1071   const int kSizes1[] = { 16, 24, 32, 48, 256 };
   1072   std::vector<FaviconURL> urls1(kSourceIconURLs,
   1073                                 kSourceIconURLs + arraysize(kSizes1));
   1074   DownloadTillDoneIgnoringHistory(&handler1, kPageURL, urls1, kSizes1);
   1075 
   1076   EXPECT_EQ(0u, handler1.image_urls().size());
   1077   EXPECT_TRUE(driver1.GetActiveFaviconValidity());
   1078   EXPECT_FALSE(driver1.GetActiveFaviconImage().IsEmpty());
   1079   EXPECT_EQ(gfx::kFaviconSize, driver1.GetActiveFaviconImage().Width());
   1080 
   1081   size_t expected_index = 2u;
   1082   EXPECT_EQ(32, kSizes1[expected_index]);
   1083   EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
   1084             driver1.GetActiveFaviconURL());
   1085 
   1086   // 2) Test that if there are several single resolution favicons to choose
   1087   // from, the exact match is preferred even if it results in upsampling.
   1088   TestFaviconDriver driver2;
   1089   TestFaviconHandler handler2(
   1090       kPageURL, &client, &driver2, FaviconHandler::FAVICON, false);
   1091 
   1092   const int kSizes2[] = { 16, 24, 48, 256 };
   1093   std::vector<FaviconURL> urls2(kSourceIconURLs,
   1094                                 kSourceIconURLs + arraysize(kSizes2));
   1095   DownloadTillDoneIgnoringHistory(&handler2, kPageURL, urls2, kSizes2);
   1096   EXPECT_TRUE(driver2.GetActiveFaviconValidity());
   1097   expected_index = 0u;
   1098   EXPECT_EQ(16, kSizes2[expected_index]);
   1099   EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
   1100             driver2.GetActiveFaviconURL());
   1101 
   1102   // 3) Test that favicons which need to be upsampled a little or downsampled
   1103   // a little are preferred over huge favicons.
   1104   TestFaviconDriver driver3;
   1105   TestFaviconHandler handler3(
   1106       kPageURL, &client, &driver3, FaviconHandler::FAVICON, false);
   1107 
   1108   const int kSizes3[] = { 256, 48 };
   1109   std::vector<FaviconURL> urls3(kSourceIconURLs,
   1110                                 kSourceIconURLs + arraysize(kSizes3));
   1111   DownloadTillDoneIgnoringHistory(&handler3, kPageURL, urls3, kSizes3);
   1112   EXPECT_TRUE(driver3.GetActiveFaviconValidity());
   1113   expected_index = 1u;
   1114   EXPECT_EQ(48, kSizes3[expected_index]);
   1115   EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
   1116             driver3.GetActiveFaviconURL());
   1117 
   1118   TestFaviconDriver driver4;
   1119   TestFaviconHandler handler4(
   1120       kPageURL, &client, &driver4, FaviconHandler::FAVICON, false);
   1121 
   1122   const int kSizes4[] = { 17, 256 };
   1123   std::vector<FaviconURL> urls4(kSourceIconURLs,
   1124                                 kSourceIconURLs + arraysize(kSizes4));
   1125   DownloadTillDoneIgnoringHistory(&handler4, kPageURL, urls4, kSizes4);
   1126   EXPECT_TRUE(driver4.GetActiveFaviconValidity());
   1127   expected_index = 0u;
   1128   EXPECT_EQ(17, kSizes4[expected_index]);
   1129   EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
   1130             driver4.GetActiveFaviconURL());
   1131 }
   1132 
   1133 #endif
   1134 
   1135 TEST_F(FaviconHandlerTest, TestSortFavicon) {
   1136   const GURL kPageURL("http://www.google.com");
   1137   std::vector<gfx::Size> icon1;
   1138   icon1.push_back(gfx::Size(1024, 1024));
   1139   icon1.push_back(gfx::Size(512, 512));
   1140 
   1141   std::vector<gfx::Size> icon2;
   1142   icon2.push_back(gfx::Size(15, 15));
   1143   icon2.push_back(gfx::Size(16, 16));
   1144 
   1145   std::vector<gfx::Size> icon3;
   1146   icon3.push_back(gfx::Size(16, 16));
   1147   icon3.push_back(gfx::Size(14, 14));
   1148 
   1149   const FaviconURL kSourceIconURLs[] = {
   1150       FaviconURL(GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
   1151       FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
   1152       FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
   1153       FaviconURL(GURL("http://www.google.com/d"),
   1154                  favicon_base::FAVICON,
   1155                  std::vector<gfx::Size>()),
   1156       FaviconURL(GURL("http://www.google.com/e"),
   1157                  favicon_base::FAVICON,
   1158                  std::vector<gfx::Size>())};
   1159 
   1160   TestFaviconClient client;
   1161   TestFaviconDriver driver1;
   1162   TestFaviconHandler handler1(
   1163       kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
   1164   std::vector<FaviconURL> urls1(kSourceIconURLs,
   1165                                 kSourceIconURLs + arraysize(kSourceIconURLs));
   1166   UpdateFaviconURL(&handler1, kPageURL, urls1);
   1167 
   1168   struct ExpectedResult {
   1169     // The favicon's index in kSourceIconURLs.
   1170     size_t favicon_index;
   1171     // Width of largest bitmap.
   1172     int width;
   1173   } results[] = {
   1174     // First is icon1
   1175     // The 16x16 is largest.
   1176     {1, 16},
   1177     // Second is iocn2 though it has same size as icon1.
   1178     // The 16x16 is largest.
   1179     {2, 16},
   1180     // The rest of bitmaps come in order, there is no sizes attribute.
   1181     {3, -1},
   1182     {4, -1},
   1183   };
   1184   const std::vector<FaviconURL>& icons = handler1.image_urls();
   1185   ASSERT_EQ(4u, icons.size());
   1186   for (size_t i = 0; i < 4; ++i) {
   1187     EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
   1188               icons[i].icon_url);
   1189     if (results[i].width != -1)
   1190       EXPECT_EQ(results[i].width, icons[i].icon_sizes[0].width());
   1191   }
   1192 }
   1193 
   1194 TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {
   1195   const GURL kPageURL("http://www.google.com");
   1196   std::vector<gfx::Size> too_large;
   1197   too_large.push_back(gfx::Size(1024, 1024));
   1198   too_large.push_back(gfx::Size(512, 512));
   1199 
   1200   std::vector<gfx::Size> one_icon;
   1201   one_icon.push_back(gfx::Size(15, 15));
   1202   one_icon.push_back(gfx::Size(512, 512));
   1203 
   1204   std::vector<gfx::Size> two_icons;
   1205   two_icons.push_back(gfx::Size(16, 16));
   1206   two_icons.push_back(gfx::Size(14, 14));
   1207 
   1208   const FaviconURL kSourceIconURLs[] = {
   1209       FaviconURL(
   1210           GURL("http://www.google.com/a"), favicon_base::FAVICON, too_large),
   1211       FaviconURL(
   1212           GURL("http://www.google.com/b"), favicon_base::FAVICON, one_icon),
   1213       FaviconURL(
   1214           GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons),
   1215       FaviconURL(GURL("http://www.google.com/d"),
   1216                  favicon_base::FAVICON,
   1217                  std::vector<gfx::Size>()),
   1218       FaviconURL(GURL("http://www.google.com/e"),
   1219                  favicon_base::FAVICON,
   1220                  std::vector<gfx::Size>())};
   1221 
   1222   TestFaviconClient client;
   1223   TestFaviconDriver driver1;
   1224   TestFaviconHandler handler1(
   1225       kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
   1226   std::vector<FaviconURL> urls1(kSourceIconURLs,
   1227                                 kSourceIconURLs + arraysize(kSourceIconURLs));
   1228   UpdateFaviconURL(&handler1, kPageURL, urls1);
   1229 
   1230   // Simulate the download failed, to check whether the icons were requested
   1231   // to download according their size.
   1232   struct ExpectedResult {
   1233     // The size of image_urls_.
   1234     size_t image_urls_size;
   1235     // The favicon's index in kSourceIconURLs.
   1236     size_t favicon_index;
   1237     // Width of largest bitmap.
   1238     int width;
   1239   } results[] = {
   1240     // The 1024x1024 and 512x512 icons were dropped as it excceeds maximal size,
   1241     // image_urls_ is 4 elements.
   1242     // The 16x16 is largest.
   1243     {4, 2, 16},
   1244     // The 16x16 was dropped.
   1245     // The 15x15 is largest.
   1246     {3, 1, 15},
   1247     // The rest of bitmaps come in order.
   1248     {2, 3, -1},
   1249     {1, 4, -1},
   1250   };
   1251 
   1252   for (int i = 0; i < 4; ++i) {
   1253     ASSERT_EQ(results[i].image_urls_size, handler1.image_urls().size());
   1254     EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
   1255               handler1.current_candidate()->icon_url);
   1256     if (results[i].width != -1) {
   1257       EXPECT_EQ(results[i].width, handler1.current_candidate()->
   1258                 icon_sizes[0].width());
   1259     }
   1260 
   1261     // Simulate no favicon from history.
   1262     handler1.history_handler()->history_results_.clear();
   1263     handler1.history_handler()->InvokeCallback();
   1264 
   1265     // Verify download request
   1266     ASSERT_TRUE(handler1.download_handler()->HasDownload());
   1267     EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
   1268               handler1.download_handler()->GetImageUrl());
   1269 
   1270     // Simulate the download failed.
   1271     handler1.download_handler()->set_failed(true);
   1272     handler1.download_handler()->InvokeCallback();
   1273   }
   1274 }
   1275 
   1276 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
   1277   const GURL kPageURL("http://www.google.com");
   1278 
   1279   std::vector<gfx::Size> one_icon;
   1280   one_icon.push_back(gfx::Size(15, 15));
   1281 
   1282   std::vector<gfx::Size> two_icons;
   1283   two_icons.push_back(gfx::Size(14, 14));
   1284   two_icons.push_back(gfx::Size(16, 16));
   1285 
   1286   const FaviconURL kSourceIconURLs[] = {
   1287       FaviconURL(
   1288           GURL("http://www.google.com/b"), favicon_base::FAVICON, one_icon),
   1289       FaviconURL(
   1290           GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons)};
   1291 
   1292   TestFaviconClient client;
   1293   TestFaviconDriver driver1;
   1294   TestFaviconHandler handler1(
   1295       kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
   1296   std::vector<FaviconURL> urls1(kSourceIconURLs,
   1297                                 kSourceIconURLs + arraysize(kSourceIconURLs));
   1298   UpdateFaviconURL(&handler1, kPageURL, urls1);
   1299 
   1300   ASSERT_EQ(2u, handler1.urls().size());
   1301 
   1302   // Index of largest favicon in kSourceIconURLs.
   1303   size_t i = 1;
   1304   // The largest bitmap's index in Favicon .
   1305   int b = 1;
   1306 
   1307   // Verify the icon_bitmaps_ was initialized correctly.
   1308   EXPECT_EQ(kSourceIconURLs[i].icon_url,
   1309             handler1.current_candidate()->icon_url);
   1310   EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
   1311             handler1.current_candidate()->icon_sizes[0]);
   1312 
   1313   // Simulate no favicon from history.
   1314   handler1.history_handler()->history_results_.clear();
   1315   handler1.history_handler()->InvokeCallback();
   1316 
   1317   // Verify download request
   1318   ASSERT_TRUE(handler1.download_handler()->HasDownload());
   1319   EXPECT_EQ(kSourceIconURLs[i].icon_url,
   1320             handler1.download_handler()->GetImageUrl());
   1321 
   1322   // Give the correct download result.
   1323   std::vector<int> sizes;
   1324   for (std::vector<gfx::Size>::const_iterator j =
   1325            kSourceIconURLs[i].icon_sizes.begin();
   1326        j != kSourceIconURLs[i].icon_sizes.end(); ++j)
   1327     sizes.push_back(j->width());
   1328 
   1329   handler1.download_handler()->SetImageSizes(sizes);
   1330   handler1.download_handler()->InvokeCallback();
   1331 
   1332   // Verify the largest bitmap has been saved into history.
   1333   EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
   1334   EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
   1335             handler1.history_handler()->size_);
   1336 }
   1337 
   1338 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
   1339   const GURL kPageURL("http://www.google.com");
   1340 
   1341   std::vector<gfx::Size> icon1;
   1342   icon1.push_back(gfx::Size(16, 16));
   1343   const int actual_size1 = 10;
   1344 
   1345   std::vector<gfx::Size> icon2;
   1346   icon2.push_back(gfx::Size(15, 15));
   1347   const int actual_size2 = 12;
   1348 
   1349   const FaviconURL kSourceIconURLs[] = {
   1350       FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
   1351       FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2),
   1352       FaviconURL(GURL("http://www.google.com/d"),
   1353                  favicon_base::FAVICON,
   1354                  std::vector<gfx::Size>())};
   1355 
   1356   TestFaviconClient client;
   1357   TestFaviconDriver driver1;
   1358   TestFaviconHandler handler1(
   1359       kPageURL, &client, &driver1, FaviconHandler::FAVICON, true);
   1360   std::vector<FaviconURL> urls1(kSourceIconURLs,
   1361                                 kSourceIconURLs + arraysize(kSourceIconURLs));
   1362   UpdateFaviconURL(&handler1, kPageURL, urls1);
   1363   ASSERT_EQ(3u, handler1.urls().size());
   1364 
   1365   // Simulate no favicon from history.
   1366   handler1.history_handler()->history_results_.clear();
   1367   handler1.history_handler()->InvokeCallback();
   1368 
   1369   // Verify the first icon was request to download
   1370   ASSERT_TRUE(handler1.download_handler()->HasDownload());
   1371   EXPECT_EQ(kSourceIconURLs[0].icon_url,
   1372             handler1.download_handler()->GetImageUrl());
   1373 
   1374   // Give the incorrect size.
   1375   std::vector<int> sizes;
   1376   sizes.push_back(actual_size1);
   1377   handler1.download_handler()->SetImageSizes(sizes);
   1378   handler1.download_handler()->InvokeCallback();
   1379 
   1380   // Simulate no favicon from history.
   1381   handler1.history_handler()->history_results_.clear();
   1382   handler1.history_handler()->InvokeCallback();
   1383 
   1384   // Verify the 2nd icon was request to download
   1385   ASSERT_TRUE(handler1.download_handler()->HasDownload());
   1386   EXPECT_EQ(kSourceIconURLs[1].icon_url,
   1387             handler1.download_handler()->GetImageUrl());
   1388 
   1389   // Very the best candidate is icon1
   1390   EXPECT_EQ(kSourceIconURLs[0].icon_url,
   1391             handler1.best_favicon_candidate().image_url);
   1392   EXPECT_EQ(gfx::Size(actual_size1, actual_size1),
   1393             handler1.best_favicon_candidate().image.Size());
   1394 
   1395   // Give the incorrect size.
   1396   sizes.clear();
   1397   sizes.push_back(actual_size2);
   1398   handler1.download_handler()->SetImageSizes(sizes);
   1399   handler1.download_handler()->InvokeCallback();
   1400 
   1401   // Verify icon2 has been saved into history.
   1402   EXPECT_EQ(kSourceIconURLs[1].icon_url, handler1.history_handler()->icon_url_);
   1403   EXPECT_EQ(gfx::Size(actual_size2, actual_size2),
   1404             handler1.history_handler()->size_);
   1405 }
   1406 
   1407 static KeyedService* BuildFaviconService(content::BrowserContext* profile) {
   1408   return new FaviconService(static_cast<Profile*>(profile));
   1409 }
   1410 
   1411 static KeyedService* BuildHistoryService(content::BrowserContext* profile) {
   1412   return NULL;
   1413 }
   1414 
   1415 // Test that Favicon is not requested repeatedly during the same session if
   1416 // server returns HTTP 404 status.
   1417 TEST_F(FaviconHandlerTest, UnableToDownloadFavicon) {
   1418   const GURL missing_icon_url("http://www.google.com/favicon.ico");
   1419   const GURL another_icon_url("http://www.youtube.com/favicon.ico");
   1420 
   1421   Profile* profile = Profile::FromBrowserContext(
   1422       web_contents()->GetBrowserContext());
   1423 
   1424   FaviconServiceFactory::GetInstance()->SetTestingFactory(
   1425       profile, BuildFaviconService);
   1426 
   1427   HistoryServiceFactory::GetInstance()->SetTestingFactory(
   1428       profile, BuildHistoryService);
   1429 
   1430   FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
   1431       profile, Profile::IMPLICIT_ACCESS);
   1432 
   1433   FaviconTabHelper::CreateForWebContents(web_contents());
   1434   FaviconTabHelper* favicon_tab_helper =
   1435       FaviconTabHelper::FromWebContents(web_contents());
   1436 
   1437   std::vector<SkBitmap> empty_icons;
   1438   std::vector<gfx::Size> empty_icon_sizes;
   1439   int download_id = 0;
   1440 
   1441   // Try to download missing icon.
   1442   download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
   1443   EXPECT_NE(0, download_id);
   1444   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1445 
   1446   // Report download failure with HTTP 503 status.
   1447   favicon_tab_helper->DidDownloadFavicon(download_id, 503, missing_icon_url,
   1448       empty_icons, empty_icon_sizes);
   1449   // Icon is not marked as UnableToDownload as HTTP status is not 404.
   1450   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1451 
   1452   // Try to download again.
   1453   download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
   1454   EXPECT_NE(0, download_id);
   1455   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1456 
   1457   // Report download failure with HTTP 404 status.
   1458   favicon_tab_helper->DidDownloadFavicon(download_id, 404, missing_icon_url,
   1459       empty_icons, empty_icon_sizes);
   1460   // Icon is marked as UnableToDownload.
   1461   EXPECT_TRUE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1462 
   1463   // Try to download again.
   1464   download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
   1465   // Download is not started and Icon is still marked as UnableToDownload.
   1466   EXPECT_EQ(0, download_id);
   1467   EXPECT_TRUE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1468 
   1469   // Try to download another icon.
   1470   download_id = favicon_tab_helper->StartDownload(another_icon_url, 0);
   1471   // Download is started as another icon URL is not same as missing_icon_url.
   1472   EXPECT_NE(0, download_id);
   1473   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(another_icon_url));
   1474 
   1475   // Clear the list of missing icons.
   1476   favicon_service->ClearUnableToDownloadFavicons();
   1477   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1478   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(another_icon_url));
   1479 
   1480   // Try to download again.
   1481   download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
   1482   EXPECT_NE(0, download_id);
   1483   // Report download success with HTTP 200 status.
   1484   favicon_tab_helper->DidDownloadFavicon(download_id, 200, missing_icon_url,
   1485       empty_icons, empty_icon_sizes);
   1486   // Icon is not marked as UnableToDownload as HTTP status is not 404.
   1487   EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
   1488 }
   1489 
   1490 }  // namespace.
   1491