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

Commit 239267b0 authored by Song Hu's avatar Song Hu
Browse files

Remove append/quota mechanism from direct share target surfacing, due to...

Remove append/quota mechanism from direct share target surfacing, due to ChooserTargetSevice sunset.

Bug: 182146792
Test: verify on local phone
Change-Id: Id9f76c9e1be5b0dfdff5ff1256b90a4b397045d6
Merged-In: Id9f76c9e1be5b0dfdff5ff1256b90a4b397045d6
(cherry picked from commit b5a385a1)
parent 47067afd
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -28,11 +28,9 @@ import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Message;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.Log;

import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;

import java.util.ArrayList;
import java.util.HashMap;
@@ -62,11 +60,6 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
    // back to using the ResolverRankerService.
    private ResolverRankerServiceResolverComparator mResolverRankerService;

    private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
            DeviceConfig.NAMESPACE_SYSTEMUI,
            SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
            true);

    AppPredictionServiceResolverComparator(
                Context context,
                Intent intent,
@@ -183,9 +176,6 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
        if (mResolverRankerService != null) {
            return mResolverRankerService.getScore(name);
        }
        if (mAppendDirectShareEnabled && !mTargetScores.isEmpty()) {
            return mTargetScores.get(name);
        }
        Integer rank = mTargetRanks.get(name);
        if (rank == null) {
            Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
+3 −80
Original line number Diff line number Diff line
@@ -256,15 +256,6 @@ public class ChooserActivity extends ResolverActivity implements
            SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
            DEFAULT_SALT_EXPIRATION_DAYS);

    private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
            DeviceConfig.NAMESPACE_SYSTEMUI,
            SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
            true);
    private boolean mChooserTargetRankingEnabled = DeviceConfig.getBoolean(
            DeviceConfig.NAMESPACE_SYSTEMUI,
            SystemUiDeviceConfigFlags.CHOOSER_TARGET_RANKING_ENABLED,
            true);

    private Bundle mReplacementExtras;
    private IntentSender mChosenComponentSender;
    private IntentSender mRefinementIntentSender;
@@ -472,16 +463,10 @@ public class ChooserActivity extends ResolverActivity implements
        private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 4;
        private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 5;
        private static final int LIST_VIEW_UPDATE_MESSAGE = 6;
        private static final int CHOOSER_TARGET_RANKING_SCORE = 7;

        private static final int WATCHDOG_TIMEOUT_MAX_MILLIS = 10000;
        private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 3000;

        private static final int DEFAULT_DIRECT_SHARE_TIMEOUT_MILLIS = 1500;
        private int mDirectShareTimeout = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.SHARE_SHEET_DIRECT_SHARE_TIMEOUT,
                DEFAULT_DIRECT_SHARE_TIMEOUT_MILLIS);

        private boolean mMinTimeoutPassed = false;

        private void removeAllMessages() {
@@ -491,7 +476,6 @@ public class ChooserActivity extends ResolverActivity implements
            removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
            removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
            removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
            removeMessages(CHOOSER_TARGET_RANKING_SCORE);
        }

        private void restartServiceRequestTimer() {
@@ -501,14 +485,13 @@ public class ChooserActivity extends ResolverActivity implements

            if (DEBUG) {
                Log.d(TAG, "queryTargets setting watchdog timer for "
                        + mDirectShareTimeout + "-"
                        + WATCHDOG_TIMEOUT_MAX_MILLIS + "ms");
            }

            sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT,
                    WATCHDOG_TIMEOUT_MIN_MILLIS);
            sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
                    mAppendDirectShareEnabled ? mDirectShareTimeout : WATCHDOG_TIMEOUT_MAX_MILLIS);
                    WATCHDOG_TIMEOUT_MAX_MILLIS);
        }

        private void maybeStopServiceRequestTimer() {
@@ -608,17 +591,6 @@ public class ChooserActivity extends ResolverActivity implements
                    getChooserActivityLogger().logSharesheetDirectLoadComplete();
                    break;

                case CHOOSER_TARGET_RANKING_SCORE:
                    if (DEBUG) Log.d(TAG, "CHOOSER_TARGET_RANKING_SCORE");
                    final ChooserTargetRankingInfo scoreInfo = (ChooserTargetRankingInfo) msg.obj;
                    ChooserListAdapter adapterForUserHandle =
                            mChooserMultiProfilePagerAdapter.getListAdapterForUserHandle(
                                    scoreInfo.userHandle);
                    if (adapterForUserHandle != null) {
                        adapterForUserHandle.addChooserTargetRankingScore(scoreInfo.scores);
                    }
                    break;

                default:
                    super.handleMessage(msg);
            }
