Adds locus Id to ShortcutQuery to find shortcuts based on LocusId

Bug: 148085173
Test: atest com.android.server.pm.ShortcutManagerTest1 \
            com.android.server.pm.ShortcutManagerTest2 \
            com.android.server.pm.ShortcutManagerTest3 \
            com.android.server.pm.ShortcutManagerTest4 \
            com.android.server.pm.ShortcutManagerTest5 \
            com.android.server.pm.ShortcutManagerTest6 \
            com.android.server.pm.ShortcutManagerTest7 \
            com.android.server.pm.ShortcutManagerTest8 \
            com.android.server.pm.ShortcutManagerTest9 \
            com.android.server.pm.ShortcutManagerTest10
Test: atest DataManagerTest

Change-Id: Ie789582a43db6d53130f4a0e5bff646a3c08c71e
This commit is contained in:
Mehdi Alizadeh
2020-01-21 13:39:53 -08:00
parent 9f68019066
commit ae808ff765
10 changed files with 130 additions and 34 deletions

View File

@@ -2100,6 +2100,10 @@ package android.content.pm {
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR;
}
public static class LauncherApps.ShortcutQuery {
method @NonNull public android.content.pm.LauncherApps.ShortcutQuery setLocusIds(@Nullable java.util.List<android.content.LocusId>);
}
public class PackageInstaller {
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2

View File

@@ -20,6 +20,7 @@ import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IOnAppsChangedListener;
@@ -67,7 +68,8 @@ interface ILauncherApps {
in UserHandle user);
ParceledListSlice getShortcuts(String callingPackage, long changedSince, String packageName,
in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user);
in List shortcutIds, in List<LocusId> locusIds, in ComponentName componentName,
int flags, in UserHandle user);
void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
in UserHandle user);
boolean startShortcut(String callingPackage, String packageName, String id,
@@ -92,7 +94,8 @@ interface ILauncherApps {
ParceledListSlice getAllSessions(String callingPackage);
void registerShortcutChangeCallback(String callingPackage, long changedSince,
String packageName, in List shortcutIds, in ComponentName componentName, int flags,
in IShortcutChangeCallback callback, int callbackId);
String packageName, in List shortcutIds, in List<LocusId> locusIds,
in ComponentName componentName, int flags, in IShortcutChangeCallback callback,
int callbackId);
void unregisterShortcutChangeCallback(String callingPackage, int callbackId);
}

View File

