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

Commit 3bbd43a9 authored by George Hodulik's avatar George Hodulik Committed by Android (Google) Code Review
Browse files

Merge "Use App Prediction Service to get share suggestions."

parents 5818b8bd 69d4a083
Loading
Loading
Loading
Loading
+96 −32
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@ package com.android.internal.app;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -98,6 +102,20 @@ public class ChooserActivity extends ResolverActivity {

    private static final boolean DEBUG = false;


    /**
     * If {@link #USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS} and this is set to true,
     * {@link AppPredictionManager} will be queried for direct share targets.
     */
    // TODO(b/123089490): Replace with system flag
    private static final boolean USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS = false;
    // TODO(b/123088566) Share these in a better way.
    private static final String APP_PREDICTION_SHARE_UI_SURFACE = "share";
    private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
    public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter";
    private AppPredictor mAppPredictor;
    private AppPredictor.Callback mAppPredictorCallback;

    /**
     * If set to true, use ShortcutManager to retrieve the matching direct share targets, instead of
     * binding to every ChooserTargetService implementation.
@@ -309,6 +327,35 @@ public class ChooserActivity extends ResolverActivity {
        mChooserShownTime = System.currentTimeMillis();
        final long systemCost = mChooserShownTime - intentReceivedTime;
        MetricsLogger.histogram(null, "system_cost_for_smart_sharing", (int) systemCost);

        if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
            final IntentFilter filter = getTargetIntentFilter();
            Bundle extras = new Bundle();
            extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter);
            AppPredictionManager appPredictionManager =
                    getSystemService(AppPredictionManager.class);
            mAppPredictor = appPredictionManager.createAppPredictionSession(
                new AppPredictionContext.Builder(this)
                    .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT)
                    .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE)
                    .setExtras(extras)
                    .build());
            mAppPredictorCallback = resultList -> {
                final List<DisplayResolveInfo> driList =
                        getDisplayResolveInfos(mChooserListAdapter);
                final List<ShortcutManager.ShareShortcutInfo> shareShortcutInfos =
                        new ArrayList<>();
                for (AppTarget appTarget : resultList) {
                    shareShortcutInfos.add(new ShortcutManager.ShareShortcutInfo(
                            appTarget.getShortcutInfo(),
                            new ComponentName(
                                appTarget.getPackageName(), appTarget.getClassName())));
                }
                sendShareShortcutInfoList(shareShortcutInfos, driList);
            };
            mAppPredictor.registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback);
        }

        if (DEBUG) {
            Log.d(TAG, "System Time Cost is " + systemCost);
        }
@@ -339,6 +386,10 @@ public class ChooserActivity extends ResolverActivity {
        }
        unbindRemainingServices();
        mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
        if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
            mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
            mAppPredictor.destroy();
        }
    }

    @Override
@@ -606,15 +657,10 @@ public class ChooserActivity extends ResolverActivity {
        }
    }

    private void queryDirectShareTargets(ChooserListAdapter adapter) {
        final IntentFilter filter = getTargetIntentFilter();
        if (filter == null) {
            return;
        }

    private List<DisplayResolveInfo> getDisplayResolveInfos(ChooserListAdapter adapter) {
        // Need to keep the original DisplayResolveInfos to be able to reconstruct ServiceResultInfo
        // and use the old code path. This Ugliness should go away when Sharesheet is refactored.
        final List<DisplayResolveInfo> driList = new ArrayList<>();
        List<DisplayResolveInfo> driList = new ArrayList<>();
        int targetsToQuery = 0;
        for (int i = 0, n = adapter.getDisplayResolveInfoCount(); i < n; i++) {
            final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
@@ -634,11 +680,30 @@ public class ChooserActivity extends ResolverActivity {
                break;
            }
        }
        return driList;
    }

    private void queryDirectShareTargets(ChooserListAdapter adapter) {
        if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
            mAppPredictor.requestPredictionUpdate();
            return;
        }
        final IntentFilter filter = getTargetIntentFilter();
        if (filter == null) {
            return;
        }
        final List<DisplayResolveInfo> driList = getDisplayResolveInfos(adapter);

        AsyncTask.execute(() -> {
            ShortcutManager sm = (ShortcutManager) getSystemService(Context.SHORTCUT_SERVICE);
            List<ShortcutManager.ShareShortcutInfo> resultList = sm.getShareTargets(filter);
            sendShareShortcutInfoList(resultList, driList);
        });
    }

    private void sendShareShortcutInfoList(
                List<ShortcutManager.ShareShortcutInfo> resultList,
                List<DisplayResolveInfo> driList) {
        // 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
        // ShareShortcutInfos directly.
@@ -654,7 +719,6 @@ public class ChooserActivity extends ResolverActivity {
            if (chooserTargets.isEmpty()) {
                continue;
            }

            final Message msg = Message.obtain();
            msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
            msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null);
@@ -667,7 +731,6 @@ public class ChooserActivity extends ResolverActivity {
            msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED;
            mChooserHandler.sendMessage(msg);
        }
        });
    }

    private ChooserTarget convertToChooserTarget(ShortcutManager.ShareShortcutInfo shareShortcut) {
@@ -724,6 +787,7 @@ public class ChooserActivity extends ResolverActivity {
        // Do nothing. We'll send the voice stuff ourselves.
    }

    // TODO(b/123377860) Send clicked ShortcutInfo to mAppPredictor
    void updateModelAndChooserCounts(TargetInfo info) {
        if (info != null) {
            final ResolveInfo ri = info.getResolveInfo();