@@ -885,17 +857,9 @@ public class ChooserActivity extends ResolverActivity implements
                if (appTarget.getShortcutInfo() == null) {
                    continue;
                }
                if (appTarget.getShortcutInfo().getId().equals(CHOOSER_TARGET)) {
                    chooserTargetScores.add(appTarget);
                } else {
                shortcutResults.add(appTarget);
            }
            }
            resultList = shortcutResults;
            if (mChooserTargetRankingEnabled) {
                sendChooserTargetRankingScore(chooserTargetScores,
                        chooserListAdapter.getUserHandle());
            }
            for (AppTarget appTarget : resultList) {
                shareShortcutInfos.add(new ShortcutManager.ShareShortcutInfo(
                        appTarget.getShortcutInfo(),
@@ -2148,14 +2112,6 @@ public class ChooserActivity extends ResolverActivity implements
        return true;
    }

    private void sendChooserTargetRankingScore(List<AppTarget> chooserTargetScores,
            UserHandle userHandle) {
        final Message msg = Message.obtain();
        msg.what = ChooserHandler.CHOOSER_TARGET_RANKING_SCORE;
        msg.obj = new ChooserTargetRankingInfo(chooserTargetScores, userHandle);
        mChooserHandler.sendMessage(msg);
    }

    private void sendShareShortcutInfoList(
                List<ShortcutManager.ShareShortcutInfo> resultList,
                ChooserListAdapter chooserListAdapter,
@@ -2376,9 +2332,6 @@ public class ChooserActivity extends ResolverActivity implements
    }

    private void sendImpressionToAppPredictor(TargetInfo targetInfo, ChooserListAdapter adapter) {
        if (!mChooserTargetRankingEnabled) {
            return;
        }
        AppPredictor directShareAppPredictor = getAppPredictorForDirectShareIfEnabled(
                mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
        if (directShareAppPredictor == null) {
@@ -2399,11 +2352,6 @@ public class ChooserActivity extends ResolverActivity implements
                targetIds.add(new AppTargetId(
                        String.format("%s/%s/%s", shortcutId, componentName.flattenToString(),
                                SHORTCUT_TARGET)));
            } else {
                String titleHash = ChooserUtil.md5(chooserTarget.getTitle().toString());
                targetIds.add(new AppTargetId(
                        String.format("%s/%s/%s", titleHash, componentName.flattenToString(),
                                CHOOSER_TARGET)));
            }
        }
        directShareAppPredictor.notifyLaunchLocationShown(LAUNCH_LOCATION_DIRECT_SHARE, targetIds);
@@ -2423,29 +2371,6 @@ public class ChooserActivity extends ResolverActivity implements
        if (mDirectShareAppTargetCache != null) {
            appTarget = mDirectShareAppTargetCache.get(chooserTarget);
        }
        if (mChooserTargetRankingEnabled && appTarget == null) {
            // Send ChooserTarget sharing info to AppPredictor.
            ComponentName componentName = mChooserTargetComponentNameCache.getOrDefault(
                    chooserTarget.getComponentName(), chooserTarget.getComponentName());
            try {
                appTarget = new AppTarget.Builder(
                        new AppTargetId(componentName.flattenToString()),
                        new ShortcutInfo.Builder(
                                createPackageContextAsUser(
                                        componentName.getPackageName(),
                                        0 /* flags */,
                                        getUser()),
                                CHOOSER_TARGET)
                            .setActivity(componentName)
                            .setShortLabel(ChooserUtil.md5(chooserTarget.getTitle().toString()))
                            .build())
                        .setClassName(componentName.getClassName())
                        .build();
            } catch (NameNotFoundException e) {
                Log.e(TAG, "Could not look up service " + componentName
                        + "; component name not found");
            }
        }
        // This is a direct share click that was provided by the APS
        if (appTarget != null) {
            directShareAppPredictor.notifyAppTargetEvent(
@@ -3971,9 +3896,7 @@ public class ChooserActivity extends ResolverActivity implements
                // until they start to scroll
                ChooserListAdapter adapter =
                        mChooserMultiProfilePagerAdapter.getActiveListAdapter();
                int validTargets =
                        mAppendDirectShareEnabled ? adapter.getNumServiceTargetsForExpand()
                                : adapter.getSelectableServiceTargetCount();
                int validTargets = adapter.getSelectableServiceTargetCount();
                if (validTargets <= maxTargetsPerRow) {
                    mHideDirectShareExpansion = true;
                    return;
+1 −225
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FRO

import android.app.ActivityManager;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -34,7 +33,6 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.service.chooser.ChooserTarget;
import android.util.Log;
import android.util.Pair;
@@ -48,7 +46,6 @@ import com.android.internal.app.chooser.DisplayResolveInfo;
import com.android.internal.app.chooser.MultiDisplayResolveInfo;
import com.android.internal.app.chooser.SelectableTargetInfo;
import com.android.internal.app.chooser.TargetInfo;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;

import java.util.ArrayList;
import java.util.Collections;
@@ -57,17 +54,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class ChooserListAdapter extends ResolverListAdapter {
    private static final String TAG = "ChooserListAdapter";
    private static final boolean DEBUG = false;

    private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
            DeviceConfig.NAMESPACE_SYSTEMUI,
            SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
            true);

    private boolean mEnableStackedApps = true;

    public static final int NO_POSITION = -1;
@@ -209,9 +200,6 @@ public class ChooserListAdapter extends ResolverListAdapter {

    void refreshListView() {
        if (mListViewDataChanged) {
            if (mAppendDirectShareEnabled) {
                appendServiceTargetsWithQuota();
            }
            super.notifyDataSetChanged();
        }
        mListViewDataChanged = false;
@@ -517,11 +505,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
                    + targets.size()
                    + " targets");
        }
        if (mAppendDirectShareEnabled) {
            parkTargetIntoMemory(origTarget, targets, targetType, directShareToShortcutInfos,
                    pendingChooserTargetServiceConnections);
            return;
        }
        if (targets.size() == 0) {
            return;
        }
@@ -572,210 +555,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
        }
    }

    /**
     * Store ChooserTarget ranking scores info wrapped in {@code targets}.
     */
    public void addChooserTargetRankingScore(List<AppTarget> targets) {
        Log.i(TAG, "addChooserTargetRankingScore " + targets.size() + " targets score.");
        for (AppTarget target : targets) {
            if (target.getShortcutInfo() == null) {
                continue;
            }
            ShortcutInfo shortcutInfo = target.getShortcutInfo();
            if (!shortcutInfo.getId().equals(ChooserActivity.CHOOSER_TARGET)
                    || shortcutInfo.getActivity() == null) {
                continue;
            }
            ComponentName componentName = shortcutInfo.getActivity();
            if (!mChooserTargetScores.containsKey(componentName)) {
                mChooserTargetScores.put(componentName, new HashMap<>());
            }
            mChooserTargetScores.get(componentName).put(shortcutInfo.getShortLabel().toString(),
                    target.getRank());
        }
        mChooserTargetScores.keySet().forEach(key -> rankTargetsWithinComponent(key));
    }

    /**
     * Rank chooserTargets of the given {@code componentName} in mParkingDirectShareTargets as per
     * available scores stored in mChooserTargetScores.
     */
    private void rankTargetsWithinComponent(ComponentName componentName) {
        if (!mParkingDirectShareTargets.containsKey(componentName)
                || !mChooserTargetScores.containsKey(componentName)) {
            return;
        }
        Map<String, Integer> scores = mChooserTargetScores.get(componentName);
        Collections.sort(mParkingDirectShareTargets.get(componentName).first, (o1, o2) -> {
            // The score has been normalized between 0 and 2000, the default is 1000.
            int score1 = scores.getOrDefault(
                    ChooserUtil.md5(o1.getChooserTarget().getTitle().toString()),
                    DEFAULT_DIRECT_SHARE_RANKING_SCORE);
            int score2 = scores.getOrDefault(
                    ChooserUtil.md5(o2.getChooserTarget().getTitle().toString()),
                    DEFAULT_DIRECT_SHARE_RANKING_SCORE);
            return score2 - score1;
        });
    }

    /**
     * Park {@code targets} into memory for the moment to surface them later when view is refreshed.
     * Components pending on ChooserTargetService query are also recorded.
     */
    private void parkTargetIntoMemory(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
            @ChooserActivity.ShareTargetType int targetType,
            Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos,
            List<ChooserActivity.ChooserTargetServiceConnection>
                    pendingChooserTargetServiceConnections) {
        ComponentName origComponentName = origTarget != null ? origTarget.getResolvedComponentName()
                : !targets.isEmpty() ? targets.get(0).getComponentName() : null;
        Log.i(TAG,
                "parkTargetIntoMemory " + origComponentName + ", " + targets.size() + " targets");
        mPendingChooserTargetService = pendingChooserTargetServiceConnections.stream()
                .map(ChooserActivity.ChooserTargetServiceConnection::getComponentName)
                .filter(componentName -> !componentName.equals(origComponentName))
                .collect(Collectors.toSet());
        // Park targets in memory
        if (!targets.isEmpty()) {
            final boolean isShortcutResult =
                    (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER
                            || targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
            Context contextAsUser = mContext.createContextAsUser(getUserHandle(),
                    0 /* flags */);
            List<ChooserTargetInfo> parkingTargetInfos = targets.stream()
                    .map(target ->
                            new SelectableTargetInfo(
                                    contextAsUser, origTarget, target, target.getScore(),
                                    mSelectableTargetInfoCommunicator,
                                    (isShortcutResult ? directShareToShortcutInfos.get(target)
                                            : null))
                    )
                    .collect(Collectors.toList());
            Pair<List<ChooserTargetInfo>, Integer> parkingTargetInfoPair =
                    mParkingDirectShareTargets.getOrDefault(origComponentName,
                            new Pair<>(new ArrayList<>(), 0));
            for (ChooserTargetInfo target : parkingTargetInfos) {
                if (!checkDuplicateTarget(target, parkingTargetInfoPair.first)
                        && !checkDuplicateTarget(target, mServiceTargets)) {
                    parkingTargetInfoPair.first.add(target);
                    mAvailableServiceTargetsNum++;
                }
            }
            mParkingDirectShareTargets.put(origComponentName, parkingTargetInfoPair);
            rankTargetsWithinComponent(origComponentName);
            if (isShortcutResult) {
                mShortcutComponents.add(origComponentName);
            }
        }
        notifyDataSetChanged();
    }

    /**
     * Append targets of top ranked share app into direct share row with quota limit. Remove
     * appended ones from memory.
     */
    private void appendServiceTargetsWithQuota() {
        int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets();
        List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets);
        float totalScore = 0f;
        for (ComponentName component : topComponentNames) {
            if (!mPendingChooserTargetService.contains(component)
                    && !mParkingDirectShareTargets.containsKey(component)) {
                continue;
            }
            totalScore += super.getScore(component);
        }
        boolean shouldWaitPendingService = false;
        for (ComponentName component : topComponentNames) {
            if (!mPendingChooserTargetService.contains(component)
                    && !mParkingDirectShareTargets.containsKey(component)) {
                continue;
            }
            float score = super.getScore(component);
            int quota = Math.round(maxRankedTargets * score / totalScore);
            if (mPendingChooserTargetService.contains(component) && quota >= 1) {
                shouldWaitPendingService = true;
            }
            if (!mParkingDirectShareTargets.containsKey(component)) {
                continue;
            }
            // Append targets into direct share row as per quota.
            Pair<List<ChooserTargetInfo>, Integer> parkingTargetsItem =
                    mParkingDirectShareTargets.get(component);
            List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first;
            int insertedNum = parkingTargetsItem.second;
            while (insertedNum < quota && !parkingTargets.isEmpty()) {
                if (!checkDuplicateTarget(parkingTargets.get(0), mServiceTargets)) {
                    mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0));
                    mValidServiceTargetsNum++;
                    insertedNum++;
                }
                parkingTargets.remove(0);
            }
            Log.i(TAG, " appendServiceTargetsWithQuota component=" + component
                    + " appendNum=" + (insertedNum - parkingTargetsItem.second));
            if (DEBUG) {
                Log.d(TAG, " appendServiceTargetsWithQuota component=" + component
                        + " score=" + score
                        + " totalScore=" + totalScore
                        + " quota=" + quota);
            }
            mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum));
        }
        if (!shouldWaitPendingService) {
            fillAllServiceTargets();
        }
    }

    /**
     * Append all remaining targets (parking in memory) into direct share row as per their ranking.
     */
    private void fillAllServiceTargets() {
        if (mParkingDirectShareTargets.isEmpty()) {
            return;
        }
        Log.i(TAG, " fillAllServiceTargets");
        List<ComponentName> topComponentNames = getTopComponentNames(MAX_SERVICE_TARGET_APP);
        // Append all remaining targets of top recommended components into direct share row.
        for (ComponentName component : topComponentNames) {
            if (!mParkingDirectShareTargets.containsKey(component)) {
                continue;
            }
            mParkingDirectShareTargets.get(component).first.stream()
                    .filter(target -> !checkDuplicateTarget(target, mServiceTargets))
                    .forEach(target -> {
                        mServiceTargets.add(mValidServiceTargetsNum, target);
                        mValidServiceTargetsNum++;
                    });
            mParkingDirectShareTargets.remove(component);
        }
        // Append all remaining shortcuts targets into direct share row.
        mParkingDirectShareTargets.entrySet().stream()
                .filter(entry -> mShortcutComponents.contains(entry.getKey()))
                .map(entry -> entry.getValue())
                .map(pair -> pair.first)
                .forEach(targets -> {
                    for (ChooserTargetInfo target : targets) {
                        if (!checkDuplicateTarget(target, mServiceTargets)) {
                            mServiceTargets.add(mValidServiceTargetsNum, target);
                            mValidServiceTargetsNum++;
                        }
                    }
                });
        mParkingDirectShareTargets.clear();
    }

    private boolean checkDuplicateTarget(ChooserTargetInfo target,
            List<ChooserTargetInfo> destination) {
        // Check for duplicates and abort if found
        for (ChooserTargetInfo otherTargetInfo : destination) {
            if (target.isSimilar(otherTargetInfo)) {
                return true;
            }
        }
        return false;
    }

    /**
     * The return number have to exceed a minimum limit to make direct share area expandable. When
     * append direct share targets is enabled, return count of all available targets parking in the
@@ -783,7 +562,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
     * shuffling due to older-style direct share targets.
     */
    int getNumServiceTargetsForExpand() {
        return mAppendDirectShareEnabled ? mAvailableServiceTargetsNum : mNumShortcutResults;
        return mNumShortcutResults;
    }

    /**
@@ -820,9 +599,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
     */
    public void completeServiceTargetLoading() {
        mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
        if (mAppendDirectShareEnabled) {
            fillAllServiceTargets();
        }
        if (mServiceTargets.isEmpty()) {
            mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
        }