diff options
Diffstat (limited to 'java/src')
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  |