Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31f4460d authored by Song Hu's avatar Song Hu Committed by Android (Google) Code Review
Browse files

Merge "Open dialog panel after long pressing a direct share target to allow...

Merge "Open dialog panel after long pressing a direct share target to allow pin/unpin the target. Communicate with ShortcutManager/Launcherapps to store pin info in ShortcutService."
parents fde81bf7 63932258
Loading
Loading
Loading
Loading
+46 −31
Original line number Diff line number Diff line
@@ -1620,29 +1620,48 @@ public class ChooserActivity extends ResolverActivity implements
        return getIntent().getBooleanExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, true);
    }

    private void showTargetDetails(DisplayResolveInfo ti) {
        if (ti == null) return;
    private void showTargetDetails(TargetInfo targetInfo) {
        if (targetInfo == null) return;

        ArrayList<DisplayResolveInfo> targetList;

        ChooserTargetActionsDialogFragment fragment = new ChooserTargetActionsDialogFragment();
        Bundle bundle = new Bundle();

        if (targetInfo instanceof SelectableTargetInfo) {
            SelectableTargetInfo selectableTargetInfo = (SelectableTargetInfo) targetInfo;
            if (selectableTargetInfo.getDisplayResolveInfo() == null
                    || selectableTargetInfo.getChooserTarget() == null) {
                Log.e(TAG, "displayResolveInfo or chooserTarget in selectableTargetInfo are null");
                return;
            }
            targetList = new ArrayList<>();
            targetList.add(selectableTargetInfo.getDisplayResolveInfo());
            bundle.putString(ChooserTargetActionsDialogFragment.SHORTCUT_ID_KEY,
                    selectableTargetInfo.getChooserTarget().getIntentExtras().getString(
                            Intent.EXTRA_SHORTCUT_ID));
            bundle.putBoolean(ChooserTargetActionsDialogFragment.IS_SHORTCUT_PINNED_KEY,
                    selectableTargetInfo.isPinned());
            bundle.putParcelable(ChooserTargetActionsDialogFragment.INTENT_FILTER_KEY,
                    getTargetIntentFilter());
            if (selectableTargetInfo.getDisplayLabel() != null) {
                bundle.putString(ChooserTargetActionsDialogFragment.SHORTCUT_TITLE_KEY,
                        selectableTargetInfo.getDisplayLabel().toString());
            }
        } else if (targetInfo instanceof MultiDisplayResolveInfo) {
            // For multiple targets, include info on all targets
        if (ti instanceof MultiDisplayResolveInfo) {
            MultiDisplayResolveInfo mti = (MultiDisplayResolveInfo) ti;
            MultiDisplayResolveInfo mti = (MultiDisplayResolveInfo) targetInfo;
            targetList = mti.getTargets();
        } else {
            targetList = new ArrayList<DisplayResolveInfo>();
            targetList.add(ti);
            targetList.add((DisplayResolveInfo) targetInfo);
        }

        ChooserTargetActionsDialogFragment f = new ChooserTargetActionsDialogFragment();
        Bundle b = new Bundle();
        b.putParcelable(ChooserTargetActionsDialogFragment.USER_HANDLE_KEY,
        bundle.putParcelable(ChooserTargetActionsDialogFragment.USER_HANDLE_KEY,
                mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
        b.putParcelableArrayList(ChooserTargetActionsDialogFragment.TARGET_INFOS_KEY,
        bundle.putParcelableArrayList(ChooserTargetActionsDialogFragment.TARGET_INFOS_KEY,
                targetList);
        f.setArguments(b);
        fragment.setArguments(bundle);

        f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG);
        fragment.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG);
    }

    private void modifyTargetIntent(Intent in) {
@@ -2868,8 +2887,10 @@ public class ChooserActivity extends ResolverActivity implements
    private boolean shouldShowTargetDetails(TargetInfo ti) {
        ComponentName nearbyShare = getNearbySharingComponent();
        //  Suppress target details for nearby share to hide pin/unpin action
        return !(nearbyShare != null && nearbyShare.equals(ti.getResolvedComponentName())
                && shouldNearbyShareBeFirstInRankedRow());
        boolean isNearbyShare = nearbyShare != null && nearbyShare.equals(
                ti.getResolvedComponentName()) && shouldNearbyShareBeFirstInRankedRow();
        return ti instanceof SelectableTargetInfo
                || (ti instanceof DisplayResolveInfo && !isNearbyShare);
    }

    /**
@@ -2966,8 +2987,6 @@ public class ChooserActivity extends ResolverActivity implements
        private DirectShareViewHolder mDirectShareViewHolder;
        private int mChooserTargetWidth = 0;
        private boolean mShowAzLabelIfPoss;

        private boolean mHideContentPreview = false;
        private boolean mLayoutRequested = false;

        private int mFooterHeight = 0;
@@ -3038,7 +3057,6 @@ public class ChooserActivity extends ResolverActivity implements
         * personal and work tabs.
         */
        public void hideContentPreview() {
            mHideContentPreview = true;
            mLayoutRequested = true;
            notifyDataSetChanged();
        }
@@ -3228,18 +3246,15 @@ public class ChooserActivity extends ResolverActivity implements
                    }
                });

                // Direct Share targets should not show any menu
                if (!isDirectShare) {
                // Show menu for both direct share and app share targets after long click.
                v.setOnLongClickListener(v1 -> {
                        final TargetInfo ti = mChooserListAdapter.targetInfoForPosition(
                    TargetInfo ti = mChooserListAdapter.targetInfoForPosition(
                            holder.getItemIndex(column), true);
                        // This should always be the case for non-DS targets, check for validity
                        if (ti instanceof DisplayResolveInfo && shouldShowTargetDetails(ti)) {
                            showTargetDetails((DisplayResolveInfo) ti);
                    if (shouldShowTargetDetails(ti)) {
                        showTargetDetails(ti);
                    }
                    return true;
                });
                }

                holder.addView(i, v);

+11 −3
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
    public static final float CALLER_TARGET_SCORE_BOOST = 900.f;
    /** {@link #getBaseScore} */
    public static final float SHORTCUT_TARGET_SCORE_BOOST = 90.f;
    private static final float PINNED_SHORTCUT_TARGET_SCORE_BOOST = 1000.f;

    private final int mMaxShortcutTargetsPerApp;
    private final ChooserListCommunicator mChooserListCommunicator;
@@ -275,8 +276,10 @@ public class ChooserListAdapter extends ResolverListAdapter {
            Drawable bkg = mContext.getDrawable(R.drawable.chooser_group_background);
            holder.text.setPaddingRelative(0, 0, bkg.getIntrinsicWidth() /* end */, 0);
            holder.text.setBackground(bkg);
        } else if (info.isPinned() && getPositionTargetType(position) == TARGET_STANDARD) {
            // If the target is pinned and in the suggested row show a pinned indicator
        } 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);
@@ -523,11 +526,16 @@ public class ChooserListAdapter extends ResolverListAdapter {
                    targetScore = lastScore * 0.95f;
                }
            }
            ShortcutInfo shortcutInfo = isShortcutResult ? directShareToShortcutInfos.get(target)
                    : null;
            if ((shortcutInfo != null) && shortcutInfo.isPinned()) {
                targetScore += PINNED_SHORTCUT_TARGET_SCORE_BOOST;
            }
            UserHandle userHandle = getUserHandle();
            Context contextAsUser = mContext.createContextAsUser(userHandle, 0 /* flags */);
            boolean isInserted = insertServiceTarget(new SelectableTargetInfo(contextAsUser,
                    origTarget, target, targetScore, mSelectableTargetInfoCommunicator,
                    (isShortcutResult ? directShareToShortcutInfos.get(target) : null)));
                    shortcutInfo));

            if (isInserted && isShortcutResult) {
                mNumShortcutResults++;
+69 −4
Original line number Diff line number Diff line
@@ -29,9 +29,14 @@ import android.app.ActivityManager;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -51,6 +56,7 @@ import com.android.internal.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Shows a dialog with actions to take on a chooser target.
@@ -60,9 +66,17 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment

    protected ArrayList<DisplayResolveInfo> mTargetInfos = new ArrayList<>();
    protected UserHandle mUserHandle;
    protected String mShortcutId;
    protected String mShortcutTitle;
    protected boolean mIsShortcutPinned;
    protected IntentFilter mIntentFilter;

    public static final String USER_HANDLE_KEY = "user_handle";
    public static final String TARGET_INFOS_KEY = "target_infos";
    public static final String SHORTCUT_ID_KEY = "shortcut_id";
    public static final String SHORTCUT_TITLE_KEY = "shortcut_title";
    public static final String IS_SHORTCUT_PINNED_KEY = "is_shortcut_pinned";
    public static final String INTENT_FILTER_KEY = "intent_filter";

    public ChooserTargetActionsDialogFragment() {}

@@ -79,6 +93,10 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
    void setStateFromBundle(Bundle b) {
        mTargetInfos = (ArrayList<DisplayResolveInfo>) b.get(TARGET_INFOS_KEY);
        mUserHandle = (UserHandle) b.get(USER_HANDLE_KEY);
        mShortcutId = b.getString(SHORTCUT_ID_KEY);
        mShortcutTitle = b.getString(SHORTCUT_TITLE_KEY);
        mIsShortcutPinned = b.getBoolean(IS_SHORTCUT_PINNED_KEY);
        mIntentFilter = (IntentFilter) b.get(INTENT_FILTER_KEY);
    }

    @Override
@@ -89,6 +107,11 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
                mUserHandle);
        outState.putParcelableArrayList(ChooserTargetActionsDialogFragment.TARGET_INFOS_KEY,
                mTargetInfos);
        outState.putString(ChooserTargetActionsDialogFragment.SHORTCUT_ID_KEY, mShortcutId);
        outState.putBoolean(ChooserTargetActionsDialogFragment.IS_SHORTCUT_PINNED_KEY,
                mIsShortcutPinned);
        outState.putString(ChooserTargetActionsDialogFragment.SHORTCUT_TITLE_KEY, mShortcutTitle);
        outState.putParcelable(ChooserTargetActionsDialogFragment.INTENT_FILTER_KEY, mIntentFilter);
    }

    /**
@@ -121,7 +144,7 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
        RecyclerView rv = v.findViewById(R.id.listContainer);

        final ResolveInfoPresentationGetter pg = getProvidingAppPresentationGetter();
        title.setText(pg.getLabel());
        title.setText(isShortcutTarget() ? mShortcutTitle : pg.getLabel());
        icon.setImageDrawable(pg.getIcon(mUserHandle));
        rv.setAdapter(new VHAdapter(items));

@@ -180,11 +203,45 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (isShortcutTarget()) {
            toggleShortcutPinned(mTargetInfos.get(which).getResolvedComponentName());
        } else {
            pinComponent(mTargetInfos.get(which).getResolvedComponentName());
        }
        ((ChooserActivity) getActivity()).handlePackagesChanged();
        dismiss();
    }

    private void toggleShortcutPinned(ComponentName name) {
        if (mIntentFilter == null) {
            return;
        }
        // Fetch existing pinned shortcuts of the given package.
        List<String> pinnedShortcuts = getPinnedShortcutsFromPackageAsUser(getContext(),
                mUserHandle, mIntentFilter, name.getPackageName());
        // If the shortcut has already been pinned, unpin it; otherwise, pin it.
        if (mIsShortcutPinned) {
            pinnedShortcuts.remove(mShortcutId);
        } else {
            pinnedShortcuts.add(mShortcutId);
        }
        // Update pinned shortcut list in ShortcutService via LauncherApps
        getContext().getSystemService(LauncherApps.class).pinShortcuts(
                name.getPackageName(), pinnedShortcuts, mUserHandle);
    }

    private static List<String> getPinnedShortcutsFromPackageAsUser(Context context,
            UserHandle user, IntentFilter filter, String packageName) {
        Context contextAsUser = context.createContextAsUser(user, 0 /* flags */);
        List<ShortcutManager.ShareShortcutInfo> targets = contextAsUser.getSystemService(
                ShortcutManager.class).getShareTargets(filter);
        return targets.stream()
                .map(ShortcutManager.ShareShortcutInfo::getShortcutInfo)
                .filter(s -> s.isPinned() && s.getPackage().equals(packageName))
                .map(ShortcutInfo::getId)
                .collect(Collectors.toList());
    }

    private void pinComponent(ComponentName name) {
        SharedPreferences sp = ChooserActivity.getPinnedSharedPrefs(getContext());
        final String key = name.flattenToString();
@@ -211,12 +268,13 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
    @NonNull
    protected CharSequence getItemLabel(DisplayResolveInfo dri) {
        final PackageManager pm = getContext().getPackageManager();
        return getPinLabel(dri.isPinned(), dri.getResolveInfo().loadLabel(pm));
        return getPinLabel(isPinned(dri),
                isShortcutTarget() ? "" : dri.getResolveInfo().loadLabel(pm));
    }

    @Nullable
    protected Drawable getItemIcon(DisplayResolveInfo dri) {
        return getPinIcon(dri.isPinned());
        return getPinIcon(isPinned(dri));
    }

    private ResolveInfoPresentationGetter getProvidingAppPresentationGetter() {
@@ -229,4 +287,11 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment
                mTargetInfos.get(0).getResolveInfo());
    }

    private boolean isPinned(DisplayResolveInfo dri) {
        return isShortcutTarget() ? mIsShortcutPinned : dri.isPinned();
    }

    private boolean isShortcutTarget() {
        return mShortcutId != null;
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
    private Drawable mDisplayIcon;
    private final Intent mFillInIntent;
    private final int mFillInFlags;
    private final boolean mIsPinned;
    private final float mModifiedScore;
    private boolean mIsSuspended = false;

@@ -77,6 +78,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
        mModifiedScore = modifiedScore;
        mPm = mContext.getPackageManager();
        mSelectableTargetInfoCommunicator = selectableTargetInfoComunicator;
        mIsPinned = shortcutInfo != null && shortcutInfo.isPinned();
        if (sourceInfo != null) {
            final ResolveInfo ri = sourceInfo.getResolveInfo();
            if (ri != null) {
@@ -120,6 +122,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
        mFillInIntent = fillInIntent;
        mFillInFlags = flags;
        mModifiedScore = other.mModifiedScore;
        mIsPinned = other.mIsPinned;

        mDisplayLabel = sanitizeDisplayLabel(mChooserTarget.getTitle());
    }
@@ -292,7 +295,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {

    @Override
    public boolean isPinned() {
        return mSourceInfo != null && mSourceInfo.isPinned();
        return mIsPinned;
    }

    /**