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