@@ -34,6 +34,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.LocusId;
import android.content.pm.PackageInstaller.SessionCallback;
import android.content.pm.PackageInstaller.SessionCallbackDelegate;
import android.content.pm.PackageInstaller.SessionInfo;
@@ -414,6 +415,9 @@ public class LauncherApps {
@Nullable
List<String> mShortcutIds;
@Nullable
List<LocusId> mLocusIds;
@Nullable
ComponentName mActivity;
@@ -450,6 +454,19 @@ public class LauncherApps {
return this;
}
/**
* If non-null, return only the specified shortcuts by locus ID. When setting this field,
* a package name must also be set with {@link #setPackage}.
*
* @hide
*/
@SystemApi
@NonNull
public ShortcutQuery setLocusIds(@Nullable List<LocusId> locusIds) {
mLocusIds = locusIds;
return this;
}
/**
* If non-null, returns only shortcuts associated with the activity; i.e.
* {@link ShortcutInfo}s whose {@link ShortcutInfo#getActivity()} are equal
@@ -1022,8 +1039,8 @@ public class LauncherApps {
// changed callback, but that only returns shortcuts with the "key" information, so
// that won't return disabled message.
return maybeUpdateDisabledMessage(mService.getShortcuts(mContext.getPackageName(),
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
query.mQueryFlags, user)
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mLocusIds,
query.mActivity, query.mQueryFlags, user)
.getList());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1680,8 +1697,9 @@ public class LauncherApps {
mShortcutChangeCallbacks.put(callbackId, state);
try {
mService.registerShortcutChangeCallback(mContext.getPackageName(),
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
query.mQueryFlags, new ShortcutChangeCallbackProxy(state), callbackId);
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mLocusIds,
query.mActivity, query.mQueryFlags, new ShortcutChangeCallbackProxy(state),
callbackId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -23,6 +23,7 @@ import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.content.LocusId;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -45,8 +46,8 @@ public abstract class ShortcutServiceInternal {
getShortcuts(int launcherUserId,
@NonNull String callingPackage, long changedSince,
@Nullable String packageName, @Nullable List<String> shortcutIds,
@Nullable ComponentName componentName, @ShortcutQuery.QueryFlags int flags,
int userId, int callingPid, int callingUid);
@Nullable List<LocusId> locusIds, @Nullable ComponentName componentName,
@ShortcutQuery.QueryFlags int flags, int userId, int callingPid, int callingUid);
public abstract boolean
isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,

View File

@@ -29,6 +29,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ILauncherApps;
@@ -662,8 +663,8 @@ public class LauncherAppsService extends SystemService {
@Override
public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
String packageName, List shortcutIds, ComponentName componentName, int flags,
UserHandle targetUser) {
String packageName, List shortcutIds, List<LocusId> locusIds,
ComponentName componentName, int flags, UserHandle targetUser) {
ensureShortcutPermission(callingPackage);
if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
return new ParceledListSlice<>(Collections.EMPTY_LIST);
@@ -672,19 +673,24 @@ public class LauncherAppsService extends SystemService {
throw new IllegalArgumentException(
"To query by shortcut ID, package name must also be set");
}
if (locusIds != null && packageName == null) {
throw new IllegalArgumentException(
"To query by locus ID, package name must also be set");
}
// TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below.
return new ParceledListSlice<>((List<ShortcutInfo>)
mShortcutServiceInternal.getShortcuts(getCallingUserId(),
callingPackage, changedSince, packageName, shortcutIds,
callingPackage, changedSince, packageName, shortcutIds, locusIds,
componentName, flags, targetUser.getIdentifier(),
injectBinderCallingPid(), injectBinderCallingUid()));
}
@Override
public void registerShortcutChangeCallback(String callingPackage, long changedSince,
String packageName, List shortcutIds, ComponentName componentName, int flags,
IShortcutChangeCallback callback, int callbackId) {
String packageName, List shortcutIds, List<LocusId> locusIds,
ComponentName componentName, int flags, IShortcutChangeCallback callback,
int callbackId) {
}
@Override
@@ -1148,7 +1154,7 @@ public class LauncherAppsService extends SystemService {
mShortcutServiceInternal.getShortcuts(launcherUserId,
cookie.packageName,
/* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
/* component= */ null,
/* locusIds=*/ null, /* component= */ null,
ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
| ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED
, userId, cookie.callingPid, cookie.callingUid);

View File

