| Index: chrome/browser/manifest/manifest_icon_selector.cc
|
| diff --git a/chrome/browser/manifest/manifest_icon_selector.cc b/chrome/browser/manifest/manifest_icon_selector.cc
|
| index 7e3bd1f900508d23abdba6ff4efb41443fff4285..67f9024c47ad8a5508585c0f04cc4f0d96bc83a8 100644
|
| --- a/chrome/browser/manifest/manifest_icon_selector.cc
|
| +++ b/chrome/browser/manifest/manifest_icon_selector.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chrome/browser/manifest/manifest_icon_selector.h"
|
|
|
| +#include <algorithm>
|
| +#include <cmath>
|
| #include <limits>
|
|
|
| #include "base/strings/utf_string_conversions.h"
|
| @@ -13,8 +15,10 @@
|
|
|
| using content::Manifest;
|
|
|
| -ManifestIconSelector::ManifestIconSelector(float preferred_icon_size_in_pixels)
|
| - : preferred_icon_size_in_pixels_(preferred_icon_size_in_pixels) {
|
| +ManifestIconSelector::ManifestIconSelector(float preferred_icon_size_in_pixels,
|
| + float minimum_icon_size_in_pixels)
|
| + : preferred_icon_size_in_pixels_(preferred_icon_size_in_pixels),
|
| + minimum_icon_size_in_pixels_(minimum_icon_size_in_pixels) {
|
| }
|
|
|
| bool ManifestIconSelector::IconSizesContainsPreferredSize(
|
| @@ -29,10 +33,21 @@ bool ManifestIconSelector::IconSizesContainsPreferredSize(
|
| return false;
|
| }
|
|
|
| -GURL ManifestIconSelector::FindBestMatchingIconForDensity(
|
| +bool ManifestIconSelector::IconSizesContainsBiggerThanMinimumSize(
|
| + const std::vector<gfx::Size>& sizes) {
|
| + for (size_t i = 0; i < sizes.size(); ++i) {
|
| + if (sizes[i].height() != sizes[i].width())
|
| + continue;
|
| + if (sizes[i].width() >= minimum_icon_size_in_pixels_)
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +int ManifestIconSelector::FindBestMatchingIconForDensity(
|
| const std::vector<content::Manifest::Icon>& icons,
|
| float density) {
|
| - GURL url;
|
| + int best_index = -1;
|
| int best_delta = std::numeric_limits<int>::min();
|
|
|
| for (size_t i = 0; i < icons.size(); ++i) {
|
| @@ -45,67 +60,77 @@ GURL ManifestIconSelector::FindBestMatchingIconForDensity(
|
| continue;
|
| int delta = sizes[j].width() - preferred_icon_size_in_pixels_;
|
| if (delta == 0)
|
| - return icons[i].src;
|
| + return i;
|
| if (best_delta > 0 && delta < 0)
|
| continue;
|
| if ((best_delta > 0 && delta < best_delta) ||
|
| (best_delta < 0 && delta > best_delta)) {
|
| - url = icons[i].src;
|
| + best_index = i;
|
| best_delta = delta;
|
| }
|
| }
|
| }
|
|
|
| - return url;
|
| + return best_index;
|
| }
|
|
|
| -GURL ManifestIconSelector::FindBestMatchingIcon(
|
| - const std::vector<content::Manifest::Icon>& unfiltered_icons,
|
| +int ManifestIconSelector::FindBestMatchingIcon(
|
| + const std::vector<content::Manifest::Icon>& icons,
|
| float density) {
|
| - GURL url;
|
| - std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons);
|
| + int best_index = -1;
|
|
|
| // The first pass is to find the ideal icon. That icon is of the right size
|
| // with the default density or the device's density.
|
| for (size_t i = 0; i < icons.size(); ++i) {
|
| if (icons[i].density == density &&
|
| IconSizesContainsPreferredSize(icons[i].sizes)) {
|
| - return icons[i].src;
|
| + return i;
|
| }
|
|
|
| // If there is an icon with the right size but not the right density, keep
|
| // it on the side and only use it if nothing better is found.
|
| if (icons[i].density == Manifest::Icon::kDefaultDensity &&
|
| IconSizesContainsPreferredSize(icons[i].sizes)) {
|
| - url = icons[i].src;
|
| + best_index = i;
|
| }
|
| }
|
|
|
| + if (best_index != -1)
|
| + return best_index;
|
| +
|
| // The second pass is to find an icon with 'any'. The current device scale
|
| // factor is preferred. Otherwise, the default scale factor is used.
|
| for (size_t i = 0; i < icons.size(); ++i) {
|
| if (icons[i].density == density &&
|
| IconSizesContainsAny(icons[i].sizes)) {
|
| - return icons[i].src;
|
| + return i;
|
| }
|
|
|
| // If there is an icon with 'any' but not the right density, keep it on the
|
| // side and only use it if nothing better is found.
|
| if (icons[i].density == Manifest::Icon::kDefaultDensity &&
|
| IconSizesContainsAny(icons[i].sizes)) {
|
| - url = icons[i].src;
|
| + best_index = i;
|
| }
|
| }
|
|
|
| + if (best_index != -1)
|
| + return best_index;
|
| +
|
| // The last pass will try to find the best suitable icon for the device's
|
| // scale factor. If none, another pass will be run using kDefaultDensity.
|
| - if (!url.is_valid())
|
| - url = FindBestMatchingIconForDensity(icons, density);
|
| - if (!url.is_valid())
|
| - url = FindBestMatchingIconForDensity(icons,
|
| - Manifest::Icon::kDefaultDensity);
|
| -
|
| - return url;
|
| + best_index = FindBestMatchingIconForDensity(icons, density);
|
| + if (best_index != -1 &&
|
| + IconSizesContainsBiggerThanMinimumSize(icons[best_index].sizes))
|
| + return best_index;
|
| +
|
| + best_index = FindBestMatchingIconForDensity(icons,
|
| + Manifest::Icon::kDefaultDensity);
|
| + if (best_index != -1 &&
|
| + IconSizesContainsBiggerThanMinimumSize(icons[best_index].sizes))
|
| + return best_index;
|
| +
|
| + return -1;
|
| }
|
|
|
|
|
| @@ -116,7 +141,6 @@ bool ManifestIconSelector::IconSizesContainsAny(
|
| if (sizes[i].IsEmpty())
|
| return true;
|
| }
|
| -
|
| return false;
|
| }
|
|
|
| @@ -146,6 +170,18 @@ GURL ManifestIconSelector::FindBestMatchingIcon(
|
| const float preferred_icon_size_in_pixels =
|
| preferred_icon_size_in_dp * device_scale_factor;
|
|
|
| - ManifestIconSelector selector(preferred_icon_size_in_pixels);
|
| - return selector.FindBestMatchingIcon(unfiltered_icons, device_scale_factor);
|
| + const int minimum_scale_factor = std::max(
|
| + static_cast<int>(floor(device_scale_factor - 1)), 1);
|
| + const float minimum_icon_size_in_pixels =
|
| + preferred_icon_size_in_dp * minimum_scale_factor;
|
| +
|
| + std::vector<Manifest::Icon> icons =
|
| + ManifestIconSelector::FilterIconsByType(unfiltered_icons);
|
| +
|
| + ManifestIconSelector selector(preferred_icon_size_in_pixels,
|
| + minimum_icon_size_in_pixels);
|
| + int index = selector.FindBestMatchingIcon(icons, device_scale_factor);
|
| + if (index == -1)
|
| + return GURL();
|
| + return icons[index].src;
|
| }
|
|
|