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

Commit aa5238c9 authored by George Hodulik's avatar George Hodulik
Browse files

Send shortcutinfo to APS for direct shares.

We cache the AppTargets returned by APS, and just return them
when one is clicked. For share activities, that is handled in
AppPredictionServiceResolverComparator.

Bug:124404997
Test: manual test using patched AiAi apk cl/248961808
Test: atest frameworks/base/core/tests/coretests/src/com/android/internal/app
Change-Id: I7bb61b65bd361acdbfd16e1d9499f094b3ae39d8
parent b6c55dfa
Loading
Loading
Loading
Loading
+26 −25
Original line number Original line Diff line number Diff line
@@ -32,7 +32,6 @@ import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
import android.app.prediction.AppTargetEvent;
import android.app.prediction.AppTargetId;
import android.content.ClipData;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.ComponentName;
@@ -125,7 +124,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.Collections;
import java.util.Comparator;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.Map;


/**
/**
 * The Chooser Activity handles intent resolution specifically for sharing intents -
 * The Chooser Activity handles intent resolution specifically for sharing intents -
@@ -162,6 +163,7 @@ public class ChooserActivity extends ResolverActivity {
    public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter";
    public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter";
    private AppPredictor mAppPredictor;
    private AppPredictor mAppPredictor;
    private AppPredictor.Callback mAppPredictorCallback;
    private AppPredictor.Callback mAppPredictorCallback;
    private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;


    /**
    /**
     * If set to true, use ShortcutManager to retrieve the matching direct share targets, instead of
     * If set to true, use ShortcutManager to retrieve the matching direct share targets, instead of
@@ -454,6 +456,7 @@ public class ChooserActivity extends ResolverActivity {


        AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled();
        AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled();
        if (appPredictor != null) {
        if (appPredictor != null) {
            mDirectShareAppTargetCache = new HashMap<>();
            mAppPredictorCallback = resultList -> {
            mAppPredictorCallback = resultList -> {
                if (isFinishing() || isDestroyed()) {
                if (isFinishing() || isDestroyed()) {
                    return;
                    return;
@@ -480,8 +483,7 @@ public class ChooserActivity extends ResolverActivity {
                            new ComponentName(
                            new ComponentName(
                                appTarget.getPackageName(), appTarget.getClassName())));
                                appTarget.getPackageName(), appTarget.getClassName())));
                }
                }
                sendShareShortcutInfoList(shareShortcutInfos, driList);
                sendShareShortcutInfoList(shareShortcutInfos, driList, resultList);
                sendShortcutManagerShareTargetResultCompleted();
            };
            };
            appPredictor
            appPredictor
                .registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback);
                .registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback);
@@ -1318,13 +1320,14 @@ public class ChooserActivity extends ResolverActivity {
        AsyncTask.execute(() -> {
        AsyncTask.execute(() -> {
            ShortcutManager sm = (ShortcutManager) getSystemService(Context.SHORTCUT_SERVICE);
            ShortcutManager sm = (ShortcutManager) getSystemService(Context.SHORTCUT_SERVICE);
            List<ShortcutManager.ShareShortcutInfo> resultList = sm.getShareTargets(filter);
            List<ShortcutManager.ShareShortcutInfo> resultList = sm.getShareTargets(filter);
            sendShareShortcutInfoList(resultList, driList);
            sendShareShortcutInfoList(resultList, driList, null);
        });
        });
    }
    }


    private void sendShareShortcutInfoList(
    private void sendShareShortcutInfoList(
                List<ShortcutManager.ShareShortcutInfo> resultList,
                List<ShortcutManager.ShareShortcutInfo> resultList,
                List<DisplayResolveInfo> driList) {
                List<DisplayResolveInfo> driList,
                @Nullable List<AppTarget> appTargets) {
        // Match ShareShortcutInfos with DisplayResolveInfos to be able to use the old code path
        // Match ShareShortcutInfos with DisplayResolveInfos to be able to use the old code path
        // for direct share targets. After ShareSheet is refactored we should use the
        // for direct share targets. After ShareSheet is refactored we should use the
        // ShareShortcutInfos directly.
        // ShareShortcutInfos directly.
@@ -1334,7 +1337,13 @@ public class ChooserActivity extends ResolverActivity {
            for (int j = 0; j < resultList.size(); j++) {
            for (int j = 0; j < resultList.size(); j++) {
                if (driList.get(i).getResolvedComponentName().equals(
                if (driList.get(i).getResolvedComponentName().equals(
                            resultList.get(j).getTargetComponent())) {
                            resultList.get(j).getTargetComponent())) {
                    chooserTargets.add(convertToChooserTarget(resultList.get(j)));
                    ShortcutManager.ShareShortcutInfo shareShortcutInfo = resultList.get(j);
                    ChooserTarget chooserTarget = convertToChooserTarget(shareShortcutInfo);
                    chooserTargets.add(chooserTarget);
                    if (mDirectShareAppTargetCache != null && appTargets != null) {
                        // Note that appTargets.size() == resultList.size() is always true.
                        mDirectShareAppTargetCache.put(chooserTarget, appTargets.get(j));
                    }
                }
                }
            }
            }
            if (chooserTargets.isEmpty()) {
            if (chooserTargets.isEmpty()) {
@@ -1442,34 +1451,26 @@ public class ChooserActivity extends ResolverActivity {
    }
    }


    private void sendClickToAppPredictor(TargetInfo targetInfo) {
    private void sendClickToAppPredictor(TargetInfo targetInfo) {
        AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled();
        AppPredictor directShareAppPredictor = getAppPredictorForDirectShareIfEnabled();
        if (appPredictor == null) {
        if (directShareAppPredictor == null) {
            return;
            return;
        }
        }
        if (!(targetInfo instanceof ChooserTargetInfo)) {
        if (!(targetInfo instanceof ChooserTargetInfo)) {
            return;
            return;
        }
        }
        ChooserTarget chooserTarget = ((ChooserTargetInfo) targetInfo).getChooserTarget();
        ChooserTarget chooserTarget = ((ChooserTargetInfo) targetInfo).getChooserTarget();
        ComponentName componentName = chooserTarget.getComponentName();
        AppTarget appTarget = null;
        Bundle extras = chooserTarget.getIntentExtras();
        if (mDirectShareAppTargetCache != null) {
        if (extras == null) {
            appTarget = mDirectShareAppTargetCache.get(chooserTarget);
            return;
        }
        }
        // This is a direct share click that was provided by the APS
        String shortcutId = extras.getString(Intent.EXTRA_SHORTCUT_ID);
        if (appTarget != null) {
        if (shortcutId == null) {
            directShareAppPredictor.notifyAppTargetEvent(
            return;
                    new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_LAUNCH)
        }
        appPredictor.notifyAppTargetEvent(
                new AppTargetEvent.Builder(
                    // TODO(b/124404997) Send full shortcut info, not just Id with AppTargetId.
                    new AppTarget.Builder(new AppTargetId(shortcutId),
                            componentName.getPackageName(), getUser())
                        .setClassName(componentName.getClassName())
                        .build(),
                    AppTargetEvent.ACTION_LAUNCH)
                        .setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE)
                        .setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE)
                        .build());
                        .build());
        }
        }
    }


    @Nullable
    @Nullable
    private AppPredictor getAppPredictor() {
    private AppPredictor getAppPredictor() {