Loading core/java/android/content/pm/AppSearchShortcutInfo.java +14 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Set; Loading Loading @@ -327,6 +328,19 @@ public class AppSearchShortcutInfo extends GenericDocument { return si; } /** * @hide */ @NonNull public static List<GenericDocument> toGenericDocuments( @NonNull final Collection<ShortcutInfo> shortcuts) { final List<GenericDocument> docs = new ArrayList<>(shortcuts.size()); for (ShortcutInfo si : shortcuts) { docs.add(AppSearchShortcutInfo.instance(si)); } return docs; } /** @hide */ @VisibleForTesting public static class Builder extends GenericDocument.Builder<Builder> { Loading services/core/java/com/android/server/pm/ShortcutPackage.java +476 −383 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/pm/ShortcutService.java +11 −1 Original line number Diff line number Diff line Loading @@ -2590,7 +2590,6 @@ public class ShortcutService extends IShortcutService.Stub { final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); ps.findAll(ret, query, cloneFlags); return new ParceledListSlice<>(setReturnedByServer(ret)); } Loading Loading @@ -5077,6 +5076,17 @@ public class ShortcutService extends IShortcutService.Stub { } } @VisibleForTesting void updatePackageShortcutForTest(String packageName, String shortcutId, int userId, Consumer<ShortcutInfo> cb) { synchronized (mLock) { final ShortcutPackage pkg = getPackageShortcutForTest(packageName, userId); if (pkg == null) return; pkg.mutateShortcut(shortcutId, null, cb); } } @VisibleForTesting ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) { synchronized (mLock) { Loading services/core/java/com/android/server/pm/ShortcutUser.java +15 −6 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.appsearch.AppSearchManager; import android.app.appsearch.AppSearchResult; import android.app.appsearch.AppSearchSession; import android.content.pm.ShortcutManager; import android.metrics.LogMaker; Loading @@ -35,6 +34,7 @@ import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.server.FgThread; Loading Loading @@ -715,17 +715,26 @@ class ShortcutUser { .setSubtype(totalSharingShortcutCount)); } void runInAppSearch(@NonNull final AppSearchManager.SearchContext searchContext, @NonNull final Consumer<AppSearchResult<AppSearchSession>> callback) { AndroidFuture<AppSearchSession> getAppSearch( @NonNull final AppSearchManager.SearchContext searchContext) { final AndroidFuture<AppSearchSession> future = new AndroidFuture<>(); if (mAppSearchManager == null) { Slog.e(TAG, "app search manager is null"); return; future.completeExceptionally(new RuntimeException("app search manager is null")); return future; } final long callingIdentity = Binder.clearCallingIdentity(); try { mAppSearchManager.createSearchSession(searchContext, mExecutor, callback); mAppSearchManager.createSearchSession(searchContext, mExecutor, result -> { if (!result.isSuccess()) { future.completeExceptionally( new RuntimeException(result.getErrorMessage())); return; } future.complete(result.getResultValue()); }); } finally { Binder.restoreCallingIdentity(callingIdentity); } return future; } } services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +132 −17 Original line number Diff line number Diff line Loading @@ -48,10 +48,12 @@ import android.app.admin.DevicePolicyManager; import android.app.appsearch.AppSearchBatchResult; import android.app.appsearch.AppSearchManager; import android.app.appsearch.AppSearchResult; import android.app.appsearch.GenericDocument; import android.app.appsearch.IAppSearchBatchResultCallback; import android.app.appsearch.IAppSearchManager; import android.app.appsearch.IAppSearchResultCallback; import android.app.appsearch.PackageIdentifier; import android.app.appsearch.SearchResultPage; import android.app.role.OnRoleHoldersChangedListener; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; Loading Loading @@ -159,7 +161,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { case Context.DEVICE_POLICY_SERVICE: return mMockDevicePolicyManager; case Context.APP_SEARCH_SERVICE: return new AppSearchManager(getTestContext(), mMockAppSearchManager); return new AppSearchManager(this, mMockAppSearchManager); case Context.ROLE_SERVICE: // RoleManager is final and cannot be mocked, so we only override the inject // accessor methods in ShortcutService. Loading Loading @@ -188,6 +190,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return getTestContext().getResources(); } @Override public Context createContextAsUser(UserHandle user, int flags) { when(mMockPackageManager.getUserId()).thenReturn(user.getIdentifier()); return this; } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler) { Loading @@ -195,12 +203,6 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return null; } @Override public Context createContextAsUser(UserHandle user, int flags) { when(mMockPackageManager.getUserId()).thenReturn(user.getIdentifier()); return this; } @Override public void unregisterReceiver(BroadcastReceiver receiver) { // ignore. Loading Loading @@ -237,6 +239,15 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { mInjectedCallingUid = (int) token; } @Override public Context createContextAsUser(UserHandle user, int flags) { super.createContextAsUser(user, flags); final ServiceContext ctx = spy(new ServiceContext()); when(ctx.getUser()).thenReturn(user); when(ctx.getUserId()).thenReturn(user.getIdentifier()); return ctx; } @Override public int getUserId() { return UserHandle.USER_SYSTEM; Loading Loading @@ -620,6 +631,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected Map<String, List<PackageIdentifier>> mSchemasPackageAccessible = new ArrayMap<>(1); private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1); private String getKey(int userId, String databaseName) { return new StringBuilder().append(userId).append("@").append(databaseName).toString(); } @Override public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles, Loading Loading @@ -653,21 +669,77 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { public void putDocuments(String packageName, String databaseName, List<Bundle> documentBundles, int userId, IAppSearchBatchResultCallback callback) throws RemoteException { ignore(callback); final List<GenericDocument> docs = new ArrayList<>(documentBundles.size()); for (Bundle bundle : documentBundles) { docs.add(new GenericDocument(bundle)); } final AppSearchBatchResult.Builder<String, Void> builder = new AppSearchBatchResult.Builder<>(); final String key = getKey(userId, databaseName); Map<String, GenericDocument> docMap = mDocumentMap.get(key); for (GenericDocument doc : docs) { builder.setSuccess(doc.getUri(), null); if (docMap == null) { docMap = new ArrayMap<>(1); mDocumentMap.put(key, docMap); } docMap.put(doc.getUri(), doc); } callback.onResult(builder.build()); } @Override public void getDocuments(String packageName, String databaseName, String namespace, List<String> uris, Map<String, List<String>> typePropertyPaths, int userId, IAppSearchBatchResultCallback callback) throws RemoteException { ignore(callback); final AppSearchBatchResult.Builder<String, Bundle> builder = new AppSearchBatchResult.Builder<>(); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { for (String uri : uris) { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, key + " not found when getting: " + uri); } } else { final Map<String, GenericDocument> docs = mDocumentMap.get(key); for (String uri : uris) { if (docs.containsKey(uri)) { builder.setSuccess(uri, docs.get(uri).getBundle()); } else { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, "shortcut not found: " + uri); } } } callback.onResult(builder.build()); } @Override public void query(String packageName, String databaseName, String queryExpression, Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>()); callback.onResult(AppSearchResult.newSuccessfulResult(page)); return; } final List<GenericDocument> documents = new ArrayList<>(mDocumentMap.get(key).values()); final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 0); final ArrayList<Bundle> resultBundles = new ArrayList<>(); for (GenericDocument document : documents) { final Bundle resultBundle = new Bundle(); resultBundle.putBundle("document", document.getBundle()); resultBundle.putString("packageName", packageName); resultBundle.putString("databaseName", databaseName); resultBundle.putParcelableArrayList("matches", new ArrayList<>()); resultBundles.add(resultBundle); } page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles); callback.onResult(AppSearchResult.newSuccessfulResult(page)); } @Override Loading @@ -679,7 +751,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void getNextPage(long nextPageToken, int userId, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>()); callback.onResult(AppSearchResult.newSuccessfulResult(page)); } @Override Loading @@ -698,14 +773,40 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { public void removeByUri(String packageName, String databaseName, String namespace, List<String> uris, int userId, IAppSearchBatchResultCallback callback) throws RemoteException { ignore(callback); final AppSearchBatchResult.Builder<String, Void> builder = new AppSearchBatchResult.Builder<>(); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { for (String uri : uris) { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, "package " + key + " not found when removing " + uri); } } else { final Map<String, GenericDocument> docs = mDocumentMap.get(key); for (String uri : uris) { if (docs.containsKey(uri)) { docs.remove(uri); builder.setSuccess(uri, null); } else { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, "shortcut not found when removing " + uri); } } } callback.onResult(builder.build()); } @Override public void removeByQuery(String packageName, String databaseName, String queryExpression, Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { callback.onResult(AppSearchResult.newSuccessfulResult(null)); return; } mDocumentMap.get(key).clear(); callback.onResult(AppSearchResult.newSuccessfulResult(null)); } @Override Loading @@ -724,12 +825,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return null; } private void ignore(IAppSearchResultCallback callback) throws RemoteException { callback.onResult(AppSearchResult.newSuccessfulResult(null)); private void removeShortcuts() { mDocumentMap.clear(); } private void ignore(IAppSearchBatchResultCallback callback) throws RemoteException { callback.onResult(new AppSearchBatchResult.Builder().build()); private void ignore(IAppSearchResultCallback callback) throws RemoteException { callback.onResult(AppSearchResult.newSuccessfulResult(null)); } } Loading Loading @@ -1146,6 +1247,9 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { shutdownServices(); mMockAppSearchManager.removeShortcuts(); mMockAppSearchManager = null; super.tearDown(); } Loading Loading @@ -1891,6 +1995,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mService.getPackageShortcutForTest(packageName, shortcutId, userId); } protected void updatePackageShortcut(String packageName, String shortcutId, int userId, Consumer<ShortcutInfo> cb) { mService.updatePackageShortcutForTest(packageName, shortcutId, userId, cb); } protected void assertShortcutExists(String packageName, String shortcutId, int userId) { assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null); } Loading Loading @@ -2086,6 +2195,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId()); } protected void updateCallerShortcut(String shortcutId, Consumer<ShortcutInfo> cb) { updatePackageShortcut(getCallingPackage(), shortcutId, getCallingUserId(), cb); } protected List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) { final List<ShortcutInfo>[] ret = new List[1]; runWithCaller(launcher, userId, () -> { Loading Loading @@ -2245,6 +2358,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { deleteAllSavedFiles(); mMockAppSearchManager.removeShortcuts(); initService(); mService.applyRestore(payload, USER_0); Loading Loading
core/java/android/content/pm/AppSearchShortcutInfo.java +14 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Set; Loading Loading @@ -327,6 +328,19 @@ public class AppSearchShortcutInfo extends GenericDocument { return si; } /** * @hide */ @NonNull public static List<GenericDocument> toGenericDocuments( @NonNull final Collection<ShortcutInfo> shortcuts) { final List<GenericDocument> docs = new ArrayList<>(shortcuts.size()); for (ShortcutInfo si : shortcuts) { docs.add(AppSearchShortcutInfo.instance(si)); } return docs; } /** @hide */ @VisibleForTesting public static class Builder extends GenericDocument.Builder<Builder> { Loading
services/core/java/com/android/server/pm/ShortcutPackage.java +476 −383 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/pm/ShortcutService.java +11 −1 Original line number Diff line number Diff line Loading @@ -2590,7 +2590,6 @@ public class ShortcutService extends IShortcutService.Stub { final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); ps.findAll(ret, query, cloneFlags); return new ParceledListSlice<>(setReturnedByServer(ret)); } Loading Loading @@ -5077,6 +5076,17 @@ public class ShortcutService extends IShortcutService.Stub { } } @VisibleForTesting void updatePackageShortcutForTest(String packageName, String shortcutId, int userId, Consumer<ShortcutInfo> cb) { synchronized (mLock) { final ShortcutPackage pkg = getPackageShortcutForTest(packageName, userId); if (pkg == null) return; pkg.mutateShortcut(shortcutId, null, cb); } } @VisibleForTesting ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) { synchronized (mLock) { Loading
services/core/java/com/android/server/pm/ShortcutUser.java +15 −6 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.appsearch.AppSearchManager; import android.app.appsearch.AppSearchResult; import android.app.appsearch.AppSearchSession; import android.content.pm.ShortcutManager; import android.metrics.LogMaker; Loading @@ -35,6 +34,7 @@ import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.server.FgThread; Loading Loading @@ -715,17 +715,26 @@ class ShortcutUser { .setSubtype(totalSharingShortcutCount)); } void runInAppSearch(@NonNull final AppSearchManager.SearchContext searchContext, @NonNull final Consumer<AppSearchResult<AppSearchSession>> callback) { AndroidFuture<AppSearchSession> getAppSearch( @NonNull final AppSearchManager.SearchContext searchContext) { final AndroidFuture<AppSearchSession> future = new AndroidFuture<>(); if (mAppSearchManager == null) { Slog.e(TAG, "app search manager is null"); return; future.completeExceptionally(new RuntimeException("app search manager is null")); return future; } final long callingIdentity = Binder.clearCallingIdentity(); try { mAppSearchManager.createSearchSession(searchContext, mExecutor, callback); mAppSearchManager.createSearchSession(searchContext, mExecutor, result -> { if (!result.isSuccess()) { future.completeExceptionally( new RuntimeException(result.getErrorMessage())); return; } future.complete(result.getResultValue()); }); } finally { Binder.restoreCallingIdentity(callingIdentity); } return future; } }
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +132 −17 Original line number Diff line number Diff line Loading @@ -48,10 +48,12 @@ import android.app.admin.DevicePolicyManager; import android.app.appsearch.AppSearchBatchResult; import android.app.appsearch.AppSearchManager; import android.app.appsearch.AppSearchResult; import android.app.appsearch.GenericDocument; import android.app.appsearch.IAppSearchBatchResultCallback; import android.app.appsearch.IAppSearchManager; import android.app.appsearch.IAppSearchResultCallback; import android.app.appsearch.PackageIdentifier; import android.app.appsearch.SearchResultPage; import android.app.role.OnRoleHoldersChangedListener; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; Loading Loading @@ -159,7 +161,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { case Context.DEVICE_POLICY_SERVICE: return mMockDevicePolicyManager; case Context.APP_SEARCH_SERVICE: return new AppSearchManager(getTestContext(), mMockAppSearchManager); return new AppSearchManager(this, mMockAppSearchManager); case Context.ROLE_SERVICE: // RoleManager is final and cannot be mocked, so we only override the inject // accessor methods in ShortcutService. Loading Loading @@ -188,6 +190,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return getTestContext().getResources(); } @Override public Context createContextAsUser(UserHandle user, int flags) { when(mMockPackageManager.getUserId()).thenReturn(user.getIdentifier()); return this; } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler) { Loading @@ -195,12 +203,6 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return null; } @Override public Context createContextAsUser(UserHandle user, int flags) { when(mMockPackageManager.getUserId()).thenReturn(user.getIdentifier()); return this; } @Override public void unregisterReceiver(BroadcastReceiver receiver) { // ignore. Loading Loading @@ -237,6 +239,15 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { mInjectedCallingUid = (int) token; } @Override public Context createContextAsUser(UserHandle user, int flags) { super.createContextAsUser(user, flags); final ServiceContext ctx = spy(new ServiceContext()); when(ctx.getUser()).thenReturn(user); when(ctx.getUserId()).thenReturn(user.getIdentifier()); return ctx; } @Override public int getUserId() { return UserHandle.USER_SYSTEM; Loading Loading @@ -620,6 +631,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected Map<String, List<PackageIdentifier>> mSchemasPackageAccessible = new ArrayMap<>(1); private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1); private String getKey(int userId, String databaseName) { return new StringBuilder().append(userId).append("@").append(databaseName).toString(); } @Override public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles, Loading Loading @@ -653,21 +669,77 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { public void putDocuments(String packageName, String databaseName, List<Bundle> documentBundles, int userId, IAppSearchBatchResultCallback callback) throws RemoteException { ignore(callback); final List<GenericDocument> docs = new ArrayList<>(documentBundles.size()); for (Bundle bundle : documentBundles) { docs.add(new GenericDocument(bundle)); } final AppSearchBatchResult.Builder<String, Void> builder = new AppSearchBatchResult.Builder<>(); final String key = getKey(userId, databaseName); Map<String, GenericDocument> docMap = mDocumentMap.get(key); for (GenericDocument doc : docs) { builder.setSuccess(doc.getUri(), null); if (docMap == null) { docMap = new ArrayMap<>(1); mDocumentMap.put(key, docMap); } docMap.put(doc.getUri(), doc); } callback.onResult(builder.build()); } @Override public void getDocuments(String packageName, String databaseName, String namespace, List<String> uris, Map<String, List<String>> typePropertyPaths, int userId, IAppSearchBatchResultCallback callback) throws RemoteException { ignore(callback); final AppSearchBatchResult.Builder<String, Bundle> builder = new AppSearchBatchResult.Builder<>(); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { for (String uri : uris) { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, key + " not found when getting: " + uri); } } else { final Map<String, GenericDocument> docs = mDocumentMap.get(key); for (String uri : uris) { if (docs.containsKey(uri)) { builder.setSuccess(uri, docs.get(uri).getBundle()); } else { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, "shortcut not found: " + uri); } } } callback.onResult(builder.build()); } @Override public void query(String packageName, String databaseName, String queryExpression, Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>()); callback.onResult(AppSearchResult.newSuccessfulResult(page)); return; } final List<GenericDocument> documents = new ArrayList<>(mDocumentMap.get(key).values()); final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 0); final ArrayList<Bundle> resultBundles = new ArrayList<>(); for (GenericDocument document : documents) { final Bundle resultBundle = new Bundle(); resultBundle.putBundle("document", document.getBundle()); resultBundle.putString("packageName", packageName); resultBundle.putString("databaseName", databaseName); resultBundle.putParcelableArrayList("matches", new ArrayList<>()); resultBundles.add(resultBundle); } page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles); callback.onResult(AppSearchResult.newSuccessfulResult(page)); } @Override Loading @@ -679,7 +751,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void getNextPage(long nextPageToken, int userId, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>()); callback.onResult(AppSearchResult.newSuccessfulResult(page)); } @Override Loading @@ -698,14 +773,40 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { public void removeByUri(String packageName, String databaseName, String namespace, List<String> uris, int userId, IAppSearchBatchResultCallback callback) throws RemoteException { ignore(callback); final AppSearchBatchResult.Builder<String, Void> builder = new AppSearchBatchResult.Builder<>(); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { for (String uri : uris) { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, "package " + key + " not found when removing " + uri); } } else { final Map<String, GenericDocument> docs = mDocumentMap.get(key); for (String uri : uris) { if (docs.containsKey(uri)) { docs.remove(uri); builder.setSuccess(uri, null); } else { builder.setFailure(uri, AppSearchResult.RESULT_NOT_FOUND, "shortcut not found when removing " + uri); } } } callback.onResult(builder.build()); } @Override public void removeByQuery(String packageName, String databaseName, String queryExpression, Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); final String key = getKey(userId, databaseName); if (!mDocumentMap.containsKey(key)) { callback.onResult(AppSearchResult.newSuccessfulResult(null)); return; } mDocumentMap.get(key).clear(); callback.onResult(AppSearchResult.newSuccessfulResult(null)); } @Override Loading @@ -724,12 +825,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return null; } private void ignore(IAppSearchResultCallback callback) throws RemoteException { callback.onResult(AppSearchResult.newSuccessfulResult(null)); private void removeShortcuts() { mDocumentMap.clear(); } private void ignore(IAppSearchBatchResultCallback callback) throws RemoteException { callback.onResult(new AppSearchBatchResult.Builder().build()); private void ignore(IAppSearchResultCallback callback) throws RemoteException { callback.onResult(AppSearchResult.newSuccessfulResult(null)); } } Loading Loading @@ -1146,6 +1247,9 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { shutdownServices(); mMockAppSearchManager.removeShortcuts(); mMockAppSearchManager = null; super.tearDown(); } Loading Loading @@ -1891,6 +1995,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mService.getPackageShortcutForTest(packageName, shortcutId, userId); } protected void updatePackageShortcut(String packageName, String shortcutId, int userId, Consumer<ShortcutInfo> cb) { mService.updatePackageShortcutForTest(packageName, shortcutId, userId, cb); } protected void assertShortcutExists(String packageName, String shortcutId, int userId) { assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null); } Loading Loading @@ -2086,6 +2195,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId()); } protected void updateCallerShortcut(String shortcutId, Consumer<ShortcutInfo> cb) { updatePackageShortcut(getCallingPackage(), shortcutId, getCallingUserId(), cb); } protected List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) { final List<ShortcutInfo>[] ret = new List[1]; runWithCaller(launcher, userId, () -> { Loading Loading @@ -2245,6 +2358,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { deleteAllSavedFiles(); mMockAppSearchManager.removeShortcuts(); initService(); mService.applyRestore(payload, USER_0); Loading