diff options
| author | 2023-06-07 21:18:19 -0700 | |
|---|---|---|
| committer | 2023-06-07 21:33:42 -0700 | |
| commit | 6ccc32c949215ab372ca58fadcf6ee830d29cef3 (patch) | |
| tree | bbd74b43aacdbfdfbb3818c285a9b3a6c4985e1b /java/src | |
| parent | 32c149cf885b52579c102875e33d7e596f8fa9cd (diff) | |
Check shortcut icon validity
Check if a shortcut icon is available for the curent user.
This is important for callter provided targets (see
Intent#EXTRA_CHOOSER_TARGETS) which icons are specified by the calling
app.
Bug: 277207798
Test: manual testing with some debug code injections and a custom test
app.
Change-Id: Idcf7f415abb77b585fddbc26e887909b07c8af17
Diffstat (limited to 'java/src')
3 files changed, 31 insertions, 17 deletions
diff --git a/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt b/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt index 0414dea7..0e4d0209 100644 --- a/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt +++ b/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt @@ -86,7 +86,6 @@ class DefaultTargetDataLoader( LoadDirectShareIconTask( context.createContextAsUser(userHandle, 0), info, - userHandle, presentationFactory, ) { result -> removeTask(taskId) diff --git a/java/src/com/android/intentresolver/icons/LoadDirectShareIconTask.java b/java/src/com/android/intentresolver/icons/LoadDirectShareIconTask.java index b7bacc90..6aee69b5 100644 --- a/java/src/com/android/intentresolver/icons/LoadDirectShareIconTask.java +++ b/java/src/com/android/intentresolver/icons/LoadDirectShareIconTask.java @@ -28,7 +28,6 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.os.Trace; -import android.os.UserHandle; import android.util.Log; import androidx.annotation.WorkerThread; @@ -36,6 +35,7 @@ import androidx.annotation.WorkerThread; import com.android.intentresolver.SimpleIconFactory; import com.android.intentresolver.TargetPresentationGetter; import com.android.intentresolver.chooser.SelectableTargetInfo; +import com.android.intentresolver.util.UriFilters; import java.util.function.Consumer; @@ -49,7 +49,6 @@ class LoadDirectShareIconTask extends BaseLoadIconTask { LoadDirectShareIconTask( Context context, SelectableTargetInfo targetInfo, - UserHandle userHandle, TargetPresentationGetter.Factory presentationFactory, Consumer<Drawable> callback) { super(context, presentationFactory, callback); @@ -61,11 +60,18 @@ class LoadDirectShareIconTask extends BaseLoadIconTask { Drawable drawable; Trace.beginSection("shortcut-icon"); try { - drawable = getChooserTargetIconDrawable( - mContext, - mTargetInfo.getChooserTargetIcon(), - mTargetInfo.getChooserTargetComponentName(), - mTargetInfo.getDirectShareShortcutInfo()); + final Icon icon = mTargetInfo.getChooserTargetIcon(); + if (icon == null || UriFilters.hasValidIcon(icon)) { + drawable = getChooserTargetIconDrawable( + mContext, + icon, + mTargetInfo.getChooserTargetComponentName(), + mTargetInfo.getDirectShareShortcutInfo()); + } else { + Log.e(TAG, "Failed to load shortcut icon for " + + mTargetInfo.getChooserTargetComponentName() + "; no access"); + drawable = loadIconPlaceholder(); + } } catch (Exception e) { Log.e( TAG, diff --git a/java/src/com/android/intentresolver/util/UriFilters.kt b/java/src/com/android/intentresolver/util/UriFilters.kt index 8714c314..a4c6e574 100644 --- a/java/src/com/android/intentresolver/util/UriFilters.kt +++ b/java/src/com/android/intentresolver/util/UriFilters.kt @@ -19,6 +19,7 @@ package com.android.intentresolver.util import android.content.ContentProvider.getUserIdFromUri import android.content.ContentResolver.SCHEME_CONTENT +import android.graphics.drawable.Icon import android.graphics.drawable.Icon.TYPE_URI import android.graphics.drawable.Icon.TYPE_URI_ADAPTIVE_BITMAP import android.net.Uri @@ -38,13 +39,14 @@ import android.service.chooser.ChooserAction */ val Uri?.ownedByCurrentUser: Boolean @JvmName("isOwnedByCurrentUser") - get() = this?.let { - when (getUserIdFromUri(this, UserHandle.USER_CURRENT)) { - UserHandle.USER_CURRENT, - UserHandle.myUserId() -> true - else -> false - } - } == true + get() = + this?.let { + when (getUserIdFromUri(this, UserHandle.USER_CURRENT)) { + UserHandle.USER_CURRENT, + UserHandle.myUserId() -> true + else -> false + } + } == true /** Does the [Uri] reference a content provider ('content://')? */ internal val Uri.contentScheme: Boolean @@ -56,8 +58,15 @@ internal val Uri.contentScheme: Boolean * @param action the chooser action * @see [Uri.ownedByCurrentUser] */ -fun hasValidIcon(action: ChooserAction) = - with(action.icon) { +fun hasValidIcon(action: ChooserAction) = hasValidIcon(action.icon) + +/** + * Checks if the Icon backed by content:// [Uri] is safe for display. + * + * @see [Uri.ownedByCurrentUser] + */ +fun hasValidIcon(icon: Icon) = + with(icon) { when (type) { TYPE_URI, TYPE_URI_ADAPTIVE_BITMAP -> !uri.contentScheme || uri.ownedByCurrentUser |