Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / chrome / browser / android / manifest_icon_selector_unittest.cc
blobb2cafbcf8d18ac7798126e34d6ee25932b14ad38
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 "chrome/browser/android/manifest_icon_selector.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gfx/screen.h"
10 #include "ui/gfx/screen_type_delegate.h"
12 namespace {
14 const int kPreferredIconSize = 48;
18 // A dummy implementation of gfx::Screen, since ManifestIconSelector needs
19 // access to a gfx::Display's device scale factor.
20 // This is inspired by web_contents_video_capture_device_unittest.cc
21 // A bug has been opened to merge all those mocks: http://crbug.com/417227
22 class FakeScreen : public gfx::Screen {
23 public:
24 FakeScreen() : display_(0x1337, gfx::Rect(0, 0, 2560, 1440)) {
26 ~FakeScreen() override {}
28 void SetDisplayDeviceScaleFactor(float device_scale_factor) {
29 display_.set_device_scale_factor(device_scale_factor);
32 // gfx::Screen implementation (only what's needed for testing).
33 gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
34 gfx::NativeWindow GetWindowUnderCursor() override { return nullptr; }
35 gfx::NativeWindow GetWindowAtScreenPoint(
36 const gfx::Point& point) override { return nullptr; }
37 int GetNumDisplays() const override { return 1; }
38 std::vector<gfx::Display> GetAllDisplays() const override {
39 return std::vector<gfx::Display>(1, display_);
41 gfx::Display GetDisplayNearestWindow(
42 gfx::NativeView view) const override {
43 return display_;
45 gfx::Display GetDisplayNearestPoint(
46 const gfx::Point& point) const override {
47 return display_;
49 gfx::Display GetDisplayMatching(
50 const gfx::Rect& match_rect) const override {
51 return display_;
53 gfx::Display GetPrimaryDisplay() const override {
54 return display_;
56 void AddObserver(gfx::DisplayObserver* observer) override {}
57 void RemoveObserver(gfx::DisplayObserver* observer) override {}
59 private:
60 gfx::Display display_;
62 DISALLOW_COPY_AND_ASSIGN(FakeScreen);
65 class ManifestIconSelectorTest : public testing::Test {
66 protected:
67 ManifestIconSelectorTest() {}
68 ~ManifestIconSelectorTest() override {}
70 GURL FindBestMatchingIcon(const std::vector<content::Manifest::Icon>& icons) {
71 return ManifestIconSelector::FindBestMatchingIcon(
72 icons,
73 GetPreferredIconSizeInDp(),
74 &fake_screen_);
77 void SetDisplayDeviceScaleFactor(float device_scale_factor) {
78 fake_screen_.SetDisplayDeviceScaleFactor(device_scale_factor);
81 static int GetPreferredIconSizeInDp() {
82 return kPreferredIconSize;
85 static content::Manifest::Icon CreateIcon(
86 const std::string& url,
87 const std::string& type,
88 double density,
89 const std::vector<gfx::Size> sizes) {
90 content::Manifest::Icon icon;
91 icon.src = GURL(url);
92 if (!type.empty())
93 icon.type = base::NullableString16(base::UTF8ToUTF16(type), false);
94 icon.density = density;
95 icon.sizes = sizes;
97 return icon;
100 private:
101 FakeScreen fake_screen_;
103 DISALLOW_COPY_AND_ASSIGN(ManifestIconSelectorTest);
106 TEST_F(ManifestIconSelectorTest, NoIcons) {
107 // No icons should return the empty URL.
108 std::vector<content::Manifest::Icon> icons;
109 GURL url = FindBestMatchingIcon(icons);
110 EXPECT_TRUE(url.is_empty());
113 TEST_F(ManifestIconSelectorTest, NoSizes) {
114 // Icon with no sizes are ignored.
115 std::vector<content::Manifest::Icon> icons;
116 icons.push_back(
117 CreateIcon("http://foo.com/icon.png", "", 1.0, std::vector<gfx::Size>()));
119 GURL url = FindBestMatchingIcon(icons);
120 EXPECT_TRUE(url.is_empty());
123 TEST_F(ManifestIconSelectorTest, MIMETypeFiltering) {
124 // Icons with type specified to a MIME type that isn't a valid image MIME type
125 // are ignored.
126 std::vector<gfx::Size> sizes;
127 sizes.push_back(gfx::Size(10, 10));
129 std::vector<content::Manifest::Icon> icons;
130 icons.push_back(
131 CreateIcon("http://foo.com/icon.png", "image/foo_bar", 1.0, sizes));
132 icons.push_back(CreateIcon("http://foo.com/icon.png", "image/", 1.0, sizes));
133 icons.push_back(CreateIcon("http://foo.com/icon.png", "image/", 1.0, sizes));
134 icons.push_back(
135 CreateIcon("http://foo.com/icon.png", "video/mp4", 1.0, sizes));
137 GURL url = FindBestMatchingIcon(icons);
138 EXPECT_TRUE(url.is_empty());
140 icons.clear();
141 icons.push_back(
142 CreateIcon("http://foo.com/icon.png", "image/png", 1.0, sizes));
143 url = FindBestMatchingIcon(icons);
144 EXPECT_EQ("http://foo.com/icon.png", url.spec());
146 icons.clear();
147 icons.push_back(
148 CreateIcon("http://foo.com/icon.png", "image/gif", 1.0, sizes));
149 url = FindBestMatchingIcon(icons);
150 EXPECT_EQ("http://foo.com/icon.png", url.spec());
152 icons.clear();
153 icons.push_back(
154 CreateIcon("http://foo.com/icon.png", "image/jpeg", 1.0, sizes));
155 url = FindBestMatchingIcon(icons);
156 EXPECT_EQ("http://foo.com/icon.png", url.spec());
159 TEST_F(ManifestIconSelectorTest, PreferredSizeOfCurrentDensityIsUsedFirst) {
160 // This test has three icons each are marked with sizes set to the preferred
161 // icon size for the associated density.
162 std::vector<gfx::Size> sizes_1;
163 sizes_1.push_back(gfx::Size(GetPreferredIconSizeInDp(),
164 GetPreferredIconSizeInDp()));
166 std::vector<gfx::Size> sizes_2;
167 sizes_2.push_back(gfx::Size(GetPreferredIconSizeInDp() * 2,
168 GetPreferredIconSizeInDp() * 2));
170 std::vector<gfx::Size> sizes_3;
171 sizes_3.push_back(gfx::Size(GetPreferredIconSizeInDp() * 3,
172 GetPreferredIconSizeInDp() * 3));
174 std::vector<content::Manifest::Icon> icons;
175 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes_1));
176 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes_2));
177 icons.push_back(CreateIcon("http://foo.com/icon_x3.png", "", 3.0, sizes_3));
179 SetDisplayDeviceScaleFactor(1.0f);
180 GURL url = FindBestMatchingIcon(icons);
181 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
183 SetDisplayDeviceScaleFactor(2.0f);
184 url = FindBestMatchingIcon(icons);
185 EXPECT_EQ("http://foo.com/icon_x2.png", url.spec());
187 SetDisplayDeviceScaleFactor(3.0f);
188 url = FindBestMatchingIcon(icons);
189 EXPECT_EQ("http://foo.com/icon_x3.png", url.spec());
192 TEST_F(ManifestIconSelectorTest, PreferredSizeOfDefaultDensityIsUsedSecond) {
193 // This test has three icons. The first one is of density zero and is marked
194 // with three sizes which are the preferred icon size for density 1, 2 and 3.
195 // The icon for density 2 and 3 have a size set to 2x2 and 3x3.
196 // Regardless of the device scale factor, the icon of density 1 is going to be
197 // used because it matches the preferred size.
198 std::vector<gfx::Size> sizes_1;
199 sizes_1.push_back(gfx::Size(GetPreferredIconSizeInDp(),
200 GetPreferredIconSizeInDp()));
201 sizes_1.push_back(gfx::Size(GetPreferredIconSizeInDp() * 2,
202 GetPreferredIconSizeInDp() * 2));
203 sizes_1.push_back(gfx::Size(GetPreferredIconSizeInDp() * 3,
204 GetPreferredIconSizeInDp() * 3));
206 std::vector<gfx::Size> sizes_2;
207 sizes_2.push_back(gfx::Size(2, 2));
209 std::vector<gfx::Size> sizes_3;
210 sizes_3.push_back(gfx::Size(3, 3));
212 std::vector<content::Manifest::Icon> icons;
213 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes_1));
214 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes_2));
215 icons.push_back(CreateIcon("http://foo.com/icon_x3.png", "", 3.0, sizes_3));
217 SetDisplayDeviceScaleFactor(1.0f);
218 GURL url = FindBestMatchingIcon(icons);
219 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
221 SetDisplayDeviceScaleFactor(2.0f);
222 url = FindBestMatchingIcon(icons);
223 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
225 SetDisplayDeviceScaleFactor(3.0f);
226 url = FindBestMatchingIcon(icons);
227 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
230 TEST_F(ManifestIconSelectorTest, DeviceDensityFirst) {
231 // If there is no perfect icon but an icon of the current device density is
232 // present, it will be picked.
233 // This test has three icons each are marked with sizes set to the preferred
234 // icon size for the associated density.
235 std::vector<gfx::Size> sizes;
236 sizes.push_back(gfx::Size(2, 2));
238 std::vector<content::Manifest::Icon> icons;
239 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes));
240 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes));
241 icons.push_back(CreateIcon("http://foo.com/icon_x3.png", "", 3.0, sizes));
243 SetDisplayDeviceScaleFactor(1.0f);
244 GURL url = FindBestMatchingIcon(icons);
245 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
247 SetDisplayDeviceScaleFactor(2.0f);
248 url = FindBestMatchingIcon(icons);
249 EXPECT_EQ("http://foo.com/icon_x2.png", url.spec());
251 SetDisplayDeviceScaleFactor(3.0f);
252 url = FindBestMatchingIcon(icons);
253 EXPECT_EQ("http://foo.com/icon_x3.png", url.spec());
256 TEST_F(ManifestIconSelectorTest, DeviceDensityFallback) {
257 // If there is no perfect icon but and no icon of the current display density,
258 // an icon of density 1.0 will be used.
259 std::vector<gfx::Size> sizes;
260 sizes.push_back(gfx::Size(2, 2));
262 std::vector<content::Manifest::Icon> icons;
263 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes));
264 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes));
266 SetDisplayDeviceScaleFactor(3.0f);
267 GURL url = FindBestMatchingIcon(icons);
268 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
271 TEST_F(ManifestIconSelectorTest, DoNotUseOtherDensities) {
272 // If there are only icons of densities that are not the current display
273 // density or the default density, they are ignored.
274 std::vector<gfx::Size> sizes;
275 sizes.push_back(gfx::Size(2, 2));
277 std::vector<content::Manifest::Icon> icons;
278 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes));
280 SetDisplayDeviceScaleFactor(3.0f);
281 GURL url = FindBestMatchingIcon(icons);
282 EXPECT_TRUE(url.is_empty());
285 TEST_F(ManifestIconSelectorTest, NotSquareIconsAreIgnored) {
286 std::vector<gfx::Size> sizes;
287 sizes.push_back(gfx::Size(20, 2));
289 std::vector<content::Manifest::Icon> icons;
290 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes));
292 GURL url = FindBestMatchingIcon(icons);
293 EXPECT_TRUE(url.is_empty());
296 TEST_F(ManifestIconSelectorTest, ClosestIconToPreferred) {
297 // This test verifies ManifestIconSelector::FindBestMatchingIcon by passing
298 // different icon sizes and checking which one is picked.
299 // The Device Scale Factor is 1.0 and the preferred icon size is returned by
300 // GetPreferredIconSizeInDp().
301 int very_small = GetPreferredIconSizeInDp() / 4;
302 int small = GetPreferredIconSizeInDp() / 2;
303 int bit_small = GetPreferredIconSizeInDp() - 1;
304 int bit_big = GetPreferredIconSizeInDp() + 1;
305 int big = GetPreferredIconSizeInDp() * 2;
306 int very_big = GetPreferredIconSizeInDp() * 4;
308 // (very_small, bit_small) => bit_small
310 std::vector<gfx::Size> sizes_1;
311 sizes_1.push_back(gfx::Size(very_small, very_small));
313 std::vector<gfx::Size> sizes_2;
314 sizes_2.push_back(gfx::Size(bit_small, bit_small));
316 std::vector<content::Manifest::Icon> icons;
317 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
318 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2));
320 GURL url = FindBestMatchingIcon(icons);
321 EXPECT_EQ("http://foo.com/icon.png", url.spec());
324 // (very_small, bit_small, smaller) => bit_small
326 std::vector<gfx::Size> sizes_1;
327 sizes_1.push_back(gfx::Size(very_small, very_small));
329 std::vector<gfx::Size> sizes_2;
330 sizes_2.push_back(gfx::Size(bit_small, bit_small));
332 std::vector<gfx::Size> sizes_3;
333 sizes_3.push_back(gfx::Size(small, small));
335 std::vector<content::Manifest::Icon> icons;
336 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
337 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2));
338 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_3));
340 GURL url = FindBestMatchingIcon(icons);
341 EXPECT_EQ("http://foo.com/icon.png", url.spec());
344 // (very_big, big) => big
346 std::vector<gfx::Size> sizes_1;
347 sizes_1.push_back(gfx::Size(very_big, very_big));
349 std::vector<gfx::Size> sizes_2;
350 sizes_2.push_back(gfx::Size(big, big));
352 std::vector<content::Manifest::Icon> icons;
353 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
354 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2));
356 GURL url = FindBestMatchingIcon(icons);
357 EXPECT_EQ("http://foo.com/icon.png", url.spec());
360 // (very_big, big, bit_big) => bit_big
362 std::vector<gfx::Size> sizes_1;
363 sizes_1.push_back(gfx::Size(very_big, very_big));
365 std::vector<gfx::Size> sizes_2;
366 sizes_2.push_back(gfx::Size(big, big));
368 std::vector<gfx::Size> sizes_3;
369 sizes_3.push_back(gfx::Size(bit_big, bit_big));
371 std::vector<content::Manifest::Icon> icons;
372 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
373 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_2));
374 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_3));
376 GURL url = FindBestMatchingIcon(icons);
377 EXPECT_EQ("http://foo.com/icon.png", url.spec());
380 // (bit_small, very_big) => very_big
382 std::vector<gfx::Size> sizes_1;
383 sizes_1.push_back(gfx::Size(bit_small, bit_small));
385 std::vector<gfx::Size> sizes_2;
386 sizes_2.push_back(gfx::Size(very_big, very_big));
388 std::vector<content::Manifest::Icon> icons;
389 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
390 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2));
392 GURL url = FindBestMatchingIcon(icons);
393 EXPECT_EQ("http://foo.com/icon.png", url.spec());
396 // (bit_small, bit_big) => bit_big
398 std::vector<gfx::Size> sizes_1;
399 sizes_1.push_back(gfx::Size(bit_small, bit_small));
401 std::vector<gfx::Size> sizes_2;
402 sizes_2.push_back(gfx::Size(bit_big, bit_big));
404 std::vector<content::Manifest::Icon> icons;
405 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
406 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2));
408 GURL url = FindBestMatchingIcon(icons);
409 EXPECT_EQ("http://foo.com/icon.png", url.spec());
413 TEST_F(ManifestIconSelectorTest, UseAnyIfNoPreferredSize) {
414 // 'any' (ie. gfx::Size(0,0)) should be used if there is no icon of a
415 // preferred size. An icon with the current device scale factor is preferred
416 // over one with the default density.
418 // 'any' with preferred size => preferred size
420 std::vector<gfx::Size> sizes_1;
421 sizes_1.push_back(gfx::Size(GetPreferredIconSizeInDp(),
422 GetPreferredIconSizeInDp()));
423 std::vector<gfx::Size> sizes_2;
424 sizes_2.push_back(gfx::Size(0,0));
426 std::vector<content::Manifest::Icon> icons;
427 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_1));
428 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_2));
430 GURL url = FindBestMatchingIcon(icons);
431 EXPECT_EQ("http://foo.com/icon.png", url.spec());
434 // 'any' with nearly preferred size => any
436 std::vector<gfx::Size> sizes_1;
437 sizes_1.push_back(gfx::Size(GetPreferredIconSizeInDp() + 1,
438 GetPreferredIconSizeInDp() + 1));
439 std::vector<gfx::Size> sizes_2;
440 sizes_2.push_back(gfx::Size(0,0));
442 std::vector<content::Manifest::Icon> icons;
443 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1));
444 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2));
446 GURL url = FindBestMatchingIcon(icons);
447 EXPECT_EQ("http://foo.com/icon.png", url.spec());
450 // 'any' on default density and current density => current density.
452 std::vector<gfx::Size> sizes;
453 sizes.push_back(gfx::Size(0,0));
455 std::vector<content::Manifest::Icon> icons;
456 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes));
457 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 3.0, sizes));
459 SetDisplayDeviceScaleFactor(3.0f);
460 GURL url = FindBestMatchingIcon(icons);
461 EXPECT_EQ("http://foo.com/icon.png", url.spec());