Vectorize website settings icons in omnibox
[chromium-blink-merge.git] / components / favicon / core / large_icon_service_unittest.cc
blobacc088c583ed4b99173a965e4bafef152f92b70f
1 // Copyright 2015 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.
5 #include "components/favicon/core/large_icon_service.h"
7 #include <deque>
9 #include "base/bind.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/task/cancelable_task_tracker.h"
14 #include "components/favicon/core/favicon_client.h"
15 #include "components/favicon/core/favicon_service.h"
16 #include "components/favicon_base/fallback_icon_style.h"
17 #include "components/favicon_base/favicon_types.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "third_party/skia/include/core/SkColor.h"
21 #include "ui/gfx/codec/png_codec.h"
22 #include "ui/gfx/geometry/size.h"
23 #include "ui/gfx/image/image.h"
24 #include "url/gurl.h"
26 namespace favicon {
27 namespace {
29 const char kDummyUrl[] = "http://www.example.com";
30 const char kDummyIconUrl[] = "http://www.example.com/touch_icon.png";
32 const SkColor kTestColor = SK_ColorRED;
34 favicon_base::FaviconRawBitmapResult CreateTestBitmap(
35 int w, int h, SkColor color) {
36 favicon_base::FaviconRawBitmapResult result;
37 result.expired = false;
39 // Create bitmap and fill with |color|.
40 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
41 SkBitmap bitmap;
42 bitmap.allocN32Pixels(w, h);
43 bitmap.eraseColor(color);
44 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data->data());
45 result.bitmap_data = data;
47 result.pixel_size = gfx::Size(w, h);
48 result.icon_url = GURL(kDummyIconUrl);
49 result.icon_type = favicon_base::TOUCH_ICON;
50 CHECK(result.is_valid());
51 return result;
54 // A mock FaviconService that emits pre-programmed response.
55 class MockFaviconService : public FaviconService {
56 public:
57 MockFaviconService() : FaviconService(nullptr, nullptr) {
60 ~MockFaviconService() override {
63 base::CancelableTaskTracker::TaskId GetLargestRawFaviconForPageURL(
64 const GURL& page_url,
65 const std::vector<int>& icon_types,
66 int minimum_size_in_pixels,
67 const favicon_base::FaviconRawBitmapCallback& callback,
68 base::CancelableTaskTracker* tracker) override {
69 favicon_base::FaviconRawBitmapResult mock_result =
70 mock_result_queue_.front();
71 mock_result_queue_.pop_front();
72 return tracker->PostTask(
73 base::MessageLoop::current()->task_runner().get(), FROM_HERE,
74 base::Bind(callback, mock_result));
77 void InjectResult(const favicon_base::FaviconRawBitmapResult& mock_result) {
78 mock_result_queue_.push_back(mock_result);
81 bool HasUnusedResults() {
82 return !mock_result_queue_.empty();
85 private:
86 std::deque<favicon_base::FaviconRawBitmapResult> mock_result_queue_;
88 DISALLOW_COPY_AND_ASSIGN(MockFaviconService);
91 // This class provides access to LargeIconService internals.
92 class TestLargeIconService : public LargeIconService {
93 public:
94 explicit TestLargeIconService(MockFaviconService* mock_favicon_service)
95 : LargeIconService(mock_favicon_service) {
97 ~TestLargeIconService() override {
100 // Using the current thread's task runner for testing.
101 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() override {
102 return base::MessageLoop::current()->task_runner();
105 private:
106 DISALLOW_COPY_AND_ASSIGN(TestLargeIconService);
109 class LargeIconServiceTest : public testing::Test {
110 public:
111 LargeIconServiceTest() : is_callback_invoked_(false) {
114 ~LargeIconServiceTest() override {
117 void SetUp() override {
118 testing::Test::SetUp();
119 mock_favicon_service_.reset(new MockFaviconService());
120 large_icon_service_.reset(
121 new TestLargeIconService(mock_favicon_service_.get()));
124 void ResultCallback(const favicon_base::LargeIconResult& result) {
125 is_callback_invoked_ = true;
127 // Checking presence and absence of results.
128 EXPECT_EQ(expected_bitmap_.is_valid(), result.bitmap.is_valid());
129 EXPECT_EQ(expected_fallback_icon_style_ != nullptr,
130 result.fallback_icon_style != nullptr);
132 if (expected_bitmap_.is_valid()) {
133 EXPECT_EQ(expected_bitmap_.pixel_size, result.bitmap.pixel_size);
134 // Not actually checking bitmap content.
136 if (expected_fallback_icon_style_.get()) {
137 EXPECT_EQ(*expected_fallback_icon_style_,
138 *result.fallback_icon_style);
140 // Ensure all mock results have been consumed.
141 EXPECT_FALSE(mock_favicon_service_->HasUnusedResults());
144 protected:
145 base::MessageLoopForIO loop_;
147 scoped_ptr<MockFaviconService> mock_favicon_service_;
148 scoped_ptr<TestLargeIconService> large_icon_service_;
149 base::CancelableTaskTracker cancelable_task_tracker_;
151 favicon_base::FaviconRawBitmapResult expected_bitmap_;
152 scoped_ptr<favicon_base::FallbackIconStyle> expected_fallback_icon_style_;
154 bool is_callback_invoked_;
156 private:
157 DISALLOW_COPY_AND_ASSIGN(LargeIconServiceTest);
160 TEST_F(LargeIconServiceTest, SameSize) {
161 mock_favicon_service_->InjectResult(CreateTestBitmap(24, 24, kTestColor));
162 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
163 large_icon_service_->GetLargeIconOrFallbackStyle(
164 GURL(kDummyUrl),
165 24, // |min_source_size_in_pixel|
166 24, // |desired_size_in_pixel|
167 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
168 &cancelable_task_tracker_);
169 base::MessageLoop::current()->RunUntilIdle();
170 EXPECT_TRUE(is_callback_invoked_);
173 TEST_F(LargeIconServiceTest, ScaleDown) {
174 mock_favicon_service_->InjectResult(CreateTestBitmap(32, 32, kTestColor));
175 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
176 large_icon_service_->GetLargeIconOrFallbackStyle(
177 GURL(kDummyUrl),
180 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
181 &cancelable_task_tracker_);
182 base::MessageLoop::current()->RunUntilIdle();
183 EXPECT_TRUE(is_callback_invoked_);
186 TEST_F(LargeIconServiceTest, ScaleUp) {
187 mock_favicon_service_->InjectResult(CreateTestBitmap(16, 16, kTestColor));
188 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
189 large_icon_service_->GetLargeIconOrFallbackStyle(
190 GURL(kDummyUrl),
191 14, // Lowered requirement so stored bitmap is admitted.
193 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
194 &cancelable_task_tracker_);
195 base::MessageLoop::current()->RunUntilIdle();
196 EXPECT_TRUE(is_callback_invoked_);
199 // |desired_size_in_pixel| == 0 means retrieve original image without scaling.
200 TEST_F(LargeIconServiceTest, NoScale) {
201 mock_favicon_service_->InjectResult(CreateTestBitmap(24, 24, kTestColor));
202 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor);
203 large_icon_service_->GetLargeIconOrFallbackStyle(
204 GURL(kDummyUrl),
207 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
208 &cancelable_task_tracker_);
209 base::MessageLoop::current()->RunUntilIdle();
210 EXPECT_TRUE(is_callback_invoked_);
213 TEST_F(LargeIconServiceTest, FallbackSinceIconTooSmall) {
214 mock_favicon_service_->InjectResult(CreateTestBitmap(16, 16, kTestColor));
215 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
216 expected_fallback_icon_style_->background_color = kTestColor;
217 large_icon_service_->GetLargeIconOrFallbackStyle(
218 GURL(kDummyUrl),
221 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
222 &cancelable_task_tracker_);
223 base::MessageLoop::current()->RunUntilIdle();
224 EXPECT_TRUE(is_callback_invoked_);
227 TEST_F(LargeIconServiceTest, FallbackSinceIconNotSquare) {
228 mock_favicon_service_->InjectResult(CreateTestBitmap(24, 32, kTestColor));
229 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
230 expected_fallback_icon_style_->background_color = kTestColor;
231 large_icon_service_->GetLargeIconOrFallbackStyle(
232 GURL(kDummyUrl),
235 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
236 &cancelable_task_tracker_);
237 base::MessageLoop::current()->RunUntilIdle();
238 EXPECT_TRUE(is_callback_invoked_);
241 TEST_F(LargeIconServiceTest, FallbackSinceIconMissing) {
242 mock_favicon_service_->InjectResult(favicon_base::FaviconRawBitmapResult());
243 // Expect default fallback style, including background.
244 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
245 large_icon_service_->GetLargeIconOrFallbackStyle(
246 GURL(kDummyUrl),
249 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
250 &cancelable_task_tracker_);
251 base::MessageLoop::current()->RunUntilIdle();
252 EXPECT_TRUE(is_callback_invoked_);
255 TEST_F(LargeIconServiceTest, FallbackSinceIconMissingNoScale) {
256 mock_favicon_service_->InjectResult(favicon_base::FaviconRawBitmapResult());
257 // Expect default fallback style, including background.
258 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
259 large_icon_service_->GetLargeIconOrFallbackStyle(
260 GURL(kDummyUrl),
263 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
264 &cancelable_task_tracker_);
265 base::MessageLoop::current()->RunUntilIdle();
266 EXPECT_TRUE(is_callback_invoked_);
269 // Oddball case where we demand a high resolution icon to scale down. Generates
270 // fallback even though an icon with the final size is available.
271 TEST_F(LargeIconServiceTest, FallbackSinceTooPicky) {
272 mock_favicon_service_->InjectResult(CreateTestBitmap(24, 24, kTestColor));
273 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
274 expected_fallback_icon_style_->background_color = kTestColor;
275 large_icon_service_->GetLargeIconOrFallbackStyle(
276 GURL(kDummyUrl),
279 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
280 &cancelable_task_tracker_);
281 base::MessageLoop::current()->RunUntilIdle();
282 EXPECT_TRUE(is_callback_invoked_);
285 } // namespace
286 } // namespace favicon