blob: d937cf6b77aaa10d45c623771fb433e63d27e82e [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
Henry Jianf78dce62019-09-22 16:58:4110#include "base/android/build_info.h"
[email protected]51208252013-08-19 21:05:3011#include "base/android/jni_android.h"
lalitm45a03c72015-09-16 13:00:4312#include "base/android/jni_array.h"
[email protected]51208252013-08-19 21:05:3013#include "base/android/jni_string.h"
dominickn6509a4de2016-04-06 08:29:0614#include "base/bind.h"
15#include "base/callback.h"
Henry Jianf78dce62019-09-22 16:58:4116#include "base/feature_list.h"
pkotwiczd0d459e2017-03-01 22:55:1017#include "base/guid.h"
Daniel Cheng8fedab22018-05-17 00:39:2718#include "base/optional.h"
[email protected]51208252013-08-19 21:05:3019#include "base/strings/string16.h"
mlamouric679bbf2014-09-24 21:24:4920#include "base/strings/utf_string_conversions.h"
Etienne Pierre-doray4f2e41bed2018-09-24 22:10:1121#include "base/threading/thread_restrictions.h"
Andrew Grieve4a42c22e2019-06-24 16:14:2922#include "chrome/android/chrome_jni_headers/ShortcutHelper_jni.h"
Daniel Cheng8fedab22018-05-17 00:39:2723#include "chrome/browser/android/color_helpers.h"
Michael Thiessene01199c942019-06-25 16:32:5324#include "chrome/browser/android/tab_android.h"
hanxi070d10a2017-01-09 15:56:5025#include "chrome/browser/android/webapk/webapk_install_service.h"
pkotwiczf4dddb32017-02-25 01:21:5526#include "chrome/browser/android/webapk/webapk_metrics.h"
Henrique Nakashima476b0b52020-01-24 22:28:0327#include "chrome/browser/flags/android/chrome_feature_list.h"
pkotwicz206673142016-07-19 19:13:3028#include "chrome/common/chrome_switches.h"
dfalcantaraaec56da2015-05-06 03:33:5629#include "content/public/browser/browser_thread.h"
jinho.bang84cadc82017-06-14 16:59:3430#include "content/public/browser/manifest_icon_downloader.h"
[email protected]51208252013-08-19 21:05:3031#include "content/public/browser/web_contents.h"
Dmitry Gozman88ca5a992018-05-18 00:13:3332#include "third_party/blink/public/common/manifest/manifest.h"
Mugdha Lakhani62db8de2018-07-10 16:00:4833#include "third_party/blink/public/common/manifest/manifest_icon_selector.h"
Daniel Cheng8fedab22018-05-17 00:39:2734#include "third_party/skia/include/core/SkColor.h"
[email protected]51208252013-08-19 21:05:3035#include "ui/gfx/android/java_bitmap.h"
mlamouribc6e8792015-10-22 20:41:1336#include "ui/gfx/color_analysis.h"
[email protected]51208252013-08-19 21:05:3037#include "url/gurl.h"
38
torne86560112016-08-04 15:59:0439using base::android::JavaParamRef;
40using base::android::ScopedJavaLocalRef;
mlamouric679bbf2014-09-24 21:24:4941
lalitm45a03c72015-09-16 13:00:4342namespace {
43
zpenge33ba852017-02-01 20:54:4244int g_ideal_homescreen_icon_size = -1;
45int g_minimum_homescreen_icon_size = -1;
46int g_ideal_splash_image_size = -1;
47int g_minimum_splash_image_size = -1;
Glen Robertson41d3c0f2020-07-15 03:42:1548int g_ideal_monochrome_icon_size = -1;
Henry Jian96ec2512019-09-13 00:34:0949int g_ideal_adaptive_launcher_icon_size = -1;
Rayan Kanso3a2f4762020-01-28 13:34:1650int g_ideal_shortcut_icon_size = -1;
lalitm45a03c72015-09-16 13:00:4351
zpenge33ba852017-02-01 20:54:4252int g_default_rgb_icon_value = 145;
mlamouribc6e8792015-10-22 20:41:1353
Rayan Kanso3a2f4762020-01-28 13:34:1654// Retrieves and caches the ideal and minimum sizes of the Home screen icon,
55// the splash screen image, and the shortcut icons.
56void GetIconSizes() {
lalitm45a03c72015-09-16 13:00:4357 JNIEnv* env = base::android::AttachCurrentThread();
58 ScopedJavaLocalRef<jintArray> java_size_array =
Rayan Kanso3a2f4762020-01-28 13:34:1659 Java_ShortcutHelper_getIconSizes(env);
lalitm45a03c72015-09-16 13:00:4360 std::vector<int> sizes;
Torne (Richard Coles)3c22e8302018-10-12 18:34:2261 base::android::JavaIntArrayToIntVector(env, java_size_array, &sizes);
lalitm45a03c72015-09-16 13:00:4362
63 // Check that the size returned is what is expected.
Rayan Kanso3a2f4762020-01-28 13:34:1664 DCHECK_EQ(7u, sizes.size());
lalitm45a03c72015-09-16 13:00:4365
66 // This ordering must be kept up to date with the Java ShortcutHelper.
zpenge33ba852017-02-01 20:54:4267 g_ideal_homescreen_icon_size = sizes[0];
68 g_minimum_homescreen_icon_size = sizes[1];
69 g_ideal_splash_image_size = sizes[2];
70 g_minimum_splash_image_size = sizes[3];
Glen Robertson41d3c0f2020-07-15 03:42:1571 g_ideal_monochrome_icon_size = sizes[4];
Henry Jian96ec2512019-09-13 00:34:0972 g_ideal_adaptive_launcher_icon_size = sizes[5];
Rayan Kanso3a2f4762020-01-28 13:34:1673 g_ideal_shortcut_icon_size = sizes[6];
lalitm45a03c72015-09-16 13:00:4374
75 // Try to ensure that the data returned is sane.
zpenge33ba852017-02-01 20:54:4276 DCHECK(g_minimum_homescreen_icon_size <= g_ideal_homescreen_icon_size);
77 DCHECK(g_minimum_splash_image_size <= g_ideal_splash_image_size);
lalitm45a03c72015-09-16 13:00:4378}
79
pkotwicz97478712017-03-01 03:39:5480// Adds a shortcut which opens in a fullscreen window to the launcher.
81// |splash_image_callback| will be invoked once the Java-side operation has
82// completed. This is necessary as Java will asynchronously create and
83// populate a WebappDataStorage object for standalone-capable sites. This must
84// exist before the splash image can be stored.
85void AddWebappWithSkBitmap(const ShortcutInfo& info,
86 const std::string& webapp_id,
87 const SkBitmap& icon_bitmap,
Peter E Connb955ae4a2018-12-03 13:02:0988 bool is_icon_maskable,
Dominick Ng40be8182019-03-11 23:21:0389 base::OnceClosure splash_image_callback) {
[email protected]51208252013-08-19 21:05:3090 // Send the data to the Java side to create the shortcut.
91 JNIEnv* env = base::android::AttachCurrentThread();
lalitmd93c2ed2015-09-04 16:22:1292 ScopedJavaLocalRef<jstring> java_webapp_id =
93 base::android::ConvertUTF8ToJavaString(env, webapp_id);
[email protected]51208252013-08-19 21:05:3094 ScopedJavaLocalRef<jstring> java_url =
dfalcantara16e84de2015-02-03 22:07:4095 base::android::ConvertUTF8ToJavaString(env, info.url.spec());
pkotwicz6bdfbe1b2016-07-08 00:26:4396 ScopedJavaLocalRef<jstring> java_scope_url =
97 base::android::ConvertUTF8ToJavaString(env, info.scope.spec());
lalitmf3ee51852015-07-21 18:13:1198 ScopedJavaLocalRef<jstring> java_user_title =
99 base::android::ConvertUTF16ToJavaString(env, info.user_title);
100 ScopedJavaLocalRef<jstring> java_name =
101 base::android::ConvertUTF16ToJavaString(env, info.name);
102 ScopedJavaLocalRef<jstring> java_short_name =
103 base::android::ConvertUTF16ToJavaString(env, info.short_name);
zpenga7856eef2017-02-07 11:42:44104 ScopedJavaLocalRef<jstring> java_best_primary_icon_url =
105 base::android::ConvertUTF8ToJavaString(env,
106 info.best_primary_icon_url.spec());
[email protected]51208252013-08-19 21:05:30107 ScopedJavaLocalRef<jobject> java_bitmap;
zpengfebce7612017-06-07 14:29:04108 if (!icon_bitmap.drawsNothing())
mlamouric679bbf2014-09-24 21:24:49109 java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap);
[email protected]51208252013-08-19 21:05:30110
pkotwicz206673142016-07-19 19:13:30111 // The callback will need to be run after shortcut creation completes in order
112 // to download the splash image and save it to the WebappDataStorage. Create a
113 // copy of the callback here and send the pointer to Java, which will send it
114 // back once the asynchronous shortcut creation process finishes.
Dominick Ng40be8182019-03-11 23:21:03115 uintptr_t callback_pointer = reinterpret_cast<uintptr_t>(
116 new base::OnceClosure(std::move(splash_image_callback)));
dominickn6509a4de2016-04-06 08:29:06117
zpenga7856eef2017-02-07 11:42:44118 Java_ShortcutHelper_addWebapp(
119 env, java_webapp_id, java_url, java_scope_url, java_user_title, java_name,
Peter E Connb955ae4a2018-12-03 13:02:09120 java_short_name, java_best_primary_icon_url, java_bitmap,
Dave Tapuska36eb28d2020-07-14 20:59:06121 is_icon_maskable, static_cast<int>(info.display),
122 static_cast<int>(info.orientation), info.source,
123 OptionalSkColorToJavaColor(info.theme_color),
Matt Jones2cd761c2019-09-18 18:53:40124 OptionalSkColorToJavaColor(info.background_color), callback_pointer);
[email protected]51208252013-08-19 21:05:30125}
benwells840ae902015-02-17 21:13:28126
pkotwicz97478712017-03-01 03:39:54127// Adds a shortcut which opens in a browser tab to the launcher.
Michael Thiessene01199c942019-06-25 16:32:53128void AddShortcutWithSkBitmap(content::WebContents* web_contents,
129 const ShortcutInfo& info,
pkotwicz97478712017-03-01 03:39:54130 const std::string& id,
Peter E Connb955ae4a2018-12-03 13:02:09131 const SkBitmap& icon_bitmap,
132 bool is_icon_maskable) {
pkotwicz206673142016-07-19 19:13:30133 JNIEnv* env = base::android::AttachCurrentThread();
martiw12166f52017-02-20 03:05:45134 ScopedJavaLocalRef<jstring> java_id =
135 base::android::ConvertUTF8ToJavaString(env, id);
pkotwicz206673142016-07-19 19:13:30136 ScopedJavaLocalRef<jstring> java_url =
137 base::android::ConvertUTF8ToJavaString(env, info.url.spec());
138 ScopedJavaLocalRef<jstring> java_user_title =
139 base::android::ConvertUTF16ToJavaString(env, info.user_title);
Michael Thiessene01199c942019-06-25 16:32:53140 ScopedJavaLocalRef<jstring> java_best_primary_icon_url =
141 base::android::ConvertUTF8ToJavaString(env,
142 info.best_primary_icon_url.spec());
pkotwicz206673142016-07-19 19:13:30143 ScopedJavaLocalRef<jobject> java_bitmap;
zpengfebce7612017-06-07 14:29:04144 if (!icon_bitmap.drawsNothing())
pkotwicz206673142016-07-19 19:13:30145 java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap);
Evan Staded7392a792020-07-16 20:59:21146 Java_ShortcutHelper_addShortcut(env, java_id, java_url, java_user_title,
Michael Thiessene01199c942019-06-25 16:32:53147 java_bitmap, is_icon_maskable, info.source,
148 java_best_primary_icon_url);
pkotwicz206673142016-07-19 19:13:30149}
150
pkotwicz97478712017-03-01 03:39:54151} // anonymous namespace
152
153// static
Dominick Ng203b4932018-02-02 05:32:45154std::unique_ptr<ShortcutInfo> ShortcutHelper::CreateShortcutInfo(
155 const GURL& manifest_url,
Dmitry Gozman88ca5a992018-05-18 00:13:33156 const blink::Manifest& manifest,
Ella Geefae3e002020-02-25 00:53:45157 const GURL& primary_icon_url) {
Dominick Ng203b4932018-02-02 05:32:45158 auto shortcut_info = std::make_unique<ShortcutInfo>(GURL());
159 if (!manifest.IsEmpty()) {
160 shortcut_info->UpdateFromManifest(manifest);
161 shortcut_info->manifest_url = manifest_url;
162 shortcut_info->best_primary_icon_url = primary_icon_url;
Dominick Ng203b4932018-02-02 05:32:45163 }
164
165 shortcut_info->ideal_splash_image_size_in_px = GetIdealSplashImageSizeInPx();
166 shortcut_info->minimum_splash_image_size_in_px =
167 GetMinimumSplashImageSizeInPx();
168 shortcut_info->splash_image_url =
Sahel Sharifyc067b74f2019-04-17 23:19:07169 blink::ManifestIconSelector::FindBestMatchingSquareIcon(
Dominick Ng203b4932018-02-02 05:32:45170 manifest.icons, shortcut_info->ideal_splash_image_size_in_px,
171 shortcut_info->minimum_splash_image_size_in_px,
Gyuyoung Kim361bbfe2020-10-28 00:21:10172 blink::mojom::ManifestImageResource_Purpose::ANY);
Dominick Ng203b4932018-02-02 05:32:45173
174 return shortcut_info;
175}
176
177// static
pkotwicz97478712017-03-01 03:39:54178void ShortcutHelper::AddToLauncherWithSkBitmap(
pkotwiczd0d459e2017-03-01 22:55:10179 content::WebContents* web_contents,
pkotwicz97478712017-03-01 03:39:54180 const ShortcutInfo& info,
Peter E Connb955ae4a2018-12-03 13:02:09181 const SkBitmap& icon_bitmap,
182 bool is_icon_maskable) {
pkotwiczd0d459e2017-03-01 22:55:10183 std::string webapp_id = base::GenerateGUID();
Eric Willigers052f0432019-10-04 04:06:57184 if (info.display == blink::mojom::DisplayMode::kStandalone ||
185 info.display == blink::mojom::DisplayMode::kFullscreen ||
186 info.display == blink::mojom::DisplayMode::kMinimalUi) {
pkotwiczd0d459e2017-03-01 22:55:10187 AddWebappWithSkBitmap(
Peter E Connb955ae4a2018-12-03 13:02:09188 info, webapp_id, icon_bitmap, is_icon_maskable,
Dominick Ng40be8182019-03-11 23:21:03189 base::BindOnce(&ShortcutHelper::FetchSplashScreenImage, web_contents,
190 info.splash_image_url,
191 info.ideal_splash_image_size_in_px,
192 info.minimum_splash_image_size_in_px, webapp_id));
pkotwicz97478712017-03-01 03:39:54193 return;
194 }
Michael Thiessene01199c942019-06-25 16:32:53195 AddShortcutWithSkBitmap(web_contents, info, webapp_id, icon_bitmap,
196 is_icon_maskable);
pkotwicz97478712017-03-01 03:39:54197}
198
hanxi070d10a2017-01-09 15:56:50199void ShortcutHelper::ShowWebApkInstallInProgressToast() {
200 Java_ShortcutHelper_showWebApkInstallInProgressToast(
201 base::android::AttachCurrentThread());
202}
203
zpeng5d8fdfc2017-01-05 15:45:06204int ShortcutHelper::GetIdealHomescreenIconSizeInPx() {
zpenge33ba852017-02-01 20:54:42205 if (g_ideal_homescreen_icon_size == -1)
Rayan Kanso3a2f4762020-01-28 13:34:16206 GetIconSizes();
zpenge33ba852017-02-01 20:54:42207 return g_ideal_homescreen_icon_size;
lalitm45a03c72015-09-16 13:00:43208}
209
zpeng5d8fdfc2017-01-05 15:45:06210int ShortcutHelper::GetMinimumHomescreenIconSizeInPx() {
zpenge33ba852017-02-01 20:54:42211 if (g_minimum_homescreen_icon_size == -1)
Rayan Kanso3a2f4762020-01-28 13:34:16212 GetIconSizes();
zpenge33ba852017-02-01 20:54:42213 return g_minimum_homescreen_icon_size;
lalitm45a03c72015-09-16 13:00:43214}
215
zpeng5d8fdfc2017-01-05 15:45:06216int ShortcutHelper::GetIdealSplashImageSizeInPx() {
zpenge33ba852017-02-01 20:54:42217 if (g_ideal_splash_image_size == -1)
Rayan Kanso3a2f4762020-01-28 13:34:16218 GetIconSizes();
zpenge33ba852017-02-01 20:54:42219 return g_ideal_splash_image_size;
lalitm45a03c72015-09-16 13:00:43220}
221
zpeng5d8fdfc2017-01-05 15:45:06222int ShortcutHelper::GetMinimumSplashImageSizeInPx() {
zpenge33ba852017-02-01 20:54:42223 if (g_minimum_splash_image_size == -1)
Rayan Kanso3a2f4762020-01-28 13:34:16224 GetIconSizes();
zpenge33ba852017-02-01 20:54:42225 return g_minimum_splash_image_size;
226}
227
Henry Jian96ec2512019-09-13 00:34:09228int ShortcutHelper::GetIdealAdaptiveLauncherIconSizeInPx() {
229 if (g_ideal_adaptive_launcher_icon_size == -1)
Rayan Kanso3a2f4762020-01-28 13:34:16230 GetIconSizes();
Henry Jian96ec2512019-09-13 00:34:09231 return g_ideal_adaptive_launcher_icon_size;
232}
233
Rayan Kanso3a2f4762020-01-28 13:34:16234int ShortcutHelper::GetIdealShortcutIconSizeInPx() {
235 if (g_ideal_shortcut_icon_size == -1)
236 GetIconSizes();
237 return g_ideal_shortcut_icon_size;
238}
239
lalitmd93c2ed2015-09-04 16:22:12240// static
241void ShortcutHelper::FetchSplashScreenImage(
242 content::WebContents* web_contents,
243 const GURL& image_url,
zpeng5d8fdfc2017-01-05 15:45:06244 const int ideal_splash_image_size_in_px,
245 const int minimum_splash_image_size_in_px,
dominickn6509a4de2016-04-06 08:29:06246 const std::string& webapp_id) {
lalitmd93c2ed2015-09-04 16:22:12247 // This is a fire and forget task. It is not vital for the splash screen image
248 // to be downloaded so if the downloader returns false there is no fallback.
jinho.bang84cadc82017-06-14 16:59:34249 content::ManifestIconDownloader::Download(
zpeng5d8fdfc2017-01-05 15:45:06250 web_contents, image_url, ideal_splash_image_size_in_px,
251 minimum_splash_image_size_in_px,
Dominick Ng40be8182019-03-11 23:21:03252 base::BindOnce(&ShortcutHelper::StoreWebappSplashImage, webapp_id));
lalitmd93c2ed2015-09-04 16:22:12253}
254
255// static
zpenga7856eef2017-02-07 11:42:44256void ShortcutHelper::StoreWebappSplashImage(const std::string& webapp_id,
257 const SkBitmap& splash_image) {
lalitmd93c2ed2015-09-04 16:22:12258 if (splash_image.drawsNothing())
259 return;
260
261 JNIEnv* env = base::android::AttachCurrentThread();
262 ScopedJavaLocalRef<jstring> java_webapp_id =
263 base::android::ConvertUTF8ToJavaString(env, webapp_id);
264 ScopedJavaLocalRef<jobject> java_splash_image =
265 gfx::ConvertToJavaBitmap(&splash_image);
266
torne948f3662016-08-16 15:10:44267 Java_ShortcutHelper_storeWebappSplashImage(env, java_webapp_id,
268 java_splash_image);
lalitmd93c2ed2015-09-04 16:22:12269}
270
mlamouribc6e8792015-10-22 20:41:13271// static
pkotwicz5774087e2016-08-10 17:36:40272SkBitmap ShortcutHelper::FinalizeLauncherIconInBackground(
273 const SkBitmap& bitmap,
Peter E Connb955ae4a2018-12-03 13:02:09274 bool is_icon_maskable,
pkotwicz5774087e2016-08-10 17:36:40275 const GURL& url,
276 bool* is_generated) {
Etienne Pierre-doray4f2e41bed2018-09-24 22:10:11277 base::AssertLongCPUWorkAllowed();
mlamouribc6e8792015-10-22 20:41:13278
279 JNIEnv* env = base::android::AttachCurrentThread();
280 ScopedJavaLocalRef<jobject> result;
281 *is_generated = false;
282
283 if (!bitmap.isNull()) {
pkotwicz45fc42b62016-06-07 00:07:10284 if (Java_ShortcutHelper_isIconLargeEnoughForLauncher(env, bitmap.width(),
285 bitmap.height())) {
newta584b9e2015-10-29 22:29:43286 ScopedJavaLocalRef<jobject> java_bitmap =
287 gfx::ConvertToJavaBitmap(&bitmap);
Peter E Connb955ae4a2018-12-03 13:02:09288 result = Java_ShortcutHelper_createHomeScreenIconFromWebIcon(
289 env, java_bitmap, is_icon_maskable);
mlamouribc6e8792015-10-22 20:41:13290 }
291 }
292
293 if (result.is_null()) {
294 ScopedJavaLocalRef<jstring> java_url =
295 base::android::ConvertUTF8ToJavaString(env, url.spec());
zpenge33ba852017-02-01 20:54:42296 SkColor mean_color =
297 SkColorSetRGB(g_default_rgb_icon_value, g_default_rgb_icon_value,
298 g_default_rgb_icon_value);
mlamouribc6e8792015-10-22 20:41:13299
300 if (!bitmap.isNull())
301 mean_color = color_utils::CalculateKMeanColorOfBitmap(bitmap);
302
303 *is_generated = true;
newta584b9e2015-10-29 22:29:43304 result = Java_ShortcutHelper_generateHomeScreenIcon(
torne948f3662016-08-16 15:10:44305 env, java_url, SkColorGetR(mean_color), SkColorGetG(mean_color),
mlamouribc6e8792015-10-22 20:41:13306 SkColorGetB(mean_color));
307 }
308
pkotwicz964382b2016-08-04 01:24:55309 return result.obj()
torned64eb5132016-10-24 12:51:28310 ? gfx::CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(result))
pkotwicz964382b2016-08-04 01:24:55311 : SkBitmap();
mlamouribc6e8792015-10-22 20:41:13312}
313
pkotwiczcda82fe2016-07-08 18:56:54314// static
Peter Kotwicz4b358c162019-01-03 01:10:58315std::string ShortcutHelper::QueryFirstWebApkPackage(const GURL& url) {
zpeng4bb58962016-10-04 02:42:29316 JNIEnv* env = base::android::AttachCurrentThread();
317 ScopedJavaLocalRef<jstring> java_url =
318 base::android::ConvertUTF8ToJavaString(env, url.spec());
319 ScopedJavaLocalRef<jstring> java_webapk_package_name =
Peter Kotwicz4b358c162019-01-03 01:10:58320 Java_ShortcutHelper_queryFirstWebApkPackage(env, java_url);
zpeng4bb58962016-10-04 02:42:29321
Lei Zhang9b0be802020-05-05 21:11:48322 std::string webapk_package_name;
zpeng4bb58962016-10-04 02:42:29323 if (java_webapk_package_name.obj()) {
zpenga7856eef2017-02-07 11:42:44324 webapk_package_name =
325 base::android::ConvertJavaStringToUTF8(env, java_webapk_package_name);
zpeng4bb58962016-10-04 02:42:29326 }
327 return webapk_package_name;
328}
329
330// static
zpenga7856eef2017-02-07 11:42:44331bool ShortcutHelper::IsWebApkInstalled(content::BrowserContext* browser_context,
Dominick Ngb1c047e72020-05-04 00:41:10332 const GURL& url) {
333 return !QueryFirstWebApkPackage(url).empty();
Dominick Ngc8244822020-04-29 06:22:30334}
335
336// static
337bool ShortcutHelper::DoesOriginContainAnyInstalledWebApk(const GURL& origin) {
338 DCHECK_EQ(origin, origin.GetOrigin());
339 JNIEnv* env = base::android::AttachCurrentThread();
340 base::android::ScopedJavaLocalRef<jstring> java_origin =
341 base::android::ConvertUTF8ToJavaString(env, origin.spec());
342 return Java_ShortcutHelper_doesOriginContainAnyInstalledWebApk(env,
343 java_origin);
344}
345
346bool ShortcutHelper::DoesOriginContainAnyInstalledTrustedWebActivity(
347 const GURL& origin) {
348 DCHECK_EQ(origin, origin.GetOrigin());
349 JNIEnv* env = base::android::AttachCurrentThread();
350 base::android::ScopedJavaLocalRef<jstring> java_origin =
351 base::android::ConvertUTF8ToJavaString(env, origin.spec());
352 return Java_ShortcutHelper_doesOriginContainAnyInstalledTwa(env, java_origin);
pkotwiczcda82fe2016-07-08 18:56:54353}
354
Jarryd583dc4d2020-06-11 20:31:34355std::set<GURL> ShortcutHelper::GetOriginsWithInstalledWebApksOrTwas() {
356 std::set<GURL> installed_origins;
357 JNIEnv* env = base::android::AttachCurrentThread();
358
359 base::android::ScopedJavaLocalRef<jobjectArray> j_installed_origins =
360 Java_ShortcutHelper_getOriginsWithInstalledWebApksOrTwas(env);
361
362 if (j_installed_origins) {
363 std::vector<std::string> installed_origins_list;
364 base::android::AppendJavaStringArrayToStringVector(env, j_installed_origins,
365 &installed_origins_list);
366 for (auto& origin : installed_origins_list)
367 installed_origins.emplace(GURL(origin));
368 }
369 return installed_origins;
370}
371
ckitagawa1fa69c02019-07-24 19:20:44372void ShortcutHelper::SetForceWebApkUpdate(const std::string& id) {
373 JNIEnv* env = base::android::AttachCurrentThread();
374 Java_ShortcutHelper_setForceWebApkUpdate(
375 env, base::android::ConvertUTF8ToJavaString(env, id));
gonzalon87192d772017-02-07 22:31:10376}
377
Henry Jianf78dce62019-09-22 16:58:41378// static
379bool ShortcutHelper::DoesAndroidSupportMaskableIcons() {
380 return base::FeatureList::IsEnabled(chrome::android::kWebApkAdaptiveIcon) &&
381 base::android::BuildInfo::GetInstance()->sdk_int() >=
382 base::android::SDK_VERSION_OREO;
383}
384
Rayan Kanso3a2f4762020-01-28 13:34:16385// static
386void ShortcutHelper::SetIdealShortcutSizeForTesting(int size) {
387 g_ideal_shortcut_icon_size = size;
388}
389
dominickn6509a4de2016-04-06 08:29:06390// Callback used by Java when the shortcut has been created.
Dominick Ng40be8182019-03-11 23:21:03391// |splash_image_callback| is a pointer to a base::OnceClosure allocated in
pkotwiczc67e6ac2016-08-12 19:56:44392// AddShortcutWithSkBitmap, so reinterpret_cast it back and run it.
dominickn6509a4de2016-04-06 08:29:06393//
394// This callback should only ever be called when the shortcut was for a
395// webapp-capable site; otherwise, |splash_image_callback| will have never been
396// allocated and doesn't need to be run or deleted.
Daniel Bratell7aacf952017-11-21 17:51:25397void JNI_ShortcutHelper_OnWebappDataStored(JNIEnv* env,
Daniel Bratell7aacf952017-11-21 17:51:25398 jlong jsplash_image_callback) {
dominickn6509a4de2016-04-06 08:29:06399 DCHECK(jsplash_image_callback);
Dominick Ng40be8182019-03-11 23:21:03400 base::OnceClosure* splash_image_callback =
401 reinterpret_cast<base::OnceClosure*>(jsplash_image_callback);
402 std::move(*splash_image_callback).Run();
dominickn6509a4de2016-04-06 08:29:06403 delete splash_image_callback;
404}