Merge "Factor native ranks provided by apps into shortcut targets ranking. This would help rank shortcuts targets properly when there is no enough sharing history on them." into rvc-dev am: d5fe3bf3ac
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11827741 Change-Id: I7e58a8b153628e3189c7052bfa7520f6b432353d
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.people.prediction;
|
package com.android.server.people.prediction;
|
||||||
|
|
||||||
|
import static java.util.Collections.reverseOrder;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
@@ -39,6 +41,7 @@ import com.android.server.people.data.PackageData;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -85,7 +88,9 @@ class ShareTargetPredictor extends AppTargetPredictor {
|
|||||||
List<ShareTarget> shareTargets = getDirectShareTargets();
|
List<ShareTarget> shareTargets = getDirectShareTargets();
|
||||||
SharesheetModelScorer.computeScore(shareTargets, getShareEventType(mIntentFilter),
|
SharesheetModelScorer.computeScore(shareTargets, getShareEventType(mIntentFilter),
|
||||||
System.currentTimeMillis());
|
System.currentTimeMillis());
|
||||||
Collections.sort(shareTargets, (t1, t2) -> -Float.compare(t1.getScore(), t2.getScore()));
|
Collections.sort(shareTargets,
|
||||||
|
Comparator.comparing(ShareTarget::getScore, reverseOrder())
|
||||||
|
.thenComparing(t -> t.getAppTarget().getRank()));
|
||||||
List<AppTarget> res = new ArrayList<>();
|
List<AppTarget> res = new ArrayList<>();
|
||||||
for (int i = 0; i < Math.min(getPredictionContext().getPredictedTargetCount(),
|
for (int i = 0; i < Math.min(getPredictionContext().getPredictedTargetCount(),
|
||||||
shareTargets.size()); i++) {
|
shareTargets.size()); i++) {
|
||||||
@@ -135,6 +140,7 @@ class ShareTargetPredictor extends AppTargetPredictor {
|
|||||||
new AppTargetId(shortcutInfo.getId()),
|
new AppTargetId(shortcutInfo.getId()),
|
||||||
shortcutInfo)
|
shortcutInfo)
|
||||||
.setClassName(shareShortcut.getTargetComponent().getClassName())
|
.setClassName(shareShortcut.getTargetComponent().getClassName())
|
||||||
|
.setRank(shortcutInfo.getRank())
|
||||||
.build();
|
.build();
|
||||||
String packageName = shortcutInfo.getPackage();
|
String packageName = shortcutInfo.getPackage();
|
||||||
int userId = shortcutInfo.getUserId();
|
int userId = shortcutInfo.getUserId();
|
||||||
|
|||||||
@@ -117,10 +117,10 @@ public final class ShareTargetPredictorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPredictTargets() {
|
public void testPredictTargets() {
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc1"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc1", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc2"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc2", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc3"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc3", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc4"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc4", 0));
|
||||||
|
|
||||||
when(mPackageData1.getConversationInfo("sc1")).thenReturn(mock(ConversationInfo.class));
|
when(mPackageData1.getConversationInfo("sc1")).thenReturn(mock(ConversationInfo.class));
|
||||||
when(mPackageData1.getConversationInfo("sc2")).thenReturn(mock(ConversationInfo.class));
|
when(mPackageData1.getConversationInfo("sc2")).thenReturn(mock(ConversationInfo.class));
|
||||||
@@ -165,12 +165,12 @@ public final class ShareTargetPredictorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPredictTargets_reachTargetsLimit() {
|
public void testPredictTargets_reachTargetsLimit() {
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc1"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc1", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc2"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc2", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc3"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc3", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc4"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc4", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc5"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc5", 0));
|
||||||
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc6"));
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc6", 0));
|
||||||
|
|
||||||
when(mPackageData1.getConversationInfo("sc1")).thenReturn(mock(ConversationInfo.class));
|
when(mPackageData1.getConversationInfo("sc1")).thenReturn(mock(ConversationInfo.class));
|
||||||
when(mPackageData1.getConversationInfo("sc2")).thenReturn(mock(ConversationInfo.class));
|
when(mPackageData1.getConversationInfo("sc2")).thenReturn(mock(ConversationInfo.class));
|
||||||
@@ -249,6 +249,41 @@ public final class ShareTargetPredictorTest {
|
|||||||
verify(mDataManager, never()).getShareShortcuts(any(), anyInt());
|
verify(mDataManager, never()).getShareShortcuts(any(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPredictTargets_noSharingHistoryRankedByShortcutRank() {
|
||||||
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc1", 3));
|
||||||
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_1, CLASS_1, "sc2", 2));
|
||||||
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc3", 1));
|
||||||
|
mShareShortcuts.add(buildShareShortcut(PACKAGE_2, CLASS_2, "sc4", 0));
|
||||||
|
|
||||||
|
when(mPackageData1.getConversationInfo("sc1")).thenReturn(mock(ConversationInfo.class));
|
||||||
|
when(mPackageData1.getConversationInfo("sc2")).thenReturn(mock(ConversationInfo.class));
|
||||||
|
when(mPackageData2.getConversationInfo("sc3")).thenReturn(mock(ConversationInfo.class));
|
||||||
|
// "sc4" does not have a ConversationInfo.
|
||||||
|
|
||||||
|
mPredictor.predictTargets();
|
||||||
|
|
||||||
|
verify(mUpdatePredictionsMethod).accept(mAppTargetCaptor.capture());
|
||||||
|
List<AppTarget> res = mAppTargetCaptor.getValue();
|
||||||
|
assertEquals(4, res.size());
|
||||||
|
|
||||||
|
assertEquals("sc4", res.get(0).getId().getId());
|
||||||
|
assertEquals(CLASS_2, res.get(0).getClassName());
|
||||||
|
assertEquals(PACKAGE_2, res.get(0).getPackageName());
|
||||||
|
|
||||||
|
assertEquals("sc3", res.get(1).getId().getId());
|
||||||
|
assertEquals(CLASS_2, res.get(1).getClassName());
|
||||||
|
assertEquals(PACKAGE_2, res.get(1).getPackageName());
|
||||||
|
|
||||||
|
assertEquals("sc2", res.get(2).getId().getId());
|
||||||
|
assertEquals(CLASS_1, res.get(2).getClassName());
|
||||||
|
assertEquals(PACKAGE_1, res.get(2).getPackageName());
|
||||||
|
|
||||||
|
assertEquals("sc1", res.get(3).getId().getId());
|
||||||
|
assertEquals(CLASS_1, res.get(3).getClassName());
|
||||||
|
assertEquals(PACKAGE_1, res.get(3).getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSortTargets() {
|
public void testSortTargets() {
|
||||||
AppTarget appTarget1 = new AppTarget.Builder(
|
AppTarget appTarget1 = new AppTarget.Builder(
|
||||||
@@ -348,19 +383,20 @@ public final class ShareTargetPredictorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ShareShortcutInfo buildShareShortcut(
|
private static ShareShortcutInfo buildShareShortcut(
|
||||||
String packageName, String className, String shortcutId) {
|
String packageName, String className, String shortcutId, int rank) {
|
||||||
ShortcutInfo shortcutInfo = buildShortcut(packageName, shortcutId);
|
ShortcutInfo shortcutInfo = buildShortcut(packageName, shortcutId, rank);
|
||||||
ComponentName componentName = new ComponentName(packageName, className);
|
ComponentName componentName = new ComponentName(packageName, className);
|
||||||
return new ShareShortcutInfo(shortcutInfo, componentName);
|
return new ShareShortcutInfo(shortcutInfo, componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ShortcutInfo buildShortcut(String packageName, String shortcutId) {
|
private static ShortcutInfo buildShortcut(String packageName, String shortcutId, int rank) {
|
||||||
Context mockContext = mock(Context.class);
|
Context mockContext = mock(Context.class);
|
||||||
when(mockContext.getPackageName()).thenReturn(packageName);
|
when(mockContext.getPackageName()).thenReturn(packageName);
|
||||||
when(mockContext.getUserId()).thenReturn(USER_ID);
|
when(mockContext.getUserId()).thenReturn(USER_ID);
|
||||||
when(mockContext.getUser()).thenReturn(UserHandle.of(USER_ID));
|
when(mockContext.getUser()).thenReturn(UserHandle.of(USER_ID));
|
||||||
ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mockContext, shortcutId)
|
ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mockContext, shortcutId)
|
||||||
.setShortLabel(shortcutId)
|
.setShortLabel(shortcutId)
|
||||||
|
.setRank(rank)
|
||||||
.setIntent(new Intent("TestIntent"));
|
.setIntent(new Intent("TestIntent"));
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user