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