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

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: 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
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 28 matching lines...) Expand all
56 ShortcutHelper::ShortcutHelper(JNIEnv* env, 57 ShortcutHelper::ShortcutHelper(JNIEnv* env,
57 jobject obj, 58 jobject obj,
58 content::WebContents* web_contents) 59 content::WebContents* web_contents)
59 : WebContentsObserver(web_contents), 60 : WebContentsObserver(web_contents),
60 java_ref_(env, obj), 61 java_ref_(env, obj),
61 url_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( 62 url_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(
62 web_contents->GetURL())), 63 web_contents->GetURL())),
63 display_(content::Manifest::DISPLAY_MODE_BROWSER), 64 display_(content::Manifest::DISPLAY_MODE_BROWSER),
64 orientation_(blink::WebScreenOrientationLockDefault), 65 orientation_(blink::WebScreenOrientationLockDefault),
65 add_shortcut_requested_(false), 66 add_shortcut_requested_(false),
67 manifest_icon_selector_(web_contents, kPreferredIconSizeInDp),
66 manifest_icon_status_(MANIFEST_ICON_STATUS_NONE), 68 manifest_icon_status_(MANIFEST_ICON_STATUS_NONE),
67 preferred_icon_size_in_px_(kPreferredIconSizeInDp * 69 preferred_icon_size_in_px_(kPreferredIconSizeInDp *
68 gfx::Screen::GetScreenFor(web_contents->GetNativeView())-> 70 gfx::Screen::GetScreenFor(web_contents->GetNativeView())->
69 GetPrimaryDisplay().device_scale_factor()), 71 GetPrimaryDisplay().device_scale_factor()),
70 weak_ptr_factory_(this) { 72 weak_ptr_factory_(this) {
71 } 73 }
72 74
73 void ShortcutHelper::Initialize() { 75 void ShortcutHelper::Initialize() {
74 // Send a message to the renderer to retrieve information about the page. 76 // Send a message to the renderer to retrieve information about the page.
75 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); 77 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id()));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: 110 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED:
109 content::RecordAction( 111 content::RecordAction(
110 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); 112 base::UserMetricsAction("webapps.AddShortcut.Bookmark"));
111 break; 113 break;
112 } 114 }
113 115
114 web_contents()->GetManifest(base::Bind(&ShortcutHelper::OnDidGetManifest, 116 web_contents()->GetManifest(base::Bind(&ShortcutHelper::OnDidGetManifest,
115 weak_ptr_factory_.GetWeakPtr())); 117 weak_ptr_factory_.GetWeakPtr()));
116 } 118 }
117 119
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) { 120 void ShortcutHelper::OnDidGetManifest(const content::Manifest& manifest) {
237 if (!manifest.IsEmpty()) { 121 if (!manifest.IsEmpty()) {
238 content::RecordAction( 122 content::RecordAction(
239 base::UserMetricsAction("webapps.AddShortcut.Manifest")); 123 base::UserMetricsAction("webapps.AddShortcut.Manifest"));
240 } 124 }
241 125
242 // Set the title based on the manifest value, if any. 126 // Set the title based on the manifest value, if any.
243 if (!manifest.short_name.is_null()) 127 if (!manifest.short_name.is_null())
244 title_ = manifest.short_name.string(); 128 title_ = manifest.short_name.string();
245 else if (!manifest.name.is_null()) 129 else if (!manifest.name.is_null())
(...skipping 16 matching lines...) Expand all
262 146
263 // Set the orientation based on the manifest value, if any. 147 // Set the orientation based on the manifest value, if any.
264 if (manifest.orientation != blink::WebScreenOrientationLockDefault) { 148 if (manifest.orientation != blink::WebScreenOrientationLockDefault) {
265 // Ignore the orientation if the display mode is different from 149 // Ignore the orientation if the display mode is different from
266 // 'standalone'. 150 // 'standalone'.
267 // TODO(mlamouri): send a message to the developer console about this. 151 // TODO(mlamouri): send a message to the developer console about this.
268 if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE) 152 if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE)
269 orientation_ = manifest.orientation; 153 orientation_ = manifest.orientation;
270 } 154 }
271 155
272 GURL icon_src = FindBestMatchingIcon(manifest.icons); 156 GURL icon_src = manifest_icon_selector_.FindBestMatchingIcon(manifest.icons,
157 web_contents());
273 if (icon_src.is_valid()) { 158 if (icon_src.is_valid()) {
274 web_contents()->DownloadImage(icon_src, 159 web_contents()->DownloadImage(icon_src,
275 false, 160 false,
276 preferred_icon_size_in_px_, 161 preferred_icon_size_in_px_,
277 base::Bind(&ShortcutHelper::OnDidDownloadIcon, 162 base::Bind(&ShortcutHelper::OnDidDownloadIcon,
278 weak_ptr_factory_.GetWeakPtr())); 163 weak_ptr_factory_.GetWeakPtr()));
279 manifest_icon_status_ = MANIFEST_ICON_STATUS_FETCHING; 164 manifest_icon_status_ = MANIFEST_ICON_STATUS_FETCHING;
280 } 165 }
281 166
282 // The ShortcutHelper is now able to notify its Java counterpart that it is 167 // 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(), 368 base::android::GetApplicationContext(),
484 java_url.obj(), 369 java_url.obj(),
485 java_title.obj(), 370 java_title.obj(),
486 java_bitmap.obj(), 371 java_bitmap.obj(),
487 r_value, 372 r_value,
488 g_value, 373 g_value,
489 b_value, 374 b_value,
490 display == content::Manifest::DISPLAY_MODE_STANDALONE, 375 display == content::Manifest::DISPLAY_MODE_STANDALONE,
491 orientation); 376 orientation);
492 } 377 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698