summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Joshua Trask <joshtrask@google.com> 2022-10-07 14:19:26 -0400
committer Joshua Trask <joshtrask@google.com> 2022-10-07 16:12:40 -0400
commit93eadc3993a768cfac005faed2dcf56093cae2d5 (patch)
tree2812af63aa34ac45b8bec55e56f1dd3b020c628c
parente4b8aee927ca7f5ed6407cb1d9f621473b2dd778 (diff)
Missing changes from fork CL ag/20001357.
This is essentially porting the set of framework changes that either weren't synced to my local client at the time that the fork CL was cut, or else were merged only to framework since then, and not yet ported to IntentResolver. (Any future changes to framework Chooser should, hopefully, be accompanied by the parallel port CL at the time of submission.) This CL was constructed by a mostly-manual process: 1. Review the history of all framework changes under ../core/internal/app and ../core/internal/widget for changes in any files that have been ported to IntentResolver, and apply those diffs to the forked files (keeping in mind that each of these CLs could expand the scope beyond files that had been forked to-date). Also briefly review history in framework resources (no changes appear to be related to Chooser). 2. Review the set of diffs between relative paths in the IntentResolver package and the corresponding path resolved in the framework(*) to observe/enforce the expected set from ag/20001357 (effectively manually rolling back IntentResolver changes since fork; probably would've been better as a setup step, but:) 3. Manually re-apply IntentResolver-only changes that have been merged since the fork. 4. Review diffs in the IntentResolver package (i.e., this CL) to ensure that they're attributable to changes encountered in [1]. 5. Fix (pre-existing) lint errors in the changed files (only caught by presubmits after this CL was otherwise ready to upload / still good to address while we're here.) Re-build/test. Test: atest IntentResolverUnitTests Bug: 202166832 Change-Id: I23f4d4e763072abd0e9a4bb2d61fefc5f6b39830
-rw-r--r--java/src/com/android/intentresolver/ChooserActivity.java49
-rw-r--r--java/src/com/android/intentresolver/ChooserListAdapter.java85
-rw-r--r--java/src/com/android/intentresolver/ResolverActivity.java19
-rw-r--r--java/src/com/android/intentresolver/ResolverListAdapter.java82
-rw-r--r--java/src/com/android/intentresolver/SimpleIconFactory.java16
-rw-r--r--java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java11
-rw-r--r--java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java1
-rw-r--r--java/src/com/android/intentresolver/chooser/TargetInfo.java11
8 files changed, 151 insertions, 123 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java
index 5d169d24..d0e47562 100644
--- a/java/src/com/android/intentresolver/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/ChooserActivity.java
@@ -26,6 +26,7 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -140,6 +141,7 @@ import java.lang.annotation.RetentionPolicy;
import java.net.URISyntaxException;
import java.text.Collator;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -149,7 +151,7 @@ import java.util.function.Supplier;
/**
* The Chooser Activity handles intent resolution specifically for sharing intents -
- * for example, those generated by @see android.content.Intent#createChooser(Intent, CharSequence).
+ * for example, as generated by {@see android.content.Intent#createChooser(Intent, CharSequence)}.
*
*/
public class ChooserActivity extends ResolverActivity implements
@@ -1068,7 +1070,12 @@ public class ChooserActivity extends ResolverActivity implements
}
}
- private ViewGroup createContentPreviewView(ViewGroup parent) {
+ /**
+ * Create a view that will be shown in the content preview area
+ * @param parent reference to the parent container where the view should be attached to
+ * @return content preview view
+ */
+ protected ViewGroup createContentPreviewView(ViewGroup parent) {
Intent targetIntent = getTargetIntent();
int previewType = findPreferredContentPreview(targetIntent, getContentResolver());
return displayContentPreview(previewType, targetIntent, getLayoutInflater(), parent);
@@ -2067,6 +2074,7 @@ public class ChooserActivity extends ResolverActivity implements
if (matchingShortcuts.isEmpty()) {
continue;
}
+
List<ChooserTarget> chooserTargets = mShortcutToChooserTargetConverter
.convertToChooserTarget(
matchingShortcuts,
@@ -2588,7 +2596,7 @@ public class ChooserActivity extends ResolverActivity implements
boolean isExpandable = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
- if (directShareHeight != 0 && isSendAction(getTargetIntent())
+ if (directShareHeight != 0 && shouldShowContentPreview()
&& isExpandable) {
// make sure to leave room for direct share 4->8 expansion
int requiredExpansionHeight =
@@ -2828,7 +2836,14 @@ public class ChooserActivity extends ResolverActivity implements
return shouldShowTabs()
&& mMultiProfilePagerAdapter.getListAdapterForUserHandle(
UserHandle.of(UserHandle.myUserId())).getCount() > 0
- && isSendAction(getTargetIntent());
+ && shouldShowContentPreview();
+ }
+
+ /**
+ * @return true if we want to show the content preview area
+ */
+ protected boolean shouldShowContentPreview() {
+ return isSendAction(getTargetIntent());
}
private void updateStickyContentPreview() {
@@ -2880,12 +2895,14 @@ public class ChooserActivity extends ResolverActivity implements
private void startFinishAnimation() {
View rootView = findRootView();
- rootView.startAnimation(new FinishAnimation(this, rootView));
+ if (rootView != null) {
+ rootView.startAnimation(new FinishAnimation(this, rootView));
+ }
}
private boolean maybeCancelFinishAnimation() {
View rootView = findRootView();
- Animation animation = rootView.getAnimation();
+ Animation animation = (rootView == null) ? null : rootView.getAnimation();
if (animation instanceof FinishAnimation) {
boolean hasEnded = animation.hasEnded();
animation.cancel();
@@ -3159,7 +3176,7 @@ public class ChooserActivity extends ResolverActivity implements
return 0;
}
- if (!isSendAction(getTargetIntent())) {
+ if (!shouldShowContentPreview()) {
return 0;
}
@@ -3190,7 +3207,7 @@ public class ChooserActivity extends ResolverActivity implements
// There can be at most one row in the listview, that is internally
// a ViewGroup with 2 rows
public int getServiceTargetRowCount() {
- if (isSendAction(getTargetIntent())
+ if (shouldShowContentPreview()
&& !ActivityManager.isLowRamDeviceStatic()) {
return 1;
}
@@ -3649,6 +3666,7 @@ public class ChooserActivity extends ResolverActivity implements
this.mRows = rows;
this.mCellCountPerRow = cellCountPerRow;
this.mCellVisibility = new boolean[rows.size() * cellCountPerRow];
+ Arrays.fill(mCellVisibility, true);
this.mListAdapterSupplier = listAdapterSupplier;
}
@@ -4012,11 +4030,13 @@ public class ChooserActivity extends ResolverActivity implements
*/
private static class FinishAnimation extends AlphaAnimation implements
Animation.AnimationListener {
+ @Nullable
private Activity mActivity;
+ @Nullable
private View mRootView;
private final float mFromAlpha;
- FinishAnimation(Activity activity, View rootView) {
+ FinishAnimation(@NonNull Activity activity, @NonNull View rootView) {
super(rootView.getAlpha(), 0.0f);
mActivity = activity;
mRootView = rootView;
@@ -4040,7 +4060,9 @@ public class ChooserActivity extends ResolverActivity implements
@Override
public void cancel() {
- mRootView.setAlpha(mFromAlpha);
+ if (mRootView != null) {
+ mRootView.setAlpha(mFromAlpha);
+ }
cleanup();
super.cancel();
}
@@ -4051,9 +4073,10 @@ public class ChooserActivity extends ResolverActivity implements
@Override
public void onAnimationEnd(Animation animation) {
- if (mActivity != null) {
- mActivity.finish();
- cleanup();
+ Activity activity = mActivity;
+ cleanup();
+ if (activity != null) {
+ activity.finish();
}
}
diff --git a/java/src/com/android/intentresolver/ChooserListAdapter.java b/java/src/com/android/intentresolver/ChooserListAdapter.java
index 3d760129..5e508ed8 100644
--- a/java/src/com/android/intentresolver/ChooserListAdapter.java
+++ b/java/src/com/android/intentresolver/ChooserListAdapter.java
@@ -243,6 +243,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
mListViewDataChanged = false;
}
+
private void createPlaceHolders() {
mServiceTargets.clear();
for (int i = 0; i < mChooserListCommunicator.getMaxRankedTargets(); i++) {
@@ -252,8 +253,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
@Override
View onCreateView(ViewGroup parent) {
- return mInflater.inflate(
- R.layout.resolve_grid_item, parent, false);
+ return mInflater.inflate(R.layout.resolve_grid_item, parent, false);
}
@Override
@@ -266,25 +266,20 @@ public class ChooserListAdapter extends ResolverListAdapter {
return;
}
- if (info instanceof DisplayResolveInfo) {
+ holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
+ holder.bindIcon(info);
+ if (info instanceof SelectableTargetInfo) {
+ // direct share targets should append the application name for a better readout
+ DisplayResolveInfo rInfo = ((SelectableTargetInfo) info).getDisplayResolveInfo();
+ CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : "";
+ CharSequence extendedInfo = info.getExtendedInfo();
+ String contentDescription = String.join(" ", info.getDisplayLabel(),
+ extendedInfo != null ? extendedInfo : "", appName);
+ holder.updateContentDescription(contentDescription);
+ } else if (info instanceof DisplayResolveInfo) {
DisplayResolveInfo dri = (DisplayResolveInfo) info;
- holder.bindLabel(dri.getDisplayLabel(), dri.getExtendedInfo(), alwaysShowSubLabel());
- startDisplayResolveInfoIconLoading(holder, dri);
- } else {
- holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
-
- if (info instanceof SelectableTargetInfo) {
- SelectableTargetInfo selectableInfo = (SelectableTargetInfo) info;
- // direct share targets should append the application name for a better readout
- DisplayResolveInfo rInfo = selectableInfo.getDisplayResolveInfo();
- CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : "";
- CharSequence extendedInfo = selectableInfo.getExtendedInfo();
- String contentDescription = String.join(" ", selectableInfo.getDisplayLabel(),
- extendedInfo != null ? extendedInfo : "", appName);
- holder.updateContentDescription(contentDescription);
- startSelectableTargetInfoIconLoading(holder, selectableInfo);
- } else {
- holder.bindIcon(info);
+ if (!dri.hasDisplayIcon()) {
+ loadIcon(dri);
}
}
@@ -325,32 +320,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
}
- private void startDisplayResolveInfoIconLoading(ViewHolder holder, DisplayResolveInfo info) {
- LoadIconTask task = (LoadIconTask) mIconLoaders.get(info);
- if (task == null) {
- task = new LoadIconTask(info, holder);
- mIconLoaders.put(info, task);
- task.execute();
- } else {
- // The holder was potentially changed as the underlying items were
- // reshuffled, so reset the target holder
- task.setViewHolder(holder);
- }
- }
-
- private void startSelectableTargetInfoIconLoading(
- ViewHolder holder, SelectableTargetInfo info) {
- LoadDirectShareIconTask task = (LoadDirectShareIconTask) mIconLoaders.get(info);
- if (task == null) {
- task = mTestLoadDirectShareTaskProvider == null
- ? new LoadDirectShareIconTask(info)
- : mTestLoadDirectShareTaskProvider.get();
- mIconLoaders.put(info, task);
- task.loadIcon();
- }
- task.setViewHolder(holder);
- }
-
void updateAlphabeticalList() {
new AsyncTask<Void, Void, List<DisplayResolveInfo>>() {
@Override
@@ -560,12 +529,11 @@ public class ChooserListAdapter extends ResolverListAdapter {
List<ChooserTarget> targets,
@ChooserActivity.ShareTargetType int targetType,
Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos) {
- // Avoid inserting any potentially late results
- if (mServiceTargets.size() == 1
- && mServiceTargets.get(0) instanceof ChooserActivity.EmptyTargetInfo) {
+ // Avoid inserting any potentially late results.
+ if ((mServiceTargets.size() == 1)
+ && (mServiceTargets.get(0) instanceof ChooserActivity.EmptyTargetInfo)) {
return;
}
-
boolean isShortcutResult = targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER
|| targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
boolean isUpdated = mShortcutSelectionLogic.addServiceResults(
@@ -619,7 +587,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
notifyDataSetChanged();
}
-
public ChooserTarget getChooserTargetForValue(int value) {
return mServiceTargets.get(value).getChooserTarget();
}
@@ -678,24 +645,10 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
/**
- * An alias for onBindView to use with unit tests.
- */
- @VisibleForTesting
- public void testViewBind(View view, TargetInfo info, int position) {
- onBindView(view, info, position);
- }
-
- @VisibleForTesting
- public void setTestLoadDirectShareTaskProvider(LoadDirectShareIconTaskProvider provider) {
- mTestLoadDirectShareTaskProvider = provider;
- }
-
- /**
* Necessary methods to communicate between {@link ChooserListAdapter}
* and {@link ChooserActivity}.
*/
- @VisibleForTesting
- public interface ChooserListCommunicator extends ResolverListCommunicator {
+ interface ChooserListCommunicator extends ResolverListCommunicator {
int getMaxRankedTargets();
diff --git a/java/src/com/android/intentresolver/ResolverActivity.java b/java/src/com/android/intentresolver/ResolverActivity.java
index 453a6e84..6c013221 100644
--- a/java/src/com/android/intentresolver/ResolverActivity.java
+++ b/java/src/com/android/intentresolver/ResolverActivity.java
@@ -55,6 +55,7 @@ import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Insets;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -94,7 +95,6 @@ import com.android.intentresolver.AbstractMultiProfilePagerAdapter.Profile;
import com.android.intentresolver.chooser.ChooserTargetInfo;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.TargetInfo;
-
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.logging.MetricsLogger;
@@ -1475,14 +1475,21 @@ public class ResolverActivity extends Activity implements
mMultiProfilePagerAdapter.getActiveListAdapter().mDisplayList.get(0);
boolean inWorkProfile = getCurrentProfile() == PROFILE_WORK;
- ResolverListAdapter inactiveAdapter = mMultiProfilePagerAdapter.getInactiveListAdapter();
- DisplayResolveInfo otherProfileResolveInfo = inactiveAdapter.mDisplayList.get(0);
+ final ResolverListAdapter inactiveAdapter =
+ mMultiProfilePagerAdapter.getInactiveListAdapter();
+ final DisplayResolveInfo otherProfileResolveInfo = inactiveAdapter.mDisplayList.get(0);
// Load the icon asynchronously
ImageView icon = findViewById(com.android.internal.R.id.icon);
- ResolverListAdapter.LoadIconTask iconTask = inactiveAdapter.new LoadIconTask(
- otherProfileResolveInfo, new ResolverListAdapter.ViewHolder(icon));
- iconTask.execute();
+ inactiveAdapter.new LoadIconTask(otherProfileResolveInfo) {
+ @Override
+ protected void onPostExecute(Drawable drawable) {
+ if (!isDestroyed()) {
+ otherProfileResolveInfo.setDisplayIcon(drawable);
+ new ResolverListAdapter.ViewHolder(icon).bindIcon(otherProfileResolveInfo);
+ }
+ }
+ }.execute();
((TextView) findViewById(com.android.internal.R.id.open_cross_profile)).setText(
getResources().getString(
diff --git a/java/src/com/android/intentresolver/ResolverListAdapter.java b/java/src/com/android/intentresolver/ResolverListAdapter.java
index 898d8c8e..251b157b 100644
--- a/java/src/com/android/intentresolver/ResolverListAdapter.java
+++ b/java/src/com/android/intentresolver/ResolverListAdapter.java
@@ -54,11 +54,13 @@ import android.widget.TextView;
import com.android.intentresolver.ResolverActivity.ResolvedComponentInfo;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.TargetInfo;
-
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class ResolverListAdapter extends BaseAdapter {
private static final String TAG = "ResolverListAdapter";
@@ -87,6 +89,8 @@ public class ResolverListAdapter extends BaseAdapter {
private Runnable mPostListReadyRunnable;
private final boolean mIsAudioCaptureDevice;
private boolean mIsTabLoaded;
+ private final Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
+ private final Map<DisplayResolveInfo, LoadLabelTask> mLabelLoaders = new HashMap<>();
public ResolverListAdapter(Context context, List<Intent> payloadIntents,
Intent[] initialIntents, List<ResolveInfo> rList,
@@ -636,26 +640,47 @@ public class ResolverListAdapter extends BaseAdapter {
if (info == null) {
holder.icon.setImageDrawable(
mContext.getDrawable(R.drawable.resolver_icon_placeholder));
+ holder.bindLabel("", "", false);
return;
}
- if (info instanceof DisplayResolveInfo
- && !((DisplayResolveInfo) info).hasDisplayLabel()) {
- getLoadLabelTask((DisplayResolveInfo) info, holder).execute();
- } else {
- holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
+ if (info instanceof DisplayResolveInfo) {
+ DisplayResolveInfo dri = (DisplayResolveInfo) info;
+ boolean hasLabel = dri.hasDisplayLabel();
+ holder.bindLabel(
+ dri.getDisplayLabel(),
+ dri.getExtendedInfo(),
+ hasLabel && alwaysShowSubLabel());
+ holder.bindIcon(info);
+ if (!hasLabel) {
+ loadLabel(dri);
+ }
+ if (!dri.hasDisplayIcon()) {
+ loadIcon(dri);
+ }
}
+ }
- if (info instanceof DisplayResolveInfo
- && !((DisplayResolveInfo) info).hasDisplayIcon()) {
- new LoadIconTask((DisplayResolveInfo) info, holder).execute();
- } else {
- holder.bindIcon(info);
+ protected final void loadIcon(DisplayResolveInfo info) {
+ LoadIconTask task = mIconLoaders.get(info);
+ if (task == null) {
+ task = new LoadIconTask((DisplayResolveInfo) info);
+ mIconLoaders.put(info, task);
+ task.execute();
}
}
- protected LoadLabelTask getLoadLabelTask(DisplayResolveInfo info, ViewHolder holder) {
- return new LoadLabelTask(info, holder);
+ private void loadLabel(DisplayResolveInfo info) {
+ LoadLabelTask task = mLabelLoaders.get(info);
+ if (task == null) {
+ task = createLoadLabelTask(info);
+ mLabelLoaders.put(info, task);
+ task.execute();
+ }
+ }
+
+ protected LoadLabelTask createLoadLabelTask(DisplayResolveInfo info) {
+ return new LoadLabelTask(info);
}
public void onDestroy() {
@@ -666,6 +691,16 @@ public class ResolverListAdapter extends BaseAdapter {
if (mResolverListController != null) {
mResolverListController.destroy();
}
+ cancelTasks(mIconLoaders.values());
+ cancelTasks(mLabelLoaders.values());
+ mIconLoaders.clear();
+ mLabelLoaders.clear();
+ }
+
+ private <T extends AsyncTask> void cancelTasks(Collection<T> tasks) {
+ for (T task: tasks) {
+ task.cancel(false);
+ }
}
private static ColorMatrixColorFilter getSuspendedColorMatrix() {
@@ -888,11 +923,9 @@ public class ResolverListAdapter extends BaseAdapter {
protected class LoadLabelTask extends AsyncTask<Void, Void, CharSequence[]> {
private final DisplayResolveInfo mDisplayResolveInfo;
- private final ViewHolder mHolder;
- protected LoadLabelTask(DisplayResolveInfo dri, ViewHolder holder) {
+ protected LoadLabelTask(DisplayResolveInfo dri) {
mDisplayResolveInfo = dri;
- mHolder = holder;
}
@Override
@@ -930,21 +963,22 @@ public class ResolverListAdapter extends BaseAdapter {
@Override
protected void onPostExecute(CharSequence[] result) {
+ if (mDisplayResolveInfo.hasDisplayLabel()) {
+ return;
+ }
mDisplayResolveInfo.setDisplayLabel(result[0]);
mDisplayResolveInfo.setExtendedInfo(result[1]);
- mHolder.bindLabel(result[0], result[1], alwaysShowSubLabel());
+ notifyDataSetChanged();
}
}
class LoadIconTask extends AsyncTask<Void, Void, Drawable> {
protected final DisplayResolveInfo mDisplayResolveInfo;
private final ResolveInfo mResolveInfo;
- private ViewHolder mHolder;
- LoadIconTask(DisplayResolveInfo dri, ViewHolder holder) {
+ LoadIconTask(DisplayResolveInfo dri) {
mDisplayResolveInfo = dri;
mResolveInfo = dri.getResolveInfo();
- mHolder = holder;
}
@Override
@@ -958,17 +992,9 @@ public class ResolverListAdapter extends BaseAdapter {
mResolverListCommunicator.updateProfileViewButton();
} else if (!mDisplayResolveInfo.hasDisplayIcon()) {
mDisplayResolveInfo.setDisplayIcon(d);
- mHolder.bindIcon(mDisplayResolveInfo);
- // Notify in case view is already bound to resolve the race conditions on
- // low end devices
notifyDataSetChanged();
}
}
-
- public void setViewHolder(ViewHolder holder) {
- mHolder = holder;
- mHolder.bindIcon(mDisplayResolveInfo);
- }
}
/**
diff --git a/java/src/com/android/intentresolver/SimpleIconFactory.java b/java/src/com/android/intentresolver/SimpleIconFactory.java
index b05b4f68..ec5179ac 100644
--- a/java/src/com/android/intentresolver/SimpleIconFactory.java
+++ b/java/src/com/android/intentresolver/SimpleIconFactory.java
@@ -50,6 +50,8 @@ import android.util.AttributeSet;
import android.util.Pools.SynchronizedPool;
import android.util.TypedValue;
+import com.android.internal.annotations.VisibleForTesting;
+
import org.xmlpull.v1.XmlPullParser;
import java.nio.ByteBuffer;
@@ -67,6 +69,7 @@ public class SimpleIconFactory {
private static final SynchronizedPool<SimpleIconFactory> sPool =
new SynchronizedPool<>(Runtime.getRuntime().availableProcessors());
+ private static boolean sPoolEnabled = true;
private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE;
private static final float BLUR_FACTOR = 1.5f / 48;
@@ -90,7 +93,7 @@ public class SimpleIconFactory {
*/
@Deprecated
public static SimpleIconFactory obtain(Context ctx) {
- SimpleIconFactory instance = sPool.acquire();
+ SimpleIconFactory instance = sPoolEnabled ? sPool.acquire() : null;
if (instance == null) {
final ActivityManager am = (ActivityManager) ctx.getSystemService(ACTIVITY_SERVICE);
final int iconDpi = (am == null) ? 0 : am.getLauncherLargeIconDensity();
@@ -104,6 +107,17 @@ public class SimpleIconFactory {
return instance;
}
+ /**
+ * Enables or disables SimpleIconFactory objects pooling. It is enabled in production, you
+ * could use this method in tests and disable the pooling to make the icon rendering more
+ * deterministic because some sizing parameters will not be cached. Please ensure that you
+ * reset this value back after finishing the test.
+ */
+ @VisibleForTesting
+ public static void setPoolEnabled(boolean poolEnabled) {
+ sPoolEnabled = poolEnabled;
+ }
+
private static int getAttrDimFromContext(Context ctx, @AttrRes int attrId, String errorMsg) {
final Resources res = ctx.getResources();
TypedValue outVal = new TypedValue();
diff --git a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
index e7ffe3c6..c4bca266 100644
--- a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
+++ b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java
@@ -172,14 +172,14 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable {
@Override
public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
- prepareIntentForCrossProfileLaunch(mResolvedIntent, userId);
+ TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId);
activity.startActivityAsCaller(mResolvedIntent, options, false, userId);
return true;
}
@Override
public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
- prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier());
+ TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier());
activity.startActivityAsUser(mResolvedIntent, options, user);
return false;
}
@@ -224,13 +224,6 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable {
}
};
- private static void prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId) {
- final int currentUserId = UserHandle.myUserId();
- if (targetUserId != currentUserId) {
- intent.fixUris(currentUserId);
- }
- }
-
private DisplayResolveInfo(Parcel in) {
mDisplayLabel = in.readCharSequence();
mExtendedInfo = in.readCharSequence();
diff --git a/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java b/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java
index dffe2f6c..179966ad 100644
--- a/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java
+++ b/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java
@@ -259,6 +259,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
}
intent.setComponent(mChooserTarget.getComponentName());
intent.putExtras(mChooserTarget.getIntentExtras());
+ TargetInfo.prepareIntentForCrossProfileLaunch(intent, userId);
// Important: we will ignore the target security checks in ActivityManager
// if and only if the ChooserTarget's target package is the same package
diff --git a/java/src/com/android/intentresolver/chooser/TargetInfo.java b/java/src/com/android/intentresolver/chooser/TargetInfo.java
index fabb26c2..e1970354 100644
--- a/java/src/com/android/intentresolver/chooser/TargetInfo.java
+++ b/java/src/com/android/intentresolver/chooser/TargetInfo.java
@@ -130,4 +130,15 @@ public interface TargetInfo {
* @return true if this target should be pinned to the front by the request of the user
*/
boolean isPinned();
+
+ /**
+ * Fix the URIs in {@code intent} if cross-profile sharing is required. This should be called
+ * before launching the intent as another user.
+ */
+ static void prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId) {
+ final int currentUserId = UserHandle.myUserId();
+ if (targetUserId != currentUserId) {
+ intent.fixUris(currentUserId);
+ }
+ }
}