| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cmath> | 10 #include <cmath> |
| 11 #include <limits> | 11 #include <limits> |
| 12 | 12 |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "components/mime_util/mime_util.h" | 14 #include "components/mime_util/mime_util.h" |
| 15 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" |
| 16 #include "ui/gfx/screen.h" | 16 #include "ui/gfx/screen.h" |
| 17 | 17 |
| 18 using content::Manifest; | 18 using content::Manifest; |
| 19 | 19 |
| 20 ManifestIconSelector::ManifestIconSelector(int ideal_icon_size_in_px, | 20 ManifestIconSelector::ManifestIconSelector(int ideal_icon_size_in_px, |
| 21 int minimum_icon_size_in_px) | 21 int minimum_icon_size_in_px) |
| 22 : ideal_icon_size_in_px_(ideal_icon_size_in_px), | 22 : ideal_icon_size_in_px_(ideal_icon_size_in_px), |
| 23 minimum_icon_size_in_px_(minimum_icon_size_in_px) { | 23 minimum_icon_size_in_px_(minimum_icon_size_in_px), |
| 24 density_( |
| 25 gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor()) { |
| 24 } | 26 } |
| 25 | 27 |
| 26 bool ManifestIconSelector::IconSizesContainsPreferredSize( | 28 bool ManifestIconSelector::IconSizesContainsPreferredSize( |
| 27 const std::vector<gfx::Size>& sizes) { | 29 const std::vector<gfx::Size>& sizes) { |
| 28 for (size_t i = 0; i < sizes.size(); ++i) { | 30 for (size_t i = 0; i < sizes.size(); ++i) { |
| 29 if (sizes[i].height() != sizes[i].width()) | 31 if (sizes[i].height() != sizes[i].width()) |
| 30 continue; | 32 continue; |
| 31 if (sizes[i].width() == ideal_icon_size_in_px_) | 33 if (sizes[i].width() == ideal_icon_size_in_px_) |
| 32 return true; | 34 return true; |
| 33 } | 35 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 best_index = i; | 72 best_index = i; |
| 71 best_delta = delta; | 73 best_delta = delta; |
| 72 } | 74 } |
| 73 } | 75 } |
| 74 } | 76 } |
| 75 | 77 |
| 76 return best_index; | 78 return best_index; |
| 77 } | 79 } |
| 78 | 80 |
| 79 int ManifestIconSelector::FindBestMatchingIcon( | 81 int ManifestIconSelector::FindBestMatchingIcon( |
| 80 const std::vector<content::Manifest::Icon>& icons, | 82 const std::vector<content::Manifest::Icon>& icons) { |
| 81 float density) { | |
| 82 int best_index = -1; | 83 int best_index = -1; |
| 83 | 84 |
| 84 // The first pass is to find the ideal icon. That icon is of the right size | 85 // The first pass is to find the ideal icon. That icon is of the right size |
| 85 // with the default density or the device's density. | 86 // with the default density or the device's density. |
| 86 for (size_t i = 0; i < icons.size(); ++i) { | 87 for (size_t i = 0; i < icons.size(); ++i) { |
| 87 if (icons[i].density == density && | 88 if (icons[i].density == density_ && |
| 88 IconSizesContainsPreferredSize(icons[i].sizes)) { | 89 IconSizesContainsPreferredSize(icons[i].sizes)) { |
| 89 return i; | 90 return i; |
| 90 } | 91 } |
| 91 | 92 |
| 92 // If there is an icon with the right size but not the right density, keep | 93 // If there is an icon with the right size but not the right density, keep |
| 93 // it on the side and only use it if nothing better is found. | 94 // it on the side and only use it if nothing better is found. |
| 94 if (icons[i].density == Manifest::Icon::kDefaultDensity && | 95 if (icons[i].density == Manifest::Icon::kDefaultDensity && |
| 95 IconSizesContainsPreferredSize(icons[i].sizes)) { | 96 IconSizesContainsPreferredSize(icons[i].sizes)) { |
| 96 best_index = i; | 97 best_index = i; |
| 97 } | 98 } |
| 98 } | 99 } |
| 99 | 100 |
| 100 if (best_index != -1) | 101 if (best_index != -1) |
| 101 return best_index; | 102 return best_index; |
| 102 | 103 |
| 103 // The second pass is to find an icon with 'any'. The current device scale | 104 // The second pass is to find an icon with 'any'. The current device scale |
| 104 // factor is preferred. Otherwise, the default scale factor is used. | 105 // factor is preferred. Otherwise, the default scale factor is used. |
| 105 for (size_t i = 0; i < icons.size(); ++i) { | 106 for (size_t i = 0; i < icons.size(); ++i) { |
| 106 if (icons[i].density == density && | 107 if (icons[i].density == density_ && |
| 107 IconSizesContainsAny(icons[i].sizes)) { | 108 IconSizesContainsAny(icons[i].sizes)) { |
| 108 return i; | 109 return i; |
| 109 } | 110 } |
| 110 | 111 |
| 111 // If there is an icon with 'any' but not the right density, keep it on the | 112 // If there is an icon with 'any' but not the right density, keep it on the |
| 112 // side and only use it if nothing better is found. | 113 // side and only use it if nothing better is found. |
| 113 if (icons[i].density == Manifest::Icon::kDefaultDensity && | 114 if (icons[i].density == Manifest::Icon::kDefaultDensity && |
| 114 IconSizesContainsAny(icons[i].sizes)) { | 115 IconSizesContainsAny(icons[i].sizes)) { |
| 115 best_index = i; | 116 best_index = i; |
| 116 } | 117 } |
| 117 } | 118 } |
| 118 | 119 |
| 119 if (best_index != -1) | 120 if (best_index != -1) |
| 120 return best_index; | 121 return best_index; |
| 121 | 122 |
| 122 // The last pass will try to find the best suitable icon for the device's | 123 // The last pass will try to find the best suitable icon for the device's |
| 123 // scale factor. If none, another pass will be run using kDefaultDensity. | 124 // scale factor. If none, another pass will be run using kDefaultDensity. |
| 124 best_index = FindBestMatchingIconForDensity(icons, density); | 125 best_index = FindBestMatchingIconForDensity(icons, density_); |
| 125 if (best_index != -1 && | 126 if (best_index != -1 && |
| 126 IconSizesContainsBiggerThanMinimumSize(icons[best_index].sizes)) | 127 IconSizesContainsBiggerThanMinimumSize(icons[best_index].sizes)) |
| 127 return best_index; | 128 return best_index; |
| 128 | 129 |
| 129 best_index = FindBestMatchingIconForDensity(icons, | 130 best_index = FindBestMatchingIconForDensity(icons, |
| 130 Manifest::Icon::kDefaultDensity); | 131 Manifest::Icon::kDefaultDensity); |
| 131 if (best_index != -1 && | 132 if (best_index != -1 && |
| 132 IconSizesContainsBiggerThanMinimumSize(icons[best_index].sizes)) | 133 IconSizesContainsBiggerThanMinimumSize(icons[best_index].sizes)) |
| 133 return best_index; | 134 return best_index; |
| 134 | 135 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 162 return result; | 163 return result; |
| 163 } | 164 } |
| 164 | 165 |
| 165 // static | 166 // static |
| 166 GURL ManifestIconSelector::FindBestMatchingIcon( | 167 GURL ManifestIconSelector::FindBestMatchingIcon( |
| 167 const std::vector<Manifest::Icon>& unfiltered_icons, | 168 const std::vector<Manifest::Icon>& unfiltered_icons, |
| 168 const int ideal_icon_size_in_dp, | 169 const int ideal_icon_size_in_dp, |
| 169 const int minimum_icon_size_in_dp) { | 170 const int minimum_icon_size_in_dp) { |
| 170 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); | 171 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); |
| 171 | 172 |
| 172 const float device_scale_factor = | |
| 173 gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); | |
| 174 const int ideal_icon_size_in_px = | 173 const int ideal_icon_size_in_px = |
| 175 static_cast<int>(round(ideal_icon_size_in_dp * device_scale_factor)); | 174 ConvertIconSizeFromDpToPx(ideal_icon_size_in_dp); |
| 176 const int minimum_icon_size_in_px = | 175 const int minimum_icon_size_in_px = |
| 177 static_cast<int>(round(minimum_icon_size_in_dp * device_scale_factor)); | 176 ConvertIconSizeFromDpToPx(minimum_icon_size_in_dp); |
| 178 | 177 |
| 179 std::vector<Manifest::Icon> icons = | 178 std::vector<Manifest::Icon> icons = |
| 180 ManifestIconSelector::FilterIconsByType(unfiltered_icons); | 179 ManifestIconSelector::FilterIconsByType(unfiltered_icons); |
| 181 | 180 |
| 182 ManifestIconSelector selector(ideal_icon_size_in_px, | 181 ManifestIconSelector selector(ideal_icon_size_in_px, |
| 183 minimum_icon_size_in_px); | 182 minimum_icon_size_in_px); |
| 184 int index = selector.FindBestMatchingIcon(icons, device_scale_factor); | 183 int index = selector.FindBestMatchingIcon(icons); |
| 185 if (index == -1) | 184 if (index == -1) |
| 186 return GURL(); | 185 return GURL(); |
| 187 return icons[index].src; | 186 return icons[index].src; |
| 188 } | 187 } |
| 188 |
| 189 // static |
| 190 int ManifestIconSelector::ConvertIconSizeFromDpToPx(int icon_size_in_dp) { |
| 191 return static_cast<int>(round( |
| 192 icon_size_in_dp * |
| 193 gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor())); |
| 194 } |
| OLD | NEW |