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

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: Removing 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 "content/public/common/manifest.h"
mlamouri (slow - plz ping) 2015/01/30 19:25:42 nit: already included in the header, fwiw.
gone 2015/01/30 20:08:11 Done.
12 #include "net/base/mime_util.h"
13 #include "ui/gfx/screen.h"
14 #include "url/gurl.h"
mlamouri (slow - plz ping) 2015/01/30 19:25:42 nit: ditto
gone 2015/01/30 20:08:11 Done.
15
16 using content::Manifest;
17
18 ManifestIconSelector::ManifestIconSelector(content::WebContents* web_contents,
19 int preferred_size_in_dp)
20 : preferred_icon_size_in_px_(preferred_size_in_dp *
21 gfx::Screen::GetScreenFor(web_contents->GetNativeView())->
22 GetPrimaryDisplay().device_scale_factor()) {
23 }
24
25 bool ManifestIconSelector::IconSizesContainsPreferredSize(
26 const std::vector<gfx::Size>& sizes) const {
27 for (size_t i = 0; i < sizes.size(); ++i) {
28 if (sizes[i].height() != sizes[i].width())
29 continue;
30 if (sizes[i].width() == preferred_icon_size_in_px_)
31 return true;
32 }
33
34 return false;
35 }
36
37 bool ManifestIconSelector::IconSizesContainsAny(
38 const std::vector<gfx::Size>& sizes) const {
39 for (size_t i = 0; i < sizes.size(); ++i) {
40 if (sizes[i].IsEmpty())
41 return true;
42 }
43
44 return false;
45 }
46
47 GURL ManifestIconSelector::FindBestMatchingIcon(
48 const std::vector<Manifest::Icon>& icons, float density) const {
49 GURL url;
50 int best_delta = std::numeric_limits<int>::min();
51
52 for (size_t i = 0; i < icons.size(); ++i) {
53 if (icons[i].density != density)
54 continue;
55
56 const std::vector<gfx::Size>& sizes = icons[i].sizes;
57 for (size_t j = 0; j < sizes.size(); ++j) {
58 if (sizes[j].height() != sizes[j].width())
59 continue;
60 int delta = sizes[j].width() - preferred_icon_size_in_px_;
61 if (delta == 0)
62 return icons[i].src;
63 if (best_delta > 0 && delta < 0)
64 continue;
65 if ((best_delta > 0 && delta < best_delta) ||
66 (best_delta < 0 && delta > best_delta)) {
67 url = icons[i].src;
68 best_delta = delta;
69 }
70 }
71 }
72
73 return url;
74 }
75
76 // static
77 std::vector<Manifest::Icon> ManifestIconSelector::FilterIconsByType(
78 const std::vector<Manifest::Icon>& icons) {
79 std::vector<Manifest::Icon> result;
80
81 for (size_t i = 0; i < icons.size(); ++i) {
82 if (icons[i].type.is_null() ||
83 net::IsSupportedImageMimeType(
84 base::UTF16ToUTF8(icons[i].type.string()))) {
85 result.push_back(icons[i]);
86 }
87 }
88
89 return result;
90 }
91
92 GURL ManifestIconSelector::FindBestMatchingIcon(
93 const std::vector<Manifest::Icon>& unfiltered_icons,
94 content::WebContents* web_contents) const {
95 const float device_scale_factor =
96 gfx::Screen::GetScreenFor(web_contents->GetNativeView())->
97 GetPrimaryDisplay().device_scale_factor();
98
99 GURL url;
100 std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons);
101
102 // The first pass is to find the ideal icon. That icon is of the right size
103 // with the default density or the device's density.
104 for (size_t i = 0; i < icons.size(); ++i) {
105 if (icons[i].density == device_scale_factor &&
106 IconSizesContainsPreferredSize(icons[i].sizes)) {
107 return icons[i].src;
108 }
109
110 // If there is an icon with the right size but not the right density, keep
111 // it on the side and only use it if nothing better is found.
112 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
113 IconSizesContainsPreferredSize(icons[i].sizes)) {
114 url = icons[i].src;
115 }
116 }
117
118 // The second pass is to find an icon with 'any'. The current device scale
119 // factor is preferred. Otherwise, the default scale factor is used.
120 for (size_t i = 0; i < icons.size(); ++i) {
121 if (icons[i].density == device_scale_factor &&
122 IconSizesContainsAny(icons[i].sizes)) {
123 return icons[i].src;
124 }
125
126 // If there is an icon with 'any' but not the right density, keep it on the
127 // side and only use it if nothing better is found.
128 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
129 IconSizesContainsAny(icons[i].sizes)) {
130 url = icons[i].src;
131 }
132 }
133
134 // The last pass will try to find the best suitable icon for the device's
135 // scale factor. If none, another pass will be run using kDefaultDensity.
136 if (!url.is_valid())
137 url = FindBestMatchingIcon(icons, device_scale_factor);
138 if (!url.is_valid())
139 url = FindBestMatchingIcon(icons, Manifest::Icon::kDefaultDensity);
140
141 return url;
142 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698