diff options
16 files changed, 195 insertions, 167 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActionFactory.java b/java/src/com/android/intentresolver/ChooserActionFactory.java index 2c97c0b1..6d56146d 100644 --- a/java/src/com/android/intentresolver/ChooserActionFactory.java +++ b/java/src/com/android/intentresolver/ChooserActionFactory.java @@ -317,8 +317,7 @@ public final class ChooserActionFactory implements ChooserContentPreviewUi.Actio ri, context.getString(R.string.screenshot_edit), "", - resolveIntent, - null); + resolveIntent); dri.getDisplayIconHolder().setDisplayIcon( context.getDrawable(com.android.internal.R.drawable.ic_screenshot_edit)); return dri; diff --git a/java/src/com/android/intentresolver/ChooserListAdapter.java b/java/src/com/android/intentresolver/ChooserListAdapter.java index a9ed983d..2e1476d8 100644 --- a/java/src/com/android/intentresolver/ChooserListAdapter.java +++ b/java/src/com/android/intentresolver/ChooserListAdapter.java @@ -38,6 +38,7 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.service.chooser.ChooserTarget; import android.text.Layout; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -60,6 +61,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -230,9 +232,8 @@ public class ChooserListAdapter extends ResolverListAdapter { ri.icon = 0; } ri.userHandle = initialIntentsUserSpace; - // TODO: remove DisplayResolveInfo dependency on presentation getter - DisplayResolveInfo displayResolveInfo = DisplayResolveInfo.newDisplayResolveInfo( - ii, ri, ii, mTargetDataLoader.createPresentationGetter(ri)); + DisplayResolveInfo displayResolveInfo = + DisplayResolveInfo.newDisplayResolveInfo(ii, ri, ii); mCallerTargets.add(displayResolveInfo); if (mCallerTargets.size() == MAX_SUGGESTED_APP_TARGETS) break; } @@ -275,35 +276,42 @@ public class ChooserListAdapter extends ResolverListAdapter { public void onBindView(View view, TargetInfo info, int position) { final ViewHolder holder = (ViewHolder) view.getTag(); + holder.reset(); + // Always remove the spacing listener, attach as needed to direct share targets below. + holder.text.removeOnLayoutChangeListener(mPinTextSpacingListener); + if (info == null) { holder.icon.setImageDrawable(loadIconPlaceholder()); return; } - holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo()); - mAnimationTracker.animateLabel(holder.text, info); - if (holder.text2.getVisibility() == View.VISIBLE) { + final CharSequence displayLabel = Objects.requireNonNullElse(info.getDisplayLabel(), ""); + final CharSequence extendedInfo = Objects.requireNonNullElse(info.getExtendedInfo(), ""); + holder.bindLabel(displayLabel, extendedInfo); + if (!TextUtils.isEmpty(displayLabel)) { + mAnimationTracker.animateLabel(holder.text, info); + } + if (!TextUtils.isEmpty(extendedInfo) && holder.text2.getVisibility() == View.VISIBLE) { mAnimationTracker.animateLabel(holder.text2, info); } + holder.bindIcon(info); - if (info.getDisplayIconHolder().getDisplayIcon() != null) { + if (info.hasDisplayIcon()) { mAnimationTracker.animateIcon(holder.icon, info); - } else { - holder.icon.clearAnimation(); } if (info.isSelectableTargetInfo()) { // direct share targets should append the application name for a better readout DisplayResolveInfo rInfo = info.getDisplayResolveInfo(); - CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : ""; - CharSequence extendedInfo = info.getExtendedInfo(); - String contentDescription = String.join(" ", info.getDisplayLabel(), - extendedInfo != null ? extendedInfo : "", appName); + CharSequence appName = + Objects.requireNonNullElse(rInfo == null ? null : rInfo.getDisplayLabel(), ""); + String contentDescription = + String.join(" ", info.getDisplayLabel(), extendedInfo, appName); if (info.isPinned()) { contentDescription = String.join( - ". ", - contentDescription, - mContext.getResources().getString(R.string.pinned)); + ". ", + contentDescription, + mContext.getResources().getString(R.string.pinned)); } holder.updateContentDescription(contentDescription); if (!info.hasDisplayIcon()) { @@ -320,42 +328,30 @@ public class ChooserListAdapter extends ResolverListAdapter { if (!dri.hasDisplayIcon()) { loadIcon(dri); } + if (!dri.hasDisplayLabel()) { + loadLabel(dri); + } } // If target is loading, show a special placeholder shape in the label, make unclickable if (info.isPlaceHolderTargetInfo()) { - final int maxWidth = mContext.getResources().getDimensionPixelSize( + int maxTextWidth = mContext.getResources().getDimensionPixelSize( R.dimen.chooser_direct_share_label_placeholder_max_width); - holder.text.setMaxWidth(maxWidth); - holder.text.setBackground(mContext.getResources().getDrawable( - R.drawable.chooser_direct_share_label_placeholder, mContext.getTheme())); - // Prevent rippling by removing background containing ripple - holder.itemView.setBackground(null); - } else { - holder.text.setMaxWidth(Integer.MAX_VALUE); - holder.text.setBackground(null); - holder.itemView.setBackground(holder.defaultItemViewBackground); + Drawable placeholderDrawable = mContext.getResources().getDrawable( + R.drawable.chooser_direct_share_label_placeholder, mContext.getTheme()); + holder.bindPlaceholderDrawable(maxTextWidth, placeholderDrawable); } - // Always remove the spacing listener, attach as needed to direct share targets below. - holder.text.removeOnLayoutChangeListener(mPinTextSpacingListener); - if (info.isMultiDisplayResolveInfo()) { // If the target is grouped show an indicator - Drawable bkg = mContext.getDrawable(R.drawable.chooser_group_background); - holder.text.setPaddingRelative(0, 0, bkg.getIntrinsicWidth() /* end */, 0); - holder.text.setBackground(bkg); + holder.bindGroupIndicator( + mContext.getDrawable(R.drawable.chooser_group_background)); } else if (info.isPinned() && (getPositionTargetType(position) == TARGET_STANDARD || getPositionTargetType(position) == TARGET_SERVICE)) { // If the appShare or directShare target is pinned and in the suggested row show a // pinned indicator - Drawable bkg = mContext.getDrawable(R.drawable.chooser_pinned_background); - holder.text.setPaddingRelative(bkg.getIntrinsicWidth() /* start */, 0, 0, 0); - holder.text.setBackground(bkg); + holder.bindPinnedIndicator(mContext.getDrawable(R.drawable.chooser_pinned_background)); holder.text.addOnLayoutChangeListener(mPinTextSpacingListener); - } else { - holder.text.setBackground(null); - holder.text.setPaddingRelative(0, 0, 0, 0); } } @@ -376,8 +372,12 @@ public class ChooserListAdapter extends ResolverListAdapter { } void updateAlphabeticalList() { - // TODO: this procedure seems like it should be relatively lightweight. Why does it need to - // run in an `AsyncTask`? + final ChooserActivity.AzInfoComparator comparator = + new ChooserActivity.AzInfoComparator(mContext); + final List<DisplayResolveInfo> allTargets = new ArrayList<>(); + allTargets.addAll(getTargetsInCurrentDisplayList()); + allTargets.addAll(mCallerTargets); + new AsyncTask<Void, Void, List<DisplayResolveInfo>>() { @Override protected List<DisplayResolveInfo> doInBackground(Void... voids) { @@ -390,9 +390,7 @@ public class ChooserListAdapter extends ResolverListAdapter { } private List<DisplayResolveInfo> updateList() { - List<DisplayResolveInfo> allTargets = new ArrayList<>(); - allTargets.addAll(getTargetsInCurrentDisplayList()); - allTargets.addAll(mCallerTargets); + loadMissingLabels(allTargets); // Consolidate multiple targets from same app. return allTargets @@ -408,8 +406,8 @@ public class ChooserListAdapter extends ResolverListAdapter { (appTargets.size() == 1) ? appTargets.get(0) : MultiDisplayResolveInfo.newMultiDisplayResolveInfo( - appTargets)) - .sorted(new ChooserActivity.AzInfoComparator(mContext)) + appTargets)) + .sorted(comparator) .collect(Collectors.toList()); } @@ -418,6 +416,12 @@ public class ChooserListAdapter extends ResolverListAdapter { mSortedList = newList; notifyDataSetChanged(); } + + private void loadMissingLabels(List<DisplayResolveInfo> targets) { + for (DisplayResolveInfo target: targets) { + mTargetDataLoader.getOrLoadLabel(target); + } + } }.execute(); } diff --git a/java/src/com/android/intentresolver/ResolverActivity.java b/java/src/com/android/intentresolver/ResolverActivity.java index 47a8bf2a..1161ca81 100644 --- a/java/src/com/android/intentresolver/ResolverActivity.java +++ b/java/src/com/android/intentresolver/ResolverActivity.java @@ -33,7 +33,6 @@ import static android.content.PermissionChecker.PID_UNKNOWN; import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; - import static com.android.internal.annotations.VisibleForTesting.Visibility.PROTECTED; import android.annotation.Nullable; @@ -199,6 +198,8 @@ public class ResolverActivity extends FragmentActivity implements private PackageMonitor mPersonalPackageMonitor; private PackageMonitor mWorkPackageMonitor; + private TargetDataLoader mTargetDataLoader; + @VisibleForTesting protected AbstractMultiProfilePagerAdapter mMultiProfilePagerAdapter; @@ -427,6 +428,7 @@ public class ResolverActivity extends FragmentActivity implements mSupportsAlwaysUseOption = supportsAlwaysUseOption; mSafeForwardingMode = safeForwardingMode; + mTargetDataLoader = targetDataLoader; // The last argument of createResolverListAdapter is whether to do special handling // of the last used choice to highlight it in the list. We need to always @@ -1387,7 +1389,7 @@ public class ResolverActivity extends FragmentActivity implements } final Option optionForChooserTarget(TargetInfo target, int index) { - return new Option(target.getDisplayLabel(), index); + return new Option(getOrLoadDisplayLabel(target), index); } public final Intent getTargetIntent() { @@ -1463,8 +1465,11 @@ public class ResolverActivity extends FragmentActivity implements return getString(defaultTitleRes); } else { return named - ? getString(title.namedTitleRes, mMultiProfilePagerAdapter - .getActiveListAdapter().getFilteredItem().getDisplayLabel()) + ? getString( + title.namedTitleRes, + getOrLoadDisplayLabel( + mMultiProfilePagerAdapter + .getActiveListAdapter().getFilteredItem())) : getString(title.titleRes); } } @@ -1801,9 +1806,10 @@ public class ResolverActivity extends FragmentActivity implements ((TextView) findViewById(com.android.internal.R.id.open_cross_profile)).setText( getResources().getString( - inWorkProfile ? R.string.miniresolver_open_in_personal + inWorkProfile + ? R.string.miniresolver_open_in_personal : R.string.miniresolver_open_in_work, - otherProfileResolveInfo.getDisplayLabel())); + getOrLoadDisplayLabel(otherProfileResolveInfo))); ((Button) findViewById(com.android.internal.R.id.use_same_profile_browser)).setText( inWorkProfile ? R.string.miniresolver_use_work_browser : R.string.miniresolver_use_personal_browser); @@ -2397,4 +2403,12 @@ public class ResolverActivity extends FragmentActivity implements } return userList; } + + private CharSequence getOrLoadDisplayLabel(TargetInfo info) { + if (info.isDisplayResolveInfo()) { + mTargetDataLoader.getOrLoadLabel((DisplayResolveInfo) info); + } + CharSequence displayLabel = info.getDisplayLabel(); + return displayLabel == null ? "" : displayLabel; + } } diff --git a/java/src/com/android/intentresolver/ResolverListAdapter.java b/java/src/com/android/intentresolver/ResolverListAdapter.java index 14ce0e0e..a243ac2a 100644 --- a/java/src/com/android/intentresolver/ResolverListAdapter.java +++ b/java/src/com/android/intentresolver/ResolverListAdapter.java @@ -397,8 +397,8 @@ public class ResolverListAdapter extends BaseAdapter { otherProfileInfo, mPm, mTargetIntent, - mResolverListCommunicator, - mTargetDataLoader); + mResolverListCommunicator + ); } else { mOtherProfile = null; try { @@ -518,8 +518,7 @@ public class ResolverListAdapter extends BaseAdapter { ri, ri.loadLabel(mPm), null, - ii, - mTargetDataLoader.createPresentationGetter(ri))); + ii)); } } @@ -571,8 +570,7 @@ public class ResolverListAdapter extends BaseAdapter { final DisplayResolveInfo dri = DisplayResolveInfo.newDisplayResolveInfo( intent, add, - (replaceIntent != null) ? replaceIntent : defaultIntent, - mTargetDataLoader.createPresentationGetter(add)); + (replaceIntent != null) ? replaceIntent : defaultIntent); dri.setPinned(rci.isPinned()); if (rci.isPinned()) { Log.i(TAG, "Pinned item: " + rci.name); @@ -757,7 +755,7 @@ public class ResolverListAdapter extends BaseAdapter { } } - private void loadLabel(DisplayResolveInfo info) { + protected final void loadLabel(DisplayResolveInfo info) { if (mRequestedLabels.add(info)) { mTargetDataLoader.loadLabel(info, (result) -> onLabelLoaded(info, result)); } @@ -875,8 +873,7 @@ public class ResolverListAdapter extends BaseAdapter { ResolvedComponentInfo resolvedComponentInfo, PackageManager pm, Intent targetIntent, - ResolverListCommunicator resolverListCommunicator, - TargetDataLoader targetDataLoader) { + ResolverListCommunicator resolverListCommunicator) { ResolveInfo resolveInfo = resolvedComponentInfo.getResolveInfoAt(0); Intent pOrigIntent = resolverListCommunicator.getReplacementIntent( @@ -885,16 +882,12 @@ public class ResolverListAdapter extends BaseAdapter { Intent replacementIntent = resolverListCommunicator.getReplacementIntent( resolveInfo.activityInfo, targetIntent); - TargetPresentationGetter presentationGetter = - targetDataLoader.createPresentationGetter(resolveInfo); - return DisplayResolveInfo.newDisplayResolveInfo( resolvedComponentInfo.getIntentAt(0), resolveInfo, resolveInfo.loadLabel(pm), resolveInfo.loadLabel(pm), - pOrigIntent != null ? pOrigIntent : replacementIntent, - presentationGetter); + pOrigIntent != null ? pOrigIntent : replacementIntent); } /** @@ -938,6 +931,24 @@ public class ResolverListAdapter extends BaseAdapter { public TextView text2; public ImageView icon; + public final void reset() { + text.setText(""); + text.setMaxLines(2); + text.setMaxWidth(Integer.MAX_VALUE); + text.setBackground(null); + text.setPaddingRelative(0, 0, 0, 0); + + text2.setVisibility(View.GONE); + text2.setText(""); + + itemView.setContentDescription(null); + itemView.setBackground(defaultItemViewBackground); + + icon.setImageDrawable(null); + icon.setColorFilter(null); + icon.clearAnimation(); + } + @VisibleForTesting public ViewHolder(View view) { itemView = view; @@ -982,5 +993,22 @@ public class ResolverListAdapter extends BaseAdapter { icon.setColorFilter(null); } } + + public void bindPlaceholderDrawable(int maxTextWidth, Drawable drawable) { + text.setMaxWidth(maxTextWidth); + text.setBackground(drawable); + // Prevent rippling by removing background containing ripple + itemView.setBackground(null); + } + + public void bindGroupIndicator(Drawable indicator) { + text.setPaddingRelative(0, 0, /*end = */indicator.getIntrinsicWidth(), 0); + text.setBackground(indicator); + } + + public void bindPinnedIndicator(Drawable indicator) { + text.setPaddingRelative(/*start = */indicator.getIntrinsicWidth(), 0, 0, 0); + text.setBackground(indicator); + } } } diff --git a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java index 09cf319f..866da5f6 100644 --- a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java +++ b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java @@ -27,10 +27,7 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.UserHandle; -import com.android.intentresolver.TargetPresentationGetter; - import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -39,12 +36,11 @@ import java.util.List; */ public class DisplayResolveInfo implements TargetInfo { private final ResolveInfo mResolveInfo; - private CharSequence mDisplayLabel; - private CharSequence mExtendedInfo; + private volatile CharSequence mDisplayLabel; + private volatile CharSequence mExtendedInfo; private final Intent mResolvedIntent; private final List<Intent> mSourceIntents = new ArrayList<>(); private final boolean mIsSuspended; - private TargetPresentationGetter mPresentationGetter; private boolean mPinned = false; private final IconHolder mDisplayIconHolder = new SettableIconHolder(); @@ -52,15 +48,13 @@ public class DisplayResolveInfo implements TargetInfo { public static DisplayResolveInfo newDisplayResolveInfo( Intent originalIntent, ResolveInfo resolveInfo, - @NonNull Intent resolvedIntent, - @Nullable TargetPresentationGetter presentationGetter) { + @NonNull Intent resolvedIntent) { return newDisplayResolveInfo( originalIntent, resolveInfo, /* displayLabel=*/ null, /* extendedInfo=*/ null, - resolvedIntent, - presentationGetter); + resolvedIntent); } /** Create a new {@code DisplayResolveInfo} instance. */ @@ -69,15 +63,13 @@ public class DisplayResolveInfo implements TargetInfo { ResolveInfo resolveInfo, CharSequence displayLabel, CharSequence extendedInfo, - @NonNull Intent resolvedIntent, - @Nullable TargetPresentationGetter presentationGetter) { + @NonNull Intent resolvedIntent) { return new DisplayResolveInfo( originalIntent, resolveInfo, displayLabel, extendedInfo, - resolvedIntent, - presentationGetter); + resolvedIntent); } private DisplayResolveInfo( @@ -85,13 +77,11 @@ public class DisplayResolveInfo implements TargetInfo { ResolveInfo resolveInfo, CharSequence displayLabel, CharSequence extendedInfo, - @NonNull Intent resolvedIntent, - @Nullable TargetPresentationGetter presentationGetter) { + @NonNull Intent resolvedIntent) { mSourceIntents.add(originalIntent); mResolveInfo = resolveInfo; mDisplayLabel = displayLabel; mExtendedInfo = extendedInfo; - mPresentationGetter = presentationGetter; final ActivityInfo ai = mResolveInfo.activityInfo; mIsSuspended = (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0; @@ -101,8 +91,7 @@ public class DisplayResolveInfo implements TargetInfo { private DisplayResolveInfo( DisplayResolveInfo other, - @Nullable Intent baseIntentToSend, - TargetPresentationGetter presentationGetter) { + @Nullable Intent baseIntentToSend) { mSourceIntents.addAll(other.getAllSourceIntents()); mResolveInfo = other.mResolveInfo; mIsSuspended = other.mIsSuspended; @@ -112,7 +101,6 @@ public class DisplayResolveInfo implements TargetInfo { mResolvedIntent = createResolvedIntent( baseIntentToSend == null ? other.mResolvedIntent : baseIntentToSend, mResolveInfo.activityInfo); - mPresentationGetter = presentationGetter; mDisplayIconHolder.setDisplayIcon(other.mDisplayIconHolder.getDisplayIcon()); } @@ -124,7 +112,6 @@ public class DisplayResolveInfo implements TargetInfo { mDisplayLabel = other.mDisplayLabel; mExtendedInfo = other.mExtendedInfo; mResolvedIntent = other.mResolvedIntent; - mPresentationGetter = other.mPresentationGetter; mDisplayIconHolder.setDisplayIcon(other.mDisplayIconHolder.getDisplayIcon()); } @@ -147,10 +134,6 @@ public class DisplayResolveInfo implements TargetInfo { } public CharSequence getDisplayLabel() { - if (mDisplayLabel == null && mPresentationGetter != null) { - mDisplayLabel = mPresentationGetter.getLabel(); - mExtendedInfo = mPresentationGetter.getSubLabel(); - } return mDisplayLabel; } @@ -186,8 +169,7 @@ public class DisplayResolveInfo implements TargetInfo { return new DisplayResolveInfo( this, - TargetInfo.mergeRefinementIntoMatchingBaseIntent(matchingBase, proposedRefinement), - mPresentationGetter); + TargetInfo.mergeRefinementIntoMatchingBaseIntent(matchingBase, proposedRefinement)); } @Override @@ -197,7 +179,7 @@ public class DisplayResolveInfo implements TargetInfo { @Override public ArrayList<DisplayResolveInfo> getAllDisplayTargets() { - return new ArrayList<>(Arrays.asList(this)); + return new ArrayList<>(List.of(this)); } public void addAlternateSourceIntent(Intent alt) { diff --git a/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt b/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt index 0e4d0209..646ca8e1 100644 --- a/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt +++ b/java/src/com/android/intentresolver/icons/DefaultTargetDataLoader.kt @@ -18,7 +18,6 @@ package com.android.intentresolver.icons import android.app.ActivityManager import android.content.Context -import android.content.pm.ResolveInfo import android.graphics.drawable.Drawable import android.os.AsyncTask import android.os.UserHandle @@ -105,8 +104,14 @@ class DefaultTargetDataLoader( .executeOnExecutor(executor) } - override fun createPresentationGetter(info: ResolveInfo): TargetPresentationGetter = - presentationFactory.makePresentationGetter(info) + override fun getOrLoadLabel(info: DisplayResolveInfo) { + if (!info.hasDisplayLabel()) { + val result = + LoadLabelTask.loadLabel(context, info, isAudioCaptureDevice, presentationFactory) + info.displayLabel = result[0] + info.extendedInfo = result[1] + } + } private fun addTask(id: Int, task: AsyncTask<*, *, *>) { synchronized(activeTasks) { activeTasks.put(id, task) } diff --git a/java/src/com/android/intentresolver/icons/LoadLabelTask.java b/java/src/com/android/intentresolver/icons/LoadLabelTask.java index a0867b8e..b9a9d89d 100644 --- a/java/src/com/android/intentresolver/icons/LoadLabelTask.java +++ b/java/src/com/android/intentresolver/icons/LoadLabelTask.java @@ -49,25 +49,30 @@ class LoadLabelTask extends AsyncTask<Void, Void, CharSequence[]> { protected CharSequence[] doInBackground(Void... voids) { try { Trace.beginSection("app-label"); - return loadLabel(); + return loadLabel( + mContext, mDisplayResolveInfo, mIsAudioCaptureDevice, mPresentationFactory); } finally { Trace.endSection(); } } - private CharSequence[] loadLabel() { - TargetPresentationGetter pg = mPresentationFactory.makePresentationGetter( - mDisplayResolveInfo.getResolveInfo()); + static CharSequence[] loadLabel( + Context context, + DisplayResolveInfo displayResolveInfo, + boolean isAudioCaptureDevice, + TargetPresentationGetter.Factory presentationFactory) { + TargetPresentationGetter pg = presentationFactory.makePresentationGetter( + displayResolveInfo.getResolveInfo()); - if (mIsAudioCaptureDevice) { + if (isAudioCaptureDevice) { // This is an audio capture device, so check record permissions - ActivityInfo activityInfo = mDisplayResolveInfo.getResolveInfo().activityInfo; + ActivityInfo activityInfo = displayResolveInfo.getResolveInfo().activityInfo; String packageName = activityInfo.packageName; int uid = activityInfo.applicationInfo.uid; boolean hasRecordPermission = PermissionChecker.checkPermissionForPreflight( - mContext, + context, android.Manifest.permission.RECORD_AUDIO, -1, uid, packageName) == android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -76,7 +81,7 @@ class LoadLabelTask extends AsyncTask<Void, Void, CharSequence[]> { // Doesn't have record permission, so warn the user return new CharSequence[]{ pg.getLabel(), - mContext.getString(R.string.usb_device_resolve_prompt_warn) + context.getString(R.string.usb_device_resolve_prompt_warn) }; } } diff --git a/java/src/com/android/intentresolver/icons/TargetDataLoader.kt b/java/src/com/android/intentresolver/icons/TargetDataLoader.kt index 50f731f8..6186a5ab 100644 --- a/java/src/com/android/intentresolver/icons/TargetDataLoader.kt +++ b/java/src/com/android/intentresolver/icons/TargetDataLoader.kt @@ -16,10 +16,8 @@ package com.android.intentresolver.icons -import android.content.pm.ResolveInfo import android.graphics.drawable.Drawable import android.os.UserHandle -import com.android.intentresolver.TargetPresentationGetter import com.android.intentresolver.chooser.DisplayResolveInfo import com.android.intentresolver.chooser.SelectableTargetInfo import java.util.function.Consumer @@ -43,8 +41,6 @@ abstract class TargetDataLoader { /** Load target label */ abstract fun loadLabel(info: DisplayResolveInfo, callback: Consumer<Array<CharSequence?>>) - /** Create a presentation getter to be used with a [DisplayResolveInfo] */ - // TODO: get rid of DisplayResolveInfo's dependency on the presentation getter and remove this - // method. - abstract fun createPresentationGetter(info: ResolveInfo): TargetPresentationGetter + /** Loads DisplayResolveInfo's display label synchronously, if needed */ + abstract fun getOrLoadLabel(info: DisplayResolveInfo) } diff --git a/java/tests/src/com/android/intentresolver/ChooserListAdapterTest.kt b/java/tests/src/com/android/intentresolver/ChooserListAdapterTest.kt index 87e58954..a4078365 100644 --- a/java/tests/src/com/android/intentresolver/ChooserListAdapterTest.kt +++ b/java/tests/src/com/android/intentresolver/ChooserListAdapterTest.kt @@ -123,8 +123,7 @@ class ChooserListAdapterTest { ResolverDataProvider.createResolveInfo(2, 0, userHandle), null, "extended info", - Intent(), - /* resolveInfoPresentationGetter= */ null + Intent() ) testSubject.onBindView(view, targetInfo, 0) @@ -200,7 +199,6 @@ class ChooserListAdapterTest { appLabel, "extended info", Intent(), - /* resolveInfoPresentationGetter= */ null ) .apply { if (isPinned) { diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java index fbc99a3a..48f8be5d 100644 --- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java @@ -224,16 +224,18 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override - public DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, - CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, - @Nullable TargetPresentationGetter resolveInfoPresentationGetter) { + public DisplayResolveInfo createTestDisplayResolveInfo( + Intent originalIntent, + ResolveInfo pri, + CharSequence pLabel, + CharSequence pInfo, + Intent replacementIntent) { return DisplayResolveInfo.newDisplayResolveInfo( originalIntent, pri, pLabel, pInfo, - replacementIntent, - resolveInfoPresentationGetter); + replacementIntent); } @Override diff --git a/java/tests/src/com/android/intentresolver/IChooserWrapper.java b/java/tests/src/com/android/intentresolver/IChooserWrapper.java index d439b037..e34217a8 100644 --- a/java/tests/src/com/android/intentresolver/IChooserWrapper.java +++ b/java/tests/src/com/android/intentresolver/IChooserWrapper.java @@ -16,7 +16,6 @@ package com.android.intentresolver; -import android.annotation.Nullable; import android.app.usage.UsageStatsManager; import android.content.Intent; import android.content.pm.ResolveInfo; @@ -37,9 +36,12 @@ public interface IChooserWrapper { ChooserListAdapter getWorkListAdapter(); boolean getIsSelected(); UsageStatsManager getUsageStatsManager(); - DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, - CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, - @Nullable TargetPresentationGetter resolveInfoPresentationGetter); + DisplayResolveInfo createTestDisplayResolveInfo( + Intent originalIntent, + ResolveInfo pri, + CharSequence pLabel, + CharSequence pInfo, + Intent replacementIntent); UserHandle getCurrentUserHandle(); Executor getMainExecutor(); } diff --git a/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java b/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java index 60180c0b..1bb05437 100644 --- a/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java +++ b/java/tests/src/com/android/intentresolver/ResolverWrapperActivity.java @@ -273,10 +273,9 @@ public class ResolverWrapperActivity extends ResolverActivity { }); } - @NonNull @Override - public TargetPresentationGetter createPresentationGetter(@NonNull ResolveInfo info) { - return mTargetDataLoader.createPresentationGetter(info); + public void getOrLoadLabel(@NonNull DisplayResolveInfo info) { + mTargetDataLoader.getOrLoadLabel(info); } } } diff --git a/java/tests/src/com/android/intentresolver/ShortcutSelectionLogicTest.kt b/java/tests/src/com/android/intentresolver/ShortcutSelectionLogicTest.kt index 9ddeed84..2346d98b 100644 --- a/java/tests/src/com/android/intentresolver/ShortcutSelectionLogicTest.kt +++ b/java/tests/src/com/android/intentresolver/ShortcutSelectionLogicTest.kt @@ -19,7 +19,6 @@ package com.android.intentresolver import android.content.ComponentName import android.content.Context import android.content.Intent -import android.content.pm.ResolveInfo import android.content.pm.ShortcutInfo import android.os.UserHandle import android.service.chooser.ChooserTarget @@ -60,16 +59,16 @@ class ShortcutSelectionLogicTest { ResolverDataProvider.createResolveInfo(3, 0, PERSONAL_USER_HANDLE), "label", "extended info", - Intent(), - /* resolveInfoPresentationGetter= */ null) + Intent() + ) private val otherBaseDisplayInfo = DisplayResolveInfo.newDisplayResolveInfo( Intent(), ResolverDataProvider.createResolveInfo(4, 0, PERSONAL_USER_HANDLE), "label 2", "extended info 2", - Intent(), - /* resolveInfoPresentationGetter= */ null) + Intent() + ) private operator fun Map<String, Array<ChooserTarget>>.get(pkg: String, idx: Int) = this[pkg]?.get(idx) ?: error("missing package $pkg") diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index bc9e521c..73977f86 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -511,8 +511,8 @@ public class UnbundledChooserActivityTest { }; ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0); DisplayResolveInfo testDri = - activity.createTestDisplayResolveInfo(sendIntent, toChoose, "testLabel", "testInfo", - sendIntent, /* resolveInfoPresentationGetter */ null); + activity.createTestDisplayResolveInfo( + sendIntent, toChoose, "testLabel", "testInfo", sendIntent); onView(withText(toChoose.activityInfo.name)) .perform(click()); waitForIdle(); @@ -1425,8 +1425,7 @@ public class UnbundledChooserActivityTest { ResolverDataProvider.createResolveInfo(3, 0, PERSONAL_USER_HANDLE), "testLabel", "testInfo", - sendIntent, - /* resolveInfoPresentationGetter */ null); + sendIntent); final ChooserListAdapter adapter = activity.getAdapter(); assertThat(adapter.getBaseScore(null, 0), is(CALLER_TARGET_SCORE_BOOST)); @@ -1965,8 +1964,7 @@ public class UnbundledChooserActivityTest { ri, "testLabel", "testInfo", - sendIntent, - /* resolveInfoPresentationGetter */ null), + sendIntent), serviceTargets, TARGET_TYPE_CHOOSER_TARGET, directShareToShortcutInfos, diff --git a/java/tests/src/com/android/intentresolver/chooser/ImmutableTargetInfoTest.kt b/java/tests/src/com/android/intentresolver/chooser/ImmutableTargetInfoTest.kt index f3ca76a9..6712bf31 100644 --- a/java/tests/src/com/android/intentresolver/chooser/ImmutableTargetInfoTest.kt +++ b/java/tests/src/com/android/intentresolver/chooser/ImmutableTargetInfoTest.kt @@ -21,7 +21,6 @@ import android.app.prediction.AppTarget import android.app.prediction.AppTargetId import android.content.ComponentName import android.content.Intent -import android.content.pm.ResolveInfo import android.os.Bundle import android.os.UserHandle import com.android.intentresolver.createShortcutInfo @@ -52,15 +51,15 @@ class ImmutableTargetInfoTest { ResolverDataProvider.createResolveInfo(2, 0, PERSONAL_USER_HANDLE), "display1 label", "display1 extended info", - Intent("display1_resolved"), - /* resolveInfoPresentationGetter= */ null) + Intent("display1_resolved") + ) private val displayTarget2 = DisplayResolveInfo.newDisplayResolveInfo( Intent("display2"), ResolverDataProvider.createResolveInfo(3, 0, PERSONAL_USER_HANDLE), "display2 label", "display2 extended info", - Intent("display2_resolved"), - /* resolveInfoPresentationGetter= */ null) + Intent("display2_resolved") + ) private val directShareShortcutInfo = createShortcutInfo( "shortcutid", ResolverDataProvider.createComponentName(4), 4) private val directShareAppTarget = AppTarget( @@ -73,8 +72,8 @@ class ImmutableTargetInfoTest { ResolverDataProvider.createResolveInfo(5, 0, PERSONAL_USER_HANDLE), "displayresolve label", "displayresolve extended info", - Intent("display_resolved"), - /* resolveInfoPresentationGetter= */ null) + Intent("display_resolved") + ) private val hashProvider: ImmutableTargetInfo.TargetHashProvider = mock() @Test diff --git a/java/tests/src/com/android/intentresolver/chooser/TargetInfoTest.kt b/java/tests/src/com/android/intentresolver/chooser/TargetInfoTest.kt index 78e0c3ee..a7574c12 100644 --- a/java/tests/src/com/android/intentresolver/chooser/TargetInfoTest.kt +++ b/java/tests/src/com/android/intentresolver/chooser/TargetInfoTest.kt @@ -87,8 +87,8 @@ class TargetInfoTest { ResolverDataProvider.createResolveInfo(1, 0, PERSONAL_USER_HANDLE), "label", "extended info", - resolvedIntent, - /* resolveInfoPresentationGetter= */ null) + resolvedIntent + ) val chooserTarget = createChooserTarget( "title", 0.3f, ResolverDataProvider.createComponentName(2), "test_shortcut_id") val shortcutInfo = createShortcutInfo("id", ResolverDataProvider.createComponentName(3), 3) @@ -161,8 +161,8 @@ class TargetInfoTest { ResolverDataProvider.createResolveInfo(1, 0), "label", "extended info", - resolvedIntent, - /* resolveInfoPresentationGetter= */ null) + resolvedIntent + ) val chooserTarget = createChooserTarget( "title", 0.3f, ResolverDataProvider.createComponentName(2), "test_shortcut_id") val shortcutInfo = createShortcutInfo("id", ResolverDataProvider.createComponentName(3), 3) @@ -200,8 +200,8 @@ class TargetInfoTest { resolveInfo, "label", "extended info", - intent, - /* resolveInfoPresentationGetter= */ null) + intent + ) assertThat(targetInfo.isDisplayResolveInfo()).isTrue() assertThat(targetInfo.isMultiDisplayResolveInfo()).isFalse() assertThat(targetInfo.isChooserTargetInfo()).isFalse() @@ -223,8 +223,8 @@ class TargetInfoTest { ResolverDataProvider.createResolveInfo(3, 0), "label", "extended info", - originalIntent, - /* resolveInfoPresentationGetter= */ null) + originalIntent + ) originalInfo.addAlternateSourceIntent(mismatchedAlternate) originalInfo.addAlternateSourceIntent(targetAlternate) originalInfo.addAlternateSourceIntent(extraMatch) @@ -257,8 +257,8 @@ class TargetInfoTest { ResolverDataProvider.createResolveInfo(3, 0), "label", "extended info", - originalIntent, - /* resolveInfoPresentationGetter= */ null) + originalIntent + ) originalInfo.addAlternateSourceIntent(mismatchedAlternate) val refinement = Intent("PROPOSED_REFINEMENT") @@ -277,15 +277,15 @@ class TargetInfoTest { resolveInfo, "label 1", "extended info 1", - intent, - /* resolveInfoPresentationGetter= */ null) + intent + ) val secondTargetInfo = DisplayResolveInfo.newDisplayResolveInfo( intent, resolveInfo, "label 2", "extended info 2", - intent, - /* resolveInfoPresentationGetter= */ null) + intent + ) val multiTargetInfo = MultiDisplayResolveInfo.newMultiDisplayResolveInfo( listOf(firstTargetInfo, secondTargetInfo)) @@ -328,24 +328,23 @@ class TargetInfoTest { resolveInfo, "Send Image", "Sends only images", - sendImage, - /* resolveInfoPresentationGetter= */ null) + sendImage + ) val textOnlyTarget = DisplayResolveInfo.newDisplayResolveInfo( sendUri, resolveInfo, "Send Text", "Sends only text", - sendUri, - /* resolveInfoPresentationGetter= */ null) + sendUri + ) val imageOrTextTarget = DisplayResolveInfo.newDisplayResolveInfo( sendImage, resolveInfo, "Send Image or Text", "Sends images or text", - sendImage, - /* resolveInfoPresentationGetter= */ null + sendImage ).apply { addAlternateSourceIntent(sendUri) } @@ -377,8 +376,7 @@ class TargetInfoTest { ResolverDataProvider.createResolveInfo(1, 0), "Target One", "Target One", - sendImage, - /* resolveInfoPresentationGetter= */ null + sendImage ) ) val targetTwo = mock<DisplayResolveInfo> { |