Merge "Prototype for Sharesheet direct share row append mechanism" into rvc-dev am: e9851d5fad
Change-Id: I2715a6c4340f7b19ba45f1a42f5dd58fb3f3339a
This commit is contained in:
@@ -221,6 +221,12 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
|
|||||||
*/
|
*/
|
||||||
abstract float getScore(ComponentName name);
|
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. */
|
/** Handles result message sent to mHandler. */
|
||||||
abstract void handleResultMessage(Message message);
|
abstract void handleResultMessage(Message message);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses an {@link AppPredictor} to sort Resolver targets. If the AppPredictionService appears to be
|
* Uses an {@link AppPredictor} to sort Resolver targets. If the AppPredictionService appears to be
|
||||||
@@ -159,6 +161,15 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
|||||||
return 1.0f - (((float) rank) / consecutiveSumOfRanks);
|
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
|
@Override
|
||||||
void updateModel(ComponentName componentName) {
|
void updateModel(ComponentName componentName) {
|
||||||
if (mResolverRankerService != null) {
|
if (mResolverRankerService != null) {
|
||||||
|
|||||||
@@ -223,6 +223,11 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
|
SystemUiDeviceConfigFlags.HASH_SALT_MAX_DAYS,
|
||||||
DEFAULT_SALT_EXPIRATION_DAYS);
|
DEFAULT_SALT_EXPIRATION_DAYS);
|
||||||
|
|
||||||
|
private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
|
||||||
|
DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||||
|
SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
|
||||||
|
false);
|
||||||
|
|
||||||
private Bundle mReplacementExtras;
|
private Bundle mReplacementExtras;
|
||||||
private IntentSender mChosenComponentSender;
|
private IntentSender mChosenComponentSender;
|
||||||
private IntentSender mRefinementIntentSender;
|
private IntentSender mRefinementIntentSender;
|
||||||
@@ -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_MAX_MILLIS = 10000;
|
||||||
private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 3000;
|
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 boolean mMinTimeoutPassed = false;
|
||||||
|
|
||||||
private void removeAllMessages() {
|
private void removeAllMessages() {
|
||||||
@@ -427,15 +437,14 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "queryTargets setting watchdog timer for "
|
Log.d(TAG, "queryTargets setting watchdog timer for "
|
||||||
+ WATCHDOG_TIMEOUT_MIN_MILLIS + "-"
|
+ mDirectShareTimeout + "-"
|
||||||
+ WATCHDOG_TIMEOUT_MAX_MILLIS + "ms");
|
+ WATCHDOG_TIMEOUT_MAX_MILLIS + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT,
|
sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT,
|
||||||
WATCHDOG_TIMEOUT_MIN_MILLIS);
|
WATCHDOG_TIMEOUT_MIN_MILLIS);
|
||||||
sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
|
sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
|
||||||
WATCHDOG_TIMEOUT_MAX_MILLIS);
|
mAppendDirectShareEnabled ? mDirectShareTimeout : WATCHDOG_TIMEOUT_MAX_MILLIS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeStopServiceRequestTimer() {
|
private void maybeStopServiceRequestTimer() {
|
||||||
@@ -463,6 +472,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
final ServiceResultInfo sri = (ServiceResultInfo) msg.obj;
|
final ServiceResultInfo sri = (ServiceResultInfo) msg.obj;
|
||||||
if (!mServiceConnections.contains(sri.connection)) {
|
if (!mServiceConnections.contains(sri.connection)) {
|
||||||
Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection
|
Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection
|
||||||
|
+ sri.originalTarget.getResolveInfo().activityInfo.packageName
|
||||||
+ " returned after being removed from active connections."
|
+ " returned after being removed from active connections."
|
||||||
+ " Have you considered returning results faster?");
|
+ " Have you considered returning results faster?");
|
||||||
break;
|
break;
|
||||||
@@ -474,7 +484,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
if (adapterForUserHandle != null) {
|
if (adapterForUserHandle != null) {
|
||||||
adapterForUserHandle.addServiceResults(sri.originalTarget,
|
adapterForUserHandle.addServiceResults(sri.originalTarget,
|
||||||
sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET,
|
sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET,
|
||||||
/* directShareShortcutInfoCache */ null);
|
/* directShareShortcutInfoCache */ null, mServiceConnections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unbindService(sri.connection);
|
unbindService(sri.connection);
|
||||||
@@ -489,6 +499,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT:
|
case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT:
|
||||||
|
mMinTimeoutPassed = true;
|
||||||
unbindRemainingServices();
|
unbindRemainingServices();
|
||||||
maybeStopServiceRequestTimer();
|
maybeStopServiceRequestTimer();
|
||||||
break;
|
break;
|
||||||
@@ -513,7 +524,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
if (adapterForUserHandle != null) {
|
if (adapterForUserHandle != null) {
|
||||||
adapterForUserHandle.addServiceResults(
|
adapterForUserHandle.addServiceResults(
|
||||||
resultInfo.originalTarget, resultInfo.resultTargets, msg.arg1,
|
resultInfo.originalTarget, resultInfo.resultTargets, msg.arg1,
|
||||||
mDirectShareShortcutInfoCache);
|
mDirectShareShortcutInfoCache, mServiceConnections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1481,7 +1492,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
/* origTarget */ null,
|
/* origTarget */ null,
|
||||||
Lists.newArrayList(mCallerChooserTargets),
|
Lists.newArrayList(mCallerChooserTargets),
|
||||||
TARGET_TYPE_DEFAULT,
|
TARGET_TYPE_DEFAULT,
|
||||||
/* directShareShortcutInfoCache */ null);
|
/* directShareShortcutInfoCache */ null, mServiceConnections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3584,6 +3595,10 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
? mOriginalTarget.getResolveInfo().activityInfo.toString()
|
? mOriginalTarget.getResolveInfo().activityInfo.toString()
|
||||||
: "<connection destroyed>") + "}";
|
: "<connection destroyed>") + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ComponentName getComponentName() {
|
||||||
|
return mOriginalTarget.getResolveInfo().activityInfo.getComponentName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ServiceResultInfo {
|
static class ServiceResultInfo {
|
||||||
|
|||||||
@@ -32,8 +32,10 @@ import android.content.pm.ShortcutInfo;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
import android.service.chooser.ChooserTarget;
|
import android.service.chooser.ChooserTarget;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
@@ -44,17 +46,26 @@ import com.android.internal.app.chooser.DisplayResolveInfo;
|
|||||||
import com.android.internal.app.chooser.MultiDisplayResolveInfo;
|
import com.android.internal.app.chooser.MultiDisplayResolveInfo;
|
||||||
import com.android.internal.app.chooser.SelectableTargetInfo;
|
import com.android.internal.app.chooser.SelectableTargetInfo;
|
||||||
import com.android.internal.app.chooser.TargetInfo;
|
import com.android.internal.app.chooser.TargetInfo;
|
||||||
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ChooserListAdapter extends ResolverListAdapter {
|
public class ChooserListAdapter extends ResolverListAdapter {
|
||||||
private static final String TAG = "ChooserListAdapter";
|
private static final String TAG = "ChooserListAdapter";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
private boolean mAppendDirectShareEnabled = DeviceConfig.getBoolean(
|
||||||
|
DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||||
|
SystemUiDeviceConfigFlags.APPEND_DIRECT_SHARE_ENABLED,
|
||||||
|
false);
|
||||||
|
|
||||||
private boolean mEnableStackedApps = true;
|
private boolean mEnableStackedApps = true;
|
||||||
|
|
||||||
public static final int NO_POSITION = -1;
|
public static final int NO_POSITION = -1;
|
||||||
@@ -84,6 +95,11 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
// Reserve spots for incoming direct share targets by adding placeholders
|
// Reserve spots for incoming direct share targets by adding placeholders
|
||||||
private ChooserTargetInfo
|
private ChooserTargetInfo
|
||||||
mPlaceHolderTargetInfo = new ChooserActivity.PlaceHolderTargetInfo();
|
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<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
|
||||||
private final List<TargetInfo> mCallerTargets = new ArrayList<>();
|
private final List<TargetInfo> mCallerTargets = new ArrayList<>();
|
||||||
|
|
||||||
@@ -189,6 +205,9 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
|
|
||||||
void refreshListView() {
|
void refreshListView() {
|
||||||
if (mListViewDataChanged) {
|
if (mListViewDataChanged) {
|
||||||
|
if (mAppendDirectShareEnabled) {
|
||||||
|
appendServiceTargetsWithQuota();
|
||||||
|
}
|
||||||
super.notifyDataSetChanged();
|
super.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
mListViewDataChanged = false;
|
mListViewDataChanged = false;
|
||||||
@@ -198,6 +217,10 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
private void createPlaceHolders() {
|
private void createPlaceHolders() {
|
||||||
mNumShortcutResults = 0;
|
mNumShortcutResults = 0;
|
||||||
mServiceTargets.clear();
|
mServiceTargets.clear();
|
||||||
|
mValidServiceTargetsNum = 0;
|
||||||
|
mParkingDirectShareTargets.clear();
|
||||||
|
mPendingChooserTargetService.clear();
|
||||||
|
mShortcutComponents.clear();
|
||||||
for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
|
for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
|
||||||
mServiceTargets.add(mPlaceHolderTargetInfo);
|
mServiceTargets.add(mPlaceHolderTargetInfo);
|
||||||
}
|
}
|
||||||
@@ -393,12 +416,19 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
*/
|
*/
|
||||||
public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
|
public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
|
||||||
@ChooserActivity.ShareTargetType int targetType,
|
@ChooserActivity.ShareTargetType int targetType,
|
||||||
Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos) {
|
Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos,
|
||||||
|
List<ChooserActivity.ChooserTargetServiceConnection>
|
||||||
|
pendingChooserTargetServiceConnections) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
|
Log.d(TAG, "addServiceResults " + origTarget.getResolvedComponentName() + ", "
|
||||||
|
+ targets.size()
|
||||||
+ " targets");
|
+ " targets");
|
||||||
}
|
}
|
||||||
|
if (mAppendDirectShareEnabled) {
|
||||||
|
parkTargetIntoMemory(origTarget, targets, targetType, directShareToShortcutInfos,
|
||||||
|
pendingChooserTargetServiceConnections);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (targets.size() == 0) {
|
if (targets.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -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() {
|
int getNumShortcutResults() {
|
||||||
return mNumShortcutResults;
|
return mNumShortcutResults;
|
||||||
}
|
}
|
||||||
@@ -487,7 +637,9 @@ public class ChooserListAdapter extends ResolverListAdapter {
|
|||||||
*/
|
*/
|
||||||
public void completeServiceTargetLoading() {
|
public void completeServiceTargetLoading() {
|
||||||
mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
|
mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
|
||||||
|
if (mAppendDirectShareEnabled) {
|
||||||
|
fillAllServiceTargets();
|
||||||
|
}
|
||||||
if (mServiceTargets.isEmpty()) {
|
if (mServiceTargets.isEmpty()) {
|
||||||
mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
|
mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,14 @@ public class ResolverListAdapter extends BaseAdapter {
|
|||||||
return mResolverListController.getScore(target);
|
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) {
|
public void updateModel(ComponentName componentName) {
|
||||||
mResolverListController.updateModel(componentName);
|
mResolverListController.updateModel(componentName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,6 +367,14 @@ public class ResolverListController {
|
|||||||
return mResolverComparator.getScore(target.getResolvedComponentName());
|
return mResolverComparator.getScore(target.getResolvedComponentName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of top K component names which have highest
|
||||||
|
* {@link #getScore(DisplayResolveInfo)}
|
||||||
|
*/
|
||||||
|
public List<ComponentName> getTopComponentNames(int topK) {
|
||||||
|
return mResolverComparator.getTopComponentNames(topK);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateModel(ComponentName componentName) {
|
public void updateModel(ComponentName componentName) {
|
||||||
mResolverComparator.updateModel(componentName);
|
mResolverComparator.updateModel(componentName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ranks and compares packages based on usage stats and uses the {@link ResolverRankerService}.
|
* Ranks and compares packages based on usage stats and uses the {@link ResolverRankerService}.
|
||||||
@@ -252,6 +253,15 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
List<ComponentName> getTopComponentNames(int topK) {
|
||||||
|
return mTargetsDict.entrySet().stream()
|
||||||
|
.sorted((o1, o2) -> -Float.compare(getScore(o1.getKey()), getScore(o2.getKey())))
|
||||||
|
.limit(topK)
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
// update ranking model when the connection to it is valid.
|
// update ranking model when the connection to it is valid.
|
||||||
@Override
|
@Override
|
||||||
public void updateModel(ComponentName componentName) {
|
public void updateModel(ComponentName componentName) {
|
||||||
|
|||||||
@@ -377,6 +377,17 @@ public final class SystemUiDeviceConfigFlags {
|
|||||||
public static final String NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN =
|
public static final String NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN =
|
||||||
"nav_bar_handle_show_over_lockscreen";
|
"nav_bar_handle_show_over_lockscreen";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (int) Timeout threshold, in millisecond, that Sharesheet waits for direct share targets.
|
||||||
|
*/
|
||||||
|
public static final String SHARE_SHEET_DIRECT_SHARE_TIMEOUT =
|
||||||
|
"share_sheet_direct_share_timeout";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (boolean) Whether append direct share on Sharesheet is enabled.
|
||||||
|
*/
|
||||||
|
public static final String APPEND_DIRECT_SHARE_ENABLED = "append_direct_share_enabled";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (boolean) Whether to enable user-drag resizing for PIP.
|
* (boolean) Whether to enable user-drag resizing for PIP.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ public class AbstractResolverComparatorTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void handleResultMessage(Message message) {}
|
void handleResultMessage(Message message) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
List<ComponentName> getTopComponentNames(int topK) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return testComparator;
|
return testComparator;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -987,7 +987,8 @@ public class ChooserActivityTest {
|
|||||||
/* resolveInfoPresentationGetter */ null),
|
/* resolveInfoPresentationGetter */ null),
|
||||||
serviceTargets,
|
serviceTargets,
|
||||||
TARGET_TYPE_CHOOSER_TARGET,
|
TARGET_TYPE_CHOOSER_TARGET,
|
||||||
directShareToShortcutInfos)
|
directShareToShortcutInfos,
|
||||||
|
null)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Thread.sleep shouldn't be a thing in an integration test but it's
|
// Thread.sleep shouldn't be a thing in an integration test but it's
|
||||||
@@ -1058,7 +1059,8 @@ public class ChooserActivityTest {
|
|||||||
/* resolveInfoPresentationGetter */ null),
|
/* resolveInfoPresentationGetter */ null),
|
||||||
serviceTargets,
|
serviceTargets,
|
||||||
TARGET_TYPE_CHOOSER_TARGET,
|
TARGET_TYPE_CHOOSER_TARGET,
|
||||||
directShareToShortcutInfos)
|
directShareToShortcutInfos,
|
||||||
|
null)
|
||||||
);
|
);
|
||||||
// Thread.sleep shouldn't be a thing in an integration test but it's
|
// Thread.sleep shouldn't be a thing in an integration test but it's
|
||||||
// necessary here because of the way the code is structured
|
// necessary here because of the way the code is structured
|
||||||
@@ -1145,7 +1147,8 @@ public class ChooserActivityTest {
|
|||||||
/* resolveInfoPresentationGetter */ null),
|
/* resolveInfoPresentationGetter */ null),
|
||||||
serviceTargets,
|
serviceTargets,
|
||||||
TARGET_TYPE_CHOOSER_TARGET,
|
TARGET_TYPE_CHOOSER_TARGET,
|
||||||
directShareToShortcutInfos)
|
directShareToShortcutInfos,
|
||||||
|
null)
|
||||||
);
|
);
|
||||||
// Thread.sleep shouldn't be a thing in an integration test but it's
|
// Thread.sleep shouldn't be a thing in an integration test but it's
|
||||||
// necessary here because of the way the code is structured
|
// necessary here because of the way the code is structured
|
||||||
|
|||||||
Reference in New Issue
Block a user