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

Side by Side Diff: chrome/browser/android/shortcut_helper.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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/android/shortcut_helper.h" 5 #include "chrome/browser/android/shortcut_helper.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
11 #include "base/android/jni_string.h" 11 #include "base/android/jni_string.h"
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/strings/string16.h" 14 #include "base/strings/string16.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/task/cancelable_task_tracker.h" 16 #include "base/task/cancelable_task_tracker.h"
17 #include "base/threading/worker_pool.h" 17 #include "base/threading/worker_pool.h"
18 #include "chrome/browser/android/manifest_icon_selector.h"
18 #include "chrome/browser/android/tab_android.h" 19 #include "chrome/browser/android/tab_android.h"
19 #include "chrome/browser/favicon/favicon_service.h" 20 #include "chrome/browser/favicon/favicon_service.h"
20 #include "chrome/browser/favicon/favicon_service_factory.h" 21 #include "chrome/browser/favicon/favicon_service_factory.h"
21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/common/chrome_constants.h" 23 #include "chrome/common/chrome_constants.h"
23 #include "chrome/common/render_messages.h" 24 #include "chrome/common/render_messages.h"
24 #include "chrome/common/web_application_info.h" 25 #include "chrome/common/web_application_info.h"
25 #include "components/dom_distiller/core/url_utils.h" 26 #include "components/dom_distiller/core/url_utils.h"
26 #include "content/public/browser/user_metrics.h" 27 #include "content/public/browser/user_metrics.h"
27 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: 109 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED:
109 content::RecordAction( 110 content::RecordAction(
110 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); 111 base::UserMetricsAction("webapps.AddShortcut.Bookmark"));
111 break; 112 break;
112 } 113 }
113 114
114 web_contents()->GetManifest(base::Bind(&ShortcutHelper::OnDidGetManifest, 115 web_contents()->GetManifest(base::Bind(&ShortcutHelper::OnDidGetManifest,
115 weak_ptr_factory_.GetWeakPtr())); 116 weak_ptr_factory_.GetWeakPtr()));
116 } 117 }
117 118
118 bool ShortcutHelper::IconSizesContainsPreferredSize(
119 const std::vector<gfx::Size>& sizes) const {
120 for (size_t i = 0; i < sizes.size(); ++i) {
121 if (sizes[i].height() != sizes[i].width())
122 continue;
123 if (sizes[i].width() == preferred_icon_size_in_px_)
124 return true;
125 }
126
127 return false;
128 }
129
130 bool ShortcutHelper::IconSizesContainsAny(
131 const std::vector<gfx::Size>& sizes) const {
132 for (size_t i = 0; i < sizes.size(); ++i) {
133 if (sizes[i].IsEmpty())
134 return true;
135 }
136
137 return false;
138 }
139
140 GURL ShortcutHelper::FindBestMatchingIcon(
141 const std::vector<Manifest::Icon>& icons, float density) const {
142 GURL url;
143 int best_delta = std::numeric_limits<int>::min();
144
145 for (size_t i = 0; i < icons.size(); ++i) {
146 if (icons[i].density != density)
147 continue;
148
149 const std::vector<gfx::Size>& sizes = icons[i].sizes;
150 for (size_t j = 0; j < sizes.size(); ++j) {
151 if (sizes[j].height() != sizes[j].width())
152 continue;
153 int delta = sizes[j].width() - preferred_icon_size_in_px_;
154 if (delta == 0)
155 return icons[i].src;
156 if (best_delta > 0 && delta < 0)
157 continue;
158 if ((best_delta > 0 && delta < best_delta) ||
159 (best_delta < 0 && delta > best_delta)) {
160 url = icons[i].src;
161 best_delta = delta;
162 }
163 }
164 }
165
166 return url;
167 }
168
169 // static
170 std::vector<Manifest::Icon> ShortcutHelper::FilterIconsByType(
171 const std::vector<Manifest::Icon>& icons) {
172 std::vector<Manifest::Icon> result;
173
174 for (size_t i = 0; i < icons.size(); ++i) {
175 if (icons[i].type.is_null() ||
176 net::IsSupportedImageMimeType(
177 base::UTF16ToUTF8(icons[i].type.string()))) {
178 result.push_back(icons[i]);
179 }
180 }
181
182 return result;
183 }
184
185 GURL ShortcutHelper::FindBestMatchingIcon(
186 const std::vector<Manifest::Icon>& unfiltered_icons) const {
187 const float device_scale_factor =
188 gfx::Screen::GetScreenFor(web_contents()->GetNativeView())->
189 GetPrimaryDisplay().device_scale_factor();
190
191 GURL url;
192 std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons);
193
194 // The first pass is to find the ideal icon. That icon is of the right size
195 // with the default density or the device's density.
196 for (size_t i = 0; i < icons.size(); ++i) {
197 if (icons[i].density == device_scale_factor &&
198 IconSizesContainsPreferredSize(icons[i].sizes)) {
199 return icons[i].src;
200 }
201
202 // If there is an icon with the right size but not the right density, keep
203 // it on the side and only use it if nothing better is found.
204 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
205 IconSizesContainsPreferredSize(icons[i].sizes)) {
206 url = icons[i].src;
207 }
208 }
209
210 // The second pass is to find an icon with 'any'. The current device scale
211 // factor is preferred. Otherwise, the default scale factor is used.
212 for (size_t i = 0; i < icons.size(); ++i) {
213 if (icons[i].density == device_scale_factor &&
214 IconSizesContainsAny(icons[i].sizes)) {
215 return icons[i].src;
216 }
217
218 // If there is an icon with 'any' but not the right density, keep it on the
219 // side and only use it if nothing better is found.
220 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
221 IconSizesContainsAny(icons[i].sizes)) {
222 url = icons[i].src;
223 }
224 }
225
226 // The last pass will try to find the best suitable icon for the device's
227 // scale factor. If none, another pass will be run using kDefaultDensity.
228 if (!url.is_valid())
229 url = FindBestMatchingIcon(icons, device_scale_factor);
230 if (!url.is_valid())
231 url = FindBestMatchingIcon(icons, Manifest::Icon::kDefaultDensity);
232
233 return url;
234 }
235
236 void ShortcutHelper::OnDidGetManifest(const content::Manifest& manifest) { 119 void ShortcutHelper::OnDidGetManifest(const content::Manifest& manifest) {
237 if (!manifest.IsEmpty()) { 120 if (!manifest.IsEmpty()) {
238 content::RecordAction( 121 content::RecordAction(
239 base::UserMetricsAction("webapps.AddShortcut.Manifest")); 122 base::UserMetricsAction("webapps.AddShortcut.Manifest"));
240 } 123 }
241 124
242 // Set the title based on the manifest value, if any. 125 // Set the title based on the manifest value, if any.
243 if (!manifest.short_name.is_null()) 126 if (!manifest.short_name.is_null())
244 title_ = manifest.short_name.string(); 127 title_ = manifest.short_name.string();
245 else if (!manifest.name.is_null()) 128 else if (!manifest.name.is_null())
(...skipping 16 matching lines...) Expand all
262 145
263 // Set the orientation based on the manifest value, if any. 146 // Set the orientation based on the manifest value, if any.
264 if (manifest.orientation != blink::WebScreenOrientationLockDefault) { 147 if (manifest.orientation != blink::WebScreenOrientationLockDefault) {
265 // Ignore the orientation if the display mode is different from 148 // Ignore the orientation if the display mode is different from
266 // 'standalone'. 149 // 'standalone'.
267 // TODO(mlamouri): send a message to the developer console about this. 150 // TODO(mlamouri): send a message to the developer console about this.
268 if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE) 151 if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE)
269 orientation_ = manifest.orientation; 152 orientation_ = manifest.orientation;
270 } 153 }
271 154
272 GURL icon_src = FindBestMatchingIcon(manifest.icons); 155 GURL icon_src = ManifestIconSelector::FindBestMatchingIcon(
156 manifest.icons,
157 kPreferredIconSizeInDp,
158 gfx::Screen::GetScreenFor(web_contents()->GetNativeView()));
273 if (icon_src.is_valid()) { 159 if (icon_src.is_valid()) {
274 web_contents()->DownloadImage(icon_src, 160 web_contents()->DownloadImage(icon_src,
275 false, 161 false,
276 preferred_icon_size_in_px_, 162 preferred_icon_size_in_px_,
277 base::Bind(&ShortcutHelper::OnDidDownloadIcon, 163 base::Bind(&ShortcutHelper::OnDidDownloadIcon,
278 weak_ptr_factory_.GetWeakPtr())); 164 weak_ptr_factory_.GetWeakPtr()));
279 manifest_icon_status_ = MANIFEST_ICON_STATUS_FETCHING; 165 manifest_icon_status_ = MANIFEST_ICON_STATUS_FETCHING;
280 } 166 }
281 167
282 // The ShortcutHelper is now able to notify its Java counterpart that it is 168 // The ShortcutHelper is now able to notify its Java counterpart that it is
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 base::android::GetApplicationContext(), 369 base::android::GetApplicationContext(),
484 java_url.obj(), 370 java_url.obj(),
485 java_title.obj(), 371 java_title.obj(),
486 java_bitmap.obj(), 372 java_bitmap.obj(),
487 r_value, 373 r_value,
488 g_value, 374 g_value,
489 b_value, 375 b_value,
490 display == content::Manifest::DISPLAY_MODE_STANDALONE, 376 display == content::Manifest::DISPLAY_MODE_STANDALONE,
491 orientation); 377 orientation);
492 } 378 }
OLDNEW
« no previous file with comments | « chrome/browser/android/shortcut_helper.h ('k') | chrome/browser/android/shortcut_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698