Verify that the caller has permissions for the icons it provided.
Bug: 277207798
Test: manual testing: first reroduce the issue as described in the
ticket then check that it is not reproduceable after the fix.
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:bad47a2280c7107e1213f4adc5a3825a62698d00)
Merged-In: I08992550507572a4878c501184360a58adef53ad
Change-Id: I08992550507572a4878c501184360a58adef53ad
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ca4d1b6..3bdf3d6 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -21,6 +21,7 @@
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL;
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK;
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE;
+import static android.content.ContentProvider.getUriWithoutUserId;
import static android.content.ContentProvider.getUserIdFromUri;
import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL;
import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK;
@@ -40,7 +41,9 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.IUriGrantsManager;
import android.app.SharedElementCallback;
+import android.app.UriGrantsManager;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
@@ -77,6 +80,7 @@
import android.graphics.Path;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.AsyncTask;
@@ -86,6 +90,7 @@
import android.os.Message;
import android.os.Parcelable;
import android.os.PatternMatcher;
+import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.os.UserManager;
@@ -692,7 +697,11 @@
targets = null;
break;
}
- targets[i] = (ChooserTarget) pa[i];
+ ChooserTarget chooserTarget = (ChooserTarget) pa[i];
+ if (!hasValidIcon(chooserTarget)) {
+ chooserTarget = removeIcon(chooserTarget);
+ }
+ targets[i] = chooserTarget;
}
mCallerChooserTargets = targets;
}
@@ -4214,4 +4223,43 @@
private boolean shouldNearbyShareBeIncludedAsActionButton() {
return !shouldNearbyShareBeFirstInRankedRow();
}
+
+ private boolean hasValidIcon(ChooserTarget target) {
+ Icon icon = target.getIcon();
+ if (icon == null) {
+ return true;
+ }
+ if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {
+ Uri uri = icon.getUri();
+ try {
+ getUriGrantsManager().checkGrantUriPermission_ignoreNonSystem(
+ getLaunchedFromUid(),
+ getPackageName(),
+ getUriWithoutUserId(uri),
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ getUserIdFromUri(uri)
+ );
+ } catch (SecurityException | RemoteException e) {
+ Log.e(TAG, "Failed to get URI permission for: " + uri, e);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private IUriGrantsManager getUriGrantsManager() {
+ return UriGrantsManager.getService();
+ }
+
+ private static ChooserTarget removeIcon(ChooserTarget target) {
+ if (target == null) {
+ return null;
+ }
+ return new ChooserTarget(
+ target.getTitle(),
+ null,
+ target.getScore(),
+ target.getComponentName(),
+ target.getIntentExtras());
+ }
}