diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 36274a2b33b68..389e33ae7ae25 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -99,7 +99,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.animation.AccelerateInterpolator; @@ -1622,32 +1621,22 @@ public class ChooserActivity extends ResolverActivity implements return getIntent().getBooleanExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, true); } - void showTargetDetails(TargetInfo ti) { - if (ti == null) { - return; - } - ComponentName name = ti.getResolveInfo().activityInfo.getComponentName(); - boolean pinned = mPinnedSharedPrefs.getBoolean(name.flattenToString(), false); + private void showTargetDetails(DisplayResolveInfo ti) { + if (ti == null) return; - ResolverTargetActionsDialogFragment f; + List targetList; // For multiple targets, include info on all targets if (ti instanceof MultiDisplayResolveInfo) { MultiDisplayResolveInfo mti = (MultiDisplayResolveInfo) ti; - List labels = new ArrayList<>(); - - for (TargetInfo innerInfo : mti.getTargets()) { - labels.add(innerInfo.getResolveInfo().loadLabel(getPackageManager())); - } - f = new ResolverTargetActionsDialogFragment(mti.getDisplayLabel(), name, - mti.getTargets(), labels, - mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); + targetList = mti.getTargets(); } else { - f = new ResolverTargetActionsDialogFragment( - ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned, - mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); + targetList = Collections.singletonList(ti); } + ResolverTargetActionsDialogFragment f = new ResolverTargetActionsDialogFragment( + targetList, mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); + f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG); } @@ -2982,12 +2971,17 @@ public class ChooserActivity extends ResolverActivity implements if (isClickable) { itemView.setOnClickListener(v -> startSelected(mListPosition, false/* always */, true/* filterd */)); - itemView.setOnLongClickListener(v -> { - showTargetDetails( - mChooserMultiProfilePagerAdapter.getActiveListAdapter() - .targetInfoForPosition(mListPosition, /* filtered */ true)); - return true; - }); + + TargetInfo ti = mChooserMultiProfilePagerAdapter.getActiveListAdapter() + .targetInfoForPosition(mListPosition, /* filtered */ true); + + // This should always be the case for ItemViewHolder, check for sanity + if (ti instanceof DisplayResolveInfo) { + itemView.setOnLongClickListener(v -> { + showTargetDetails((DisplayResolveInfo) ti); + return true; + }); + } } } } @@ -3312,15 +3306,21 @@ public class ChooserActivity extends ResolverActivity implements startSelected(holder.getItemIndex(column), false, true); } }); - v.setOnLongClickListener(new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - showTargetDetails( - mChooserListAdapter.targetInfoForPosition( - holder.getItemIndex(column), true)); - return true; + + // Direct Share targets should not show any menu + if (!isDirectShare) { + final TargetInfo ti = mChooserListAdapter.targetInfoForPosition( + holder.getItemIndex(column), true); + + // This should always be the case for non-DS targets, check for sanity + if (ti instanceof DisplayResolveInfo) { + v.setOnLongClickListener(v1 -> { + showTargetDetails((DisplayResolveInfo) ti); + return true; + }); } - }); + } + holder.addView(i, v); // Force Direct Share to be 2 lines and auto-wrap to second line via hoz scroll = diff --git a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java index 35d9bcdbb033d..cdc600c51451e 100644 --- a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java +++ b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java @@ -17,21 +17,25 @@ package com.android.internal.app; +import static android.content.Context.ACTIVITY_SERVICE; + +import static com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; + +import android.app.ActivityManager; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.ComponentName; import android.content.DialogInterface; -import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; -import android.provider.Settings; import com.android.internal.R; import com.android.internal.app.chooser.DisplayResolveInfo; +import com.android.internal.app.chooser.TargetInfo; import java.util.ArrayList; import java.util.List; @@ -41,94 +45,53 @@ import java.util.List; */ public class ResolverTargetActionsDialogFragment extends DialogFragment implements DialogInterface.OnClickListener { - private static final String NAME_KEY = "componentName"; - private static final String TITLE_KEY = "title"; - private static final String PINNED_KEY = "pinned"; - private static final String USER_ID_KEY = "userId"; - - // Sync with R.array.resolver_target_actions_* resources - private static final int TOGGLE_PIN_INDEX = 0; - private static final int APP_INFO_INDEX = 1; private List mTargetInfos = new ArrayList<>(); - private List mLabels = new ArrayList<>(); - private boolean[] mPinned; + private UserHandle mUserHandle; public ResolverTargetActionsDialogFragment() { } - public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name, - boolean pinned, UserHandle userHandle) { - Bundle args = new Bundle(); - args.putCharSequence(TITLE_KEY, title); - args.putParcelable(NAME_KEY, name); - args.putBoolean(PINNED_KEY, pinned); - args.putParcelable(USER_ID_KEY, userHandle); - setArguments(args); - } - - public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name, - List targets, List labels, UserHandle userHandle) { - Bundle args = new Bundle(); - args.putCharSequence(TITLE_KEY, title); - args.putParcelable(NAME_KEY, name); - args.putParcelable(USER_ID_KEY, userHandle); + public ResolverTargetActionsDialogFragment(List targets, + UserHandle userHandle) { + mUserHandle = userHandle; mTargetInfos = targets; - mLabels = labels; - setArguments(args); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Bundle args = getArguments(); - final int itemRes = args.getBoolean(PINNED_KEY, false) - ? R.array.resolver_target_actions_unpin - : R.array.resolver_target_actions_pin; - String[] defaultActions = getResources().getStringArray(itemRes); - CharSequence[] items; + final PackageManager pm = getContext().getPackageManager(); - if (mTargetInfos == null || mTargetInfos.size() < 2) { - items = defaultActions; - } else { - // Pin item for each sub-item - items = new CharSequence[mTargetInfos.size() + 1]; - for (int i = 0; i < mTargetInfos.size(); i++) { - items[i] = mTargetInfos.get(i).isPinned() - ? getResources().getString(R.string.unpin_specific_target, mLabels.get(i)) - : getResources().getString(R.string.pin_specific_target, mLabels.get(i)); - } - // "App info" - items[mTargetInfos.size()] = defaultActions[1]; + // Pin item for each sub-item + CharSequence[] items = new CharSequence[mTargetInfos.size()]; + for (int i = 0; i < mTargetInfos.size(); i++) { + final TargetInfo ti = mTargetInfos.get(i); + final CharSequence label = ti.getResolveInfo().loadLabel(pm); + items[i] = ti.isPinned() + ? getResources().getString(R.string.unpin_specific_target, label) + : getResources().getString(R.string.pin_specific_target, label); } + // Use the matching application icon and label for the title, any TargetInfo will do + final ActivityManager am = (ActivityManager) getContext() + .getSystemService(ACTIVITY_SERVICE); + final int iconDpi = am.getLauncherLargeIconDensity(); + final ResolveInfoPresentationGetter pg = new ResolveInfoPresentationGetter(getContext(), + iconDpi, mTargetInfos.get(0).getResolveInfo()); return new Builder(getContext()) + .setTitle(pg.getLabel()) + .setIcon(pg.getIcon(mUserHandle)) .setCancelable(true) .setItems(items, this) - .setTitle(args.getCharSequence(TITLE_KEY)) .create(); } @Override public void onClick(DialogInterface dialog, int which) { - final Bundle args = getArguments(); - ComponentName name = args.getParcelable(NAME_KEY); - if (which == 0 || (mTargetInfos.size() > 0 && which < mTargetInfos.size())) { - if (mTargetInfos == null || mTargetInfos.size() == 0) { - pinComponent(name); - } else { - pinComponent(mTargetInfos.get(which).getResolvedComponentName()); - } - // Force the chooser to requery and resort things - ((ChooserActivity) getActivity()).handlePackagesChanged(); - } else { - // Last item in dialog is App Info - Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - .setData(Uri.fromParts("package", name.getPackageName(), null)) - .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); - UserHandle userHandle = args.getParcelable(USER_ID_KEY); - getActivity().startActivityAsUser(in, userHandle); - } + pinComponent(mTargetInfos.get(which).getResolvedComponentName()); + ((ChooserActivity) getActivity()).handlePackagesChanged(); dismiss(); }