summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2023-06-07 21:18:19 -0700
committer Andrey Epin <ayepin@google.com> 2023-06-07 21:33:42 -0700
commit6ccc32c949215ab372ca58fadcf6ee830d29cef3 (patch)
treebbd74b43aacdbfdfbb3818c285a9b3a6c4985e1b /java/src
parent32c149cf885b52579c102875e33d7e596f8fa9cd (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')
-rw-r--r--java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt1
-rw-r--r--java/src/com/android/intentresolver/icons/LoadDirectShareIconTask.java20
-rw-r--r--java/src/com/android/intentresolver/util/UriFilters.kt27
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