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

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

Issue 601433002: Use Manifest.icons instead of favicon in ShortcutHelper when possible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@manifest_icons_sizes
Patch Set: Created 6 years, 3 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
« no previous file with comments | « chrome/browser/android/shortcut_helper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 9
9 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h" 11 #include "base/android/jni_string.h"
11 #include "base/basictypes.h" 12 #include "base/basictypes.h"
12 #include "base/location.h" 13 #include "base/location.h"
13 #include "base/strings/string16.h" 14 #include "base/strings/string16.h"
15 #include "base/strings/utf_string_conversions.h"
14 #include "base/task/cancelable_task_tracker.h" 16 #include "base/task/cancelable_task_tracker.h"
15 #include "base/threading/worker_pool.h" 17 #include "base/threading/worker_pool.h"
16 #include "chrome/browser/android/tab_android.h" 18 #include "chrome/browser/android/tab_android.h"
17 #include "chrome/browser/favicon/favicon_service.h" 19 #include "chrome/browser/favicon/favicon_service.h"
18 #include "chrome/browser/favicon/favicon_service_factory.h" 20 #include "chrome/browser/favicon/favicon_service_factory.h"
19 #include "chrome/common/chrome_constants.h" 21 #include "chrome/common/chrome_constants.h"
20 #include "chrome/common/render_messages.h" 22 #include "chrome/common/render_messages.h"
21 #include "chrome/common/web_application_info.h" 23 #include "chrome/common/web_application_info.h"
22 #include "content/public/browser/user_metrics.h" 24 #include "content/public/browser/user_metrics.h"
23 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_contents_observer.h" 26 #include "content/public/browser/web_contents_observer.h"
25 #include "content/public/common/frame_navigate_params.h" 27 #include "content/public/common/frame_navigate_params.h"
26 #include "content/public/common/manifest.h" 28 #include "content/public/common/manifest.h"
27 #include "jni/ShortcutHelper_jni.h" 29 #include "jni/ShortcutHelper_jni.h"
30 #include "net/base/mime_util.h"
28 #include "ui/gfx/android/java_bitmap.h" 31 #include "ui/gfx/android/java_bitmap.h"
29 #include "ui/gfx/codec/png_codec.h" 32 #include "ui/gfx/codec/png_codec.h"
30 #include "ui/gfx/color_analysis.h" 33 #include "ui/gfx/color_analysis.h"
31 #include "ui/gfx/favicon_size.h" 34 #include "ui/gfx/favicon_size.h"
35 #include "ui/gfx/screen.h"
32 #include "url/gurl.h" 36 #include "url/gurl.h"
33 37
38 using content::Manifest;
39
40 // Android's preferred icon size in DP is 48, as defined in
41 // http://developer.android.com/design/style/iconography.html
42 const int ShortcutHelper::kPreferredIconSizeInDp = 48;
43
34 jlong Initialize(JNIEnv* env, jobject obj, jlong tab_android_ptr) { 44 jlong Initialize(JNIEnv* env, jobject obj, jlong tab_android_ptr) {
35 TabAndroid* tab = reinterpret_cast<TabAndroid*>(tab_android_ptr); 45 TabAndroid* tab = reinterpret_cast<TabAndroid*>(tab_android_ptr);
36 46
37 ShortcutHelper* shortcut_helper = 47 ShortcutHelper* shortcut_helper =
38 new ShortcutHelper(env, obj, tab->web_contents()); 48 new ShortcutHelper(env, obj, tab->web_contents());
39 shortcut_helper->Initialize(); 49 shortcut_helper->Initialize();
40 50
41 return reinterpret_cast<intptr_t>(shortcut_helper); 51 return reinterpret_cast<intptr_t>(shortcut_helper);
42 } 52 }
43 53
44 ShortcutHelper::ShortcutHelper(JNIEnv* env, 54 ShortcutHelper::ShortcutHelper(JNIEnv* env,
45 jobject obj, 55 jobject obj,
46 content::WebContents* web_contents) 56 content::WebContents* web_contents)
47 : WebContentsObserver(web_contents), 57 : WebContentsObserver(web_contents),
48 java_ref_(env, obj), 58 java_ref_(env, obj),
49 url_(web_contents->GetURL()), 59 url_(web_contents->GetURL()),
50 display_(content::Manifest::DISPLAY_MODE_BROWSER), 60 display_(content::Manifest::DISPLAY_MODE_BROWSER),
51 orientation_(blink::WebScreenOrientationLockDefault), 61 orientation_(blink::WebScreenOrientationLockDefault),
62 add_shortcut_requested_(false),
63 manifest_icon_status_(MANIFEST_ICON_STATUS_NONE),
64 preferred_icon_size_in_px_(kPreferredIconSizeInDp *
gone 2014/09/24 18:17:24 does this calculation _have_ to go here? makes th
mlamouri (slow - plz ping) 2014/09/24 18:36:49 I possibly moved it there because of the value bei
65 gfx::Screen::GetScreenFor(web_contents->GetNativeView())->
66 GetPrimaryDisplay().device_scale_factor()),
52 weak_ptr_factory_(this) { 67 weak_ptr_factory_(this) {
53 } 68 }
54 69
55 void ShortcutHelper::Initialize() { 70 void ShortcutHelper::Initialize() {
56 // Send a message to the renderer to retrieve information about the page. 71 // Send a message to the renderer to retrieve information about the page.
57 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); 72 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id()));
58 } 73 }
59 74
60 ShortcutHelper::~ShortcutHelper() { 75 ShortcutHelper::~ShortcutHelper() {
61 } 76 }
(...skipping 28 matching lines...) Expand all
90 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: 105 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED:
91 content::RecordAction( 106 content::RecordAction(
92 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); 107 base::UserMetricsAction("webapps.AddShortcut.Bookmark"));
93 break; 108 break;
94 } 109 }
95 110
96 web_contents()->GetManifest(base::Bind(&ShortcutHelper::OnDidGetManifest, 111 web_contents()->GetManifest(base::Bind(&ShortcutHelper::OnDidGetManifest,
97 weak_ptr_factory_.GetWeakPtr())); 112 weak_ptr_factory_.GetWeakPtr()));
98 } 113 }
99 114
115 bool ShortcutHelper::IconSizesContainsPreferredSize(
116 const std::vector<gfx::Size>& sizes) const {
117 for (size_t i = 0; i < sizes.size(); ++i) {
118 if (sizes[i].height() != sizes[i].width())
119 continue;
120 if (sizes[i].width() == preferred_icon_size_in_px_)
121 return true;
122 }
123
124 return false;
125 }
126
127 GURL ShortcutHelper::FindBestMatchingIcon(
128 const std::vector<Manifest::Icon>& icons, float density) const {
129 GURL url;
130 int delta = std::numeric_limits<int>::min();
131
132 for (size_t i = 0; i < icons.size(); ++i) {
133 if (icons[i].density != density)
134 continue;
135
136 const std::vector<gfx::Size>& sizes = icons[i].sizes;
137 for (size_t j = 0; j < sizes.size(); ++j) {
138 if (sizes[j].height() != sizes[j].width())
139 continue;
140 int d = sizes[j].width() - preferred_icon_size_in_px_;
141 if (d == 0)
142 return icons[i].src;
143 if (delta > 0 && d < 0)
144 continue;
145 if ((delta > 0 && d < delta) || (delta < 0 && d > delta)) {
146 url = icons[i].src;
147 delta = d;
148 }
149 }
150 }
151
152 return url;
153 }
154
155 // static
156 std::vector<Manifest::Icon> ShortcutHelper::FilterIconsByType(
157 const std::vector<Manifest::Icon>& icons) {
158 std::vector<Manifest::Icon> result;
159
160 for (size_t i = 0; i < icons.size(); ++i) {
161 if (icons[i].type.is_null() ||
gone 2014/09/24 18:17:24 any reason why you keep the icon if the type is nu
mlamouri (slow - plz ping) 2014/09/24 18:36:49 If the type is not specified but sizes are, I woul
162 net::IsSupportedImageMimeType(
163 base::UTF16ToUTF8(icons[i].type.string()))) {
164 result.push_back(icons[i]);
165 }
166 }
167
168 return result;
169 }
170
171 GURL ShortcutHelper::FindBestMatchingIcon(
172 const std::vector<Manifest::Icon>& unfiltered_icons) const {
173 const float device_scale_factor =
174 gfx::Screen::GetScreenFor(web_contents()->GetNativeView())->
175 GetPrimaryDisplay().device_scale_factor();
176
177 GURL url;
178 std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons);
179
180 // The first pass is to find the ideal icon. That icon is of the right size
181 // with the default density or the device's density.
182 for (size_t i = 0; i < icons.size(); ++i) {
183 if (icons[i].density == device_scale_factor &&
184 IconSizesContainsPreferredSize(icons[i].sizes)) {
185 return icons[i].src;
186 }
187
188 // If there is an icon with the right size but not the right density, keep
189 // it on the side and only use it if nothing better is found.
190 if (icons[i].density == Manifest::Icon::kDefaultDensity &&
191 IconSizesContainsPreferredSize(icons[i].sizes)) {
192 url = icons[i].src;
193 }
194 }
195
196 // Second pass will try to find the best suitable icon for the device's scale
197 // factor. If none, another pass will be run using kDefaultDensity.
198 if (!url.is_valid()) {
199 url = FindBestMatchingIcon(icons, device_scale_factor);
200 if (!url.is_valid())
gone 2014/09/24 18:17:24 may as well move this if outside of the other if s
mlamouri (slow - plz ping) 2014/09/24 18:36:49 Done.
201 url = FindBestMatchingIcon(icons, Manifest::Icon::kDefaultDensity);
202 }
203
204 return url;
205 }
206
100 void ShortcutHelper::OnDidGetManifest(const content::Manifest& manifest) { 207 void ShortcutHelper::OnDidGetManifest(const content::Manifest& manifest) {
101 // Set the title based on the manifest value, if any. 208 // Set the title based on the manifest value, if any.
102 if (!manifest.short_name.is_null()) 209 if (!manifest.short_name.is_null())
103 title_ = manifest.short_name.string(); 210 title_ = manifest.short_name.string();
104 else if (!manifest.name.is_null()) 211 else if (!manifest.name.is_null())
105 title_ = manifest.name.string(); 212 title_ = manifest.name.string();
106 213
107 // Set the url based on the manifest value, if any. 214 // Set the url based on the manifest value, if any.
108 if (manifest.start_url.is_valid()) 215 if (manifest.start_url.is_valid())
109 url_ = manifest.start_url; 216 url_ = manifest.start_url;
(...skipping 11 matching lines...) Expand all
121 228
122 // Set the orientation based on the manifest value, if any. 229 // Set the orientation based on the manifest value, if any.
123 if (manifest.orientation != blink::WebScreenOrientationLockDefault) { 230 if (manifest.orientation != blink::WebScreenOrientationLockDefault) {
124 // Ignore the orientation if the display mode is different from 231 // Ignore the orientation if the display mode is different from
125 // 'standalone'. 232 // 'standalone'.
126 // TODO(mlamouri): send a message to the developer console about this. 233 // TODO(mlamouri): send a message to the developer console about this.
127 if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE) 234 if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE)
128 orientation_ = manifest.orientation; 235 orientation_ = manifest.orientation;
129 } 236 }
130 237
238 GURL icon_src = FindBestMatchingIcon(manifest.icons);
239 if (icon_src.is_valid()) {
240 web_contents()->DownloadImage(icon_src,
241 false,
242 preferred_icon_size_in_px_,
243 base::Bind(&ShortcutHelper::OnDidDownloadIcon,
244 weak_ptr_factory_.GetWeakPtr()));
245 manifest_icon_status_ = MANIFEST_ICON_STATUS_FETCHING;
246 }
247
131 // The ShortcutHelper is now able to notify its Java counterpart that it is 248 // The ShortcutHelper is now able to notify its Java counterpart that it is
132 // initialized. OnInitialized method is not conceptually part of getting the 249 // initialized. OnInitialized method is not conceptually part of getting the
133 // manifest data but it happens that the initialization is finalized when 250 // manifest data but it happens that the initialization is finalized when
134 // these data are available. 251 // these data are available.
135 JNIEnv* env = base::android::AttachCurrentThread(); 252 JNIEnv* env = base::android::AttachCurrentThread();
136 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); 253 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
137 ScopedJavaLocalRef<jstring> j_title = 254 ScopedJavaLocalRef<jstring> j_title =
138 base::android::ConvertUTF16ToJavaString(env, title_); 255 base::android::ConvertUTF16ToJavaString(env, title_);
139 256
140 Java_ShortcutHelper_onInitialized(env, j_obj.obj(), j_title.obj()); 257 Java_ShortcutHelper_onInitialized(env, j_obj.obj(), j_title.obj());
141 } 258 }
142 259
260 void ShortcutHelper::OnDidDownloadIcon(int id,
261 int http_status_code,
262 const GURL& url,
263 const std::vector<SkBitmap>& bitmaps,
264 const std::vector<gfx::Size>& sizes) {
265 // If getting the candidate manifest icon failed, the ShortcutHelper should
266 // fallback to the favicon.
267 // If the user already requested to add the shortcut, it will do so but use
268 // the favicon instead.
269 // Otherwise, it sets the state as if there was no manifest icon pending.
270 if (bitmaps.empty()) {
271 if (add_shortcut_requested_)
272 AddShortcutUsingFavicon();
273 else
274 manifest_icon_status_ = MANIFEST_ICON_STATUS_NONE;
275 return;
276 }
277
278 // There might be multiple bitmaps returned. The one to pick is bigger or
279 // equal to the preferred size. |bitmaps| is ordered from bigger to smaller.
280 int preferred_bitmap_index = 0;
281 for (size_t i = 0; i < bitmaps.size(); ++i) {
282 if (bitmaps[i].height() < preferred_icon_size_in_px_)
283 break;
284 preferred_bitmap_index = i;
285 }
286
287 manifest_icon_ = bitmaps[preferred_bitmap_index];
288 manifest_icon_status_ = MANIFEST_ICON_STATUS_DONE;
289
290 if (add_shortcut_requested_)
291 AddShortcutUsingManifestIcon();
gone 2014/09/24 18:17:24 what happens if a shortcut wasn't requested? what
mlamouri (slow - plz ping) 2014/09/24 18:36:49 If the shortcut wasn't requested but is later requ
292 }
293
143 void ShortcutHelper::TearDown(JNIEnv*, jobject) { 294 void ShortcutHelper::TearDown(JNIEnv*, jobject) {
144 Destroy(); 295 Destroy();
145 } 296 }
146 297
147 void ShortcutHelper::Destroy() { 298 void ShortcutHelper::Destroy() {
148 delete this; 299 delete this;
149 } 300 }
150 301
151 void ShortcutHelper::AddShortcut( 302 void ShortcutHelper::AddShortcut(
152 JNIEnv* env, 303 JNIEnv* env,
153 jobject obj, 304 jobject obj,
154 jstring jtitle, 305 jstring jtitle,
155 jint launcher_large_icon_size) { 306 jint launcher_large_icon_size) {
307 add_shortcut_requested_ = true;
308
156 base::string16 title = base::android::ConvertJavaStringToUTF16(env, jtitle); 309 base::string16 title = base::android::ConvertJavaStringToUTF16(env, jtitle);
157 if (!title.empty()) 310 if (!title.empty())
158 title_ = title; 311 title_ = title;
159 312
313 switch (manifest_icon_status_) {
gone 2014/09/24 18:17:24 indentation seems off here
mlamouri (slow - plz ping) 2014/09/24 18:36:49 How so?
gone 2014/09/24 18:39:21 http://google-styleguide.googlecode.com/svn/trunk/
mlamouri (slow - plz ping) 2014/09/24 19:41:38 I got hit again by Blink and Chromium having diffe
314 case MANIFEST_ICON_STATUS_NONE:
315 AddShortcutUsingFavicon();
316 break;
317 case MANIFEST_ICON_STATUS_FETCHING:
318 // ::OnDidDownloadIcon() will call AddShortcutUsingManifestIcon() when run.
319 break;
320 case MANIFEST_ICON_STATUS_DONE:
321 AddShortcutUsingManifestIcon();
322 break;
323 }
324 }
325
326 void ShortcutHelper::AddShortcutUsingManifestIcon() {
327 // Stop observing so we don't get destroyed while doing the last steps.
328 Observe(NULL);
329
330 base::WorkerPool::PostTask(
331 FROM_HERE,
332 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap,
333 url_,
334 title_,
335 display_,
336 manifest_icon_,
337 orientation_),
338 true);
339
340 Destroy();
341 }
342
343 void ShortcutHelper::AddShortcutUsingFavicon() {
160 Profile* profile = 344 Profile* profile =
161 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 345 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
162 346
163 // Grab the best, largest icon we can find to represent this bookmark. 347 // Grab the best, largest icon we can find to represent this bookmark.
164 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its 348 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its
165 // rewrite is further along. 349 // rewrite is further along.
166 std::vector<int> icon_types; 350 std::vector<int> icon_types;
167 icon_types.push_back(favicon_base::FAVICON); 351 icon_types.push_back(favicon_base::FAVICON);
168 icon_types.push_back(favicon_base::TOUCH_PRECOMPOSED_ICON | 352 icon_types.push_back(favicon_base::TOUCH_PRECOMPOSED_ICON |
169 favicon_base::TOUCH_ICON); 353 favicon_base::TOUCH_ICON);
170 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( 354 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
171 profile, Profile::EXPLICIT_ACCESS); 355 profile, Profile::EXPLICIT_ACCESS);
172 356
173 // Using favicon if its size is not smaller than platform required size, 357 // Using favicon if its size is not smaller than platform required size,
174 // otherwise using the largest icon among all avaliable icons. 358 // otherwise using the largest icon among all avaliable icons.
175 int threshold_to_get_any_largest_icon = launcher_large_icon_size_ - 1; 359 int threshold_to_get_any_largest_icon = preferred_icon_size_in_px_ - 1;
176 favicon_service->GetLargestRawFaviconForPageURL(url_, icon_types, 360 favicon_service->GetLargestRawFaviconForPageURL(url_, icon_types,
177 threshold_to_get_any_largest_icon, 361 threshold_to_get_any_largest_icon,
178 base::Bind(&ShortcutHelper::FinishAddingShortcut, 362 base::Bind(&ShortcutHelper::OnDidGetFavicon,
179 base::Unretained(this)), 363 base::Unretained(this)),
180 &cancelable_task_tracker_); 364 &cancelable_task_tracker_);
181 } 365 }
182 366
183 void ShortcutHelper::FinishAddingShortcut( 367 void ShortcutHelper::OnDidGetFavicon(
184 const favicon_base::FaviconRawBitmapResult& bitmap_result) { 368 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
185 icon_ = bitmap_result;
186
187 // Stop observing so we don't get destroyed while doing the last steps. 369 // Stop observing so we don't get destroyed while doing the last steps.
188 Observe(NULL); 370 Observe(NULL);
189 371
190 base::WorkerPool::PostTask( 372 base::WorkerPool::PostTask(
191 FROM_HERE, 373 FROM_HERE,
192 base::Bind(&ShortcutHelper::AddShortcutInBackground, 374 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithRawBitmap,
193 url_, 375 url_,
194 title_, 376 title_,
195 display_, 377 display_,
196 icon_, 378 bitmap_result,
197 orientation_), 379 orientation_),
198 true); 380 true);
199 381
200 Destroy(); 382 Destroy();
201 } 383 }
202 384
203 bool ShortcutHelper::OnMessageReceived(const IPC::Message& message) { 385 bool ShortcutHelper::OnMessageReceived(const IPC::Message& message) {
204 bool handled = true; 386 bool handled = true;
205 387
206 IPC_BEGIN_MESSAGE_MAP(ShortcutHelper, message) 388 IPC_BEGIN_MESSAGE_MAP(ShortcutHelper, message)
207 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, 389 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo,
208 OnDidGetWebApplicationInfo) 390 OnDidGetWebApplicationInfo)
209 IPC_MESSAGE_UNHANDLED(handled = false) 391 IPC_MESSAGE_UNHANDLED(handled = false)
210 IPC_END_MESSAGE_MAP() 392 IPC_END_MESSAGE_MAP()
211 393
212 return handled; 394 return handled;
213 } 395 }
214 396
215 void ShortcutHelper::WebContentsDestroyed() { 397 void ShortcutHelper::WebContentsDestroyed() {
216 Destroy(); 398 Destroy();
217 } 399 }
218 400
219 bool ShortcutHelper::RegisterShortcutHelper(JNIEnv* env) { 401 bool ShortcutHelper::RegisterShortcutHelper(JNIEnv* env) {
220 return RegisterNativesImpl(env); 402 return RegisterNativesImpl(env);
221 } 403 }
222 404
223 void ShortcutHelper::AddShortcutInBackground( 405 void ShortcutHelper::AddShortcutInBackgroundWithRawBitmap(
224 const GURL& url, 406 const GURL& url,
225 const base::string16& title, 407 const base::string16& title,
226 content::Manifest::DisplayMode display, 408 content::Manifest::DisplayMode display,
227 const favicon_base::FaviconRawBitmapResult& bitmap_result, 409 const favicon_base::FaviconRawBitmapResult& bitmap_result,
228 blink::WebScreenOrientationLockType orientation) { 410 blink::WebScreenOrientationLockType orientation) {
229 DCHECK(base::WorkerPool::RunsTasksOnCurrentThread()); 411 DCHECK(base::WorkerPool::RunsTasksOnCurrentThread());
230 412
231 // Grab the average color from the bitmap. 413 SkBitmap icon_bitmap;
232 SkColor color = SK_ColorWHITE;
233 SkBitmap favicon_bitmap;
234 if (bitmap_result.is_valid()) { 414 if (bitmap_result.is_valid()) {
235 if (gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), 415 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
236 bitmap_result.bitmap_data->size(), 416 bitmap_result.bitmap_data->size(),
237 &favicon_bitmap)) 417 &icon_bitmap);
238 color = color_utils::CalculateKMeanColorOfBitmap(favicon_bitmap);
239 } 418 }
240 419
420 AddShortcutInBackgroundWithSkBitmap(
421 url, title, display, icon_bitmap, orientation);
422 }
423
424 void ShortcutHelper::AddShortcutInBackgroundWithSkBitmap(
425 const GURL& url,
426 const base::string16& title,
427 content::Manifest::DisplayMode display,
428 const SkBitmap& icon_bitmap,
429 blink::WebScreenOrientationLockType orientation) {
430 DCHECK(base::WorkerPool::RunsTasksOnCurrentThread());
431
432 SkColor color = color_utils::CalculateKMeanColorOfBitmap(icon_bitmap);
241 int r_value = SkColorGetR(color); 433 int r_value = SkColorGetR(color);
242 int g_value = SkColorGetG(color); 434 int g_value = SkColorGetG(color);
243 int b_value = SkColorGetB(color); 435 int b_value = SkColorGetB(color);
244 436
245 // Send the data to the Java side to create the shortcut. 437 // Send the data to the Java side to create the shortcut.
246 JNIEnv* env = base::android::AttachCurrentThread(); 438 JNIEnv* env = base::android::AttachCurrentThread();
247 ScopedJavaLocalRef<jstring> java_url = 439 ScopedJavaLocalRef<jstring> java_url =
248 base::android::ConvertUTF8ToJavaString(env, url.spec()); 440 base::android::ConvertUTF8ToJavaString(env, url.spec());
249 ScopedJavaLocalRef<jstring> java_title = 441 ScopedJavaLocalRef<jstring> java_title =
250 base::android::ConvertUTF16ToJavaString(env, title); 442 base::android::ConvertUTF16ToJavaString(env, title);
251 ScopedJavaLocalRef<jobject> java_bitmap; 443 ScopedJavaLocalRef<jobject> java_bitmap;
252 if (favicon_bitmap.getSize()) 444 if (icon_bitmap.getSize())
253 java_bitmap = gfx::ConvertToJavaBitmap(&favicon_bitmap); 445 java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap);
254 446
255 Java_ShortcutHelper_addShortcut( 447 Java_ShortcutHelper_addShortcut(
256 env, 448 env,
257 base::android::GetApplicationContext(), 449 base::android::GetApplicationContext(),
258 java_url.obj(), 450 java_url.obj(),
259 java_title.obj(), 451 java_title.obj(),
260 java_bitmap.obj(), 452 java_bitmap.obj(),
261 r_value, 453 r_value,
262 g_value, 454 g_value,
263 b_value, 455 b_value,
264 display == content::Manifest::DISPLAY_MODE_STANDALONE, 456 display == content::Manifest::DISPLAY_MODE_STANDALONE,
265 orientation); 457 orientation);
266 } 458 }
OLDNEW
« no previous file with comments | « chrome/browser/android/shortcut_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698