blob: 8a7b589fe8e92779dbd98ab26fdb428d46340d97 [file] [log] [blame]
[email protected]51208252013-08-19 21:05:301// Copyright 2013 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/shortcut_helper.h"
6
7#include <jni.h>
gonzalon87192d772017-02-07 22:31:108#include <utility>
[email protected]51208252013-08-19 21:05:309
10#include "base/android/jni_android.h"
lalitm45a03c72015-09-16 13:00:4311#include "base/android/jni_array.h"
[email protected]51208252013-08-19 21:05:3012#include "base/android/jni_string.h"
dominickn6509a4de2016-04-06 08:29:0613#include "base/bind.h"
14#include "base/callback.h"
Piotr Swigon549c0432017-08-16 02:48:4115#include "base/feature_list.h"
pkotwiczd0d459e2017-03-01 22:55:1016#include "base/guid.h"
[email protected]51208252013-08-19 21:05:3017#include "base/strings/string16.h"
mlamouric679bbf2014-09-24 21:24:4918#include "base/strings/utf_string_conversions.h"
tzika1fd66f2017-02-15 07:58:4519#include "base/threading/sequenced_worker_pool.h"
hanxi563f3532016-08-19 20:09:0120#include "chrome/browser/android/webapk/chrome_webapk_host.h"
hanxi070d10a2017-01-09 15:56:5021#include "chrome/browser/android/webapk/webapk_install_service.h"
pkotwiczf4dddb32017-02-25 01:21:5522#include "chrome/browser/android/webapk/webapk_metrics.h"
Piotr Swigon549c0432017-08-16 02:48:4123#include "chrome/common/chrome_features.h"
pkotwicz206673142016-07-19 19:13:3024#include "chrome/common/chrome_switches.h"
dfalcantaraaec56da2015-05-06 03:33:5625#include "content/public/browser/browser_thread.h"
jinho.bang84cadc82017-06-14 16:59:3426#include "content/public/browser/manifest_icon_downloader.h"
[email protected]51208252013-08-19 21:05:3027#include "content/public/browser/web_contents.h"
[email protected]51208252013-08-19 21:05:3028#include "jni/ShortcutHelper_jni.h"
29#include "ui/gfx/android/java_bitmap.h"
mlamouribc6e8792015-10-22 20:41:1330#include "ui/gfx/color_analysis.h"
[email protected]51208252013-08-19 21:05:3031#include "url/gurl.h"
32
torne86560112016-08-04 15:59:0433using base::android::JavaParamRef;
34using base::android::ScopedJavaLocalRef;
mlamouric679bbf2014-09-24 21:24:4935using content::Manifest;
36
lalitm45a03c72015-09-16 13:00:4337namespace {
38
zpenge33ba852017-02-01 20:54:4239int g_ideal_homescreen_icon_size = -1;
40int g_minimum_homescreen_icon_size = -1;
41int g_ideal_splash_image_size = -1;
42int g_minimum_splash_image_size = -1;
43int g_ideal_badge_icon_size = -1;
lalitm45a03c72015-09-16 13:00:4344
zpenge33ba852017-02-01 20:54:4245int g_default_rgb_icon_value = 145;
mlamouribc6e8792015-10-22 20:41:1346
lalitm45a03c72015-09-16 13:00:4347// Retrieves and caches the ideal and minimum sizes of the Home screen icon
48// and the splash screen image.
49void GetHomescreenIconAndSplashImageSizes() {
50 JNIEnv* env = base::android::AttachCurrentThread();
51 ScopedJavaLocalRef<jintArray> java_size_array =
pkotwicz45fc42b62016-06-07 00:07:1052 Java_ShortcutHelper_getHomeScreenIconAndSplashImageSizes(env);
lalitm45a03c72015-09-16 13:00:4353 std::vector<int> sizes;
zpenga7856eef2017-02-07 11:42:4454 base::android::JavaIntArrayToIntVector(env, java_size_array.obj(), &sizes);
lalitm45a03c72015-09-16 13:00:4355
56 // Check that the size returned is what is expected.
zpenge33ba852017-02-01 20:54:4257 DCHECK(sizes.size() == 5);
lalitm45a03c72015-09-16 13:00:4358
59 // This ordering must be kept up to date with the Java ShortcutHelper.
zpenge33ba852017-02-01 20:54:4260 g_ideal_homescreen_icon_size = sizes[0];
61 g_minimum_homescreen_icon_size = sizes[1];
62 g_ideal_splash_image_size = sizes[2];
63 g_minimum_splash_image_size = sizes[3];
64 g_ideal_badge_icon_size = sizes[4];
lalitm45a03c72015-09-16 13:00:4365
66 // Try to ensure that the data returned is sane.
zpenge33ba852017-02-01 20:54:4267 DCHECK(g_minimum_homescreen_icon_size <= g_ideal_homescreen_icon_size);
68 DCHECK(g_minimum_splash_image_size <= g_ideal_splash_image_size);
lalitm45a03c72015-09-16 13:00:4369}
70
pkotwicz97478712017-03-01 03:39:5471// Adds a shortcut which opens in a fullscreen window to the launcher.
72// |splash_image_callback| will be invoked once the Java-side operation has
73// completed. This is necessary as Java will asynchronously create and
74// populate a WebappDataStorage object for standalone-capable sites. This must
75// exist before the splash image can be stored.
76void AddWebappWithSkBitmap(const ShortcutInfo& info,
77 const std::string& webapp_id,
78 const SkBitmap& icon_bitmap,
79 const base::Closure& splash_image_callback) {
[email protected]51208252013-08-19 21:05:3080 // Send the data to the Java side to create the shortcut.
81 JNIEnv* env = base::android::AttachCurrentThread();
lalitmd93c2ed2015-09-04 16:22:1282 ScopedJavaLocalRef<jstring> java_webapp_id =
83 base::android::ConvertUTF8ToJavaString(env, webapp_id);
[email protected]51208252013-08-19 21:05:3084 ScopedJavaLocalRef<jstring> java_url =
dfalcantara16e84de2015-02-03 22:07:4085 base::android::ConvertUTF8ToJavaString(env, info.url.spec());
pkotwicz6bdfbe1b2016-07-08 00:26:4386 ScopedJavaLocalRef<jstring> java_scope_url =
87 base::android::ConvertUTF8ToJavaString(env, info.scope.spec());
lalitmf3ee51852015-07-21 18:13:1188 ScopedJavaLocalRef<jstring> java_user_title =
89 base::android::ConvertUTF16ToJavaString(env, info.user_title);
90 ScopedJavaLocalRef<jstring> java_name =
91 base::android::ConvertUTF16ToJavaString(env, info.name);
92 ScopedJavaLocalRef<jstring> java_short_name =
93 base::android::ConvertUTF16ToJavaString(env, info.short_name);
zpenga7856eef2017-02-07 11:42:4494 ScopedJavaLocalRef<jstring> java_best_primary_icon_url =
95 base::android::ConvertUTF8ToJavaString(env,
96 info.best_primary_icon_url.spec());
[email protected]51208252013-08-19 21:05:3097 ScopedJavaLocalRef<jobject> java_bitmap;
zpengfebce7612017-06-07 14:29:0498 if (!icon_bitmap.drawsNothing())
mlamouric679bbf2014-09-24 21:24:4999 java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap);
[email protected]51208252013-08-19 21:05:30100
pkotwicz206673142016-07-19 19:13:30101 // The callback will need to be run after shortcut creation completes in order
102 // to download the splash image and save it to the WebappDataStorage. Create a
103 // copy of the callback here and send the pointer to Java, which will send it
104 // back once the asynchronous shortcut creation process finishes.
105 uintptr_t callback_pointer =
106 reinterpret_cast<uintptr_t>(new base::Closure(splash_image_callback));
dominickn6509a4de2016-04-06 08:29:06107
zpenga7856eef2017-02-07 11:42:44108 Java_ShortcutHelper_addWebapp(
109 env, java_webapp_id, java_url, java_scope_url, java_user_title, java_name,
110 java_short_name, java_best_primary_icon_url, java_bitmap, info.display,
111 info.orientation, info.source, info.theme_color, info.background_color,
112 callback_pointer);
[email protected]51208252013-08-19 21:05:30113}
benwells840ae902015-02-17 21:13:28114
pkotwicz97478712017-03-01 03:39:54115// Adds a shortcut which opens in a browser tab to the launcher.
116void AddShortcutWithSkBitmap(const ShortcutInfo& info,
117 const std::string& id,
118 const SkBitmap& icon_bitmap) {
pkotwicz206673142016-07-19 19:13:30119 JNIEnv* env = base::android::AttachCurrentThread();
martiw12166f52017-02-20 03:05:45120 ScopedJavaLocalRef<jstring> java_id =
121 base::android::ConvertUTF8ToJavaString(env, id);
pkotwicz206673142016-07-19 19:13:30122 ScopedJavaLocalRef<jstring> java_url =
123 base::android::ConvertUTF8ToJavaString(env, info.url.spec());
124 ScopedJavaLocalRef<jstring> java_user_title =
125 base::android::ConvertUTF16ToJavaString(env, info.user_title);
126 ScopedJavaLocalRef<jobject> java_bitmap;
zpengfebce7612017-06-07 14:29:04127 if (!icon_bitmap.drawsNothing())
pkotwicz206673142016-07-19 19:13:30128 java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap);
129
martiw12166f52017-02-20 03:05:45130 Java_ShortcutHelper_addShortcut(env, java_id, java_url, java_user_title,
131 java_bitmap, info.source);
pkotwicz206673142016-07-19 19:13:30132}
133
pkotwicz97478712017-03-01 03:39:54134} // anonymous namespace
135
136// static
137void ShortcutHelper::AddToLauncherWithSkBitmap(
pkotwiczd0d459e2017-03-01 22:55:10138 content::WebContents* web_contents,
pkotwicz97478712017-03-01 03:39:54139 const ShortcutInfo& info,
pkotwiczd0d459e2017-03-01 22:55:10140 const SkBitmap& icon_bitmap) {
141 std::string webapp_id = base::GenerateGUID();
Blink Reformat1c4d759e2017-04-09 16:34:54142 if (info.display == blink::kWebDisplayModeStandalone ||
Piotr Swigon549c0432017-08-16 02:48:41143 info.display == blink::kWebDisplayModeFullscreen ||
144 (info.display == blink::kWebDisplayModeMinimalUi &&
145 base::FeatureList::IsEnabled(features::kPwaMinimalUi))) {
pkotwiczd0d459e2017-03-01 22:55:10146 AddWebappWithSkBitmap(
147 info, webapp_id, icon_bitmap,
148 base::Bind(&ShortcutHelper::FetchSplashScreenImage, web_contents,
149 info.splash_image_url, info.ideal_splash_image_size_in_px,
150 info.minimum_splash_image_size_in_px, webapp_id));
pkotwicz97478712017-03-01 03:39:54151 return;
152 }
153 AddShortcutWithSkBitmap(info, webapp_id, icon_bitmap);
154}
155
156// static
157void ShortcutHelper::InstallWebApkWithSkBitmap(
pkotwiczd0d459e2017-03-01 22:55:10158 content::WebContents* web_contents,
pkotwicz97478712017-03-01 03:39:54159 const ShortcutInfo& info,
zpeng1fd959d62017-04-07 19:34:30160 const SkBitmap& primary_icon_bitmap,
161 const SkBitmap& badge_icon_bitmap,
pkotwiczfc494852017-03-03 02:58:41162 const WebApkInstallService::FinishCallback& callback) {
pkotwiczd0d459e2017-03-01 22:55:10163 WebApkInstallService::Get(web_contents->GetBrowserContext())
zpeng1fd959d62017-04-07 19:34:30164 ->InstallAsync(info, primary_icon_bitmap, badge_icon_bitmap, callback);
pkotwicz97478712017-03-01 03:39:54165}
166
hanxi070d10a2017-01-09 15:56:50167void ShortcutHelper::ShowWebApkInstallInProgressToast() {
168 Java_ShortcutHelper_showWebApkInstallInProgressToast(
169 base::android::AttachCurrentThread());
170}
171
zpeng5d8fdfc2017-01-05 15:45:06172int ShortcutHelper::GetIdealHomescreenIconSizeInPx() {
zpenge33ba852017-02-01 20:54:42173 if (g_ideal_homescreen_icon_size == -1)
lalitm45a03c72015-09-16 13:00:43174 GetHomescreenIconAndSplashImageSizes();
zpenge33ba852017-02-01 20:54:42175 return g_ideal_homescreen_icon_size;
lalitm45a03c72015-09-16 13:00:43176}
177
zpeng5d8fdfc2017-01-05 15:45:06178int ShortcutHelper::GetMinimumHomescreenIconSizeInPx() {
zpenge33ba852017-02-01 20:54:42179 if (g_minimum_homescreen_icon_size == -1)
lalitm45a03c72015-09-16 13:00:43180 GetHomescreenIconAndSplashImageSizes();
zpenge33ba852017-02-01 20:54:42181 return g_minimum_homescreen_icon_size;
lalitm45a03c72015-09-16 13:00:43182}
183
zpeng5d8fdfc2017-01-05 15:45:06184int ShortcutHelper::GetIdealSplashImageSizeInPx() {
zpenge33ba852017-02-01 20:54:42185 if (g_ideal_splash_image_size == -1)
lalitm45a03c72015-09-16 13:00:43186 GetHomescreenIconAndSplashImageSizes();
zpenge33ba852017-02-01 20:54:42187 return g_ideal_splash_image_size;
lalitm45a03c72015-09-16 13:00:43188}
189
zpeng5d8fdfc2017-01-05 15:45:06190int ShortcutHelper::GetMinimumSplashImageSizeInPx() {
zpenge33ba852017-02-01 20:54:42191 if (g_minimum_splash_image_size == -1)
lalitm45a03c72015-09-16 13:00:43192 GetHomescreenIconAndSplashImageSizes();
zpenge33ba852017-02-01 20:54:42193 return g_minimum_splash_image_size;
194}
195
196int ShortcutHelper::GetIdealBadgeIconSizeInPx() {
197 if (g_ideal_badge_icon_size == -1)
198 GetHomescreenIconAndSplashImageSizes();
199 return g_ideal_badge_icon_size;
lalitm45a03c72015-09-16 13:00:43200}
201
lalitmd93c2ed2015-09-04 16:22:12202// static
203void ShortcutHelper::FetchSplashScreenImage(
204 content::WebContents* web_contents,
205 const GURL& image_url,
zpeng5d8fdfc2017-01-05 15:45:06206 const int ideal_splash_image_size_in_px,
207 const int minimum_splash_image_size_in_px,
dominickn6509a4de2016-04-06 08:29:06208 const std::string& webapp_id) {
lalitmd93c2ed2015-09-04 16:22:12209 // This is a fire and forget task. It is not vital for the splash screen image
210 // to be downloaded so if the downloader returns false there is no fallback.
jinho.bang84cadc82017-06-14 16:59:34211 content::ManifestIconDownloader::Download(
zpeng5d8fdfc2017-01-05 15:45:06212 web_contents, image_url, ideal_splash_image_size_in_px,
213 minimum_splash_image_size_in_px,
dominickn6509a4de2016-04-06 08:29:06214 base::Bind(&ShortcutHelper::StoreWebappSplashImage, webapp_id));
lalitmd93c2ed2015-09-04 16:22:12215}
216
217// static
zpenga7856eef2017-02-07 11:42:44218void ShortcutHelper::StoreWebappSplashImage(const std::string& webapp_id,
219 const SkBitmap& splash_image) {
lalitmd93c2ed2015-09-04 16:22:12220 if (splash_image.drawsNothing())
221 return;
222
223 JNIEnv* env = base::android::AttachCurrentThread();
224 ScopedJavaLocalRef<jstring> java_webapp_id =
225 base::android::ConvertUTF8ToJavaString(env, webapp_id);
226 ScopedJavaLocalRef<jobject> java_splash_image =
227 gfx::ConvertToJavaBitmap(&splash_image);
228
torne948f3662016-08-16 15:10:44229 Java_ShortcutHelper_storeWebappSplashImage(env, java_webapp_id,
230 java_splash_image);
lalitmd93c2ed2015-09-04 16:22:12231}
232
mlamouribc6e8792015-10-22 20:41:13233// static
pkotwicz5774087e2016-08-10 17:36:40234SkBitmap ShortcutHelper::FinalizeLauncherIconInBackground(
235 const SkBitmap& bitmap,
236 const GURL& url,
237 bool* is_generated) {
peary2be588082017-05-17 01:59:49238 base::ThreadRestrictions::AssertIOAllowed();
mlamouribc6e8792015-10-22 20:41:13239
240 JNIEnv* env = base::android::AttachCurrentThread();
241 ScopedJavaLocalRef<jobject> result;
242 *is_generated = false;
243
244 if (!bitmap.isNull()) {
pkotwicz45fc42b62016-06-07 00:07:10245 if (Java_ShortcutHelper_isIconLargeEnoughForLauncher(env, bitmap.width(),
246 bitmap.height())) {
newta584b9e2015-10-29 22:29:43247 ScopedJavaLocalRef<jobject> java_bitmap =
248 gfx::ConvertToJavaBitmap(&bitmap);
torne948f3662016-08-16 15:10:44249 result =
250 Java_ShortcutHelper_createHomeScreenIconFromWebIcon(env, java_bitmap);
mlamouribc6e8792015-10-22 20:41:13251 }
252 }
253
254 if (result.is_null()) {
255 ScopedJavaLocalRef<jstring> java_url =
256 base::android::ConvertUTF8ToJavaString(env, url.spec());
zpenge33ba852017-02-01 20:54:42257 SkColor mean_color =
258 SkColorSetRGB(g_default_rgb_icon_value, g_default_rgb_icon_value,
259 g_default_rgb_icon_value);
mlamouribc6e8792015-10-22 20:41:13260
261 if (!bitmap.isNull())
262 mean_color = color_utils::CalculateKMeanColorOfBitmap(bitmap);
263
264 *is_generated = true;
newta584b9e2015-10-29 22:29:43265 result = Java_ShortcutHelper_generateHomeScreenIcon(
torne948f3662016-08-16 15:10:44266 env, java_url, SkColorGetR(mean_color), SkColorGetG(mean_color),
mlamouribc6e8792015-10-22 20:41:13267 SkColorGetB(mean_color));
268 }
269
pkotwicz964382b2016-08-04 01:24:55270 return result.obj()
torned64eb5132016-10-24 12:51:28271 ? gfx::CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(result))
pkotwicz964382b2016-08-04 01:24:55272 : SkBitmap();
mlamouribc6e8792015-10-22 20:41:13273}
274
pkotwiczcda82fe2016-07-08 18:56:54275// static
zpeng4bb58962016-10-04 02:42:29276std::string ShortcutHelper::QueryWebApkPackage(const GURL& url) {
277 JNIEnv* env = base::android::AttachCurrentThread();
278 ScopedJavaLocalRef<jstring> java_url =
279 base::android::ConvertUTF8ToJavaString(env, url.spec());
280 ScopedJavaLocalRef<jstring> java_webapk_package_name =
281 Java_ShortcutHelper_queryWebApkPackage(env, java_url);
282
283 std::string webapk_package_name = "";
284 if (java_webapk_package_name.obj()) {
zpenga7856eef2017-02-07 11:42:44285 webapk_package_name =
286 base::android::ConvertJavaStringToUTF8(env, java_webapk_package_name);
zpeng4bb58962016-10-04 02:42:29287 }
288 return webapk_package_name;
289}
290
291// static
zpenga7856eef2017-02-07 11:42:44292bool ShortcutHelper::IsWebApkInstalled(content::BrowserContext* browser_context,
293 const GURL& start_url,
294 const GURL& manifest_url) {
hanxi070d10a2017-01-09 15:56:50295 return !QueryWebApkPackage(start_url).empty() ||
zpenga7856eef2017-02-07 11:42:44296 WebApkInstallService::Get(browser_context)
297 ->IsInstallInProgress(manifest_url);
pkotwiczcda82fe2016-07-08 18:56:54298}
299
pkotwicz47136bc2016-08-06 23:55:39300GURL ShortcutHelper::GetScopeFromURL(const GURL& url) {
301 JNIEnv* env = base::android::AttachCurrentThread();
302 ScopedJavaLocalRef<jstring> java_url =
303 base::android::ConvertUTF8ToJavaString(env, url.spec());
304 ScopedJavaLocalRef<jstring> java_scope_url =
torne948f3662016-08-16 15:10:44305 Java_ShortcutHelper_getScopeFromUrl(env, java_url);
pkotwicz47136bc2016-08-06 23:55:39306 return GURL(base::android::ConvertJavaStringToUTF16(env, java_scope_url));
307}
308
gonzalon87192d772017-02-07 22:31:10309void ShortcutHelper::RetrieveWebApks(const WebApkInfoCallback& callback) {
310 uintptr_t callback_pointer =
311 reinterpret_cast<uintptr_t>(new WebApkInfoCallback(callback));
312 Java_ShortcutHelper_retrieveWebApks(base::android::AttachCurrentThread(),
313 callback_pointer);
314}
315
dominickn6509a4de2016-04-06 08:29:06316// Callback used by Java when the shortcut has been created.
317// |splash_image_callback| is a pointer to a base::Closure allocated in
pkotwiczc67e6ac2016-08-12 19:56:44318// AddShortcutWithSkBitmap, so reinterpret_cast it back and run it.
dominickn6509a4de2016-04-06 08:29:06319//
320// This callback should only ever be called when the shortcut was for a
321// webapp-capable site; otherwise, |splash_image_callback| will have never been
322// allocated and doesn't need to be run or deleted.
323void OnWebappDataStored(JNIEnv* env,
324 const JavaParamRef<jclass>& clazz,
325 jlong jsplash_image_callback) {
326 DCHECK(jsplash_image_callback);
327 base::Closure* splash_image_callback =
328 reinterpret_cast<base::Closure*>(jsplash_image_callback);
329 splash_image_callback->Run();
330 delete splash_image_callback;
331}
332
gonzalon87192d772017-02-07 22:31:10333void OnWebApksRetrieved(JNIEnv* env,
334 const JavaParamRef<jclass>& clazz,
335 const jlong jcallback_pointer,
gonzalon85e975452017-03-03 23:58:42336 const JavaParamRef<jobjectArray>& jnames,
gonzalon87192d772017-02-07 22:31:10337 const JavaParamRef<jobjectArray>& jshort_names,
338 const JavaParamRef<jobjectArray>& jpackage_names,
339 const JavaParamRef<jintArray>& jshell_apk_versions,
gonzalon85e975452017-03-03 23:58:42340 const JavaParamRef<jintArray>& jversion_codes,
341 const JavaParamRef<jobjectArray>& juris,
342 const JavaParamRef<jobjectArray>& jscopes,
343 const JavaParamRef<jobjectArray>& jmanifest_urls,
344 const JavaParamRef<jobjectArray>& jmanifest_start_urls,
345 const JavaParamRef<jintArray>& jdisplay_modes,
346 const JavaParamRef<jintArray>& jorientations,
347 const JavaParamRef<jlongArray>& jtheme_colors,
348 const JavaParamRef<jlongArray>& jbackground_colors) {
gonzalon87192d772017-02-07 22:31:10349 DCHECK(jcallback_pointer);
gonzalon85e975452017-03-03 23:58:42350 std::vector<std::string> names;
351 base::android::AppendJavaStringArrayToStringVector(env, jnames, &names);
gonzalon87192d772017-02-07 22:31:10352 std::vector<std::string> short_names;
353 base::android::AppendJavaStringArrayToStringVector(env, jshort_names,
354 &short_names);
355 std::vector<std::string> package_names;
356 base::android::AppendJavaStringArrayToStringVector(env, jpackage_names,
357 &package_names);
358 std::vector<int> shell_apk_versions;
359 base::android::JavaIntArrayToIntVector(env, jshell_apk_versions,
360 &shell_apk_versions);
361 std::vector<int> version_codes;
362 base::android::JavaIntArrayToIntVector(env, jversion_codes, &version_codes);
gonzalon85e975452017-03-03 23:58:42363 std::vector<std::string> uris;
364 base::android::AppendJavaStringArrayToStringVector(env, juris, &uris);
365 std::vector<std::string> scopes;
366 base::android::AppendJavaStringArrayToStringVector(env, jscopes, &scopes);
367 std::vector<std::string> manifest_urls;
368 base::android::AppendJavaStringArrayToStringVector(env, jmanifest_urls,
369 &manifest_urls);
370 std::vector<std::string> manifest_start_urls;
371 base::android::AppendJavaStringArrayToStringVector(env, jmanifest_start_urls,
372 &manifest_start_urls);
373 std::vector<int> display_modes;
374 base::android::JavaIntArrayToIntVector(env, jdisplay_modes, &display_modes);
375 std::vector<int> orientations;
376 base::android::JavaIntArrayToIntVector(env, jorientations, &orientations);
377 std::vector<int64_t> theme_colors;
378 base::android::JavaLongArrayToInt64Vector(env, jtheme_colors, &theme_colors);
379 std::vector<int64_t> background_colors;
380 base::android::JavaLongArrayToInt64Vector(env, jbackground_colors,
381 &background_colors);
gonzalon87192d772017-02-07 22:31:10382
gonzalon85e975452017-03-03 23:58:42383 DCHECK(short_names.size() == names.size());
gonzalon87192d772017-02-07 22:31:10384 DCHECK(short_names.size() == package_names.size());
385 DCHECK(short_names.size() == shell_apk_versions.size());
386 DCHECK(short_names.size() == version_codes.size());
gonzalon85e975452017-03-03 23:58:42387 DCHECK(short_names.size() == uris.size());
388 DCHECK(short_names.size() == scopes.size());
389 DCHECK(short_names.size() == manifest_urls.size());
390 DCHECK(short_names.size() == manifest_start_urls.size());
391 DCHECK(short_names.size() == display_modes.size());
392 DCHECK(short_names.size() == orientations.size());
393 DCHECK(short_names.size() == theme_colors.size());
394 DCHECK(short_names.size() == background_colors.size());
gonzalon87192d772017-02-07 22:31:10395
396 std::vector<WebApkInfo> webapk_list;
397 webapk_list.reserve(short_names.size());
398 for (size_t i = 0; i < short_names.size(); ++i) {
gonzalon85e975452017-03-03 23:58:42399 webapk_list.push_back(WebApkInfo(
400 std::move(names[i]), std::move(short_names[i]),
401 std::move(package_names[i]), shell_apk_versions[i], version_codes[i],
402 std::move(uris[i]), std::move(scopes[i]), std::move(manifest_urls[i]),
403 std::move(manifest_start_urls[i]),
404 static_cast<blink::WebDisplayMode>(display_modes[i]),
405 static_cast<blink::WebScreenOrientationLockType>(orientations[i]),
406 theme_colors[i], background_colors[i]));
gonzalon87192d772017-02-07 22:31:10407 }
408
409 ShortcutHelper::WebApkInfoCallback* webapk_list_callback =
410 reinterpret_cast<ShortcutHelper::WebApkInfoCallback*>(jcallback_pointer);
411 webapk_list_callback->Run(webapk_list);
412 delete webapk_list_callback;
413}