Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: chrome/browser/android/manifest_icon_selector.cc

Issue 880203004: Break out manifest icon logic from ShortcutHelper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changing unittest Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/android/manifest_icon_selector.h"
6
7 #include <limits>
8
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/public/browser/web_contents.h"
11 #include "net/base/mime_util.h"
12 #include "ui/gfx/screen.h"
13
14 using content::Manifest;
15
16 ManifestIconSelector::ManifestIconSelector(float preferred_icon_size_in_pixels)
17 : preferred_icon_size_in_pixels_(preferred_icon_size_in_pixels) {
18 }
19
20 bool ManifestIconSelector::IconSizesContainsPreferredSize(
21 const std::vector<gfx::Size>& sizes) {
22 for (size_t i = 0; i < sizes.size(); ++i) {
23 if (sizes[i].height() != sizes[i].width())
24 continue;
25 if (sizes[i].width() == preferred_icon_size_in_pixels_)
26 return true;
27 }
28
29 return false;
30 }
31
32 GURL ManifestIconSelector::FindBestMatchingIconForDensity(
33 const std::vector<content::Manifest::Icon>& icons,
34 float density) {
35 GURL url;
36 int best_delta = std::numeric_limits<int>::min();
37
38 for (size_t i = 0; i < icons.size(); ++i) {
39 if (icons[i].density != density)
40 continue;
41
42 const std::vector<gfx::Size>& sizes = icons[i].sizes;
43 for (size_t j = 0; j < sizes.size(); ++j) {
44 if (sizes[j].height() != sizes[j].width())
45 continue;
46 int delta = sizes[j].width() - preferred_icon_size_in_pixels_;
47 if (delta == 0)
48 return icons[i].src;
49 if (best_delta > 0 && delta < 0)
50 continue;
51 if ((best_delta > 0 && delta < best_delta) ||
52 (best_delta < 0 && delta > best_delta)) {
53 url = icons[i].src;
54 best_delta = delta;
55 }
56 }
57 }
58
59 return url;
60 }
61
62 GURL ManifestIconSelector::FindBestMatchingIcon(
63 const std::vector<content::Manifest::Icon>& unfiltered_icons,
64 float density) {
65 GURL url;
66 std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons);
67
68 // The first pass is to find the ideal icon. That icon is of the right size
69 // with the default density or the device's density.
70 for (size_t i = 0; i < icons.size(); ++i) {
71 if (icons[i].density == density &&
72 IconSizesContainsPreferredSize(icons[i].sizes)) {
73 return icons[i].src;
74 }
75
76 // If there is an icon with the right size but not the right density, keep
77 // it on the side and only use it if nothing better is found.
78 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
79 IconSizesContainsPreferredSize(icons[i].sizes)) {
80 url = icons[i].src;
81 }
82 }
83
84 // The second pass is to find an icon with 'any'. The current device scale
85 // factor is preferred. Otherwise, the default scale factor is used.
86 for (size_t i = 0; i < icons.size(); ++i) {
87 if (icons[i].density == density &&
88 IconSizesContainsAny(icons[i].sizes)) {
89 return icons[i].src;
90 }
91
92 // If there is an icon with 'any' but not the right density, keep it on the
93 // side and only use it if nothing better is found.
94 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
95 IconSizesContainsAny(icons[i].sizes)) {
96 url = icons[i].src;
97 }
98 }
99
100 // The last pass will try to find the best suitable icon for the device's
101 // scale factor. If none, another pass will be run using kDefaultDensity.
102 if (!url.is_valid())
103 url = FindBestMatchingIconForDensity(icons, density);
104 if (!url.is_valid())
105 url = FindBestMatchingIconForDensity(icons,
106 Manifest::Icon::kDefaultDensity);
107
108 return url;
109 }
110
111
112 // static
113 bool ManifestIconSelector::IconSizesContainsAny(
114 const std::vector<gfx::Size>& sizes) {
115 for (size_t i = 0; i < sizes.size(); ++i) {
116 if (sizes[i].IsEmpty())
117 return true;
118 }
119
120 return false;
121 }
122
123 // static
124 std::vector<Manifest::Icon> ManifestIconSelector::FilterIconsByType(
125 const std::vector<content::Manifest::Icon>& icons) {
126 std::vector<Manifest::Icon> result;
127
128 for (size_t i = 0; i < icons.size(); ++i) {
129 if (icons[i].type.is_null() ||
130 net::IsSupportedImageMimeType(
131 base::UTF16ToUTF8(icons[i].type.string()))) {
132 result.push_back(icons[i]);
133 }
134 }
135
136 return result;
137 }
138
139 // static
140 GURL ManifestIconSelector::FindBestMatchingIcon(
141 const std::vector<Manifest::Icon>& unfiltered_icons,
142 const float preferred_icon_size_in_dp,
143 const gfx::Screen* screen) {
144 const float device_scale_factor =
145 screen->GetPrimaryDisplay().device_scale_factor();
146 const float preferred_icon_size_in_pixels =
147 preferred_icon_size_in_dp * device_scale_factor;
148
149 ManifestIconSelector selector(preferred_icon_size_in_pixels);
150 return selector.FindBestMatchingIcon(unfiltered_icons, device_scale_factor);
151 }
OLDNEW
« no previous file with comments | « chrome/browser/android/manifest_icon_selector.h ('k') | chrome/browser/android/manifest_icon_selector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698