[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "chrome/browser/android/shortcut_helper.h" |
| 6 | |
| 7 | #include <jni.h> |
gonzalon | 87192d77 | 2017-02-07 22:31:10 | [diff] [blame] | 8 | #include <utility> |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 9 | |
Henry Jian | f78dce6 | 2019-09-22 16:58:41 | [diff] [blame] | 10 | #include "base/android/build_info.h" |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 11 | #include "base/android/jni_android.h" |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 12 | #include "base/android/jni_array.h" |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 13 | #include "base/android/jni_string.h" |
dominickn | 6509a4de | 2016-04-06 08:29:06 | [diff] [blame] | 14 | #include "base/bind.h" |
| 15 | #include "base/callback.h" |
pkotwicz | d0d459e | 2017-03-01 22:55:10 | [diff] [blame] | 16 | #include "base/guid.h" |
Daniel Cheng | 8fedab2 | 2018-05-17 00:39:27 | [diff] [blame] | 17 | #include "base/optional.h" |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 18 | #include "base/strings/string16.h" |
mlamouri | c679bbf | 2014-09-24 21:24:49 | [diff] [blame] | 19 | #include "base/strings/utf_string_conversions.h" |
Etienne Pierre-doray | 4f2e41bed | 2018-09-24 22:10:11 | [diff] [blame] | 20 | #include "base/threading/thread_restrictions.h" |
Andrew Grieve | 4a42c22e | 2019-06-24 16:14:29 | [diff] [blame] | 21 | #include "chrome/android/chrome_jni_headers/ShortcutHelper_jni.h" |
dfalcantara | aec56da | 2015-05-06 03:33:56 | [diff] [blame] | 22 | #include "content/public/browser/browser_thread.h" |
jinho.bang | 84cadc8 | 2017-06-14 16:59:34 | [diff] [blame] | 23 | #include "content/public/browser/manifest_icon_downloader.h" |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 24 | #include "content/public/browser/web_contents.h" |
Dmitry Gozman | 88ca5a99 | 2018-05-18 00:13:33 | [diff] [blame] | 25 | #include "third_party/blink/public/common/manifest/manifest.h" |
Mugdha Lakhani | 62db8de | 2018-07-10 16:00:48 | [diff] [blame] | 26 | #include "third_party/blink/public/common/manifest/manifest_icon_selector.h" |
Daniel Cheng | 8fedab2 | 2018-05-17 00:39:27 | [diff] [blame] | 27 | #include "third_party/skia/include/core/SkColor.h" |
Evan Stade | 7f683b76 | 2020-11-18 01:22:26 | [diff] [blame] | 28 | #include "ui/android/color_helpers.h" |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 29 | #include "ui/gfx/android/java_bitmap.h" |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 30 | #include "ui/gfx/color_analysis.h" |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 31 | #include "url/gurl.h" |
| 32 | |
torne | 8656011 | 2016-08-04 15:59:04 | [diff] [blame] | 33 | using base::android::JavaParamRef; |
| 34 | using base::android::ScopedJavaLocalRef; |
mlamouri | c679bbf | 2014-09-24 21:24:49 | [diff] [blame] | 35 | |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 36 | namespace { |
| 37 | |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 38 | int g_ideal_homescreen_icon_size = -1; |
| 39 | int g_minimum_homescreen_icon_size = -1; |
| 40 | int g_ideal_splash_image_size = -1; |
| 41 | int g_minimum_splash_image_size = -1; |
Glen Robertson | 41d3c0f | 2020-07-15 03:42:15 | [diff] [blame] | 42 | int g_ideal_monochrome_icon_size = -1; |
Henry Jian | 96ec251 | 2019-09-13 00:34:09 | [diff] [blame] | 43 | int g_ideal_adaptive_launcher_icon_size = -1; |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 44 | int g_ideal_shortcut_icon_size = -1; |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 45 | |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 46 | int g_default_rgb_icon_value = 145; |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 47 | |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 48 | // Retrieves and caches the ideal and minimum sizes of the Home screen icon, |
| 49 | // the splash screen image, and the shortcut icons. |
| 50 | void GetIconSizes() { |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 51 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 52 | ScopedJavaLocalRef<jintArray> java_size_array = |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 53 | Java_ShortcutHelper_getIconSizes(env); |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 54 | std::vector<int> sizes; |
Torne (Richard Coles) | 3c22e830 | 2018-10-12 18:34:22 | [diff] [blame] | 55 | base::android::JavaIntArrayToIntVector(env, java_size_array, &sizes); |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 56 | |
| 57 | // Check that the size returned is what is expected. |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 58 | DCHECK_EQ(7u, sizes.size()); |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 59 | |
| 60 | // This ordering must be kept up to date with the Java ShortcutHelper. |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 61 | g_ideal_homescreen_icon_size = sizes[0]; |
| 62 | g_minimum_homescreen_icon_size = sizes[1]; |
| 63 | g_ideal_splash_image_size = sizes[2]; |
| 64 | g_minimum_splash_image_size = sizes[3]; |
Glen Robertson | 41d3c0f | 2020-07-15 03:42:15 | [diff] [blame] | 65 | g_ideal_monochrome_icon_size = sizes[4]; |
Henry Jian | 96ec251 | 2019-09-13 00:34:09 | [diff] [blame] | 66 | g_ideal_adaptive_launcher_icon_size = sizes[5]; |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 67 | g_ideal_shortcut_icon_size = sizes[6]; |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 68 | |
| 69 | // Try to ensure that the data returned is sane. |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 70 | DCHECK(g_minimum_homescreen_icon_size <= g_ideal_homescreen_icon_size); |
| 71 | DCHECK(g_minimum_splash_image_size <= g_ideal_splash_image_size); |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 72 | } |
| 73 | |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 74 | // Adds a shortcut which opens in a fullscreen window to the launcher. |
Evan Stade | e978d2c | 2020-11-12 17:52:50 | [diff] [blame] | 75 | void AddWebappWithSkBitmap(content::WebContents* web_contents, |
| 76 | const ShortcutInfo& info, |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 77 | const std::string& webapp_id, |
| 78 | const SkBitmap& icon_bitmap, |
Evan Stade | e978d2c | 2020-11-12 17:52:50 | [diff] [blame] | 79 | bool is_icon_maskable) { |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 80 | // Send the data to the Java side to create the shortcut. |
| 81 | JNIEnv* env = base::android::AttachCurrentThread(); |
lalitm | d93c2ed | 2015-09-04 16:22:12 | [diff] [blame] | 82 | ScopedJavaLocalRef<jstring> java_webapp_id = |
| 83 | base::android::ConvertUTF8ToJavaString(env, webapp_id); |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 84 | ScopedJavaLocalRef<jstring> java_url = |
dfalcantara | 16e84de | 2015-02-03 22:07:40 | [diff] [blame] | 85 | base::android::ConvertUTF8ToJavaString(env, info.url.spec()); |
pkotwicz | 6bdfbe1b | 2016-07-08 00:26:43 | [diff] [blame] | 86 | ScopedJavaLocalRef<jstring> java_scope_url = |
| 87 | base::android::ConvertUTF8ToJavaString(env, info.scope.spec()); |
lalitm | f3ee5185 | 2015-07-21 18:13:11 | [diff] [blame] | 88 | 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); |
zpeng | a7856eef | 2017-02-07 11:42:44 | [diff] [blame] | 94 | ScopedJavaLocalRef<jstring> java_best_primary_icon_url = |
| 95 | base::android::ConvertUTF8ToJavaString(env, |
| 96 | info.best_primary_icon_url.spec()); |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 97 | ScopedJavaLocalRef<jobject> java_bitmap; |
zpeng | febce761 | 2017-06-07 14:29:04 | [diff] [blame] | 98 | if (!icon_bitmap.drawsNothing()) |
danakj | 5cc14ce | 2020-11-10 22:00:40 | [diff] [blame] | 99 | java_bitmap = gfx::ConvertToJavaBitmap(icon_bitmap); |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 100 | |
zpeng | a7856eef | 2017-02-07 11:42:44 | [diff] [blame] | 101 | Java_ShortcutHelper_addWebapp( |
| 102 | env, java_webapp_id, java_url, java_scope_url, java_user_title, java_name, |
Peter E Conn | b955ae4a | 2018-12-03 13:02:09 | [diff] [blame] | 103 | java_short_name, java_best_primary_icon_url, java_bitmap, |
Dave Tapuska | 36eb28d | 2020-07-14 20:59:06 | [diff] [blame] | 104 | is_icon_maskable, static_cast<int>(info.display), |
| 105 | static_cast<int>(info.orientation), info.source, |
Evan Stade | 7f683b76 | 2020-11-18 01:22:26 | [diff] [blame] | 106 | ui::OptionalSkColorToJavaColor(info.theme_color), |
| 107 | ui::OptionalSkColorToJavaColor(info.background_color)); |
Evan Stade | e978d2c | 2020-11-12 17:52:50 | [diff] [blame] | 108 | |
| 109 | // Start downloading the splash image in parallel with the app install. |
| 110 | content::ManifestIconDownloader::Download( |
| 111 | web_contents, info.splash_image_url, info.ideal_splash_image_size_in_px, |
| 112 | info.minimum_splash_image_size_in_px, |
| 113 | base::BindOnce(&ShortcutHelper::StoreWebappSplashImage, webapp_id)); |
[email protected] | 5120825 | 2013-08-19 21:05:30 | [diff] [blame] | 114 | } |
benwells | 840ae90 | 2015-02-17 21:13:28 | [diff] [blame] | 115 | |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 116 | // Adds a shortcut which opens in a browser tab to the launcher. |
Evan Stade | e978d2c | 2020-11-12 17:52:50 | [diff] [blame] | 117 | void AddShortcutWithSkBitmap(const ShortcutInfo& info, |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 118 | const std::string& id, |
Peter E Conn | b955ae4a | 2018-12-03 13:02:09 | [diff] [blame] | 119 | const SkBitmap& icon_bitmap, |
| 120 | bool is_icon_maskable) { |
pkotwicz | 20667314 | 2016-07-19 19:13:30 | [diff] [blame] | 121 | JNIEnv* env = base::android::AttachCurrentThread(); |
martiw | 12166f5 | 2017-02-20 03:05:45 | [diff] [blame] | 122 | ScopedJavaLocalRef<jstring> java_id = |
| 123 | base::android::ConvertUTF8ToJavaString(env, id); |
pkotwicz | 20667314 | 2016-07-19 19:13:30 | [diff] [blame] | 124 | ScopedJavaLocalRef<jstring> java_url = |
| 125 | base::android::ConvertUTF8ToJavaString(env, info.url.spec()); |
| 126 | ScopedJavaLocalRef<jstring> java_user_title = |
| 127 | base::android::ConvertUTF16ToJavaString(env, info.user_title); |
Michael Thiessen | e01199c94 | 2019-06-25 16:32:53 | [diff] [blame] | 128 | ScopedJavaLocalRef<jstring> java_best_primary_icon_url = |
| 129 | base::android::ConvertUTF8ToJavaString(env, |
| 130 | info.best_primary_icon_url.spec()); |
pkotwicz | 20667314 | 2016-07-19 19:13:30 | [diff] [blame] | 131 | ScopedJavaLocalRef<jobject> java_bitmap; |
zpeng | febce761 | 2017-06-07 14:29:04 | [diff] [blame] | 132 | if (!icon_bitmap.drawsNothing()) |
danakj | 5cc14ce | 2020-11-10 22:00:40 | [diff] [blame] | 133 | java_bitmap = gfx::ConvertToJavaBitmap(icon_bitmap); |
Evan Stade | d7392a79 | 2020-07-16 20:59:21 | [diff] [blame] | 134 | Java_ShortcutHelper_addShortcut(env, java_id, java_url, java_user_title, |
Michael Thiessen | e01199c94 | 2019-06-25 16:32:53 | [diff] [blame] | 135 | java_bitmap, is_icon_maskable, info.source, |
| 136 | java_best_primary_icon_url); |
pkotwicz | 20667314 | 2016-07-19 19:13:30 | [diff] [blame] | 137 | } |
| 138 | |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 139 | } // anonymous namespace |
| 140 | |
| 141 | // static |
Dominick Ng | 203b493 | 2018-02-02 05:32:45 | [diff] [blame] | 142 | std::unique_ptr<ShortcutInfo> ShortcutHelper::CreateShortcutInfo( |
| 143 | const GURL& manifest_url, |
Dmitry Gozman | 88ca5a99 | 2018-05-18 00:13:33 | [diff] [blame] | 144 | const blink::Manifest& manifest, |
Ella Ge | efae3e00 | 2020-02-25 00:53:45 | [diff] [blame] | 145 | const GURL& primary_icon_url) { |
Dominick Ng | 203b493 | 2018-02-02 05:32:45 | [diff] [blame] | 146 | auto shortcut_info = std::make_unique<ShortcutInfo>(GURL()); |
| 147 | if (!manifest.IsEmpty()) { |
| 148 | shortcut_info->UpdateFromManifest(manifest); |
| 149 | shortcut_info->manifest_url = manifest_url; |
| 150 | shortcut_info->best_primary_icon_url = primary_icon_url; |
Dominick Ng | 203b493 | 2018-02-02 05:32:45 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | shortcut_info->ideal_splash_image_size_in_px = GetIdealSplashImageSizeInPx(); |
| 154 | shortcut_info->minimum_splash_image_size_in_px = |
| 155 | GetMinimumSplashImageSizeInPx(); |
| 156 | shortcut_info->splash_image_url = |
Sahel Sharify | c067b74f | 2019-04-17 23:19:07 | [diff] [blame] | 157 | blink::ManifestIconSelector::FindBestMatchingSquareIcon( |
Dominick Ng | 203b493 | 2018-02-02 05:32:45 | [diff] [blame] | 158 | manifest.icons, shortcut_info->ideal_splash_image_size_in_px, |
| 159 | shortcut_info->minimum_splash_image_size_in_px, |
Gyuyoung Kim | 361bbfe | 2020-10-28 00:21:10 | [diff] [blame] | 160 | blink::mojom::ManifestImageResource_Purpose::ANY); |
Dominick Ng | 203b493 | 2018-02-02 05:32:45 | [diff] [blame] | 161 | |
| 162 | return shortcut_info; |
| 163 | } |
| 164 | |
| 165 | // static |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 166 | void ShortcutHelper::AddToLauncherWithSkBitmap( |
pkotwicz | d0d459e | 2017-03-01 22:55:10 | [diff] [blame] | 167 | content::WebContents* web_contents, |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 168 | const ShortcutInfo& info, |
Peter E Conn | b955ae4a | 2018-12-03 13:02:09 | [diff] [blame] | 169 | const SkBitmap& icon_bitmap, |
| 170 | bool is_icon_maskable) { |
pkotwicz | d0d459e | 2017-03-01 22:55:10 | [diff] [blame] | 171 | std::string webapp_id = base::GenerateGUID(); |
Eric Willigers | 052f043 | 2019-10-04 04:06:57 | [diff] [blame] | 172 | if (info.display == blink::mojom::DisplayMode::kStandalone || |
| 173 | info.display == blink::mojom::DisplayMode::kFullscreen || |
| 174 | info.display == blink::mojom::DisplayMode::kMinimalUi) { |
Evan Stade | e978d2c | 2020-11-12 17:52:50 | [diff] [blame] | 175 | AddWebappWithSkBitmap(web_contents, info, webapp_id, icon_bitmap, |
| 176 | is_icon_maskable); |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 177 | return; |
| 178 | } |
Evan Stade | e978d2c | 2020-11-12 17:52:50 | [diff] [blame] | 179 | AddShortcutWithSkBitmap(info, webapp_id, icon_bitmap, is_icon_maskable); |
pkotwicz | 9747871 | 2017-03-01 03:39:54 | [diff] [blame] | 180 | } |
| 181 | |
hanxi | 070d10a | 2017-01-09 15:56:50 | [diff] [blame] | 182 | void ShortcutHelper::ShowWebApkInstallInProgressToast() { |
| 183 | Java_ShortcutHelper_showWebApkInstallInProgressToast( |
| 184 | base::android::AttachCurrentThread()); |
| 185 | } |
| 186 | |
zpeng | 5d8fdfc | 2017-01-05 15:45:06 | [diff] [blame] | 187 | int ShortcutHelper::GetIdealHomescreenIconSizeInPx() { |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 188 | if (g_ideal_homescreen_icon_size == -1) |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 189 | GetIconSizes(); |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 190 | return g_ideal_homescreen_icon_size; |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 191 | } |
| 192 | |
zpeng | 5d8fdfc | 2017-01-05 15:45:06 | [diff] [blame] | 193 | int ShortcutHelper::GetMinimumHomescreenIconSizeInPx() { |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 194 | if (g_minimum_homescreen_icon_size == -1) |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 195 | GetIconSizes(); |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 196 | return g_minimum_homescreen_icon_size; |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 197 | } |
| 198 | |
zpeng | 5d8fdfc | 2017-01-05 15:45:06 | [diff] [blame] | 199 | int ShortcutHelper::GetIdealSplashImageSizeInPx() { |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 200 | if (g_ideal_splash_image_size == -1) |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 201 | GetIconSizes(); |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 202 | return g_ideal_splash_image_size; |
lalitm | 45a03c7 | 2015-09-16 13:00:43 | [diff] [blame] | 203 | } |
| 204 | |
zpeng | 5d8fdfc | 2017-01-05 15:45:06 | [diff] [blame] | 205 | int ShortcutHelper::GetMinimumSplashImageSizeInPx() { |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 206 | if (g_minimum_splash_image_size == -1) |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 207 | GetIconSizes(); |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 208 | return g_minimum_splash_image_size; |
| 209 | } |
| 210 | |
Henry Jian | 96ec251 | 2019-09-13 00:34:09 | [diff] [blame] | 211 | int ShortcutHelper::GetIdealAdaptiveLauncherIconSizeInPx() { |
| 212 | if (g_ideal_adaptive_launcher_icon_size == -1) |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 213 | GetIconSizes(); |
Henry Jian | 96ec251 | 2019-09-13 00:34:09 | [diff] [blame] | 214 | return g_ideal_adaptive_launcher_icon_size; |
| 215 | } |
| 216 | |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 217 | int ShortcutHelper::GetIdealShortcutIconSizeInPx() { |
| 218 | if (g_ideal_shortcut_icon_size == -1) |
| 219 | GetIconSizes(); |
| 220 | return g_ideal_shortcut_icon_size; |
| 221 | } |
| 222 | |
lalitm | d93c2ed | 2015-09-04 16:22:12 | [diff] [blame] | 223 | // static |
zpeng | a7856eef | 2017-02-07 11:42:44 | [diff] [blame] | 224 | void ShortcutHelper::StoreWebappSplashImage(const std::string& webapp_id, |
| 225 | const SkBitmap& splash_image) { |
lalitm | d93c2ed | 2015-09-04 16:22:12 | [diff] [blame] | 226 | if (splash_image.drawsNothing()) |
| 227 | return; |
| 228 | |
| 229 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 230 | ScopedJavaLocalRef<jstring> java_webapp_id = |
| 231 | base::android::ConvertUTF8ToJavaString(env, webapp_id); |
| 232 | ScopedJavaLocalRef<jobject> java_splash_image = |
danakj | 5cc14ce | 2020-11-10 22:00:40 | [diff] [blame] | 233 | gfx::ConvertToJavaBitmap(splash_image); |
lalitm | d93c2ed | 2015-09-04 16:22:12 | [diff] [blame] | 234 | |
torne | 948f366 | 2016-08-16 15:10:44 | [diff] [blame] | 235 | Java_ShortcutHelper_storeWebappSplashImage(env, java_webapp_id, |
| 236 | java_splash_image); |
lalitm | d93c2ed | 2015-09-04 16:22:12 | [diff] [blame] | 237 | } |
| 238 | |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 239 | // static |
pkotwicz | 5774087e | 2016-08-10 17:36:40 | [diff] [blame] | 240 | SkBitmap ShortcutHelper::FinalizeLauncherIconInBackground( |
| 241 | const SkBitmap& bitmap, |
Peter E Conn | b955ae4a | 2018-12-03 13:02:09 | [diff] [blame] | 242 | bool is_icon_maskable, |
pkotwicz | 5774087e | 2016-08-10 17:36:40 | [diff] [blame] | 243 | const GURL& url, |
| 244 | bool* is_generated) { |
Etienne Pierre-doray | 4f2e41bed | 2018-09-24 22:10:11 | [diff] [blame] | 245 | base::AssertLongCPUWorkAllowed(); |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 246 | |
| 247 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 248 | ScopedJavaLocalRef<jobject> result; |
| 249 | *is_generated = false; |
| 250 | |
| 251 | if (!bitmap.isNull()) { |
pkotwicz | 45fc42b6 | 2016-06-07 00:07:10 | [diff] [blame] | 252 | if (Java_ShortcutHelper_isIconLargeEnoughForLauncher(env, bitmap.width(), |
| 253 | bitmap.height())) { |
newt | a584b9e | 2015-10-29 22:29:43 | [diff] [blame] | 254 | ScopedJavaLocalRef<jobject> java_bitmap = |
danakj | 5cc14ce | 2020-11-10 22:00:40 | [diff] [blame] | 255 | gfx::ConvertToJavaBitmap(bitmap); |
Peter E Conn | b955ae4a | 2018-12-03 13:02:09 | [diff] [blame] | 256 | result = Java_ShortcutHelper_createHomeScreenIconFromWebIcon( |
| 257 | env, java_bitmap, is_icon_maskable); |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 258 | } |
| 259 | } |
| 260 | |
| 261 | if (result.is_null()) { |
| 262 | ScopedJavaLocalRef<jstring> java_url = |
| 263 | base::android::ConvertUTF8ToJavaString(env, url.spec()); |
zpeng | e33ba85 | 2017-02-01 20:54:42 | [diff] [blame] | 264 | SkColor mean_color = |
| 265 | SkColorSetRGB(g_default_rgb_icon_value, g_default_rgb_icon_value, |
| 266 | g_default_rgb_icon_value); |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 267 | |
| 268 | if (!bitmap.isNull()) |
| 269 | mean_color = color_utils::CalculateKMeanColorOfBitmap(bitmap); |
| 270 | |
| 271 | *is_generated = true; |
newt | a584b9e | 2015-10-29 22:29:43 | [diff] [blame] | 272 | result = Java_ShortcutHelper_generateHomeScreenIcon( |
torne | 948f366 | 2016-08-16 15:10:44 | [diff] [blame] | 273 | env, java_url, SkColorGetR(mean_color), SkColorGetG(mean_color), |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 274 | SkColorGetB(mean_color)); |
| 275 | } |
| 276 | |
pkotwicz | 964382b | 2016-08-04 01:24:55 | [diff] [blame] | 277 | return result.obj() |
torne | d64eb513 | 2016-10-24 12:51:28 | [diff] [blame] | 278 | ? gfx::CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(result)) |
pkotwicz | 964382b | 2016-08-04 01:24:55 | [diff] [blame] | 279 | : SkBitmap(); |
mlamouri | bc6e879 | 2015-10-22 20:41:13 | [diff] [blame] | 280 | } |
| 281 | |
pkotwicz | cda82fe | 2016-07-08 18:56:54 | [diff] [blame] | 282 | // static |
Peter Kotwicz | 4b358c16 | 2019-01-03 01:10:58 | [diff] [blame] | 283 | std::string ShortcutHelper::QueryFirstWebApkPackage(const GURL& url) { |
zpeng | 4bb5896 | 2016-10-04 02:42:29 | [diff] [blame] | 284 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 285 | ScopedJavaLocalRef<jstring> java_url = |
| 286 | base::android::ConvertUTF8ToJavaString(env, url.spec()); |
| 287 | ScopedJavaLocalRef<jstring> java_webapk_package_name = |
Peter Kotwicz | 4b358c16 | 2019-01-03 01:10:58 | [diff] [blame] | 288 | Java_ShortcutHelper_queryFirstWebApkPackage(env, java_url); |
zpeng | 4bb5896 | 2016-10-04 02:42:29 | [diff] [blame] | 289 | |
Lei Zhang | 9b0be80 | 2020-05-05 21:11:48 | [diff] [blame] | 290 | std::string webapk_package_name; |
zpeng | 4bb5896 | 2016-10-04 02:42:29 | [diff] [blame] | 291 | if (java_webapk_package_name.obj()) { |
zpeng | a7856eef | 2017-02-07 11:42:44 | [diff] [blame] | 292 | webapk_package_name = |
| 293 | base::android::ConvertJavaStringToUTF8(env, java_webapk_package_name); |
zpeng | 4bb5896 | 2016-10-04 02:42:29 | [diff] [blame] | 294 | } |
| 295 | return webapk_package_name; |
| 296 | } |
| 297 | |
| 298 | // static |
zpeng | a7856eef | 2017-02-07 11:42:44 | [diff] [blame] | 299 | bool ShortcutHelper::IsWebApkInstalled(content::BrowserContext* browser_context, |
Dominick Ng | b1c047e7 | 2020-05-04 00:41:10 | [diff] [blame] | 300 | const GURL& url) { |
| 301 | return !QueryFirstWebApkPackage(url).empty(); |
Dominick Ng | c824482 | 2020-04-29 06:22:30 | [diff] [blame] | 302 | } |
| 303 | |
| 304 | // static |
| 305 | bool ShortcutHelper::DoesOriginContainAnyInstalledWebApk(const GURL& origin) { |
| 306 | DCHECK_EQ(origin, origin.GetOrigin()); |
| 307 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 308 | base::android::ScopedJavaLocalRef<jstring> java_origin = |
| 309 | base::android::ConvertUTF8ToJavaString(env, origin.spec()); |
| 310 | return Java_ShortcutHelper_doesOriginContainAnyInstalledWebApk(env, |
| 311 | java_origin); |
| 312 | } |
| 313 | |
| 314 | bool ShortcutHelper::DoesOriginContainAnyInstalledTrustedWebActivity( |
| 315 | const GURL& origin) { |
| 316 | DCHECK_EQ(origin, origin.GetOrigin()); |
| 317 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 318 | base::android::ScopedJavaLocalRef<jstring> java_origin = |
| 319 | base::android::ConvertUTF8ToJavaString(env, origin.spec()); |
| 320 | return Java_ShortcutHelper_doesOriginContainAnyInstalledTwa(env, java_origin); |
pkotwicz | cda82fe | 2016-07-08 18:56:54 | [diff] [blame] | 321 | } |
| 322 | |
Jarryd | 583dc4d | 2020-06-11 20:31:34 | [diff] [blame] | 323 | std::set<GURL> ShortcutHelper::GetOriginsWithInstalledWebApksOrTwas() { |
| 324 | std::set<GURL> installed_origins; |
| 325 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 326 | |
| 327 | base::android::ScopedJavaLocalRef<jobjectArray> j_installed_origins = |
| 328 | Java_ShortcutHelper_getOriginsWithInstalledWebApksOrTwas(env); |
| 329 | |
| 330 | if (j_installed_origins) { |
| 331 | std::vector<std::string> installed_origins_list; |
| 332 | base::android::AppendJavaStringArrayToStringVector(env, j_installed_origins, |
| 333 | &installed_origins_list); |
| 334 | for (auto& origin : installed_origins_list) |
| 335 | installed_origins.emplace(GURL(origin)); |
| 336 | } |
| 337 | return installed_origins; |
| 338 | } |
| 339 | |
ckitagawa | 1fa69c0 | 2019-07-24 19:20:44 | [diff] [blame] | 340 | void ShortcutHelper::SetForceWebApkUpdate(const std::string& id) { |
| 341 | JNIEnv* env = base::android::AttachCurrentThread(); |
| 342 | Java_ShortcutHelper_setForceWebApkUpdate( |
| 343 | env, base::android::ConvertUTF8ToJavaString(env, id)); |
gonzalon | 87192d77 | 2017-02-07 22:31:10 | [diff] [blame] | 344 | } |
| 345 | |
Henry Jian | f78dce6 | 2019-09-22 16:58:41 | [diff] [blame] | 346 | // static |
| 347 | bool ShortcutHelper::DoesAndroidSupportMaskableIcons() { |
Evan Stade | d493350 | 2020-11-17 18:14:45 | [diff] [blame] | 348 | return base::android::BuildInfo::GetInstance()->sdk_int() >= |
| 349 | base::android::SDK_VERSION_OREO; |
Henry Jian | f78dce6 | 2019-09-22 16:58:41 | [diff] [blame] | 350 | } |
| 351 | |
Rayan Kanso | 3a2f476 | 2020-01-28 13:34:16 | [diff] [blame] | 352 | // static |
| 353 | void ShortcutHelper::SetIdealShortcutSizeForTesting(int size) { |
| 354 | g_ideal_shortcut_icon_size = size; |
| 355 | } |