summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/ChooserActivity.java10
-rw-r--r--java/src/com/android/intentresolver/ChooserListAdapter.java89
-rw-r--r--java/src/com/android/intentresolver/ResolverListAdapter.java2
-rw-r--r--java/src/com/android/intentresolver/ShortcutSelectionLogic.java39
-rw-r--r--java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java17
-rw-r--r--java/src/com/android/intentresolver/chooser/NotSelectableTargetInfo.java11
-rw-r--r--java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java212
-rw-r--r--java/src/com/android/intentresolver/chooser/TargetInfo.java17
8 files changed, 172 insertions, 225 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java
index 3ccefe1b..938fbb0d 100644
--- a/java/src/com/android/intentresolver/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/ChooserActivity.java
@@ -115,7 +115,6 @@ import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
-import com.android.intentresolver.ResolverListAdapter.ActivityInfoPresentationGetter;
import com.android.intentresolver.ResolverListAdapter.ViewHolder;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.MultiDisplayResolveInfo;
@@ -1128,7 +1127,7 @@ public class ChooserActivity extends ResolverActivity implements
if (ti == null) return null;
final Button b = createActionButton(
- ti.getDisplayIcon(this),
+ ti.getDisplayIcon(),
ti.getDisplayLabel(),
(View unused) -> {
// Log share completion via nearby
@@ -1151,7 +1150,7 @@ public class ChooserActivity extends ResolverActivity implements
if (ti == null) return null;
final Button b = createActionButton(
- ti.getDisplayIcon(this),
+ ti.getDisplayIcon(),
ti.getDisplayLabel(),
(View unused) -> {
// Log share completion via edit
@@ -2458,11 +2457,6 @@ public class ChooserActivity extends ResolverActivity implements
}
@Override // SelectableTargetInfoCommunicator
- public ActivityInfoPresentationGetter makePresentationGetter(ActivityInfo info) {
- return mChooserMultiProfilePagerAdapter.getActiveListAdapter().makePresentationGetter(info);
- }
-
- @Override // SelectableTargetInfoCommunicator
public Intent getReferrerFillInIntent() {
return mReferrerFillInIntent;
}
diff --git a/java/src/com/android/intentresolver/ChooserListAdapter.java b/java/src/com/android/intentresolver/ChooserListAdapter.java
index 92cd0043..f20ee38f 100644
--- a/java/src/com/android/intentresolver/ChooserListAdapter.java
+++ b/java/src/com/android/intentresolver/ChooserListAdapter.java
@@ -27,10 +27,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.LabeledIntent;
+import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.AsyncTask;
import android.os.Trace;
import android.os.UserManager;
@@ -42,10 +46,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.annotation.WorkerThread;
+
import com.android.intentresolver.ResolverActivity.ResolvedComponentInfo;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.MultiDisplayResolveInfo;
import com.android.intentresolver.chooser.NotSelectableTargetInfo;
+import com.android.intentresolver.chooser.SelectableTargetInfo;
import com.android.intentresolver.chooser.SelectableTargetInfo.SelectableTargetInfoCommunicator;
import com.android.intentresolver.chooser.TargetInfo;
import com.android.internal.annotations.VisibleForTesting;
@@ -84,8 +91,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
private final Map<TargetInfo, AsyncTask> mIconLoaders = new HashMap<>();
// Reserve spots for incoming direct share targets by adding placeholders
- private TargetInfo mPlaceHolderTargetInfo =
- NotSelectableTargetInfo.newPlaceHolderTargetInfo();
+ private final TargetInfo mPlaceHolderTargetInfo;
private final List<TargetInfo> mServiceTargets = new ArrayList<>();
private final List<DisplayResolveInfo> mCallerTargets = new ArrayList<>();
@@ -142,6 +148,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
resolverListController, chooserListCommunicator, false);
mChooserListCommunicator = chooserListCommunicator;
+ mPlaceHolderTargetInfo = NotSelectableTargetInfo.newPlaceHolderTargetInfo(context);
createPlaceHolders();
mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
mChooserActivityLogger = chooserActivityLogger;
@@ -256,7 +263,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
extendedInfo != null ? extendedInfo : "", appName);
holder.updateContentDescription(contentDescription);
if (!info.hasDisplayIcon()) {
- loadDirectShareIcon(info);
+ loadDirectShareIcon((SelectableTargetInfo) info);
}
} else if (info.isDisplayResolveInfo()) {
DisplayResolveInfo dri = (DisplayResolveInfo) info;
@@ -302,7 +309,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
}
- private void loadDirectShareIcon(TargetInfo info) {
+ private void loadDirectShareIcon(SelectableTargetInfo info) {
LoadDirectShareIconTask task = (LoadDirectShareIconTask) mIconLoaders.get(info);
if (task == null) {
task = createLoadDirectShareIconTask(info);
@@ -312,8 +319,10 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
@VisibleForTesting
- protected LoadDirectShareIconTask createLoadDirectShareIconTask(TargetInfo info) {
- return new LoadDirectShareIconTask(info);
+ protected LoadDirectShareIconTask createLoadDirectShareIconTask(SelectableTargetInfo info) {
+ return new LoadDirectShareIconTask(
+ mContext.createContextAsUser(getUserHandle(), 0),
+ info);
}
void updateAlphabeticalList() {
@@ -545,7 +554,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
directShareToShortcutInfos,
directShareToAppTargets,
mContext.createContextAsUser(getUserHandle(), 0),
- mSelectableTargetInfoCommunicator,
+ mSelectableTargetInfoCommunicator.getTargetIntent(),
+ mSelectableTargetInfoCommunicator.getReferrerFillInIntent(),
mChooserListCommunicator.getMaxRankedTargets(),
mServiceTargets);
if (isUpdated) {
@@ -641,25 +651,76 @@ public class ChooserListAdapter extends ResolverListAdapter {
* Loads direct share targets icons.
*/
@VisibleForTesting
- public class LoadDirectShareIconTask extends AsyncTask<Void, Void, Boolean> {
- private final TargetInfo mTargetInfo;
+ public class LoadDirectShareIconTask extends AsyncTask<Void, Void, Drawable> {
+ private final Context mContext;
+ private final SelectableTargetInfo mTargetInfo;
- private LoadDirectShareIconTask(TargetInfo targetInfo) {
+ private LoadDirectShareIconTask(Context context, SelectableTargetInfo targetInfo) {
+ mContext = context;
mTargetInfo = targetInfo;
}
@Override
- protected Boolean doInBackground(Void... voids) {
- return mTargetInfo.loadIcon();
+ protected Drawable doInBackground(Void... voids) {
+ return getChooserTargetIconDrawable(
+ mContext,
+ mTargetInfo.getChooserTargetIcon(),
+ mTargetInfo.getChooserTargetComponentName(),
+ mTargetInfo.getDirectShareShortcutInfo());
}
@Override
- protected void onPostExecute(Boolean isLoaded) {
- if (isLoaded) {
+ protected void onPostExecute(@Nullable Drawable icon) {
+ if (icon != null && !mTargetInfo.hasDisplayIcon()) {
+ mTargetInfo.setDisplayIcon(icon);
notifyDataSetChanged();
}
}
+ @WorkerThread
+ private Drawable getChooserTargetIconDrawable(
+ Context context,
+ @Nullable Icon icon,
+ ComponentName targetComponentName,
+ @Nullable ShortcutInfo shortcutInfo) {
+ Drawable directShareIcon = null;
+
+ // First get the target drawable and associated activity info
+ if (icon != null) {
+ directShareIcon = icon.loadDrawable(context);
+ } else if (shortcutInfo != null) {
+ LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
+ if (launcherApps != null) {
+ directShareIcon = launcherApps.getShortcutIconDrawable(shortcutInfo, 0);
+ }
+ }
+
+ if (directShareIcon == null) {
+ return null;
+ }
+
+ ActivityInfo info = null;
+ try {
+ info = context.getPackageManager().getActivityInfo(targetComponentName, 0);
+ } catch (PackageManager.NameNotFoundException error) {
+ Log.e(TAG, "Could not find activity associated with ChooserTarget");
+ }
+
+ if (info == null) {
+ return null;
+ }
+
+ // Now fetch app icon and raster with no badging even in work profile
+ Bitmap appIcon = makePresentationGetter(info).getIconBitmap(null);
+
+ // Raster target drawable with appIcon as a badge
+ SimpleIconFactory sif = SimpleIconFactory.obtain(context);
+ Bitmap directShareBadgedIcon = sif.createAppBadgedIconBitmap(directShareIcon, appIcon);
+ sif.recycle();
+
+ return new BitmapDrawable(context.getResources(), directShareBadgedIcon);
+ }
+
/**
* An alias for execute to use with unit tests.
*/
diff --git a/java/src/com/android/intentresolver/ResolverListAdapter.java b/java/src/com/android/intentresolver/ResolverListAdapter.java
index 63da842d..f74c33c0 100644
--- a/java/src/com/android/intentresolver/ResolverListAdapter.java
+++ b/java/src/com/android/intentresolver/ResolverListAdapter.java
@@ -921,7 +921,7 @@ public class ResolverListAdapter extends BaseAdapter {
}
public void bindIcon(TargetInfo info) {
- icon.setImageDrawable(info.getDisplayIcon(itemView.getContext()));
+ icon.setImageDrawable(info.getDisplayIcon());
if (info.isSuspended()) {
icon.setColorFilter(getSuspendedColorMatrix());
} else {
diff --git a/java/src/com/android/intentresolver/ShortcutSelectionLogic.java b/java/src/com/android/intentresolver/ShortcutSelectionLogic.java
index 39187bdb..645b9391 100644
--- a/java/src/com/android/intentresolver/ShortcutSelectionLogic.java
+++ b/java/src/com/android/intentresolver/ShortcutSelectionLogic.java
@@ -19,13 +19,15 @@ package com.android.intentresolver;
import android.annotation.Nullable;
import android.app.prediction.AppTarget;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.service.chooser.ChooserTarget;
import android.util.Log;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.SelectableTargetInfo;
-import com.android.intentresolver.chooser.SelectableTargetInfo.SelectableTargetInfoCommunicator;
import com.android.intentresolver.chooser.TargetInfo;
import java.util.Collections;
@@ -65,7 +67,8 @@ class ShortcutSelectionLogic {
Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos,
Map<ChooserTarget, AppTarget> directShareToAppTargets,
Context userContext,
- SelectableTargetInfoCommunicator mSelectableTargetInfoCommunicator,
+ Intent targetIntent,
+ Intent referrerFillInIntent,
int maxRankedTargets,
List<TargetInfo> serviceTargets) {
if (DEBUG) {
@@ -100,15 +103,28 @@ class ShortcutSelectionLogic {
if ((shortcutInfo != null) && shortcutInfo.isPinned()) {
targetScore += PINNED_SHORTCUT_TARGET_SCORE_BOOST;
}
+ ResolveInfo backupResolveInfo;
+ Intent resolvedIntent;
+ if (origTarget == null) {
+ resolvedIntent = createResolvedIntentForCallerTarget(target, targetIntent);
+ backupResolveInfo = userContext.getPackageManager()
+ .resolveActivity(
+ resolvedIntent,
+ PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA));
+ } else {
+ resolvedIntent = origTarget.getResolvedIntent();
+ backupResolveInfo = null;
+ }
boolean isInserted = insertServiceTarget(
SelectableTargetInfo.newSelectableTargetInfo(
- userContext,
origTarget,
+ backupResolveInfo,
+ resolvedIntent,
target,
targetScore,
- mSelectableTargetInfoCommunicator,
shortcutInfo,
- directShareToAppTargets.get(target)),
+ directShareToAppTargets.get(target),
+ referrerFillInIntent),
maxRankedTargets,
serviceTargets);
@@ -128,6 +144,19 @@ class ShortcutSelectionLogic {
return shouldNotify;
}
+ /**
+ * Creates a resolved intent for a caller-specified target.
+ * @param target, a caller-specified target.
+ * @param targetIntent, a target intent for the Chooser (see {@link Intent#EXTRA_INTENT}).
+ */
+ private static Intent createResolvedIntentForCallerTarget(
+ ChooserTarget target, Intent targetIntent) {
+ final Intent resolvedIntent = new Intent(targetIntent);
+ resolvedIntent.setComponent(target.getComponentName());
+ resolvedIntent.putExtras(target.getIntentExtras());
+ return resolvedIntent;
+ }
+
private boolean insertServiceTarget(
TargetInfo chooserTargetInfo,
int maxRankedTargets,
diff --git a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
index daa69152..16dd28bc 100644
--- a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
+++ b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -47,7 +46,7 @@ public class DisplayResolveInfo implements TargetInfo {
private CharSequence mExtendedInfo;
private final Intent mResolvedIntent;
private final List<Intent> mSourceIntents = new ArrayList<>();
- private boolean mIsSuspended;
+ private final boolean mIsSuspended;
private ResolveInfoPresentationGetter mResolveInfoPresentationGetter;
private boolean mPinned = false;
@@ -107,10 +106,14 @@ public class DisplayResolveInfo implements TargetInfo {
}
- private DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags,
+ private DisplayResolveInfo(
+ DisplayResolveInfo other,
+ Intent fillInIntent,
+ int flags,
ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
mSourceIntents.addAll(other.getAllSourceIntents());
mResolveInfo = other.mResolveInfo;
+ mIsSuspended = other.mIsSuspended;
mDisplayLabel = other.mDisplayLabel;
mDisplayIcon = other.mDisplayIcon;
mExtendedInfo = other.mExtendedInfo;
@@ -122,6 +125,7 @@ public class DisplayResolveInfo implements TargetInfo {
protected DisplayResolveInfo(DisplayResolveInfo other) {
mSourceIntents.addAll(other.getAllSourceIntents());
mResolveInfo = other.mResolveInfo;
+ mIsSuspended = other.mIsSuspended;
mDisplayLabel = other.mDisplayLabel;
mDisplayIcon = other.mDisplayIcon;
mExtendedInfo = other.mExtendedInfo;
@@ -158,7 +162,8 @@ public class DisplayResolveInfo implements TargetInfo {
mExtendedInfo = extendedInfo;
}
- public Drawable getDisplayIcon(Context context) {
+ @Override
+ public Drawable getDisplayIcon() {
return mDisplayIcon;
}
@@ -185,10 +190,6 @@ public class DisplayResolveInfo implements TargetInfo {
mDisplayIcon = icon;
}
- public boolean hasDisplayIcon() {
- return mDisplayIcon != null;
- }
-
public CharSequence getExtendedInfo() {
return mExtendedInfo;
}
diff --git a/java/src/com/android/intentresolver/chooser/NotSelectableTargetInfo.java b/java/src/com/android/intentresolver/chooser/NotSelectableTargetInfo.java
index 8ec52c8a..3b4b89b1 100644
--- a/java/src/com/android/intentresolver/chooser/NotSelectableTargetInfo.java
+++ b/java/src/com/android/intentresolver/chooser/NotSelectableTargetInfo.java
@@ -45,14 +45,9 @@ public abstract class NotSelectableTargetInfo extends ChooserTargetInfo {
}
@Override
- public Drawable getDisplayIcon(Context context) {
+ public Drawable getDisplayIcon() {
return null;
}
-
- @Override
- public boolean hasDisplayIcon() {
- return false;
- }
};
}
@@ -60,7 +55,7 @@ public abstract class NotSelectableTargetInfo extends ChooserTargetInfo {
* Create a non-selectable {@link TargetInfo} with placeholder content to be displayed
* unless/until it can be replaced by the result of a pending asynchronous load.
*/
- public static TargetInfo newPlaceHolderTargetInfo() {
+ public static TargetInfo newPlaceHolderTargetInfo(Context context) {
return new NotSelectableTargetInfo() {
@Override
public boolean isPlaceHolderTargetInfo() {
@@ -68,7 +63,7 @@ public abstract class NotSelectableTargetInfo extends ChooserTargetInfo {
}
@Override
- public Drawable getDisplayIcon(Context context) {
+ public Drawable getDisplayIcon() {
AnimatedVectorDrawable avd = (AnimatedVectorDrawable)
context.getDrawable(R.drawable.chooser_direct_share_icon_placeholder);
avd.start(); // Start animation after generation.
diff --git a/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java b/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java
index 7e6e49fb..093020b8 100644
--- a/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java
+++ b/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java
@@ -22,14 +22,8 @@ import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherApps;
-import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -42,9 +36,6 @@ import android.util.Log;
import com.android.intentresolver.ChooserActivity;
import com.android.intentresolver.ResolverActivity;
-import com.android.intentresolver.ResolverListAdapter.ActivityInfoPresentationGetter;
-import com.android.intentresolver.SimpleIconFactory;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import java.util.ArrayList;
@@ -65,84 +56,74 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
DEFAULT_SALT_EXPIRATION_DAYS);
- private final Context mContext;
@Nullable
private final DisplayResolveInfo mSourceInfo;
+ @Nullable
private final ResolveInfo mBackupResolveInfo;
+ private final Intent mResolvedIntent;
private final ChooserTarget mChooserTarget;
private final String mDisplayLabel;
- private final PackageManager mPm;
- private final SelectableTargetInfoCommunicator mSelectableTargetInfoCommunicator;
@Nullable
private final AppTarget mAppTarget;
@Nullable
private final ShortcutInfo mShortcutInfo;
+
+ /**
+ * A refinement intent from the caller, if any (see
+ * {@link Intent#EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER})
+ */
private final Intent mFillInIntent;
+
+ /**
+ * An intent containing referrer URI (see {@link Activity#getReferrer()} (possibly {@code null})
+ * in its extended data under the key {@link Intent#EXTRA_REFERRER}.
+ */
+ private final Intent mReferrerFillInIntent;
private final int mFillInFlags;
private final boolean mIsPinned;
private final float mModifiedScore;
- private final boolean mIsSuspended;
- private final Drawable mBadgeIcon;
- private final CharSequence mBadgeContentDescription;
- @GuardedBy("this")
private Drawable mDisplayIcon;
- @GuardedBy("this")
- private boolean mHasAttemptedIconLoad;
-
/** Create a new {@link TargetInfo} instance representing a selectable target. */
public static TargetInfo newSelectableTargetInfo(
- Context context,
@Nullable DisplayResolveInfo sourceInfo,
+ @Nullable ResolveInfo backupResolveInfo,
+ Intent resolvedIntent,
ChooserTarget chooserTarget,
float modifiedScore,
- SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
@Nullable ShortcutInfo shortcutInfo,
- @Nullable AppTarget appTarget) {
+ @Nullable AppTarget appTarget,
+ Intent referrerFillInIntent) {
return new SelectableTargetInfo(
- context,
sourceInfo,
+ backupResolveInfo,
+ resolvedIntent,
chooserTarget,
modifiedScore,
- selectableTargetInfoCommunicator,
shortcutInfo,
- appTarget);
+ appTarget,
+ referrerFillInIntent);
}
private SelectableTargetInfo(
- Context context,
@Nullable DisplayResolveInfo sourceInfo,
+ @Nullable ResolveInfo backupResolveInfo,
+ Intent resolvedIntent,
ChooserTarget chooserTarget,
float modifiedScore,
- SelectableTargetInfoCommunicator selectableTargetInfoComunicator,
@Nullable ShortcutInfo shortcutInfo,
- @Nullable AppTarget appTarget) {
- mContext = context;
+ @Nullable AppTarget appTarget,
+ Intent referrerFillInIntent) {
mSourceInfo = sourceInfo;
mChooserTarget = chooserTarget;
mModifiedScore = modifiedScore;
- mPm = mContext.getPackageManager();
- mSelectableTargetInfoCommunicator = selectableTargetInfoComunicator;
mShortcutInfo = shortcutInfo;
mAppTarget = appTarget;
mIsPinned = shortcutInfo != null && shortcutInfo.isPinned();
-
- final PackageManager pm = mContext.getPackageManager();
- final ApplicationInfo applicationInfo = getApplicationInfoFromSource(sourceInfo);
-
- mBadgeIcon = (applicationInfo == null) ? null : pm.getApplicationIcon(applicationInfo);
- mBadgeContentDescription =
- (applicationInfo == null) ? null : pm.getApplicationLabel(applicationInfo);
- mIsSuspended = (applicationInfo != null)
- && ((applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0);
-
- if (sourceInfo != null) {
- mBackupResolveInfo = null;
- } else {
- mBackupResolveInfo =
- mContext.getPackageManager().resolveActivity(getResolvedIntent(), 0);
- }
+ mBackupResolveInfo = backupResolveInfo;
+ mResolvedIntent = resolvedIntent;
+ mReferrerFillInIntent = referrerFillInIntent;
mFillInIntent = null;
mFillInFlags = 0;
@@ -151,25 +132,18 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
}
private SelectableTargetInfo(SelectableTargetInfo other, Intent fillInIntent, int flags) {
- mContext = other.mContext;
- mPm = other.mPm;
- mSelectableTargetInfoCommunicator = other.mSelectableTargetInfoCommunicator;
mSourceInfo = other.mSourceInfo;
mBackupResolveInfo = other.mBackupResolveInfo;
+ mResolvedIntent = other.mResolvedIntent;
mChooserTarget = other.mChooserTarget;
- mBadgeIcon = other.mBadgeIcon;
- mBadgeContentDescription = other.mBadgeContentDescription;
mShortcutInfo = other.mShortcutInfo;
mAppTarget = other.mAppTarget;
- mIsSuspended = other.mIsSuspended;
- synchronized (other) {
- mDisplayIcon = other.mDisplayIcon;
- mHasAttemptedIconLoad = other.mHasAttemptedIconLoad;
- }
+ mDisplayIcon = other.mDisplayIcon;
mFillInIntent = fillInIntent;
mFillInFlags = flags;
mModifiedScore = other.mModifiedScore;
mIsPinned = other.mIsPinned;
+ mReferrerFillInIntent = other.mReferrerFillInIntent;
mDisplayLabel = sanitizeDisplayLabel(mChooserTarget.getTitle());
}
@@ -181,7 +155,7 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
@Override
public boolean isSuspended() {
- return mIsSuspended;
+ return (mSourceInfo != null) && mSourceInfo.isSuspended();
}
@Override
@@ -190,79 +164,6 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
return mSourceInfo;
}
- /**
- * Load display icon, if needed.
- */
- @Override
- public boolean loadIcon() {
- synchronized (this) {
- // TODO: evaluating these conditions while `synchronized` ensures that we get consistent
- // reads between `mDisplayIcon` and `mHasAttemptedIconLoad`, but doesn't otherwise
- // prevent races where two threads might check the conditions (in synchrony) and then
- // both go on to load the icon (in parallel, even though one of the loads would be
- // redundant, and even though we have no logic to decide which result to keep if they
- // differ). This is probably a "safe optimization" in some cases, but our correctness
- // can't rely on this eliding the duplicate load, and with a more careful design we
- // could probably optimize it out in more cases (or else maybe we should get rid of
- // this complexity altogether).
- if ((mDisplayIcon != null) || (mShortcutInfo == null) || mHasAttemptedIconLoad) {
- return false;
- }
- }
-
- Drawable icon = getChooserTargetIconDrawable(mChooserTarget, mShortcutInfo);
- if (icon == null) {
- return false;
- }
-
- synchronized (this) {
- mDisplayIcon = icon;
- // TODO: we only end up setting `mHasAttemptedIconLoad` if we were successful in loading
- // a (non-null) display icon; in that case, our guard clause above will already
- // early-return `false` regardless of `mHasAttemptedIconLoad`. This should be refined,
- // or removed if we don't need the extra complexity (including the synchronizaiton?).
- mHasAttemptedIconLoad = true;
- }
- return true;
- }
-
- private Drawable getChooserTargetIconDrawable(ChooserTarget target,
- @Nullable ShortcutInfo shortcutInfo) {
- Drawable directShareIcon = null;
-
- // First get the target drawable and associated activity info
- final Icon icon = target.getIcon();
- if (icon != null) {
- directShareIcon = icon.loadDrawable(mContext);
- } else if (shortcutInfo != null) {
- LauncherApps launcherApps = (LauncherApps) mContext.getSystemService(
- Context.LAUNCHER_APPS_SERVICE);
- directShareIcon = launcherApps.getShortcutIconDrawable(shortcutInfo, 0);
- }
-
- if (directShareIcon == null) return null;
-
- ActivityInfo info = null;
- try {
- info = mPm.getActivityInfo(target.getComponentName(), 0);
- } catch (PackageManager.NameNotFoundException error) {
- Log.e(TAG, "Could not find activity associated with ChooserTarget");
- }
-
- if (info == null) return null;
-
- // Now fetch app icon and raster with no badging even in work profile
- Bitmap appIcon = mSelectableTargetInfoCommunicator.makePresentationGetter(info)
- .getIconBitmap(null);
-
- // Raster target drawable with appIcon as a badge
- SimpleIconFactory sif = SimpleIconFactory.obtain(mContext);
- Bitmap directShareBadgedIcon = sif.createAppBadgedIconBitmap(directShareIcon, appIcon);
- sif.recycle();
-
- return new BitmapDrawable(mContext.getResources(), directShareBadgedIcon);
- }
-
@Override
public float getModifiedScore() {
return mModifiedScore;
@@ -270,14 +171,7 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
@Override
public Intent getResolvedIntent() {
- if (mSourceInfo != null) {
- return mSourceInfo.getResolvedIntent();
- }
-
- final Intent targetIntent = new Intent(mSelectableTargetInfoCommunicator.getTargetIntent());
- targetIntent.setComponent(mChooserTarget.getComponentName());
- targetIntent.putExtras(mChooserTarget.getIntentExtras());
- return targetIntent;
+ return mResolvedIntent;
}
@Override
@@ -296,6 +190,11 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
return mChooserTarget.getComponentName();
}
+ @Nullable
+ public Icon getChooserTargetIcon() {
+ return mChooserTarget.getIcon();
+ }
+
private Intent getBaseIntentToSend() {
Intent result = getResolvedIntent();
if (result == null) {
@@ -305,7 +204,7 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
if (mFillInIntent != null) {
result.fillIn(mFillInIntent, mFillInFlags);
}
- result.fillIn(mSelectableTargetInfoCommunicator.getReferrerFillInIntent(), 0);
+ result.fillIn(mReferrerFillInIntent, 0);
}
return result;
}
@@ -362,16 +261,12 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
}
@Override
- public synchronized Drawable getDisplayIcon(Context context) {
+ public Drawable getDisplayIcon() {
return mDisplayIcon;
}
- /**
- * @return true if display icon is available
- */
- @Override
- public synchronized boolean hasDisplayIcon() {
- return mDisplayIcon != null;
+ public void setDisplayIcon(Drawable icon) {
+ mDisplayIcon = icon;
}
@Override
@@ -418,40 +313,19 @@ public final class SelectableTargetInfo extends ChooserTargetInfo {
mMaxHashSaltDays);
}
- @Nullable
- private static ApplicationInfo getApplicationInfoFromSource(
- @Nullable DisplayResolveInfo sourceInfo) {
- if (sourceInfo == null) {
- return null;
- }
-
- final ResolveInfo resolveInfo = sourceInfo.getResolveInfo();
- if (resolveInfo == null) {
- return null;
- }
-
- final ActivityInfo activityInfo = resolveInfo.activityInfo;
- if (activityInfo == null) {
- return null;
- }
-
- return activityInfo.applicationInfo;
- }
-
private static String sanitizeDisplayLabel(CharSequence label) {
SpannableStringBuilder sb = new SpannableStringBuilder(label);
sb.clearSpans();
return sb.toString();
}
+ // TODO: merge into ChooserListAdapter.ChooserListCommunicator and delete.
/**
* Necessary methods to communicate between {@link SelectableTargetInfo}
* and {@link ResolverActivity} or {@link ChooserActivity}.
*/
public interface SelectableTargetInfoCommunicator {
- ActivityInfoPresentationGetter makePresentationGetter(ActivityInfo info);
-
Intent getTargetIntent();
Intent getReferrerFillInIntent();
diff --git a/java/src/com/android/intentresolver/chooser/TargetInfo.java b/java/src/com/android/intentresolver/chooser/TargetInfo.java
index 46cd53c6..0e100d4f 100644
--- a/java/src/com/android/intentresolver/chooser/TargetInfo.java
+++ b/java/src/com/android/intentresolver/chooser/TargetInfo.java
@@ -136,14 +136,16 @@ public interface TargetInfo {
/**
* @return The drawable that should be used to represent this target including badge
- * @param context
*/
- Drawable getDisplayIcon(Context context);
+ @Nullable
+ Drawable getDisplayIcon();
/**
* @return true if display icon is available.
*/
- boolean hasDisplayIcon();
+ default boolean hasDisplayIcon() {
+ return getDisplayIcon() != null;
+ }
/**
* Clone this target with the given fill-in information.
*/
@@ -257,15 +259,6 @@ public interface TargetInfo {
}
/**
- * Attempt to load the display icon, if we have the info for one but it hasn't been loaded yet.
- * @return true if an icon may have been loaded as the result of this operation, potentially
- * prompting a UI refresh. If this returns false, clients can safely assume there was no change.
- */
- default boolean loadIcon() {
- return false;
- }
-
- /**
* Get more info about this target in the form of a {@link DisplayResolveInfo}, if available.
* TODO: this seems to return non-null only for ChooserTargetInfo subclasses. Determine the
* meaning of a TargetInfo (ChooserTargetInfo) embedding another kind of TargetInfo