| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/manifest/manifest_icon_selector.h" | 5 #include "chrome/browser/manifest/manifest_icon_selector.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 #include "ui/gfx/screen.h" | 12 #include "ui/gfx/screen.h" |
| 13 #include "ui/gfx/screen_type_delegate.h" | 13 #include "ui/gfx/screen_type_delegate.h" |
| 14 #include "ui/gfx/test/test_screen.h" | 14 #include "ui/gfx/test/test_screen.h" |
| 15 | 15 |
| 16 namespace { | |
| 17 | |
| 18 const int kPreferredIconSize = 48; | |
| 19 | |
| 20 } | |
| 21 | |
| 22 class ManifestIconSelectorTest : public testing::Test { | 16 class ManifestIconSelectorTest : public testing::Test { |
| 23 protected: | 17 protected: |
| 24 ManifestIconSelectorTest() { | 18 ManifestIconSelectorTest() { |
| 25 test_screen_.display()->set_id(0x1337); | 19 test_screen_.display()->set_id(0x1337); |
| 26 test_screen_.display()->set_bounds(gfx::Rect(0, 0, 2560, 1440)); | 20 test_screen_.display()->set_bounds(gfx::Rect(0, 0, 2560, 1440)); |
| 27 } | 21 } |
| 28 | 22 |
| 29 ~ManifestIconSelectorTest() override {} | 23 ~ManifestIconSelectorTest() override {} |
| 30 | 24 |
| 25 GURL FindBestMatchingIconWithMinimum( |
| 26 const std::vector<content::Manifest::Icon>& icons, |
| 27 int minimum_icon_size_in_dp) { |
| 28 return ManifestIconSelector::FindBestMatchingIcon( |
| 29 icons, GetPreferredIconSizeInDp(), |
| 30 minimum_icon_size_in_dp, &test_screen_); |
| 31 } |
| 32 |
| 31 GURL FindBestMatchingIcon(const std::vector<content::Manifest::Icon>& icons) { | 33 GURL FindBestMatchingIcon(const std::vector<content::Manifest::Icon>& icons) { |
| 32 return ManifestIconSelector::FindBestMatchingIcon( | 34 return FindBestMatchingIconWithMinimum(icons, 0); |
| 33 icons, GetPreferredIconSizeInDp(), &test_screen_); | |
| 34 } | 35 } |
| 35 | 36 |
| 36 void SetDisplayDeviceScaleFactor(float device_scale_factor) { | 37 void SetDisplayDeviceScaleFactor(float device_scale_factor) { |
| 37 test_screen_.display()->set_device_scale_factor(device_scale_factor); | 38 test_screen_.display()->set_device_scale_factor(device_scale_factor); |
| 38 } | 39 } |
| 39 | 40 |
| 40 static int GetPreferredIconSizeInDp() { | 41 int GetPreferredIconSizeInDp() { |
| 41 return kPreferredIconSize; | 42 return preferred_icon_size_; |
| 43 } |
| 44 |
| 45 void SetPreferredIconSizeInDp(int new_size) { |
| 46 preferred_icon_size_ = new_size; |
| 42 } | 47 } |
| 43 | 48 |
| 44 static content::Manifest::Icon CreateIcon( | 49 static content::Manifest::Icon CreateIcon( |
| 45 const std::string& url, | 50 const std::string& url, |
| 46 const std::string& type, | 51 const std::string& type, |
| 47 double density, | 52 double density, |
| 48 const std::vector<gfx::Size> sizes) { | 53 const std::vector<gfx::Size> sizes) { |
| 49 content::Manifest::Icon icon; | 54 content::Manifest::Icon icon; |
| 50 icon.src = GURL(url); | 55 icon.src = GURL(url); |
| 51 if (!type.empty()) | 56 if (!type.empty()) |
| 52 icon.type = base::NullableString16(base::UTF8ToUTF16(type), false); | 57 icon.type = base::NullableString16(base::UTF8ToUTF16(type), false); |
| 53 icon.density = density; | 58 icon.density = density; |
| 54 icon.sizes = sizes; | 59 icon.sizes = sizes; |
| 55 | 60 |
| 56 return icon; | 61 return icon; |
| 57 } | 62 } |
| 58 | 63 |
| 59 private: | 64 private: |
| 60 gfx::test::TestScreen test_screen_; | 65 gfx::test::TestScreen test_screen_; |
| 66 int preferred_icon_size_ = 48; |
| 61 | 67 |
| 62 DISALLOW_COPY_AND_ASSIGN(ManifestIconSelectorTest); | 68 DISALLOW_COPY_AND_ASSIGN(ManifestIconSelectorTest); |
| 63 }; | 69 }; |
| 64 | 70 |
| 65 TEST_F(ManifestIconSelectorTest, NoIcons) { | 71 TEST_F(ManifestIconSelectorTest, NoIcons) { |
| 66 // No icons should return the empty URL. | 72 // No icons should return the empty URL. |
| 67 std::vector<content::Manifest::Icon> icons; | 73 std::vector<content::Manifest::Icon> icons; |
| 68 GURL url = FindBestMatchingIcon(icons); | 74 GURL url = FindBestMatchingIcon(icons); |
| 69 EXPECT_TRUE(url.is_empty()); | 75 EXPECT_TRUE(url.is_empty()); |
| 70 } | 76 } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes)); | 228 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes)); |
| 223 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes)); | 229 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes)); |
| 224 | 230 |
| 225 SetDisplayDeviceScaleFactor(3.0f); | 231 SetDisplayDeviceScaleFactor(3.0f); |
| 226 GURL url = FindBestMatchingIcon(icons); | 232 GURL url = FindBestMatchingIcon(icons); |
| 227 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec()); | 233 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec()); |
| 228 } | 234 } |
| 229 | 235 |
| 230 TEST_F(ManifestIconSelectorTest, DeviceDensityMatchRejectsTooSmall) { | 236 TEST_F(ManifestIconSelectorTest, DeviceDensityMatchRejectsTooSmall) { |
| 231 // If we have to resort to density matching to find icons, then an icon of | 237 // If we have to resort to density matching to find icons, then an icon of |
| 232 // the correct size has not been found. Make sure that an icon which is just | 238 // the correct size has not been found. Make sure that the minimum passed |
| 233 // slightly smaller than one density bucket below the device is not chosen | 239 // is enforced. |
| 234 // even if the density matches. | |
| 235 std::vector<gfx::Size> sizes_1_2; | 240 std::vector<gfx::Size> sizes_1_2; |
| 236 std::vector<gfx::Size> sizes_3; | 241 std::vector<gfx::Size> sizes_3; |
| 237 | 242 |
| 238 sizes_1_2.push_back(gfx::Size(47, 47)); | 243 sizes_1_2.push_back(gfx::Size(47, 47)); |
| 239 sizes_3.push_back(gfx::Size(95, 95)); | 244 sizes_3.push_back(gfx::Size(95, 95)); |
| 240 | 245 |
| 246 // Set to a value which will not affect the calculations. |
| 247 SetPreferredIconSizeInDp(1024); |
| 248 |
| 241 std::vector<content::Manifest::Icon> icons; | 249 std::vector<content::Manifest::Icon> icons; |
| 242 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes_1_2)); | 250 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes_1_2)); |
| 243 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes_1_2)); | 251 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes_1_2)); |
| 244 icons.push_back(CreateIcon("http://foo.com/icon_x3.png", "", 3.0, sizes_3)); | 252 icons.push_back(CreateIcon("http://foo.com/icon_x3.png", "", 3.0, sizes_3)); |
| 245 | 253 |
| 246 // Nothing matches here because there is a density scale factor lower bound of | 254 // Nothing matches here because the minimum is 48. |
| 247 // of 1.0 which since there is no density bucket smaller than the one | |
| 248 // associated with this scale factor. | |
| 249 SetDisplayDeviceScaleFactor(1.0f); | 255 SetDisplayDeviceScaleFactor(1.0f); |
| 250 GURL url = FindBestMatchingIcon(icons); | 256 GURL url = FindBestMatchingIconWithMinimum(icons, 48); |
| 251 EXPECT_TRUE(url.is_empty()); | 257 EXPECT_TRUE(url.is_empty()); |
| 252 | 258 |
| 253 // Nothing matches here as the icon is just smaller than the icon size | 259 // Nothing matches here because the minimum is 48 again. |
| 254 // one density bucket below (i.e. 96 is expected and 48 is the minimum). | |
| 255 SetDisplayDeviceScaleFactor(2.0f); | 260 SetDisplayDeviceScaleFactor(2.0f); |
| 256 url = FindBestMatchingIcon(icons); | 261 url = FindBestMatchingIconWithMinimum(icons, 48); |
| 257 EXPECT_TRUE(url.is_empty()); | 262 EXPECT_TRUE(url.is_empty()); |
| 258 | 263 |
| 259 // Nothing matches here as the icon is just smaller than the icon size | 264 // Nothing matches here as the minimum is 96. |
| 260 // one density bucket below (i.e. 144 is expected and 96 is the minimum). | |
| 261 SetDisplayDeviceScaleFactor(3.0f); | 265 SetDisplayDeviceScaleFactor(3.0f); |
| 262 url = FindBestMatchingIcon(icons); | 266 url = FindBestMatchingIconWithMinimum(icons, 96); |
| 263 EXPECT_TRUE(url.is_empty()); | 267 EXPECT_TRUE(url.is_empty()); |
| 264 } | 268 } |
| 265 | 269 |
| 270 TEST_F(ManifestIconSelectorTest, IdealVeryCloseToMinimumMatches) { |
| 271 std::vector<gfx::Size> sizes; |
| 272 sizes.push_back(gfx::Size(2, 2)); |
| 273 |
| 274 std::vector<content::Manifest::Icon> icons; |
| 275 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes)); |
| 276 |
| 277 SetDisplayDeviceScaleFactor(1.0f); |
| 278 GURL url = FindBestMatchingIconWithMinimum(icons, 1); |
| 279 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec()); |
| 280 } |
| 281 |
| 282 TEST_F(ManifestIconSelectorTest, SizeVeryCloseToMinimumMatches) { |
| 283 std::vector<gfx::Size> sizes; |
| 284 sizes.push_back(gfx::Size(2, 2)); |
| 285 |
| 286 SetPreferredIconSizeInDp(200); |
| 287 |
| 288 std::vector<content::Manifest::Icon> icons; |
| 289 icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", 1.0, sizes)); |
| 290 |
| 291 SetDisplayDeviceScaleFactor(1.0f); |
| 292 GURL url = FindBestMatchingIconWithMinimum(icons, 1); |
| 293 EXPECT_EQ("http://foo.com/icon_x1.png", url.spec()); |
| 294 } |
| 295 |
| 266 TEST_F(ManifestIconSelectorTest, DoNotUseOtherDensities) { | 296 TEST_F(ManifestIconSelectorTest, DoNotUseOtherDensities) { |
| 267 // If there are only icons of densities that are not the current display | 297 // If there are only icons of densities that are not the current display |
| 268 // density or the default density, they are ignored. | 298 // density or the default density, they are ignored. |
| 269 std::vector<gfx::Size> sizes; | 299 std::vector<gfx::Size> sizes; |
| 270 sizes.push_back(gfx::Size(1024, 1024)); | 300 sizes.push_back(gfx::Size(1024, 1024)); |
| 271 | 301 |
| 272 std::vector<content::Manifest::Icon> icons; | 302 std::vector<content::Manifest::Icon> icons; |
| 273 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes)); | 303 icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", 2.0, sizes)); |
| 274 | 304 |
| 275 SetDisplayDeviceScaleFactor(3.0f); | 305 SetDisplayDeviceScaleFactor(3.0f); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 293 // different icon sizes and checking which one is picked. | 323 // different icon sizes and checking which one is picked. |
| 294 // The Device Scale Factor is 1.0 and the preferred icon size is returned by | 324 // The Device Scale Factor is 1.0 and the preferred icon size is returned by |
| 295 // GetPreferredIconSizeInDp(). | 325 // GetPreferredIconSizeInDp(). |
| 296 int very_small = GetPreferredIconSizeInDp() / 4; | 326 int very_small = GetPreferredIconSizeInDp() / 4; |
| 297 int small_size = GetPreferredIconSizeInDp() / 2; | 327 int small_size = GetPreferredIconSizeInDp() / 2; |
| 298 int bit_small = GetPreferredIconSizeInDp() - 1; | 328 int bit_small = GetPreferredIconSizeInDp() - 1; |
| 299 int bit_big = GetPreferredIconSizeInDp() + 1; | 329 int bit_big = GetPreferredIconSizeInDp() + 1; |
| 300 int big = GetPreferredIconSizeInDp() * 2; | 330 int big = GetPreferredIconSizeInDp() * 2; |
| 301 int very_big = GetPreferredIconSizeInDp() * 4; | 331 int very_big = GetPreferredIconSizeInDp() * 4; |
| 302 | 332 |
| 303 // (very_small, bit_small) => empty (since both are too small) | 333 // (very_small, bit_small) => bit_small |
| 304 { | 334 { |
| 305 std::vector<gfx::Size> sizes_1; | 335 std::vector<gfx::Size> sizes_1; |
| 306 sizes_1.push_back(gfx::Size(very_small, very_small)); | 336 sizes_1.push_back(gfx::Size(very_small, very_small)); |
| 307 | 337 |
| 308 std::vector<gfx::Size> sizes_2; | 338 std::vector<gfx::Size> sizes_2; |
| 309 sizes_2.push_back(gfx::Size(bit_small, bit_small)); | 339 sizes_2.push_back(gfx::Size(bit_small, bit_small)); |
| 310 | 340 |
| 311 std::vector<content::Manifest::Icon> icons; | 341 std::vector<content::Manifest::Icon> icons; |
| 312 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1)); | 342 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1)); |
| 313 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2)); | 343 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2)); |
| 314 | 344 |
| 315 GURL url = FindBestMatchingIcon(icons); | 345 GURL url = FindBestMatchingIcon(icons); |
| 316 EXPECT_EQ("", url.spec()); | 346 EXPECT_EQ("http://foo.com/icon.png", url.spec()); |
| 317 } | 347 } |
| 318 | 348 |
| 319 // (very_small, bit_small, smaller) => empty (since both are too small) | 349 // (very_small, bit_small, smaller) => bit_small |
| 320 { | 350 { |
| 321 std::vector<gfx::Size> sizes_1; | 351 std::vector<gfx::Size> sizes_1; |
| 322 sizes_1.push_back(gfx::Size(very_small, very_small)); | 352 sizes_1.push_back(gfx::Size(very_small, very_small)); |
| 323 | 353 |
| 324 std::vector<gfx::Size> sizes_2; | 354 std::vector<gfx::Size> sizes_2; |
| 325 sizes_2.push_back(gfx::Size(bit_small, bit_small)); | 355 sizes_2.push_back(gfx::Size(bit_small, bit_small)); |
| 326 | 356 |
| 327 std::vector<gfx::Size> sizes_3; | 357 std::vector<gfx::Size> sizes_3; |
| 328 sizes_3.push_back(gfx::Size(small_size, small_size)); | 358 sizes_3.push_back(gfx::Size(small_size, small_size)); |
| 329 | 359 |
| 330 std::vector<content::Manifest::Icon> icons; | 360 std::vector<content::Manifest::Icon> icons; |
| 331 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1)); | 361 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_1)); |
| 332 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2)); | 362 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 1.0, sizes_2)); |
| 333 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_3)); | 363 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes_3)); |
| 334 | 364 |
| 335 GURL url = FindBestMatchingIcon(icons); | 365 GURL url = FindBestMatchingIcon(icons); |
| 336 EXPECT_EQ("", url.spec()); | 366 EXPECT_EQ("http://foo.com/icon.png", url.spec()); |
| 337 } | 367 } |
| 338 | 368 |
| 339 // (very_big, big) => big | 369 // (very_big, big) => big |
| 340 { | 370 { |
| 341 std::vector<gfx::Size> sizes_1; | 371 std::vector<gfx::Size> sizes_1; |
| 342 sizes_1.push_back(gfx::Size(very_big, very_big)); | 372 sizes_1.push_back(gfx::Size(very_big, very_big)); |
| 343 | 373 |
| 344 std::vector<gfx::Size> sizes_2; | 374 std::vector<gfx::Size> sizes_2; |
| 345 sizes_2.push_back(gfx::Size(big, big)); | 375 sizes_2.push_back(gfx::Size(big, big)); |
| 346 | 376 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 | 479 |
| 450 std::vector<content::Manifest::Icon> icons; | 480 std::vector<content::Manifest::Icon> icons; |
| 451 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes)); | 481 icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", 1.0, sizes)); |
| 452 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 3.0, sizes)); | 482 icons.push_back(CreateIcon("http://foo.com/icon.png", "", 3.0, sizes)); |
| 453 | 483 |
| 454 SetDisplayDeviceScaleFactor(3.0f); | 484 SetDisplayDeviceScaleFactor(3.0f); |
| 455 GURL url = FindBestMatchingIcon(icons); | 485 GURL url = FindBestMatchingIcon(icons); |
| 456 EXPECT_EQ("http://foo.com/icon.png", url.spec()); | 486 EXPECT_EQ("http://foo.com/icon.png", url.spec()); |
| 457 } | 487 } |
| 458 } | 488 } |
| OLD | NEW |