• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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/extensions/favicon_downloader.h"
6 
7 #include "base/files/scoped_temp_dir.h"
8 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
9 #include "content/public/common/favicon_url.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12 
13 using content::RenderViewHostTester;
14 
15 namespace {
16 
17 // Creates valid SkBitmaps of the dimensions found in |sizes| and pushes them
18 // into |bitmaps|.
CreateTestBitmaps(const std::vector<gfx::Size> & sizes)19 std::vector<SkBitmap> CreateTestBitmaps(const std::vector<gfx::Size>& sizes) {
20   std::vector<SkBitmap> bitmaps(sizes.size());
21   for (size_t i = 0; i < sizes.size(); ++i) {
22     SkBitmap& bitmap = bitmaps[i];
23     bitmap.setConfig(SkBitmap::kARGB_8888_Config,
24                      sizes[i].width(),
25                      sizes[i].height());
26     bitmap.allocPixels();
27     bitmap.eraseColor(SK_ColorRED);
28   }
29   return bitmaps;
30 }
31 
32 class FaviconDownloaderTest : public ChromeRenderViewHostTestHarness {
33  protected:
FaviconDownloaderTest()34   FaviconDownloaderTest() {
35   }
36 
~FaviconDownloaderTest()37   virtual ~FaviconDownloaderTest() {
38   }
39 
40  private:
41   DISALLOW_COPY_AND_ASSIGN(FaviconDownloaderTest);
42 };
43 
44 }  // namespace
45 
46 class TestFaviconDownloader : public FaviconDownloader {
47  public:
TestFaviconDownloader(content::WebContents * web_contents,std::vector<GURL> extra_favicon_urls)48   TestFaviconDownloader(content::WebContents* web_contents,
49                         std::vector<GURL> extra_favicon_urls)
50       : FaviconDownloader(
51             web_contents,
52             extra_favicon_urls,
53             base::Bind(&TestFaviconDownloader::DownloadsComplete,
54                        base::Unretained(this))),
55         id_counter_(0) {
56   }
~TestFaviconDownloader()57   virtual ~TestFaviconDownloader() {}
58 
DownloadImage(const GURL & url)59   virtual int DownloadImage(const GURL& url) OVERRIDE {
60     return id_counter_++;
61   }
62 
GetFaviconURLsFromWebContents()63   virtual std::vector<content::FaviconURL> GetFaviconURLsFromWebContents()
64       OVERRIDE {
65     return initial_favicon_urls_;
66   }
67 
pending_requests() const68   size_t pending_requests() const {
69     return in_progress_requests_.size();
70   }
71 
DownloadsComplete(bool success,const FaviconDownloader::FaviconMap & map)72   void DownloadsComplete(bool success,
73                          const FaviconDownloader::FaviconMap& map) {
74     favicon_map_ = map;
75   }
76 
favicon_map() const77   FaviconDownloader::FaviconMap favicon_map() const {
78     return favicon_map_;
79   }
80 
CompleteImageDownload(int id,const GURL & image_url,const std::vector<gfx::Size> & original_bitmap_sizes)81   void CompleteImageDownload(
82       int id,
83       const GURL& image_url,
84       const std::vector<gfx::Size>& original_bitmap_sizes) {
85     FaviconDownloader::DidDownloadFavicon(id, 200, image_url,
86         CreateTestBitmaps(original_bitmap_sizes), original_bitmap_sizes);
87   }
88 
UpdateFaviconURLs(const std::vector<content::FaviconURL> & candidates)89   void UpdateFaviconURLs(const std::vector<content::FaviconURL>& candidates) {
90     FaviconDownloader::DidUpdateFaviconURL(candidates);
91   }
92 
set_initial_favicon_urls(const std::vector<content::FaviconURL> & urls)93   void set_initial_favicon_urls(const std::vector<content::FaviconURL>& urls) {
94     initial_favicon_urls_ = urls;
95   }
96 
97  private:
98   std::vector<content::FaviconURL> initial_favicon_urls_;
99   FaviconDownloader::FaviconMap favicon_map_;
100   int id_counter_;
101   DISALLOW_COPY_AND_ASSIGN(TestFaviconDownloader);
102 };
103 
TEST_F(FaviconDownloaderTest,SimpleDownload)104 TEST_F(FaviconDownloaderTest, SimpleDownload) {
105   const GURL favicon_url("http://www.google.com/favicon.ico");
106   TestFaviconDownloader downloader(web_contents(), std::vector<GURL>());
107 
108   std::vector<content::FaviconURL> favicon_urls;
109   favicon_urls.push_back(content::FaviconURL(
110       favicon_url, content::FaviconURL::FAVICON, std::vector<gfx::Size>()));
111   downloader.set_initial_favicon_urls(favicon_urls);
112   EXPECT_EQ(0u, downloader.pending_requests());
113 
114   downloader.Start();
115   EXPECT_EQ(1u, downloader.pending_requests());
116 
117   std::vector<gfx::Size> sizes(1, gfx::Size(32, 32));
118   downloader.CompleteImageDownload(0, favicon_urls[0].icon_url, sizes);
119   EXPECT_EQ(0u, downloader.pending_requests());
120 
121   EXPECT_EQ(1u, downloader.favicon_map().size());
122   EXPECT_EQ(1u, downloader.favicon_map()[favicon_url].size());
123 }
124 
TEST_F(FaviconDownloaderTest,DownloadWithUrlsFromWebContentsNotification)125 TEST_F(FaviconDownloaderTest, DownloadWithUrlsFromWebContentsNotification) {
126   const GURL favicon_url("http://www.google.com/favicon.ico");
127   TestFaviconDownloader downloader(web_contents(), std::vector<GURL>());
128 
129   std::vector<content::FaviconURL> favicon_urls;
130   favicon_urls.push_back(content::FaviconURL(
131       favicon_url, content::FaviconURL::FAVICON, std::vector<gfx::Size>()));
132   EXPECT_EQ(0u, downloader.pending_requests());
133 
134   // Start downloader before favicon URLs are loaded.
135   downloader.Start();
136   EXPECT_EQ(0u, downloader.pending_requests());
137 
138   downloader.UpdateFaviconURLs(favicon_urls);
139   EXPECT_EQ(1u, downloader.pending_requests());
140 
141   std::vector<gfx::Size> sizes(1, gfx::Size(32, 32));
142   downloader.CompleteImageDownload(0, favicon_urls[0].icon_url, sizes);
143   EXPECT_EQ(0u, downloader.pending_requests());
144 
145   EXPECT_EQ(1u, downloader.favicon_map().size());
146   EXPECT_EQ(1u, downloader.favicon_map()[favicon_url].size());
147 }
148 
TEST_F(FaviconDownloaderTest,DownloadMultipleUrls)149 TEST_F(FaviconDownloaderTest, DownloadMultipleUrls) {
150   const GURL empty_favicon("http://www.google.com/empty_favicon.ico");
151   const GURL favicon_url_1("http://www.google.com/favicon.ico");
152   const GURL favicon_url_2("http://www.google.com/favicon2.ico");
153 
154   std::vector<GURL> extra_urls;
155   // This should get downloaded.
156   extra_urls.push_back(favicon_url_2);
157   // This is duplicated in the favicon urls and should only be downloaded once.
158   extra_urls.push_back(empty_favicon);
159 
160   TestFaviconDownloader downloader(web_contents(), extra_urls);
161   std::vector<content::FaviconURL> favicon_urls;
162   favicon_urls.push_back(content::FaviconURL(
163       favicon_url_1, content::FaviconURL::FAVICON, std::vector<gfx::Size>()));
164   // This is duplicated in the favicon urls and should only be downloaded once.
165   favicon_urls.push_back(content::FaviconURL(
166       empty_favicon, content::FaviconURL::FAVICON, std::vector<gfx::Size>()));
167   // Invalid icons shouldn't get put into the download queue.
168   favicon_urls.push_back(
169       content::FaviconURL(GURL("http://www.google.com/invalid.ico"),
170                           content::FaviconURL::INVALID_ICON,
171                           std::vector<gfx::Size>()));
172   downloader.set_initial_favicon_urls(favicon_urls);
173   downloader.Start();
174   EXPECT_EQ(3u, downloader.pending_requests());
175 
176   std::vector<gfx::Size> sizes_1(1, gfx::Size(16, 16));
177   downloader.CompleteImageDownload(0, favicon_url_1, sizes_1);
178 
179   std::vector<gfx::Size> sizes_2;
180   sizes_2.push_back(gfx::Size(32, 32));
181   sizes_2.push_back(gfx::Size(64, 64));
182   downloader.CompleteImageDownload(1, favicon_url_2, sizes_2);
183 
184   // Only 1 download should have been initiated for |empty_favicon| even though
185   // the URL was in both the web app info and the favicon urls.
186   downloader.CompleteImageDownload(2, empty_favicon, std::vector<gfx::Size>());
187   EXPECT_EQ(0u, downloader.pending_requests());
188 
189   EXPECT_EQ(3u, downloader.favicon_map().size());
190   EXPECT_EQ(0u, downloader.favicon_map()[empty_favicon].size());
191   EXPECT_EQ(1u, downloader.favicon_map()[favicon_url_1].size());
192   EXPECT_EQ(2u, downloader.favicon_map()[favicon_url_2].size());
193 }
194