Fetch splash image earlier during web app installs.
This changes ShortcutHelper to download the splash image for a webapp
while the webapp is being installed, rather than after. If the splash
image is downloaded before the webapp installation process finishes,
the splash image will be stored in a local map until it can be
transferred to the WebappDataStorage object.
This simplifies the code and fixes a potential UAF.
Bug: 1147913
Change-Id: I9405ee9cc304eaf8b9ff2bbaca17c1c63cfd6e65
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2533031
Commit-Queue: Evan Stade <[email protected]>
Reviewed-by: Dominick Ng <[email protected]>
Cr-Commit-Position: refs/heads/master@{#826837}
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc
index b0a680f..768e612 100644
--- a/chrome/browser/android/shortcut_helper.cc
+++ b/chrome/browser/android/shortcut_helper.cc
@@ -74,15 +74,11 @@
}
// Adds a shortcut which opens in a fullscreen window to the launcher.
-// |splash_image_callback| will be invoked once the Java-side operation has
-// completed. This is necessary as Java will asynchronously create and
-// populate a WebappDataStorage object for standalone-capable sites. This must
-// exist before the splash image can be stored.
-void AddWebappWithSkBitmap(const ShortcutInfo& info,
+void AddWebappWithSkBitmap(content::WebContents* web_contents,
+ const ShortcutInfo& info,
const std::string& webapp_id,
const SkBitmap& icon_bitmap,
- bool is_icon_maskable,
- base::OnceClosure splash_image_callback) {
+ bool is_icon_maskable) {
// Send the data to the Java side to create the shortcut.
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jstring> java_webapp_id =
@@ -104,25 +100,23 @@
if (!icon_bitmap.drawsNothing())
java_bitmap = gfx::ConvertToJavaBitmap(icon_bitmap);
- // The callback will need to be run after shortcut creation completes in order
- // to download the splash image and save it to the WebappDataStorage. Create a
- // copy of the callback here and send the pointer to Java, which will send it
- // back once the asynchronous shortcut creation process finishes.
- uintptr_t callback_pointer = reinterpret_cast<uintptr_t>(
- new base::OnceClosure(std::move(splash_image_callback)));
-
Java_ShortcutHelper_addWebapp(
env, java_webapp_id, java_url, java_scope_url, java_user_title, java_name,
java_short_name, java_best_primary_icon_url, java_bitmap,
is_icon_maskable, static_cast<int>(info.display),
static_cast<int>(info.orientation), info.source,
OptionalSkColorToJavaColor(info.theme_color),
- OptionalSkColorToJavaColor(info.background_color), callback_pointer);
+ OptionalSkColorToJavaColor(info.background_color));
+
+ // Start downloading the splash image in parallel with the app install.
+ content::ManifestIconDownloader::Download(
+ web_contents, info.splash_image_url, info.ideal_splash_image_size_in_px,
+ info.minimum_splash_image_size_in_px,
+ base::BindOnce(&ShortcutHelper::StoreWebappSplashImage, webapp_id));
}
// Adds a shortcut which opens in a browser tab to the launcher.
-void AddShortcutWithSkBitmap(content::WebContents* web_contents,
- const ShortcutInfo& info,
+void AddShortcutWithSkBitmap(const ShortcutInfo& info,
const std::string& id,
const SkBitmap& icon_bitmap,
bool is_icon_maskable) {
@@ -180,16 +174,11 @@
if (info.display == blink::mojom::DisplayMode::kStandalone ||
info.display == blink::mojom::DisplayMode::kFullscreen ||
info.display == blink::mojom::DisplayMode::kMinimalUi) {
- AddWebappWithSkBitmap(
- info, webapp_id, icon_bitmap, is_icon_maskable,
- base::BindOnce(&ShortcutHelper::FetchSplashScreenImage, web_contents,
- info.splash_image_url,
- info.ideal_splash_image_size_in_px,
- info.minimum_splash_image_size_in_px, webapp_id));
+ AddWebappWithSkBitmap(web_contents, info, webapp_id, icon_bitmap,
+ is_icon_maskable);
return;
}
- AddShortcutWithSkBitmap(web_contents, info, webapp_id, icon_bitmap,
- is_icon_maskable);
+ AddShortcutWithSkBitmap(info, webapp_id, icon_bitmap, is_icon_maskable);
}
void ShortcutHelper::ShowWebApkInstallInProgressToast() {
@@ -234,21 +223,6 @@
}
// static
-void ShortcutHelper::FetchSplashScreenImage(
- content::WebContents* web_contents,
- const GURL& image_url,
- const int ideal_splash_image_size_in_px,
- const int minimum_splash_image_size_in_px,
- const std::string& webapp_id) {
- // This is a fire and forget task. It is not vital for the splash screen image
- // to be downloaded so if the downloader returns false there is no fallback.
- content::ManifestIconDownloader::Download(
- web_contents, image_url, ideal_splash_image_size_in_px,
- minimum_splash_image_size_in_px,
- base::BindOnce(&ShortcutHelper::StoreWebappSplashImage, webapp_id));
-}
-
-// static
void ShortcutHelper::StoreWebappSplashImage(const std::string& webapp_id,
const SkBitmap& splash_image) {
if (splash_image.drawsNothing())
@@ -382,19 +356,3 @@
void ShortcutHelper::SetIdealShortcutSizeForTesting(int size) {
g_ideal_shortcut_icon_size = size;
}
-
-// Callback used by Java when the shortcut has been created.
-// |splash_image_callback| is a pointer to a base::OnceClosure allocated in
-// AddShortcutWithSkBitmap, so reinterpret_cast it back and run it.
-//
-// This callback should only ever be called when the shortcut was for a
-// webapp-capable site; otherwise, |splash_image_callback| will have never been
-// allocated and doesn't need to be run or deleted.
-void JNI_ShortcutHelper_OnWebappDataStored(JNIEnv* env,
- jlong jsplash_image_callback) {
- DCHECK(jsplash_image_callback);
- base::OnceClosure* splash_image_callback =
- reinterpret_cast<base::OnceClosure*>(jsplash_image_callback);
- std::move(*splash_image_callback).Run();
- delete splash_image_callback;
-}
diff --git a/chrome/browser/android/shortcut_helper.h b/chrome/browser/android/shortcut_helper.h
index c7dedb54..9d4f1703 100644
--- a/chrome/browser/android/shortcut_helper.h
+++ b/chrome/browser/android/shortcut_helper.h
@@ -66,16 +66,6 @@
// Returns the ideal size for a shortcut icon of a WebAPK.
static int GetIdealShortcutIconSizeInPx();
- // Fetches the splash screen image and stores it inside the WebappDataStorage
- // of the webapp. The WebappDataStorage object *must* have been previously
- // created by AddToLauncherWithSkBitmap(); this method should be passed as a
- // closure to that method.
- static void FetchSplashScreenImage(content::WebContents* web_contents,
- const GURL& image_url,
- const int ideal_splash_image_size_in_px,
- const int minimum_splash_image_size_in_px,
- const std::string& webapp_id);
-
// Stores the webapp splash screen in the WebappDataStorage associated with
// |webapp_id|.
static void StoreWebappSplashImage(const std::string& webapp_id,