Loading core/java/com/android/internal/app/AbstractResolverComparator.java +6 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,12 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC */ abstract float getScore(ComponentName name); /** * Returns the list of top K component names which have highest * {@link #getScore(ComponentName)} */ abstract List<ComponentName> getTopComponentNames(int topK); /** Handles result message sent to mHandler. */ abstract void handleResultMessage(Message message); Loading core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java +11 −0 Original line number Diff line number Diff line Loading @@ -36,7 +36,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Executors; import java.util.stream.Collectors; /** * Uses an {@link AppPredictor} to sort Resolver targets. If the AppPredictionService appears to be Loading Loading @@ -159,6 +161,15 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator return 1.0f - (((float) rank) / consecutiveSumOfRanks); } @Override List<ComponentName> getTopComponentNames(int topK) { return mTargetRanks.entrySet().stream() .sorted(Entry.comparingByValue()) .limit(topK) .map(Entry::getKey) .collect(Collectors.toList()); } @Override void updateModel(ComponentName componentName) { if (mResolverRankerService != null) { Loading core/java/com/android/internal/app/ChooserActivity.java +21 −6 Original line number Diff line number Diff line Loading @@ -223,6 +223,11 @@ 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, false); private Bundle mReplacementExtras; private IntentSender mChosenComponentSender; private IntentSender mRefinementIntentSender; Loading Loading @@ -409,6 +414,11 @@ public class ChooserActivity extends ResolverActivity implements 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() { Loading @@ -427,15 +437,14 @@ public class ChooserActivity extends ResolverActivity implements if (DEBUG) { Log.d(TAG, "queryTargets setting watchdog timer for " + WATCHDOG_TIMEOUT_MIN_MILLIS + "-" + mDirectShareTimeout + "-" + WATCHDOG_TIMEOUT_MAX_MILLIS + "ms"); } sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT, WATCHDOG_TIMEOUT_MIN_MILLIS); sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT, WATCHDOG_TIMEOUT_MAX_MILLIS); mAppendDirectShareEnabled ? mDirectShareTimeout : WATCHDOG_TIMEOUT_MAX_MILLIS); } private void maybeStopServiceRequestTimer() { Loading Loading @@ -463,6 +472,7 @@ public class ChooserActivity extends ResolverActivity implements final ServiceResultInfo sri = (ServiceResultInfo) msg.obj; if (!mServiceConnections.contains(sri.connection)) { Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection + sri.originalTarget.getResolveInfo().activityInfo.packageName + " returned after being removed from active connections." + " Have you considered returning results faster?"); break; Loading @@ -474,7 +484,7 @@ public class ChooserActivity extends ResolverActivity implements if (adapterForUserHandle != null) { adapterForUserHandle.addServiceResults(sri.originalTarget, sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET, /* directShareShortcutInfoCache */ null); /* directShareShortcutInfoCache */ null, mServiceConnections); } } unbindService(sri.connection); Loading @@ -489,6 +499,7 @@ public class ChooserActivity extends ResolverActivity implements break; case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT: mMinTimeoutPassed = true; unbindRemainingServices(); maybeStopServiceRequestTimer(); break; Loading @@ -513,7 +524,7 @@ public class ChooserActivity extends ResolverActivity implements if (adapterForUserHandle != null) { adapterForUserHandle.addServiceResults( resultInfo.originalTarget, resultInfo.resultTargets, msg.arg1, mDirectShareShortcutInfoCache); mDirectShareShortcutInfoCache, mServiceConnections); } } break; Loading Loading @@ -1481,7 +1492,7 @@ public class ChooserActivity extends ResolverActivity implements /* origTarget */ null, Lists.newArrayList(mCallerChooserTargets), TARGET_TYPE_DEFAULT, /* directShareShortcutInfoCache */ null); /* directShareShortcutInfoCache */ null, mServiceConnections); } } Loading Loading @@ -3584,6 +3595,10 @@ public class ChooserActivity extends ResolverActivity implements ? mOriginalTarget.getResolveInfo().activityInfo.toString() : "<connection destroyed>") + "}"; } public ComponentName getComponentName() { return mOriginalTarget.getResolveInfo().activityInfo.getComponentName(); } } static class ServiceResultInfo { Loading core/java/com/android/internal/app/ChooserListAdapter.java +156 −4 Original line number Diff line number Diff line Loading @@ -32,8 +32,10 @@ import android.content.pm.ShortcutInfo; 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; import android.view.View; import android.view.ViewGroup; Loading @@ -44,17 +46,26 @@ 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; import java.util.HashMap; 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, false); private boolean mEnableStackedApps = true; public static final int NO_POSITION = -1; Loading Loading @@ -84,6 +95,11 @@ public class ChooserListAdapter extends ResolverListAdapter { // Reserve spots for incoming direct share targets by adding placeholders private ChooserTargetInfo mPlaceHolderTargetInfo = new ChooserActivity.PlaceHolderTargetInfo(); private int mValidServiceTargetsNum = 0; private final Map<ComponentName, Pair<List<ChooserTargetInfo>, Integer>> mParkingDirectShareTargets = new HashMap<>(); private Set<ComponentName> mPendingChooserTargetService = new HashSet<>(); private Set<ComponentName> mShortcutComponents = new HashSet<>(); private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>(); private final List<TargetInfo> mCallerTargets = new ArrayList<>(); Loading Loading @@ -189,6 +205,9 @@ public class ChooserListAdapter extends ResolverListAdapter { void refreshListView() { if (mListViewDataChanged) { if (mAppendDirectShareEnabled) { appendServiceTargetsWithQuota(); } super.notifyDataSetChanged(); } mListViewDataChanged = false; Loading @@ -198,6 +217,10 @@ public class ChooserListAdapter extends ResolverListAdapter { private void createPlaceHolders() { mNumShortcutResults = 0; mServiceTargets.clear(); mValidServiceTargetsNum = 0; mParkingDirectShareTargets.clear(); mPendingChooserTargetService.clear(); mShortcutComponents.clear(); for (int i = 0; i < MAX_SERVICE_TARGETS; i++) { mServiceTargets.add(mPlaceHolderTargetInfo); } Loading Loading @@ -393,12 +416,19 @@ public class ChooserListAdapter extends ResolverListAdapter { */ public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets, @ChooserActivity.ShareTargetType int targetType, Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos) { Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos, List<ChooserActivity.ChooserTargetServiceConnection> pendingChooserTargetServiceConnections) { if (DEBUG) { Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size() Log.d(TAG, "addServiceResults " + origTarget.getResolvedComponentName() + ", " + targets.size() + " targets"); } if (mAppendDirectShareEnabled) { parkTargetIntoMemory(origTarget, targets, targetType, directShareToShortcutInfos, pendingChooserTargetServiceConnections); return; } if (targets.size() == 0) { return; } Loading Loading @@ -449,6 +479,126 @@ public class ChooserListAdapter extends ResolverListAdapter { } } /** * 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.getResolvedComponentName(); mPendingChooserTargetService = pendingChooserTargetServiceConnections.stream() .map(ChooserActivity.ChooserTargetServiceConnection::getComponentName) .filter(componentName -> !componentName.equals(origComponentName)) .collect(Collectors.toSet()); // Park targets in memory if (!targets.isEmpty() && !mParkingDirectShareTargets.containsKey(origComponentName)) { 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(), mSelectableTargetInfoComunicator, (isShortcutResult ? directShareToShortcutInfos.get(target) : null)) ) .collect(Collectors.toList()); mParkingDirectShareTargets.put(origComponentName, new Pair<>(parkingTargetInfos, 0)); 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); int appRank = 0; for (ComponentName component : topComponentNames) { if (!mPendingChooserTargetService.contains(component) && !mParkingDirectShareTargets.containsKey(component)) { continue; } appRank++; Pair<List<ChooserTargetInfo>, Integer> parkingTargetsItem = mParkingDirectShareTargets.get(component); if (parkingTargetsItem != null && parkingTargetsItem.second == 0) { List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first; int initTargetsQuota = appRank <= maxRankedTargets / 2 ? 2 : 1; int insertedNum = 0; while (insertedNum < initTargetsQuota && !parkingTargets.isEmpty()) { if (!checkDuplicateTarget(parkingTargets.get(0))) { mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0)); mValidServiceTargetsNum++; insertedNum++; } parkingTargets.remove(0); } mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum)); if (mShortcutComponents.contains(component)) { mNumShortcutResults += insertedNum; } } } } /** * Append all remaining targets (parking in memory) into direct share row as per their ranking. */ private void fillAllServiceTargets() { int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets(); List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets); // 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)) .forEach(target -> { if (mShortcutComponents.contains(component)) { mNumShortcutResults++; } mServiceTargets.add(target); }); mParkingDirectShareTargets.remove(component); } // Append all remaining shortcuts targets into direct share row. List<ChooserTargetInfo> remainingTargets = new ArrayList<>(); mParkingDirectShareTargets.entrySet().stream() .filter(entry -> mShortcutComponents.contains(entry.getKey())) .map(entry -> entry.getValue()) .map(pair -> pair.first) .forEach(remainingTargets::addAll); remainingTargets.sort( (t1, t2) -> -Float.compare(t1.getModifiedScore(), t2.getModifiedScore())); mServiceTargets.addAll(remainingTargets); mNumShortcutResults += remainingTargets.size(); mParkingDirectShareTargets.clear(); } private boolean checkDuplicateTarget(ChooserTargetInfo chooserTargetInfo) { // Check for duplicates and abort if found for (ChooserTargetInfo otherTargetInfo : mServiceTargets) { if (chooserTargetInfo.isSimilar(otherTargetInfo)) { return true; } } return false; } int getNumShortcutResults() { return mNumShortcutResults; } Loading Loading @@ -487,7 +637,9 @@ 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()); } Loading core/java/com/android/internal/app/ResolverListAdapter.java +8 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,14 @@ public class ResolverListAdapter extends BaseAdapter { return mResolverListController.getScore(target); } /** * Returns the list of top K component names which have highest * {@link #getScore(DisplayResolveInfo)} */ public List<ComponentName> getTopComponentNames(int topK) { return mResolverListController.getTopComponentNames(topK); } public void updateModel(ComponentName componentName) { mResolverListController.updateModel(componentName); } Loading Loading
core/java/com/android/internal/app/AbstractResolverComparator.java +6 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,12 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC */ abstract float getScore(ComponentName name); /** * Returns the list of top K component names which have highest * {@link #getScore(ComponentName)} */ abstract List<ComponentName> getTopComponentNames(int topK); /** Handles result message sent to mHandler. */ abstract void handleResultMessage(Message message); Loading
core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java +11 −0 Original line number Diff line number Diff line Loading @@ -36,7 +36,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Executors; import java.util.stream.Collectors; /** * Uses an {@link AppPredictor} to sort Resolver targets. If the AppPredictionService appears to be Loading Loading @@ -159,6 +161,15 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator return 1.0f - (((float) rank) / consecutiveSumOfRanks); } @Override List<ComponentName> getTopComponentNames(int topK) { return mTargetRanks.entrySet().stream() .sorted(Entry.comparingByValue()) .limit(topK) .map(Entry::getKey) .collect(Collectors.toList()); } @Override void updateModel(ComponentName componentName) { if (mResolverRankerService != null) { Loading
core/java/com/android/internal/app/ChooserActivity.java +21 −6 Original line number Diff line number Diff line Loading @@ -223,6 +223,11 @@ 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, false); private Bundle mReplacementExtras; private IntentSender mChosenComponentSender; private IntentSender mRefinementIntentSender; Loading Loading @@ -409,6 +414,11 @@ public class ChooserActivity extends ResolverActivity implements 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() { Loading @@ -427,15 +437,14 @@ public class ChooserActivity extends ResolverActivity implements if (DEBUG) { Log.d(TAG, "queryTargets setting watchdog timer for " + WATCHDOG_TIMEOUT_MIN_MILLIS + "-" + mDirectShareTimeout + "-" + WATCHDOG_TIMEOUT_MAX_MILLIS + "ms"); } sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT, WATCHDOG_TIMEOUT_MIN_MILLIS); sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT, WATCHDOG_TIMEOUT_MAX_MILLIS); mAppendDirectShareEnabled ? mDirectShareTimeout : WATCHDOG_TIMEOUT_MAX_MILLIS); } private void maybeStopServiceRequestTimer() { Loading Loading @@ -463,6 +472,7 @@ public class ChooserActivity extends ResolverActivity implements final ServiceResultInfo sri = (ServiceResultInfo) msg.obj; if (!mServiceConnections.contains(sri.connection)) { Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection + sri.originalTarget.getResolveInfo().activityInfo.packageName + " returned after being removed from active connections." + " Have you considered returning results faster?"); break; Loading @@ -474,7 +484,7 @@ public class ChooserActivity extends ResolverActivity implements if (adapterForUserHandle != null) { adapterForUserHandle.addServiceResults(sri.originalTarget, sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET, /* directShareShortcutInfoCache */ null); /* directShareShortcutInfoCache */ null, mServiceConnections); } } unbindService(sri.connection); Loading @@ -489,6 +499,7 @@ public class ChooserActivity extends ResolverActivity implements break; case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT: mMinTimeoutPassed = true; unbindRemainingServices(); maybeStopServiceRequestTimer(); break; Loading @@ -513,7 +524,7 @@ public class ChooserActivity extends ResolverActivity implements if (adapterForUserHandle != null) { adapterForUserHandle.addServiceResults( resultInfo.originalTarget, resultInfo.resultTargets, msg.arg1, mDirectShareShortcutInfoCache); mDirectShareShortcutInfoCache, mServiceConnections); } } break; Loading Loading @@ -1481,7 +1492,7 @@ public class ChooserActivity extends ResolverActivity implements /* origTarget */ null, Lists.newArrayList(mCallerChooserTargets), TARGET_TYPE_DEFAULT, /* directShareShortcutInfoCache */ null); /* directShareShortcutInfoCache */ null, mServiceConnections); } } Loading Loading @@ -3584,6 +3595,10 @@ public class ChooserActivity extends ResolverActivity implements ? mOriginalTarget.getResolveInfo().activityInfo.toString() : "<connection destroyed>") + "}"; } public ComponentName getComponentName() { return mOriginalTarget.getResolveInfo().activityInfo.getComponentName(); } } static class ServiceResultInfo { Loading
core/java/com/android/internal/app/ChooserListAdapter.java +156 −4 Original line number Diff line number Diff line Loading @@ -32,8 +32,10 @@ import android.content.pm.ShortcutInfo; 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; import android.view.View; import android.view.ViewGroup; Loading @@ -44,17 +46,26 @@ 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; import java.util.HashMap; 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, false); private boolean mEnableStackedApps = true; public static final int NO_POSITION = -1; Loading Loading @@ -84,6 +95,11 @@ public class ChooserListAdapter extends ResolverListAdapter { // Reserve spots for incoming direct share targets by adding placeholders private ChooserTargetInfo mPlaceHolderTargetInfo = new ChooserActivity.PlaceHolderTargetInfo(); private int mValidServiceTargetsNum = 0; private final Map<ComponentName, Pair<List<ChooserTargetInfo>, Integer>> mParkingDirectShareTargets = new HashMap<>(); private Set<ComponentName> mPendingChooserTargetService = new HashSet<>(); private Set<ComponentName> mShortcutComponents = new HashSet<>(); private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>(); private final List<TargetInfo> mCallerTargets = new ArrayList<>(); Loading Loading @@ -189,6 +205,9 @@ public class ChooserListAdapter extends ResolverListAdapter { void refreshListView() { if (mListViewDataChanged) { if (mAppendDirectShareEnabled) { appendServiceTargetsWithQuota(); } super.notifyDataSetChanged(); } mListViewDataChanged = false; Loading @@ -198,6 +217,10 @@ public class ChooserListAdapter extends ResolverListAdapter { private void createPlaceHolders() { mNumShortcutResults = 0; mServiceTargets.clear(); mValidServiceTargetsNum = 0; mParkingDirectShareTargets.clear(); mPendingChooserTargetService.clear(); mShortcutComponents.clear(); for (int i = 0; i < MAX_SERVICE_TARGETS; i++) { mServiceTargets.add(mPlaceHolderTargetInfo); } Loading Loading @@ -393,12 +416,19 @@ public class ChooserListAdapter extends ResolverListAdapter { */ public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets, @ChooserActivity.ShareTargetType int targetType, Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos) { Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos, List<ChooserActivity.ChooserTargetServiceConnection> pendingChooserTargetServiceConnections) { if (DEBUG) { Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size() Log.d(TAG, "addServiceResults " + origTarget.getResolvedComponentName() + ", " + targets.size() + " targets"); } if (mAppendDirectShareEnabled) { parkTargetIntoMemory(origTarget, targets, targetType, directShareToShortcutInfos, pendingChooserTargetServiceConnections); return; } if (targets.size() == 0) { return; } Loading Loading @@ -449,6 +479,126 @@ public class ChooserListAdapter extends ResolverListAdapter { } } /** * 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.getResolvedComponentName(); mPendingChooserTargetService = pendingChooserTargetServiceConnections.stream() .map(ChooserActivity.ChooserTargetServiceConnection::getComponentName) .filter(componentName -> !componentName.equals(origComponentName)) .collect(Collectors.toSet()); // Park targets in memory if (!targets.isEmpty() && !mParkingDirectShareTargets.containsKey(origComponentName)) { 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(), mSelectableTargetInfoComunicator, (isShortcutResult ? directShareToShortcutInfos.get(target) : null)) ) .collect(Collectors.toList()); mParkingDirectShareTargets.put(origComponentName, new Pair<>(parkingTargetInfos, 0)); 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); int appRank = 0; for (ComponentName component : topComponentNames) { if (!mPendingChooserTargetService.contains(component) && !mParkingDirectShareTargets.containsKey(component)) { continue; } appRank++; Pair<List<ChooserTargetInfo>, Integer> parkingTargetsItem = mParkingDirectShareTargets.get(component); if (parkingTargetsItem != null && parkingTargetsItem.second == 0) { List<ChooserTargetInfo> parkingTargets = parkingTargetsItem.first; int initTargetsQuota = appRank <= maxRankedTargets / 2 ? 2 : 1; int insertedNum = 0; while (insertedNum < initTargetsQuota && !parkingTargets.isEmpty()) { if (!checkDuplicateTarget(parkingTargets.get(0))) { mServiceTargets.add(mValidServiceTargetsNum, parkingTargets.get(0)); mValidServiceTargetsNum++; insertedNum++; } parkingTargets.remove(0); } mParkingDirectShareTargets.put(component, new Pair<>(parkingTargets, insertedNum)); if (mShortcutComponents.contains(component)) { mNumShortcutResults += insertedNum; } } } } /** * Append all remaining targets (parking in memory) into direct share row as per their ranking. */ private void fillAllServiceTargets() { int maxRankedTargets = mChooserListCommunicator.getMaxRankedTargets(); List<ComponentName> topComponentNames = getTopComponentNames(maxRankedTargets); // 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)) .forEach(target -> { if (mShortcutComponents.contains(component)) { mNumShortcutResults++; } mServiceTargets.add(target); }); mParkingDirectShareTargets.remove(component); } // Append all remaining shortcuts targets into direct share row. List<ChooserTargetInfo> remainingTargets = new ArrayList<>(); mParkingDirectShareTargets.entrySet().stream() .filter(entry -> mShortcutComponents.contains(entry.getKey())) .map(entry -> entry.getValue()) .map(pair -> pair.first) .forEach(remainingTargets::addAll); remainingTargets.sort( (t1, t2) -> -Float.compare(t1.getModifiedScore(), t2.getModifiedScore())); mServiceTargets.addAll(remainingTargets); mNumShortcutResults += remainingTargets.size(); mParkingDirectShareTargets.clear(); } private boolean checkDuplicateTarget(ChooserTargetInfo chooserTargetInfo) { // Check for duplicates and abort if found for (ChooserTargetInfo otherTargetInfo : mServiceTargets) { if (chooserTargetInfo.isSimilar(otherTargetInfo)) { return true; } } return false; } int getNumShortcutResults() { return mNumShortcutResults; } Loading Loading @@ -487,7 +637,9 @@ 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()); } Loading
core/java/com/android/internal/app/ResolverListAdapter.java +8 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,14 @@ public class ResolverListAdapter extends BaseAdapter { return mResolverListController.getScore(target); } /** * Returns the list of top K component names which have highest * {@link #getScore(DisplayResolveInfo)} */ public List<ComponentName> getTopComponentNames(int topK) { return mResolverListController.getTopComponentNames(topK); } public void updateModel(ComponentName componentName) { mResolverListController.updateModel(componentName); } Loading