@@ -33,6 +33,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
@@ -2626,7 +2627,7 @@ public class ShortcutService extends IShortcutService.Stub {
public List<ShortcutInfo> getShortcuts(int launcherUserId,
@NonNull String callingPackage, long changedSince,
@Nullable String packageName, @Nullable List<String> shortcutIds,
@Nullable ComponentName componentName,
@Nullable List<LocusId> locusIds, @Nullable ComponentName componentName,
int queryFlags, int userId, int callingPid, int callingUid) {
final ArrayList<ShortcutInfo> ret = new ArrayList<>();
@@ -2647,15 +2648,16 @@ public class ShortcutService extends IShortcutService.Stub {
if (packageName != null) {
getShortcutsInnerLocked(launcherUserId,
callingPackage, packageName, shortcutIds, changedSince,
callingPackage, packageName, shortcutIds, locusIds, changedSince,
componentName, queryFlags, userId, ret, cloneFlag,
callingPid, callingUid);
} else {
final List<String> shortcutIdsF = shortcutIds;
final List<LocusId> locusIdsF = locusIds;
getUserShortcutsLocked(userId).forAllPackages(p -> {
getShortcutsInnerLocked(launcherUserId,
callingPackage, p.getPackageName(), shortcutIdsF, changedSince,
componentName, queryFlags, userId, ret, cloneFlag,
callingPackage, p.getPackageName(), shortcutIdsF, locusIdsF,
changedSince, componentName, queryFlags, userId, ret, cloneFlag,
callingPid, callingUid);
});
}
@@ -2665,12 +2667,15 @@ public class ShortcutService extends IShortcutService.Stub {
@GuardedBy("ShortcutService.this.mLock")
private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage,
@Nullable String packageName, @Nullable List<String> shortcutIds, long changedSince,
@Nullable String packageName, @Nullable List<String> shortcutIds,
@Nullable List<LocusId> locusIds, long changedSince,
@Nullable ComponentName componentName, int queryFlags,
int userId, ArrayList<ShortcutInfo> ret, int cloneFlag,
int callingPid, int callingUid) {
final ArraySet<String> ids = shortcutIds == null ? null
: new ArraySet<>(shortcutIds);
final ArraySet<LocusId> locIds = locusIds == null ? null
: new ArraySet<>(locusIds);
final ShortcutUser user = getUserShortcutsLocked(userId);
final ShortcutPackage p = user.getPackageShortcutsIfExists(packageName);
@@ -2697,6 +2702,9 @@ public class ShortcutService extends IShortcutService.Stub {
if (ids != null && !ids.contains(si.getId())) {
return false;
}
if (locIds != null && !locIds.contains(si.getLocusId())) {
return false;
}
if (componentName != null) {
if (si.getActivity() != null
&& !si.getActivity().equals(componentName)) {

View File

@@ -270,8 +270,8 @@ public class DataManager {
| ShortcutQuery.FLAG_MATCH_PINNED | ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER;
return mShortcutServiceInternal.getShortcuts(
mInjector.getCallingUserId(), /*callingPackage=*/ PLATFORM_PACKAGE_NAME,
/*changedSince=*/ 0, packageName, shortcutIds, /*componentName=*/ null, queryFlags,
userId, MY_PID, MY_UID);
/*changedSince=*/ 0, packageName, shortcutIds, /*locusIds=*/ null,
/*componentName=*/ null, queryFlags, userId, MY_PID, MY_UID);
}
@Nullable

View File

@@ -218,7 +218,7 @@ public final class DataManagerTest {
mDataManager.getShortcut(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID);
verify(mShortcutServiceInternal).getShortcuts(anyInt(), anyString(), anyLong(),
eq(TEST_PKG_NAME), eq(Collections.singletonList(TEST_SHORTCUT_ID)),
eq(null), anyInt(), eq(USER_ID_PRIMARY), anyInt(), anyInt());
eq(null), eq(null), anyInt(), eq(USER_ID_PRIMARY), anyInt(), anyInt());
}
@Test

View File

@@ -52,6 +52,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ILauncherApps;
@@ -1599,6 +1600,22 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
return s;
}
/**
* Make a shortcut with an ID and a locus ID.
*/
protected ShortcutInfo makeShortcutWithLocusId(String id, LocusId locusId) {
final ShortcutInfo.Builder b = new ShortcutInfo.Builder(mClientContext, id)
.setActivity(new ComponentName(mClientContext.getPackageName(), "main"))
.setShortLabel("title-" + id)
.setIntent(makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class))
.setLocusId(locusId);
final ShortcutInfo s = b.build();
s.setTimestamp(mInjectedCurrentTimeMillis); // HACK
return s;
}
/**
* Make an intent.
*/
@@ -1617,6 +1634,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
return builder.setName(name).setKey(key).setUri(uri).build();
}
/**
* Make a LocusId.
*/
protected LocusId makeLocusId(String id) {
return new LocusId(id);
}
/**
* Make an component name, with the client context.
*/
@@ -1955,16 +1979,17 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
protected static ShortcutQuery buildQuery(long changedSince,
String packageName, ComponentName componentName,
/* @ShortcutQuery.QueryFlags */ int flags) {
return buildQuery(changedSince, packageName, null, componentName, flags);
return buildQuery(changedSince, packageName, null, null, componentName, flags);
}
protected static ShortcutQuery buildQuery(long changedSince,
String packageName, List<String> shortcutIds, ComponentName componentName,
/* @ShortcutQuery.QueryFlags */ int flags) {
String packageName, List<String> shortcutIds, List<LocusId> locusIds,
ComponentName componentName, /* @ShortcutQuery.QueryFlags */ int flags) {
final ShortcutQuery q = new ShortcutQuery();
q.setChangedSince(changedSince);
q.setPackage(packageName);
q.setShortcutIds(shortcutIds);
q.setLocusIds(locusIds);
q.setActivity(componentName);
q.setQueryFlags(flags);
return q;

View File

@@ -1372,7 +1372,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
setCaller(CALLING_PACKAGE_1);
final ShortcutInfo s1_1 = makeShortcut("s1");
final ShortcutInfo s1_2 = makeShortcut("s2");
final ShortcutInfo s1_2 = makeShortcutWithLocusId("s2", makeLocusId("l1"));
assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
@@ -1394,7 +1394,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
getCallerShortcut("s4").setTimestamp(500);
setCaller(CALLING_PACKAGE_3);
final ShortcutInfo s3_2 = makeShortcut("s3");
final ShortcutInfo s3_2 = makeShortcutWithLocusId("s3", makeLocusId("l2"));
assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
getCallerShortcut("s3").setTimestamp(START_TIME + 5000);
@@ -1446,7 +1446,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// With ID.
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_2, list("s3"),
/* time =*/ 1000, CALLING_PACKAGE_2, list("s3"), /* locusIds =*/ null,
/* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser())),
@@ -1454,20 +1454,51 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_2, list("s3", "s2", "ss"),
/* activity =*/ null,
/* locusIds =*/ null, /* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser())),
"s2", "s3"))));
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_2, list("s3x", "s2x"),
/* activity =*/ null,
/* locusIds =*/ null, /* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser()))
/* empty */))));
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_2, list(),
/* time =*/ 1000, CALLING_PACKAGE_2, list(), /* locusIds =*/ null,
/* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser()))
/* empty */))));
// With locus ID.
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_3, /* shortcutIds =*/ null,
list(makeLocusId("l2")), /* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser())),
"s3"))));
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_1, /* shortcutIds =*/ null,
list(makeLocusId("l1"), makeLocusId("l2"), makeLocusId("l3")),
/* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser())),
"s2"))));
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_1, /* shortcutIds =*/ null,
list(makeLocusId("lx1"), makeLocusId("lx2")), /* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser()))
/* empty */))));
assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds(
assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 1000, CALLING_PACKAGE_3, /* shortcutIds =*/ null, list(),
/* activity =*/ null,
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY),
getCallingUser()))
@@ -1498,7 +1529,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertExpectException(
IllegalArgumentException.class, "package name must also be set", () -> {
mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 0, /* package= */ null, list("id"),
/* time =*/ 0, /* package= */ null, list("id"), /* locusIds =*/ null,
/* activity =*/ null, /* flags */ 0), getCallingUser());
});
@@ -1537,7 +1568,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertExpectException(
IllegalArgumentException.class, "package name must also be set", () -> {
mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 0, /* package= */ null, list("id"),
/* time =*/ 0, /* package= */ null, list("id"), /* locusIds= */ null,
/* activity =*/ null, /* flags */ 0), getCallingUser());
});