summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Joshua Trask <joshtrask@google.com> 2022-12-16 17:36:27 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-16 17:36:27 +0000
commit4ebf21f578b78ed83de87f829c4a126c9bb40759 (patch)
treef78dbe0381fcd8cf202afdfaa1ffef83885546d1 /java/src
parent9ebd81953ce60236381a068a0b7c52c8164bbfea (diff)
parent6e627be666fe43a9f13559856e158196d8ed7f4e (diff)
Merge "Extract TargetPresentationGetter hierarchy" into tm-qpr-dev
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/ChooserListAdapter.java4
-rw-r--r--java/src/com/android/intentresolver/ChooserTargetActionsDialogFragment.java10
-rw-r--r--java/src/com/android/intentresolver/ResolverListAdapter.java219
-rw-r--r--java/src/com/android/intentresolver/TargetPresentationGetter.java267
-rw-r--r--java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java28
5 files changed, 297 insertions, 231 deletions
diff --git a/java/src/com/android/intentresolver/ChooserListAdapter.java b/java/src/com/android/intentresolver/ChooserListAdapter.java
index 12a054b9..699190f9 100644
--- a/java/src/com/android/intentresolver/ChooserListAdapter.java
+++ b/java/src/com/android/intentresolver/ChooserListAdapter.java
@@ -224,7 +224,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
ri.icon = 0;
}
DisplayResolveInfo displayResolveInfo = DisplayResolveInfo.newDisplayResolveInfo(
- ii, ri, ii, makePresentationGetter(ri));
+ ii, ri, ii, mPresentationFactory.makePresentationGetter(ri));
mCallerTargets.add(displayResolveInfo);
if (mCallerTargets.size() == MAX_SUGGESTED_APP_TARGETS) break;
}
@@ -715,7 +715,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
// Now fetch app icon and raster with no badging even in work profile
- Bitmap appIcon = makePresentationGetter(info).getIconBitmap(null);
+ Bitmap appIcon = mPresentationFactory.makePresentationGetter(info).getIconBitmap(null);
// Raster target drawable with appIcon as a badge
SimpleIconFactory sif = SimpleIconFactory.obtain(context);
diff --git a/java/src/com/android/intentresolver/ChooserTargetActionsDialogFragment.java b/java/src/com/android/intentresolver/ChooserTargetActionsDialogFragment.java
index f4d4a6d1..0aa32505 100644
--- a/java/src/com/android/intentresolver/ChooserTargetActionsDialogFragment.java
+++ b/java/src/com/android/intentresolver/ChooserTargetActionsDialogFragment.java
@@ -19,8 +19,6 @@ package com.android.intentresolver;
import static android.content.Context.ACTIVITY_SERVICE;
-import static com.android.intentresolver.ResolverListAdapter.ResolveInfoPresentationGetter;
-
import static java.util.stream.Collectors.toList;
import android.annotation.NonNull;
@@ -136,7 +134,7 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
ImageView icon = v.findViewById(com.android.internal.R.id.icon);
RecyclerView rv = v.findViewById(com.android.internal.R.id.listContainer);
- final ResolveInfoPresentationGetter pg = getProvidingAppPresentationGetter();
+ final TargetPresentationGetter pg = getProvidingAppPresentationGetter();
title.setText(isShortcutTarget() ? mShortcutTitle : pg.getLabel());
icon.setImageDrawable(pg.getIcon(mUserHandle));
rv.setAdapter(new VHAdapter(items));
@@ -270,14 +268,14 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
return getPinIcon(isPinned(dri));
}
- private ResolveInfoPresentationGetter getProvidingAppPresentationGetter() {
+ private TargetPresentationGetter getProvidingAppPresentationGetter() {
final ActivityManager am = (ActivityManager) getContext()
.getSystemService(ACTIVITY_SERVICE);
final int iconDpi = am.getLauncherLargeIconDensity();
// Use the matching application icon and label for the title, any TargetInfo will do
- return new ResolveInfoPresentationGetter(getContext(), iconDpi,
- mTargetInfos.get(0).getResolveInfo());
+ return new TargetPresentationGetter.Factory(getContext(), iconDpi)
+ .makePresentationGetter(mTargetInfos.get(0).getResolveInfo());
}
private boolean isPinned(DisplayResolveInfo dri) {
diff --git a/java/src/com/android/intentresolver/ResolverListAdapter.java b/java/src/com/android/intentresolver/ResolverListAdapter.java
index 5513eda2..eecb914c 100644
--- a/java/src/com/android/intentresolver/ResolverListAdapter.java
+++ b/java/src/com/android/intentresolver/ResolverListAdapter.java
@@ -26,15 +26,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
import android.content.pm.LabeledIntent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.RemoteException;
@@ -74,6 +70,7 @@ public class ResolverListAdapter extends BaseAdapter {
protected final LayoutInflater mInflater;
protected final ResolverListCommunicator mResolverListCommunicator;
protected final ResolverListController mResolverListController;
+ protected final TargetPresentationGetter.Factory mPresentationFactory;
private final List<Intent> mIntents;
private final Intent[] mInitialIntents;
@@ -126,6 +123,7 @@ public class ResolverListAdapter extends BaseAdapter {
mIsAudioCaptureDevice = isAudioCaptureDevice;
final ActivityManager am = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
mIconDpi = am.getLauncherLargeIconDensity();
+ mPresentationFactory = new TargetPresentationGetter.Factory(mContext, mIconDpi);
}
public final DisplayResolveInfo getFirstDisplayResolveInfo() {
@@ -479,7 +477,7 @@ public class ResolverListAdapter extends BaseAdapter {
ri.loadLabel(mPm),
null,
ii,
- makePresentationGetter(ri)));
+ mPresentationFactory.makePresentationGetter(ri)));
}
}
@@ -532,7 +530,7 @@ public class ResolverListAdapter extends BaseAdapter {
intent,
add,
(replaceIntent != null) ? replaceIntent : defaultIntent,
- makePresentationGetter(add));
+ mPresentationFactory.makePresentationGetter(add));
dri.setPinned(rci.isPinned());
if (rci.isPinned()) {
Log.i(TAG, "Pinned item: " + rci.name);
@@ -765,17 +763,9 @@ public class ResolverListAdapter extends BaseAdapter {
return sSuspendedMatrixColorFilter;
}
- ActivityInfoPresentationGetter makePresentationGetter(ActivityInfo ai) {
- return new ActivityInfoPresentationGetter(mContext, mIconDpi, ai);
- }
-
- ResolveInfoPresentationGetter makePresentationGetter(ResolveInfo ri) {
- return new ResolveInfoPresentationGetter(mContext, mIconDpi, ri);
- }
-
Drawable loadIconForResolveInfo(ResolveInfo ri) {
// Load icons based on the current process. If in work profile icons should be badged.
- return makePresentationGetter(ri).getIcon(getUserHandle());
+ return mPresentationFactory.makePresentationGetter(ri).getIcon(getUserHandle());
}
protected final Drawable loadIconPlaceholder() {
@@ -875,8 +865,9 @@ public class ResolverListAdapter extends BaseAdapter {
Intent replacementIntent = resolverListCommunicator.getReplacementIntent(
resolveInfo.activityInfo, targetIntent);
- ResolveInfoPresentationGetter presentationGetter =
- new ResolveInfoPresentationGetter(context, iconDpi, resolveInfo);
+ TargetPresentationGetter presentationGetter =
+ new TargetPresentationGetter.Factory(context, iconDpi)
+ .makePresentationGetter(resolveInfo);
return DisplayResolveInfo.newDisplayResolveInfo(
resolvedComponentInfo.getIntentAt(0),
@@ -979,8 +970,8 @@ public class ResolverListAdapter extends BaseAdapter {
@Override
protected CharSequence[] doInBackground(Void... voids) {
- ResolveInfoPresentationGetter pg =
- makePresentationGetter(mDisplayResolveInfo.getResolveInfo());
+ TargetPresentationGetter pg = mPresentationFactory.makePresentationGetter(
+ mDisplayResolveInfo.getResolveInfo());
if (mIsAudioCaptureDevice) {
// This is an audio capture device, so check record permissions
@@ -1051,194 +1042,4 @@ public class ResolverListAdapter extends BaseAdapter {
}
}
}
-
- /**
- * Loads the icon and label for the provided ResolveInfo.
- */
- @VisibleForTesting
- public static class ResolveInfoPresentationGetter extends ActivityInfoPresentationGetter {
- private final ResolveInfo mRi;
- public ResolveInfoPresentationGetter(Context ctx, int iconDpi, ResolveInfo ri) {
- super(ctx, iconDpi, ri.activityInfo);
- mRi = ri;
- }
-
- @Override
- Drawable getIconSubstituteInternal() {
- Drawable dr = null;
- try {
- // Do not use ResolveInfo#getIconResource() as it defaults to the app
- if (mRi.resolvePackageName != null && mRi.icon != 0) {
- dr = loadIconFromResource(
- mPm.getResourcesForApplication(mRi.resolvePackageName), mRi.icon);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but "
- + "couldn't find resources for package", e);
- }
-
- // Fall back to ActivityInfo if no icon is found via ResolveInfo
- if (dr == null) dr = super.getIconSubstituteInternal();
-
- return dr;
- }
-
- @Override
- String getAppSubLabelInternal() {
- // Will default to app name if no intent filter or activity label set, make sure to
- // check if subLabel matches label before final display
- return mRi.loadLabel(mPm).toString();
- }
-
- @Override
- String getAppLabelForSubstitutePermission() {
- // Will default to app name if no activity label set
- return mRi.getComponentInfo().loadLabel(mPm).toString();
- }
- }
-
- /**
- * Loads the icon and label for the provided ActivityInfo.
- */
- @VisibleForTesting
- public static class ActivityInfoPresentationGetter extends
- TargetPresentationGetter {
- private final ActivityInfo mActivityInfo;
- public ActivityInfoPresentationGetter(Context ctx, int iconDpi,
- ActivityInfo activityInfo) {
- super(ctx, iconDpi, activityInfo.applicationInfo);
- mActivityInfo = activityInfo;
- }
-
- @Override
- Drawable getIconSubstituteInternal() {
- Drawable dr = null;
- try {
- // Do not use ActivityInfo#getIconResource() as it defaults to the app
- if (mActivityInfo.icon != 0) {
- dr = loadIconFromResource(
- mPm.getResourcesForApplication(mActivityInfo.applicationInfo),
- mActivityInfo.icon);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but "
- + "couldn't find resources for package", e);
- }
-
- return dr;
- }
-
- @Override
- String getAppSubLabelInternal() {
- // Will default to app name if no activity label set, make sure to check if subLabel
- // matches label before final display
- return (String) mActivityInfo.loadLabel(mPm);
- }
-
- @Override
- String getAppLabelForSubstitutePermission() {
- return getAppSubLabelInternal();
- }
- }
-
- /**
- * Loads the icon and label for the provided ApplicationInfo. Defaults to using the application
- * icon and label over any IntentFilter or Activity icon to increase user understanding, with an
- * exception for applications that hold the right permission. Always attempts to use available
- * resources over PackageManager loading mechanisms so badging can be done by iconloader. Uses
- * Strings to strip creative formatting.
- */
- private abstract static class TargetPresentationGetter {
- @Nullable abstract Drawable getIconSubstituteInternal();
- @Nullable abstract String getAppSubLabelInternal();
- @Nullable abstract String getAppLabelForSubstitutePermission();
-
- private Context mCtx;
- private final int mIconDpi;
- private final boolean mHasSubstitutePermission;
- private final ApplicationInfo mAi;
-
- protected PackageManager mPm;
-
- TargetPresentationGetter(Context ctx, int iconDpi, ApplicationInfo ai) {
- mCtx = ctx;
- mPm = ctx.getPackageManager();
- mAi = ai;
- mIconDpi = iconDpi;
- mHasSubstitutePermission = PackageManager.PERMISSION_GRANTED == mPm.checkPermission(
- android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON,
- mAi.packageName);
- }
-
- public Drawable getIcon(UserHandle userHandle) {
- return new BitmapDrawable(mCtx.getResources(), getIconBitmap(userHandle));
- }
-
- public Bitmap getIconBitmap(@Nullable UserHandle userHandle) {
- Drawable dr = null;
- if (mHasSubstitutePermission) {
- dr = getIconSubstituteInternal();
- }
-
- if (dr == null) {
- try {
- if (mAi.icon != 0) {
- dr = loadIconFromResource(mPm.getResourcesForApplication(mAi), mAi.icon);
- }
- } catch (PackageManager.NameNotFoundException ignore) {
- }
- }
-
- // Fall back to ApplicationInfo#loadIcon if nothing has been loaded
- if (dr == null) {
- dr = mAi.loadIcon(mPm);
- }
-
- SimpleIconFactory sif = SimpleIconFactory.obtain(mCtx);
- Bitmap icon = sif.createUserBadgedIconBitmap(dr, userHandle);
- sif.recycle();
-
- return icon;
- }
-
- public String getLabel() {
- String label = null;
- // Apps with the substitute permission will always show the activity label as the
- // app label if provided
- if (mHasSubstitutePermission) {
- label = getAppLabelForSubstitutePermission();
- }
-
- if (label == null) {
- label = (String) mAi.loadLabel(mPm);
- }
-
- return label;
- }
-
- public String getSubLabel() {
- // Apps with the substitute permission will always show the resolve info label as the
- // sublabel if provided
- if (mHasSubstitutePermission){
- String appSubLabel = getAppSubLabelInternal();
- // Use the resolve info label as sublabel if it is set
- if(!TextUtils.isEmpty(appSubLabel)
- && !TextUtils.equals(appSubLabel, getLabel())){
- return appSubLabel;
- }
- return null;
- }
- return getAppSubLabelInternal();
- }
-
- protected String loadLabelFromResource(Resources res, int resId) {
- return res.getString(resId);
- }
-
- @Nullable
- protected Drawable loadIconFromResource(Resources res, int resId) {
- return res.getDrawableForDensity(resId, mIconDpi);
- }
-
- }
}
diff --git a/java/src/com/android/intentresolver/TargetPresentationGetter.java b/java/src/com/android/intentresolver/TargetPresentationGetter.java
new file mode 100644
index 00000000..f8b36566
--- /dev/null
+++ b/java/src/com/android/intentresolver/TargetPresentationGetter.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.intentresolver;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Loads the icon and label for the provided ApplicationInfo. Defaults to using the application icon
+ * and label over any IntentFilter or Activity icon to increase user understanding, with an
+ * exception for applications that hold the right permission. Always attempts to use available
+ * resources over PackageManager loading mechanisms so badging can be done by iconloader. Uses
+ * Strings to strip creative formatting.
+ *
+ * Use one of the {@link TargetPresentationGetter#Factory} methods to create an instance of the
+ * appropriate concrete type.
+ *
+ * TODO: once this component (and its tests) are merged, it should be possible to refactor and
+ * vastly simplify by precomputing conditional logic at initialization.
+ */
+public abstract class TargetPresentationGetter {
+ private static final String TAG = "ResolverListAdapter";
+
+ /** Helper to build appropriate type-specific {@link TargetPresentationGetter} instances. */
+ public static class Factory {
+ private final Context mContext;
+ private final int mIconDpi;
+
+ public Factory(Context context, int iconDpi) {
+ mContext = context;
+ mIconDpi = iconDpi;
+ }
+
+ /** Make a {@link TargetPresentationGetter} for an {@link ActivityInfo}. */
+ public TargetPresentationGetter makePresentationGetter(ActivityInfo activityInfo) {
+ return new ActivityInfoPresentationGetter(mContext, mIconDpi, activityInfo);
+ }
+
+ /** Make a {@link TargetPresentationGetter} for a {@link ResolveInfo}. */
+ public TargetPresentationGetter makePresentationGetter(ResolveInfo resolveInfo) {
+ return new ResolveInfoPresentationGetter(mContext, mIconDpi, resolveInfo);
+ }
+ }
+
+ @Nullable
+ protected abstract Drawable getIconSubstituteInternal();
+
+ @Nullable
+ protected abstract String getAppSubLabelInternal();
+
+ @Nullable
+ protected abstract String getAppLabelForSubstitutePermission();
+
+ private Context mContext;
+ private final int mIconDpi;
+ private final boolean mHasSubstitutePermission;
+ private final ApplicationInfo mAppInfo;
+
+ protected PackageManager mPm;
+
+ /**
+ * Retrieve the image that should be displayed as the icon when this target is presented to the
+ * specified {@code userHandle}.
+ */
+ public Drawable getIcon(UserHandle userHandle) {
+ return new BitmapDrawable(mContext.getResources(), getIconBitmap(userHandle));
+ }
+
+ /**
+ * Retrieve the image that should be displayed as the icon when this target is presented to the
+ * specified {@code userHandle}.
+ */
+ public Bitmap getIconBitmap(@Nullable UserHandle userHandle) {
+ Drawable drawable = null;
+ if (mHasSubstitutePermission) {
+ drawable = getIconSubstituteInternal();
+ }
+
+ if (drawable == null) {
+ try {
+ if (mAppInfo.icon != 0) {
+ drawable = loadIconFromResource(
+ mPm.getResourcesForApplication(mAppInfo), mAppInfo.icon);
+ }
+ } catch (PackageManager.NameNotFoundException ignore) { }
+ }
+
+ // Fall back to ApplicationInfo#loadIcon if nothing has been loaded
+ if (drawable == null) {
+ drawable = mAppInfo.loadIcon(mPm);
+ }
+
+ SimpleIconFactory iconFactory = SimpleIconFactory.obtain(mContext);
+ Bitmap icon = iconFactory.createUserBadgedIconBitmap(drawable, userHandle);
+ iconFactory.recycle();
+
+ return icon;
+ }
+
+ /** Get the label to display for the target. */
+ public String getLabel() {
+ String label = null;
+ // Apps with the substitute permission will always show the activity label as the app label
+ // if provided.
+ if (mHasSubstitutePermission) {
+ label = getAppLabelForSubstitutePermission();
+ }
+
+ if (label == null) {
+ label = (String) mAppInfo.loadLabel(mPm);
+ }
+
+ return label;
+ }
+
+ /**
+ * Get the sublabel to display for the target. Clients are responsible for deduping their
+ * presentation if this returns the same value as {@link #getLabel()}.
+ * TODO: this class should take responsibility for that deduping internally so it's an
+ * authoritative record of exactly the content that should be presented.
+ */
+ public String getSubLabel() {
+ // Apps with the substitute permission will always show the resolve info label as the
+ // sublabel if provided
+ if (mHasSubstitutePermission) {
+ String appSubLabel = getAppSubLabelInternal();
+ // Use the resolve info label as sublabel if it is set
+ if (!TextUtils.isEmpty(appSubLabel) && !TextUtils.equals(appSubLabel, getLabel())) {
+ return appSubLabel;
+ }
+ return null;
+ }
+ return getAppSubLabelInternal();
+ }
+
+ protected String loadLabelFromResource(Resources res, int resId) {
+ return res.getString(resId);
+ }
+
+ @Nullable
+ protected Drawable loadIconFromResource(Resources res, int resId) {
+ return res.getDrawableForDensity(resId, mIconDpi);
+ }
+
+ private TargetPresentationGetter(Context context, int iconDpi, ApplicationInfo appInfo) {
+ mContext = context;
+ mPm = context.getPackageManager();
+ mAppInfo = appInfo;
+ mIconDpi = iconDpi;
+ mHasSubstitutePermission = (PackageManager.PERMISSION_GRANTED == mPm.checkPermission(
+ android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON,
+ mAppInfo.packageName));
+ }
+
+ /** Loads the icon and label for the provided ResolveInfo. */
+ private static class ResolveInfoPresentationGetter extends ActivityInfoPresentationGetter {
+ private final ResolveInfo mResolveInfo;
+
+ ResolveInfoPresentationGetter(
+ Context context, int iconDpi, ResolveInfo resolveInfo) {
+ super(context, iconDpi, resolveInfo.activityInfo);
+ mResolveInfo = resolveInfo;
+ }
+
+ @Override
+ protected Drawable getIconSubstituteInternal() {
+ Drawable drawable = null;
+ try {
+ // Do not use ResolveInfo#getIconResource() as it defaults to the app
+ if (mResolveInfo.resolvePackageName != null && mResolveInfo.icon != 0) {
+ drawable = loadIconFromResource(
+ mPm.getResourcesForApplication(mResolveInfo.resolvePackageName),
+ mResolveInfo.icon);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but "
+ + "couldn't find resources for package", e);
+ }
+
+ // Fall back to ActivityInfo if no icon is found via ResolveInfo
+ if (drawable == null) {
+ drawable = super.getIconSubstituteInternal();
+ }
+
+ return drawable;
+ }
+
+ @Override
+ protected String getAppSubLabelInternal() {
+ // Will default to app name if no intent filter or activity label set, make sure to
+ // check if subLabel matches label before final display
+ return mResolveInfo.loadLabel(mPm).toString();
+ }
+
+ @Override
+ protected String getAppLabelForSubstitutePermission() {
+ // Will default to app name if no activity label set
+ return mResolveInfo.getComponentInfo().loadLabel(mPm).toString();
+ }
+ }
+
+ /** Loads the icon and label for the provided {@link ActivityInfo}. */
+ private static class ActivityInfoPresentationGetter extends TargetPresentationGetter {
+ private final ActivityInfo mActivityInfo;
+
+ ActivityInfoPresentationGetter(
+ Context context, int iconDpi, ActivityInfo activityInfo) {
+ super(context, iconDpi, activityInfo.applicationInfo);
+ mActivityInfo = activityInfo;
+ }
+
+ @Override
+ protected Drawable getIconSubstituteInternal() {
+ Drawable drawable = null;
+ try {
+ // Do not use ActivityInfo#getIconResource() as it defaults to the app
+ if (mActivityInfo.icon != 0) {
+ drawable = loadIconFromResource(
+ mPm.getResourcesForApplication(mActivityInfo.applicationInfo),
+ mActivityInfo.icon);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but "
+ + "couldn't find resources for package", e);
+ }
+
+ return drawable;
+ }
+
+ @Override
+ protected String getAppSubLabelInternal() {
+ // Will default to app name if no activity label set, make sure to check if subLabel
+ // matches label before final display
+ return (String) mActivityInfo.loadLabel(mPm);
+ }
+
+ @Override
+ protected String getAppLabelForSubstitutePermission() {
+ return getAppSubLabelInternal();
+ }
+ }
+}
diff --git a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
index c1b007af..db5ae0b4 100644
--- a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
+++ b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
@@ -28,7 +28,7 @@ import android.os.Bundle;
import android.os.UserHandle;
import com.android.intentresolver.ResolverActivity;
-import com.android.intentresolver.ResolverListAdapter.ResolveInfoPresentationGetter;
+import com.android.intentresolver.TargetPresentationGetter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -45,7 +45,7 @@ public class DisplayResolveInfo implements TargetInfo {
private final Intent mResolvedIntent;
private final List<Intent> mSourceIntents = new ArrayList<>();
private final boolean mIsSuspended;
- private ResolveInfoPresentationGetter mResolveInfoPresentationGetter;
+ private TargetPresentationGetter mPresentationGetter;
private boolean mPinned = false;
private final IconHolder mDisplayIconHolder = new SettableIconHolder();
@@ -54,7 +54,7 @@ public class DisplayResolveInfo implements TargetInfo {
Intent originalIntent,
ResolveInfo resolveInfo,
@NonNull Intent resolvedIntent,
- @Nullable ResolveInfoPresentationGetter presentationGetter) {
+ @Nullable TargetPresentationGetter presentationGetter) {
return newDisplayResolveInfo(
originalIntent,
resolveInfo,
@@ -71,14 +71,14 @@ public class DisplayResolveInfo implements TargetInfo {
CharSequence displayLabel,
CharSequence extendedInfo,
@NonNull Intent resolvedIntent,
- @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
+ @Nullable TargetPresentationGetter presentationGetter) {
return new DisplayResolveInfo(
originalIntent,
resolveInfo,
displayLabel,
extendedInfo,
resolvedIntent,
- resolveInfoPresentationGetter);
+ presentationGetter);
}
private DisplayResolveInfo(
@@ -87,12 +87,12 @@ public class DisplayResolveInfo implements TargetInfo {
CharSequence displayLabel,
CharSequence extendedInfo,
@NonNull Intent resolvedIntent,
- @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
+ @Nullable TargetPresentationGetter presentationGetter) {
mSourceIntents.add(originalIntent);
mResolveInfo = resolveInfo;
mDisplayLabel = displayLabel;
mExtendedInfo = extendedInfo;
- mResolveInfoPresentationGetter = resolveInfoPresentationGetter;
+ mPresentationGetter = presentationGetter;
final ActivityInfo ai = mResolveInfo.activityInfo;
mIsSuspended = (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
@@ -108,7 +108,7 @@ public class DisplayResolveInfo implements TargetInfo {
DisplayResolveInfo other,
Intent fillInIntent,
int flags,
- ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
+ TargetPresentationGetter presentationGetter) {
mSourceIntents.addAll(other.getAllSourceIntents());
mResolveInfo = other.mResolveInfo;
mIsSuspended = other.mIsSuspended;
@@ -116,7 +116,7 @@ public class DisplayResolveInfo implements TargetInfo {
mExtendedInfo = other.mExtendedInfo;
mResolvedIntent = new Intent(other.mResolvedIntent);
mResolvedIntent.fillIn(fillInIntent, flags);
- mResolveInfoPresentationGetter = resolveInfoPresentationGetter;
+ mPresentationGetter = presentationGetter;
mDisplayIconHolder.setDisplayIcon(other.mDisplayIconHolder.getDisplayIcon());
}
@@ -128,7 +128,7 @@ public class DisplayResolveInfo implements TargetInfo {
mDisplayLabel = other.mDisplayLabel;
mExtendedInfo = other.mExtendedInfo;
mResolvedIntent = other.mResolvedIntent;
- mResolveInfoPresentationGetter = other.mResolveInfoPresentationGetter;
+ mPresentationGetter = other.mPresentationGetter;
mDisplayIconHolder.setDisplayIcon(other.mDisplayIconHolder.getDisplayIcon());
}
@@ -143,9 +143,9 @@ public class DisplayResolveInfo implements TargetInfo {
}
public CharSequence getDisplayLabel() {
- if (mDisplayLabel == null && mResolveInfoPresentationGetter != null) {
- mDisplayLabel = mResolveInfoPresentationGetter.getLabel();
- mExtendedInfo = mResolveInfoPresentationGetter.getSubLabel();
+ if (mDisplayLabel == null && mPresentationGetter != null) {
+ mDisplayLabel = mPresentationGetter.getLabel();
+ mExtendedInfo = mPresentationGetter.getSubLabel();
}
return mDisplayLabel;
}
@@ -169,7 +169,7 @@ public class DisplayResolveInfo implements TargetInfo {
@Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
- return new DisplayResolveInfo(this, fillInIntent, flags, mResolveInfoPresentationGetter);
+ return new DisplayResolveInfo(this, fillInIntent, flags, mPresentationGetter);
}
@Override