Merge "Remove PackageManagerInternal from AppSearchService." into sc-dev

This commit is contained in:
Alexander Dorokhine
2021-05-20 20:36:04 +00:00
committed by Android (Google) Code Review
12 changed files with 439 additions and 342 deletions

View File

@@ -205,7 +205,7 @@ public class AppSearchManager {
AppSearchSession.createSearchSession( AppSearchSession.createSearchSession(
searchContext, searchContext,
mService, mService,
mContext.getUser().getIdentifier(), mContext.getUser(),
getPackageName(), getPackageName(),
executor, executor,
callback); callback);
@@ -228,7 +228,7 @@ public class AppSearchManager {
Objects.requireNonNull(executor); Objects.requireNonNull(executor);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
GlobalSearchSession.createGlobalSearchSession( GlobalSearchSession.createGlobalSearchSession(
mService, mContext.getUser().getIdentifier(), getPackageName(), executor, callback); mService, mContext.getUser(), getPackageName(), executor, callback);
} }
/** Returns the package name that should be used for uid verification. */ /** Returns the package name that should be used for uid verification. */

View File

@@ -21,7 +21,6 @@ import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread; import android.annotation.WorkerThread;
import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.AppSearchResultParcel;
import android.app.appsearch.aidl.IAppSearchManager; import android.app.appsearch.aidl.IAppSearchManager;
@@ -31,6 +30,7 @@ import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet; import android.util.ArraySet;
import java.io.Closeable; import java.io.Closeable;
@@ -57,20 +57,20 @@ public class AppSearchMigrationHelper implements Closeable {
private final IAppSearchManager mService; private final IAppSearchManager mService;
private final String mPackageName; private final String mPackageName;
private final String mDatabaseName; private final String mDatabaseName;
private final int mUserId; private final UserHandle mUserHandle;
private final File mMigratedFile; private final File mMigratedFile;
private final Set<String> mDestinationTypes; private final Set<String> mDestinationTypes;
private boolean mAreDocumentsMigrated = false; private boolean mAreDocumentsMigrated = false;
AppSearchMigrationHelper(@NonNull IAppSearchManager service, AppSearchMigrationHelper(@NonNull IAppSearchManager service,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull String packageName, @NonNull String packageName,
@NonNull String databaseName, @NonNull String databaseName,
@NonNull Set<AppSearchSchema> newSchemas) throws IOException { @NonNull Set<AppSearchSchema> newSchemas) throws IOException {
mService = Objects.requireNonNull(service); mService = Objects.requireNonNull(service);
mUserHandle = Objects.requireNonNull(userHandle);
mPackageName = Objects.requireNonNull(packageName); mPackageName = Objects.requireNonNull(packageName);
mDatabaseName = Objects.requireNonNull(databaseName); mDatabaseName = Objects.requireNonNull(databaseName);
mUserId = userId;
mMigratedFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null); mMigratedFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null);
mDestinationTypes = new ArraySet<>(newSchemas.size()); mDestinationTypes = new ArraySet<>(newSchemas.size());
for (AppSearchSchema newSchema : newSchemas) { for (AppSearchSchema newSchema : newSchemas) {
@@ -105,7 +105,7 @@ public class AppSearchMigrationHelper implements Closeable {
.addFilterSchemas(schemaType) .addFilterSchemas(schemaType)
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY) .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
.build().getBundle(), .build().getBundle(),
mUserId, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {
@@ -145,7 +145,7 @@ public class AppSearchMigrationHelper implements Closeable {
try (ParcelFileDescriptor fileDescriptor = try (ParcelFileDescriptor fileDescriptor =
ParcelFileDescriptor.open(mMigratedFile, MODE_READ_ONLY)) { ParcelFileDescriptor.open(mMigratedFile, MODE_READ_ONLY)) {
CompletableFuture<AppSearchResult<List<Bundle>>> future = new CompletableFuture<>(); CompletableFuture<AppSearchResult<List<Bundle>>> future = new CompletableFuture<>();
mService.putDocumentsFromFile(mPackageName, mDatabaseName, fileDescriptor, mUserId, mService.putDocumentsFromFile(mPackageName, mDatabaseName, fileDescriptor, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {

View File

@@ -18,7 +18,6 @@ package android.app.appsearch;
import android.annotation.CallbackExecutor; import android.annotation.CallbackExecutor;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.appsearch.aidl.AppSearchBatchResultParcel; import android.app.appsearch.aidl.AppSearchBatchResultParcel;
import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.AppSearchResultParcel;
import android.app.appsearch.aidl.IAppSearchBatchResultCallback; import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
@@ -30,6 +29,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Log; import android.util.Log;
@@ -61,26 +61,25 @@ public final class AppSearchSession implements Closeable {
private final String mPackageName; private final String mPackageName;
private final String mDatabaseName; private final String mDatabaseName;
@UserIdInt private final UserHandle mUserHandle;
private final int mUserId;
private final IAppSearchManager mService; private final IAppSearchManager mService;
private boolean mIsMutated = false; private boolean mIsMutated = false;
private boolean mIsClosed = false; private boolean mIsClosed = false;
/** /**
* Creates a search session for the client, defined by the {@code userId} and * Creates a search session for the client, defined by the {@code userHandle} and
* {@code packageName}. * {@code packageName}.
*/ */
static void createSearchSession( static void createSearchSession(
@NonNull AppSearchManager.SearchContext searchContext, @NonNull AppSearchManager.SearchContext searchContext,
@NonNull IAppSearchManager service, @NonNull IAppSearchManager service,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull String packageName, @NonNull String packageName,
@NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
AppSearchSession searchSession = AppSearchSession searchSession =
new AppSearchSession(service, userId, packageName, searchContext.mDatabaseName); new AppSearchSession(service, userHandle, packageName, searchContext.mDatabaseName);
searchSession.initialize(executor, callback); searchSession.initialize(executor, callback);
} }
@@ -90,7 +89,8 @@ public final class AppSearchSession implements Closeable {
@NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
try { try {
mService.initialize(mUserId, mService.initialize(
mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
@@ -112,10 +112,10 @@ public final class AppSearchSession implements Closeable {
} }
} }
private AppSearchSession(@NonNull IAppSearchManager service, @UserIdInt int userId, private AppSearchSession(@NonNull IAppSearchManager service, @NonNull UserHandle userHandle,
@NonNull String packageName, @NonNull String databaseName) { @NonNull String packageName, @NonNull String databaseName) {
mService = service; mService = service;
mUserId = userId; mUserHandle = userHandle;
mPackageName = packageName; mPackageName = packageName;
mDatabaseName = databaseName; mDatabaseName = databaseName;
} }
@@ -199,7 +199,7 @@ public final class AppSearchSession implements Closeable {
mService.getSchema( mService.getSchema(
mPackageName, mPackageName,
mDatabaseName, mDatabaseName,
mUserId, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {
@@ -236,7 +236,7 @@ public final class AppSearchSession implements Closeable {
mService.getNamespaces( mService.getNamespaces(
mPackageName, mPackageName,
mDatabaseName, mDatabaseName,
mUserId, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {
@@ -289,7 +289,7 @@ public final class AppSearchSession implements Closeable {
documentBundles.add(documents.get(i).getBundle()); documentBundles.add(documents.get(i).getBundle());
} }
try { try {
mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserId, mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchBatchResultCallback.Stub() { new IAppSearchBatchResultCallback.Stub() {
@Override @Override
@@ -352,7 +352,7 @@ public final class AppSearchSession implements Closeable {
request.getNamespace(), request.getNamespace(),
new ArrayList<>(request.getIds()), new ArrayList<>(request.getIds()),
request.getProjectionsInternal(), request.getProjectionsInternal(),
mUserId, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchBatchResultCallback.Stub() { new IAppSearchBatchResultCallback.Stub() {
@Override @Override
@@ -472,7 +472,7 @@ public final class AppSearchSession implements Closeable {
Objects.requireNonNull(searchSpec); Objects.requireNonNull(searchSpec);
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
return new SearchResults(mService, mPackageName, mDatabaseName, queryExpression, return new SearchResults(mService, mPackageName, mDatabaseName, queryExpression,
searchSpec, mUserId); searchSpec, mUserHandle);
} }
/** /**
@@ -508,7 +508,7 @@ public final class AppSearchSession implements Closeable {
request.getDocumentId(), request.getDocumentId(),
request.getUsageTimestampMillis(), request.getUsageTimestampMillis(),
/*systemUsage=*/ false, /*systemUsage=*/ false,
mUserId, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {
@@ -565,8 +565,12 @@ public final class AppSearchSession implements Closeable {
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
try { try {
mService.removeByDocumentId(mPackageName, mDatabaseName, request.getNamespace(), mService.removeByDocumentId(
new ArrayList<>(request.getIds()), mUserId, mPackageName,
mDatabaseName,
request.getNamespace(),
new ArrayList<>(request.getIds()),
mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchBatchResultCallback.Stub() { new IAppSearchBatchResultCallback.Stub() {
@Override @Override
@@ -616,8 +620,12 @@ public final class AppSearchSession implements Closeable {
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
try { try {
mService.removeByQuery(mPackageName, mDatabaseName, queryExpression, mService.removeByQuery(
searchSpec.getBundle(), mUserId, mPackageName,
mDatabaseName,
queryExpression,
searchSpec.getBundle(),
mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
@@ -650,7 +658,7 @@ public final class AppSearchSession implements Closeable {
mService.getStorageInfo( mService.getStorageInfo(
mPackageName, mPackageName,
mDatabaseName, mDatabaseName,
mUserId, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {
@@ -678,8 +686,8 @@ public final class AppSearchSession implements Closeable {
public void close() { public void close() {
if (mIsMutated && !mIsClosed) { if (mIsMutated && !mIsClosed) {
try { try {
mService.persistToDisk(mUserId, mService.persistToDisk(
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
mIsClosed = true; mIsClosed = true;
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to close the AppSearchSession", e); Log.e(TAG, "Unable to close the AppSearchSession", e);
@@ -708,7 +716,7 @@ public final class AppSearchSession implements Closeable {
schemasPackageAccessibleBundles, schemasPackageAccessibleBundles,
request.isForceOverride(), request.isForceOverride(),
request.getVersion(), request.getVersion(),
mUserId, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
@@ -796,7 +804,7 @@ public final class AppSearchSession implements Closeable {
schemasPackageAccessibleBundles, schemasPackageAccessibleBundles,
/*forceOverride=*/ false, /*forceOverride=*/ false,
request.getVersion(), request.getVersion(),
mUserId, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
@@ -822,7 +830,7 @@ public final class AppSearchSession implements Closeable {
} }
try (AppSearchMigrationHelper migrationHelper = new AppSearchMigrationHelper( try (AppSearchMigrationHelper migrationHelper = new AppSearchMigrationHelper(
mService, mUserId, mPackageName, mDatabaseName, request.getSchemas())) { mService, mUserHandle, mPackageName, mDatabaseName, request.getSchemas())) {
// 4. Trigger migration for all migrators. // 4. Trigger migration for all migrators.
// TODO(b/177266929) trigger migration for all types together rather than // TODO(b/177266929) trigger migration for all types together rather than
@@ -848,7 +856,7 @@ public final class AppSearchSession implements Closeable {
schemasPackageAccessibleBundles, schemasPackageAccessibleBundles,
/*forceOverride=*/ true, /*forceOverride=*/ true,
request.getVersion(), request.getVersion(),
mUserId, mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override

View File

@@ -18,12 +18,12 @@ package android.app.appsearch;
import android.annotation.CallbackExecutor; import android.annotation.CallbackExecutor;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.AppSearchResultParcel;
import android.app.appsearch.aidl.IAppSearchManager; import android.app.appsearch.aidl.IAppSearchManager;
import android.app.appsearch.aidl.IAppSearchResultCallback; import android.app.appsearch.aidl.IAppSearchResultCallback;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
@@ -45,24 +45,23 @@ public class GlobalSearchSession implements Closeable {
private static final String TAG = "AppSearchGlobalSearchSe"; private static final String TAG = "AppSearchGlobalSearchSe";
private final String mPackageName; private final String mPackageName;
@UserIdInt private final UserHandle mUserHandle;
private final int mUserId;
private final IAppSearchManager mService; private final IAppSearchManager mService;
private boolean mIsMutated = false; private boolean mIsMutated = false;
private boolean mIsClosed = false; private boolean mIsClosed = false;
/** /**
* Creates a search session for the client, defined by the {@code userId} and * Creates a search session for the client, defined by the {@code userHandle} and
* {@code packageName}. * {@code packageName}.
*/ */
static void createGlobalSearchSession( static void createGlobalSearchSession(
@NonNull IAppSearchManager service, @NonNull IAppSearchManager service,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull String packageName, @NonNull String packageName,
@NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) { @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userId, GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userHandle,
packageName); packageName);
globalSearchSession.initialize(executor, callback); globalSearchSession.initialize(executor, callback);
} }
@@ -73,7 +72,8 @@ public class GlobalSearchSession implements Closeable {
@NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) { @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
try { try {
mService.initialize(mUserId, mService.initialize(
mUserHandle,
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
@@ -95,10 +95,10 @@ public class GlobalSearchSession implements Closeable {
} }
} }
private GlobalSearchSession(@NonNull IAppSearchManager service, @UserIdInt int userId, private GlobalSearchSession(@NonNull IAppSearchManager service, @NonNull UserHandle userHandle,
@NonNull String packageName) { @NonNull String packageName) {
mService = service; mService = service;
mUserId = userId; mUserHandle = userHandle;
mPackageName = packageName; mPackageName = packageName;
} }
@@ -127,7 +127,7 @@ public class GlobalSearchSession implements Closeable {
Objects.requireNonNull(searchSpec); Objects.requireNonNull(searchSpec);
Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed"); Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
return new SearchResults(mService, mPackageName, /*databaseName=*/null, queryExpression, return new SearchResults(mService, mPackageName, /*databaseName=*/null, queryExpression,
searchSpec, mUserId); searchSpec, mUserHandle);
} }
/** /**
@@ -165,7 +165,7 @@ public class GlobalSearchSession implements Closeable {
request.getDocumentId(), request.getDocumentId(),
request.getUsageTimestampMillis(), request.getUsageTimestampMillis(),
/*systemUsage=*/ true, /*systemUsage=*/ true,
mUserId, mUserHandle,
new IAppSearchResultCallback.Stub() { new IAppSearchResultCallback.Stub() {
@Override @Override
public void onResult(AppSearchResultParcel resultParcel) { public void onResult(AppSearchResultParcel resultParcel) {
@@ -186,8 +186,8 @@ public class GlobalSearchSession implements Closeable {
public void close() { public void close() {
if (mIsMutated && !mIsClosed) { if (mIsMutated && !mIsClosed) {
try { try {
mService.persistToDisk(mUserId, mService.persistToDisk(
/*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
mIsClosed = true; mIsClosed = true;
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to close the GlobalSearchSession", e); Log.e(TAG, "Unable to close the GlobalSearchSession", e);

View File

@@ -19,13 +19,13 @@ package android.app.appsearch;
import android.annotation.CallbackExecutor; import android.annotation.CallbackExecutor;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.AppSearchResultParcel;
import android.app.appsearch.aidl.IAppSearchManager; import android.app.appsearch.aidl.IAppSearchManager;
import android.app.appsearch.aidl.IAppSearchResultCallback; import android.app.appsearch.aidl.IAppSearchResultCallback;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
@@ -66,8 +66,7 @@ public class SearchResults implements Closeable {
private final SearchSpec mSearchSpec; private final SearchSpec mSearchSpec;
@UserIdInt private final UserHandle mUserHandle;
private final int mUserId;
private long mNextPageToken; private long mNextPageToken;
@@ -81,13 +80,13 @@ public class SearchResults implements Closeable {
@Nullable String databaseName, @Nullable String databaseName,
@NonNull String queryExpression, @NonNull String queryExpression,
@NonNull SearchSpec searchSpec, @NonNull SearchSpec searchSpec,
@UserIdInt int userId) { @NonNull UserHandle userHandle) {
mService = Objects.requireNonNull(service); mService = Objects.requireNonNull(service);
mPackageName = packageName; mPackageName = packageName;
mDatabaseName = databaseName; mDatabaseName = databaseName;
mQueryExpression = Objects.requireNonNull(queryExpression); mQueryExpression = Objects.requireNonNull(queryExpression);
mSearchSpec = Objects.requireNonNull(searchSpec); mSearchSpec = Objects.requireNonNull(searchSpec);
mUserId = userId; mUserHandle = Objects.requireNonNull(userHandle);
} }
/** /**
@@ -114,18 +113,18 @@ public class SearchResults implements Closeable {
if (mDatabaseName == null) { if (mDatabaseName == null) {
// Global query, there's no one package-database combination to check. // Global query, there's no one package-database combination to check.
mService.globalQuery(mPackageName, mQueryExpression, mService.globalQuery(mPackageName, mQueryExpression,
mSearchSpec.getBundle(), mUserId, mSearchSpec.getBundle(), mUserHandle,
binderCallStartTimeMillis, binderCallStartTimeMillis,
wrapCallback(executor, callback)); wrapCallback(executor, callback));
} else { } else {
// Normal local query, pass in specified database. // Normal local query, pass in specified database.
mService.query(mPackageName, mDatabaseName, mQueryExpression, mService.query(mPackageName, mDatabaseName, mQueryExpression,
mSearchSpec.getBundle(), mUserId, mSearchSpec.getBundle(), mUserHandle,
binderCallStartTimeMillis, binderCallStartTimeMillis,
wrapCallback(executor, callback)); wrapCallback(executor, callback));
} }
} else { } else {
mService.getNextPage(mNextPageToken, mUserId, wrapCallback(executor, callback)); mService.getNextPage(mNextPageToken, mUserHandle, wrapCallback(executor, callback));
} }
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
@@ -136,7 +135,7 @@ public class SearchResults implements Closeable {
public void close() { public void close() {
if (!mIsClosed) { if (!mIsClosed) {
try { try {
mService.invalidateNextPageToken(mNextPageToken, mUserId); mService.invalidateNextPageToken(mNextPageToken, mUserHandle);
mIsClosed = true; mIsClosed = true;
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to close the SearchResults", e); Log.e(TAG, "Unable to close the SearchResults", e);

View File

@@ -16,6 +16,7 @@
package android.app.appsearch.aidl; package android.app.appsearch.aidl;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle;
import android.app.appsearch.aidl.IAppSearchBatchResultCallback; import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
import android.app.appsearch.aidl.IAppSearchResultCallback; import android.app.appsearch.aidl.IAppSearchResultCallback;
@@ -36,7 +37,7 @@ interface IAppSearchManager {
* @param forceOverride Whether to apply the new schema even if it is incompatible. All * @param forceOverride Whether to apply the new schema even if it is incompatible. All
* incompatible documents will be deleted. * incompatible documents will be deleted.
* @param schemaVersion The overall schema version number of the request. * @param schemaVersion The overall schema version number of the request.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value are * {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value are
@@ -50,7 +51,7 @@ interface IAppSearchManager {
in Map<String, List<Bundle>> schemasPackageAccessibleBundles, in Map<String, List<Bundle>> schemasPackageAccessibleBundles,
boolean forceOverride, boolean forceOverride,
in int schemaVersion, in int schemaVersion,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
@@ -59,14 +60,14 @@ interface IAppSearchManager {
* *
* @param packageName The name of the package that owns the schema. * @param packageName The name of the package that owns the schema.
* @param databaseName The name of the database to retrieve. * @param databaseName The name of the database to retrieve.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Bundle}&gt; where the bundle is a GetSchemaResponse. * {@link AppSearchResult}&lt;{@link Bundle}&gt; where the bundle is a GetSchemaResponse.
*/ */
void getSchema( void getSchema(
in String packageName, in String packageName,
in String databaseName, in String databaseName,
in int userId, in UserHandle userHandle,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
/** /**
@@ -74,14 +75,14 @@ interface IAppSearchManager {
* *
* @param packageName The name of the package that owns the schema. * @param packageName The name of the package that owns the schema.
* @param databaseName The name of the database to retrieve. * @param databaseName The name of the database to retrieve.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link List}&lt;{@link String}&gt;&gt;. * {@link AppSearchResult}&lt;{@link List}&lt;{@link String}&gt;&gt;.
*/ */
void getNamespaces( void getNamespaces(
in String packageName, in String packageName,
in String databaseName, in String databaseName,
in int userId, in UserHandle userHandle,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
/** /**
@@ -90,7 +91,7 @@ interface IAppSearchManager {
* @param packageName The name of the package that owns this document. * @param packageName The name of the package that owns this document.
* @param databaseName The name of the database where this document lives. * @param databaseName The name of the database where this document lives.
* @param documentBundes List of GenericDocument bundles. * @param documentBundes List of GenericDocument bundles.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback * @param callback
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
@@ -103,7 +104,7 @@ interface IAppSearchManager {
in String packageName, in String packageName,
in String databaseName, in String databaseName,
in List<Bundle> documentBundles, in List<Bundle> documentBundles,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchBatchResultCallback callback); in IAppSearchBatchResultCallback callback);
@@ -116,7 +117,7 @@ interface IAppSearchManager {
* @param ids The IDs of the documents to retrieve * @param ids The IDs of the documents to retrieve
* @param typePropertyPaths A map of schema type to a list of property paths to return in the * @param typePropertyPaths A map of schema type to a list of property paths to return in the
* result. * result.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback * @param callback
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
@@ -131,7 +132,7 @@ interface IAppSearchManager {
in String namespace, in String namespace,
in List<String> ids, in List<String> ids,
in Map<String, List<String>> typePropertyPaths, in Map<String, List<String>> typePropertyPaths,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchBatchResultCallback callback); in IAppSearchBatchResultCallback callback);
@@ -142,7 +143,7 @@ interface IAppSearchManager {
* @param databaseName The databaseName this query for. * @param databaseName The databaseName this query for.
* @param queryExpression String to search for * @param queryExpression String to search for
* @param searchSpecBundle SearchSpec bundle * @param searchSpecBundle SearchSpec bundle
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
* operation. * operation.
@@ -152,7 +153,7 @@ interface IAppSearchManager {
in String databaseName, in String databaseName,
in String queryExpression, in String queryExpression,
in Bundle searchSpecBundle, in Bundle searchSpecBundle,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
@@ -163,7 +164,7 @@ interface IAppSearchManager {
* @param packageName The name of the package making the query. * @param packageName The name of the package making the query.
* @param queryExpression String to search for * @param queryExpression String to search for
* @param searchSpecBundle SearchSpec bundle * @param searchSpecBundle SearchSpec bundle
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
* operation. * operation.
@@ -172,7 +173,7 @@ interface IAppSearchManager {
in String packageName, in String packageName,
in String queryExpression, in String queryExpression,
in Bundle searchSpecBundle, in Bundle searchSpecBundle,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
@@ -181,20 +182,20 @@ interface IAppSearchManager {
* next-page token is invalid or all pages have been returned. * next-page token is invalid or all pages have been returned.
* *
* @param nextPageToken The token of pre-loaded results of previously executed query. * @param nextPageToken The token of pre-loaded results of previously executed query.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
* operation. * operation.
*/ */
void getNextPage(in long nextPageToken, in int userId, in IAppSearchResultCallback callback); void getNextPage(in long nextPageToken, in UserHandle userHandle, in IAppSearchResultCallback callback);
/** /**
* Invalidates the next-page token so that no more results of the related query can be returned. * Invalidates the next-page token so that no more results of the related query can be returned.
* *
* @param nextPageToken The token of pre-loaded results of previously executed query to be * @param nextPageToken The token of pre-loaded results of previously executed query to be
* Invalidated. * Invalidated.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
*/ */
void invalidateNextPageToken(in long nextPageToken, in int userId); void invalidateNextPageToken(in long nextPageToken, in UserHandle userHandle);
/** /**
* Searches a document based on a given specifications. * Searches a document based on a given specifications.
@@ -206,7 +207,7 @@ interface IAppSearchManager {
* @param fileDescriptor The ParcelFileDescriptor where documents should be written to. * @param fileDescriptor The ParcelFileDescriptor where documents should be written to.
* @param queryExpression String to search for. * @param queryExpression String to search for.
* @param searchSpecBundle SearchSpec bundle. * @param searchSpecBundle SearchSpec bundle.
* @param userId Id of the calling user. * @param userHandle Handle of the calling user.
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@code Void}&gt;. * {@link AppSearchResult}&lt;{@code Void}&gt;.
*/ */
@@ -216,7 +217,7 @@ interface IAppSearchManager {
in ParcelFileDescriptor fileDescriptor, in ParcelFileDescriptor fileDescriptor,
in String queryExpression, in String queryExpression,
in Bundle searchSpecBundle, in Bundle searchSpecBundle,
in int userId, in UserHandle userHandle,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
/** /**
@@ -225,7 +226,7 @@ interface IAppSearchManager {
* @param packageName The name of the package that owns this document. * @param packageName The name of the package that owns this document.
* @param databaseName The name of the database where this document lives. * @param databaseName The name of the database where this document lives.
* @param fileDescriptor The ParcelFileDescriptor where documents should be read from. * @param fileDescriptor The ParcelFileDescriptor where documents should be read from.
* @param userId Id of the calling user. * @param userHandle Handle of the calling user.
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link List}&lt;{@link Bundle}&gt;&gt;, where the value are * {@link AppSearchResult}&lt;{@link List}&lt;{@link Bundle}&gt;&gt;, where the value are
* MigrationFailure bundles. * MigrationFailure bundles.
@@ -234,7 +235,7 @@ interface IAppSearchManager {
in String packageName, in String packageName,
in String databaseName, in String databaseName,
in ParcelFileDescriptor fileDescriptor, in ParcelFileDescriptor fileDescriptor,
in int userId, in UserHandle userHandle,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
/** /**
@@ -255,7 +256,7 @@ interface IAppSearchManager {
* @param id ID of the document being used. * @param id ID of the document being used.
* @param usageTimestampMillis The timestamp at which the document was used. * @param usageTimestampMillis The timestamp at which the document was used.
* @param systemUsage Whether the usage was reported by a system app against another app's doc. * @param systemUsage Whether the usage was reported by a system app against another app's doc.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Void}&gt;. * {@link AppSearchResult}&lt;{@link Void}&gt;.
*/ */
@@ -266,7 +267,7 @@ interface IAppSearchManager {
in String id, in String id,
in long usageTimestampMillis, in long usageTimestampMillis,
in boolean systemUsage, in boolean systemUsage,
in int userId, in UserHandle userHandle,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
/** /**
@@ -276,7 +277,7 @@ interface IAppSearchManager {
* @param databaseName The databaseName the document is in. * @param databaseName The databaseName the document is in.
* @param namespace Namespace of the document to remove. * @param namespace Namespace of the document to remove.
* @param ids The IDs of the documents to delete * @param ids The IDs of the documents to delete
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback * @param callback
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
@@ -291,7 +292,7 @@ interface IAppSearchManager {
in String databaseName, in String databaseName,
in String namespace, in String namespace,
in List<String> ids, in List<String> ids,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchBatchResultCallback callback); in IAppSearchBatchResultCallback callback);
@@ -302,7 +303,7 @@ interface IAppSearchManager {
* @param databaseName The databaseName this query for. * @param databaseName The databaseName this query for.
* @param queryExpression String to search for * @param queryExpression String to search for
* @param searchSpecBundle SearchSpec bundle * @param searchSpecBundle SearchSpec bundle
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Void}&gt;. * {@link AppSearchResult}&lt;{@link Void}&gt;.
@@ -312,7 +313,7 @@ interface IAppSearchManager {
in String databaseName, in String databaseName,
in String queryExpression, in String queryExpression,
in Bundle searchSpecBundle, in Bundle searchSpecBundle,
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
@@ -321,7 +322,7 @@ interface IAppSearchManager {
* *
* @param packageName The name of the package to get the storage info for. * @param packageName The name of the package to get the storage info for.
* @param databaseName The databaseName to get the storage info for. * @param databaseName The databaseName to get the storage info for.
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value is a * {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value is a
* {@link StorageInfo}. * {@link StorageInfo}.
@@ -329,27 +330,27 @@ interface IAppSearchManager {
void getStorageInfo( void getStorageInfo(
in String packageName, in String packageName,
in String databaseName, in String databaseName,
in int userId, in UserHandle userHandle,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
/** /**
* Persists all update/delete requests to the disk. * Persists all update/delete requests to the disk.
* *
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
*/ */
void persistToDisk(in int userId, in long binderCallStartTimeMillis); void persistToDisk(in UserHandle userHandle, in long binderCallStartTimeMillis);
/** /**
* Creates and initializes AppSearchImpl for the calling app. * Creates and initializes AppSearchImpl for the calling app.
* *
* @param userId Id of the calling user * @param userHandle Handle of the calling user
* @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback {@link IAppSearchResultCallback#onResult} will be called with an * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
* {@link AppSearchResult}&lt;{@link Void}&gt;. * {@link AppSearchResult}&lt;{@link Void}&gt;.
*/ */
void initialize( void initialize(
in int userId, in UserHandle userHandle,
in long binderCallStartTimeMillis, in long binderCallStartTimeMillis,
in IAppSearchResultCallback callback); in IAppSearchResultCallback callback);
} }

View File

@@ -21,7 +21,6 @@ import static android.os.UserHandle.USER_NULL;
import android.annotation.ElapsedRealtimeLong; import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.appsearch.AppSearchBatchResult; import android.app.appsearch.AppSearchBatchResult;
import android.app.appsearch.AppSearchMigrationHelper; import android.app.appsearch.AppSearchMigrationHelper;
@@ -45,7 +44,6 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageStats; import android.content.pm.PackageStats;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
@@ -60,7 +58,6 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalManagerRegistry; import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.SystemService; import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.stats.CallStats; import com.android.server.appsearch.external.localstorage.stats.CallStats;
@@ -91,7 +88,6 @@ public class AppSearchManagerService extends SystemService {
private static final String TAG = "AppSearchManagerService"; private static final String TAG = "AppSearchManagerService";
private final Context mContext; private final Context mContext;
private PackageManager mPackageManager; private PackageManager mPackageManager;
private PackageManagerInternal mPackageManagerInternal;
private ImplInstanceManager mImplInstanceManager; private ImplInstanceManager mImplInstanceManager;
private UserManager mUserManager; private UserManager mUserManager;
private LoggerInstanceManager mLoggerInstanceManager; private LoggerInstanceManager mLoggerInstanceManager;
@@ -104,11 +100,11 @@ public class AppSearchManagerService extends SystemService {
Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS, Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>()); new LinkedBlockingQueue<>());
// Cache of unlocked user ids so we don't have to query UserManager service each time. The // Cache of unlocked users so we don't have to query UserManager service each time. The "locked"
// "locked" suffix refers to the fact that access to the field should be locked; unrelated to // suffix refers to the fact that access to the field should be locked; unrelated to the
// the unlocked status of user ids. // unlocked status of users.
@GuardedBy("mUnlockedUserIdsLocked") @GuardedBy("mUnlockedUsersLocked")
private final Set<Integer> mUnlockedUserIdsLocked = new ArraySet<>(); private final Set<UserHandle> mUnlockedUsersLocked = new ArraySet<>();
public AppSearchManagerService(Context context) { public AppSearchManagerService(Context context) {
super(context); super(context);
@@ -119,7 +115,6 @@ public class AppSearchManagerService extends SystemService {
public void onStart() { public void onStart() {
publishBinderService(Context.APP_SEARCH_SERVICE, new Stub()); publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
mPackageManager = getContext().getPackageManager(); mPackageManager = getContext().getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mImplInstanceManager = ImplInstanceManager.getInstance(mContext); mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
mUserManager = mContext.getSystemService(UserManager.class); mUserManager = mContext.getSystemService(UserManager.class);
mLoggerInstanceManager = LoggerInstanceManager.getInstance(); mLoggerInstanceManager = LoggerInstanceManager.getInstance();
@@ -148,6 +143,9 @@ public class AppSearchManagerService extends SystemService {
private class UserActionReceiver extends BroadcastReceiver { private class UserActionReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) { public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Objects.requireNonNull(context);
Objects.requireNonNull(intent);
switch (intent.getAction()) { switch (intent.getAction()) {
case Intent.ACTION_USER_REMOVED: case Intent.ACTION_USER_REMOVED:
int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
@@ -155,7 +153,7 @@ public class AppSearchManagerService extends SystemService {
Log.e(TAG, "userId is missing in the intent: " + intent); Log.e(TAG, "userId is missing in the intent: " + intent);
return; return;
} }
handleUserRemoved(userId); handleUserRemoved(UserHandle.of(userId));
break; break;
default: default:
Log.e(TAG, "Received unknown intent: " + intent); Log.e(TAG, "Received unknown intent: " + intent);
@@ -170,23 +168,26 @@ public class AppSearchManagerService extends SystemService {
* "credential encrypted" system directory of each user. That directory will be auto-deleted * "credential encrypted" system directory of each user. That directory will be auto-deleted
* when a user is removed. * when a user is removed.
* *
* @param userId The multi-user userId of the user that need to be removed. * @param userHandle The multi-user handle of the user that need to be removed.
* *
* @see android.os.Environment#getDataSystemCeDirectory * @see android.os.Environment#getDataSystemCeDirectory
*/ */
private void handleUserRemoved(@UserIdInt int userId) { private void handleUserRemoved(@NonNull UserHandle userHandle) {
try { try {
mImplInstanceManager.removeAppSearchImplForUser(userId); mImplInstanceManager.removeAppSearchImplForUser(userHandle);
mLoggerInstanceManager.removePlatformLoggerForUser(userId); mLoggerInstanceManager.removePlatformLoggerForUser(userHandle);
Log.i(TAG, "Removed AppSearchImpl instance for user: " + userId); Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
} catch (Throwable t) { } catch (Throwable t) {
Log.e(TAG, "Unable to remove data for user: " + userId, t); Log.e(TAG, "Unable to remove data for: " + userHandle, t);
} }
} }
private class PackageChangedReceiver extends BroadcastReceiver { private class PackageChangedReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) { public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Objects.requireNonNull(context);
Objects.requireNonNull(intent);
switch (intent.getAction()) { switch (intent.getAction()) {
case Intent.ACTION_PACKAGE_FULLY_REMOVED: case Intent.ACTION_PACKAGE_FULLY_REMOVED:
case Intent.ACTION_PACKAGE_DATA_CLEARED: case Intent.ACTION_PACKAGE_DATA_CLEARED:
@@ -208,19 +209,19 @@ public class AppSearchManagerService extends SystemService {
} }
} }
private void handlePackageRemoved(String packageName, int uid) { private void handlePackageRemoved(@NonNull String packageName, int uid) {
int userId = UserHandle.getUserId(uid); UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
try { try {
if (isUserLocked(userId)) { if (isUserLocked(userHandle)) {
//TODO(b/186151459) clear the uninstalled package data when user is unlocked. //TODO(b/186151459) clear the uninstalled package data when user is unlocked.
return; return;
} }
if (ImplInstanceManager.getAppSearchDir(userId).exists()) { if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
// Only clear the package's data if AppSearch exists for this user. // Only clear the package's data if AppSearch exists for this user.
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
userId); userHandle);
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
userId, logger); userHandle, logger);
//TODO(b/145759910) clear visibility setting for package. //TODO(b/145759910) clear visibility setting for package.
impl.clearPackageData(packageName); impl.clearPackageData(packageName);
logger.removeCachedUidForPackage(packageName); logger.removeCachedUidForPackage(packageName);
@@ -232,38 +233,42 @@ public class AppSearchManagerService extends SystemService {
@Override @Override
public void onUserUnlocking(@NonNull TargetUser user) { public void onUserUnlocking(@NonNull TargetUser user) {
synchronized (mUnlockedUserIdsLocked) { Objects.requireNonNull(user);
mUnlockedUserIdsLocked.add(user.getUserIdentifier()); synchronized (mUnlockedUsersLocked) {
mUnlockedUsersLocked.add(user.getUserHandle());
} }
} }
@Override @Override
public void onUserStopping(@NonNull TargetUser user) { public void onUserStopping(@NonNull TargetUser user) {
synchronized (mUnlockedUserIdsLocked) { Objects.requireNonNull(user);
mUnlockedUserIdsLocked.remove(user.getUserIdentifier());
synchronized (mUnlockedUsersLocked) {
UserHandle userHandle = user.getUserHandle();
mUnlockedUsersLocked.remove(userHandle);
try { try {
mImplInstanceManager.closeAndRemoveAppSearchImplForUser(user.getUserIdentifier()); mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
} catch (Throwable t) { } catch (Throwable t) {
Log.e(TAG, "Error handling user stopping.", t); Log.e(TAG, "Error handling user stopping.", t);
} }
} }
} }
private void verifyUserUnlocked(int callingUserId) { private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
if (isUserLocked(callingUserId)) { if (isUserLocked(callingUser)) {
throw new IllegalStateException("User " + callingUserId + " is locked or not running."); throw new IllegalStateException(callingUser + " is locked or not running.");
} }
} }
private boolean isUserLocked(int callingUserId) { private boolean isUserLocked(@NonNull UserHandle callingUser) {
synchronized (mUnlockedUserIdsLocked) { synchronized (mUnlockedUsersLocked) {
// First, check the local copy. // First, check the local copy.
if (mUnlockedUserIdsLocked.contains(callingUserId)) { if (mUnlockedUsersLocked.contains(callingUser)) {
return false; return false;
} }
// If the local copy says the user is locked, check with UM for the actual state, // If the local copy says the user is locked, check with UM for the actual state,
// since the user might just have been unlocked. // since the user might just have been unlocked.
return !mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId)); return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
} }
} }
@@ -277,24 +282,28 @@ public class AppSearchManagerService extends SystemService {
@NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles, @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
boolean forceOverride, boolean forceOverride,
int schemaVersion, int schemaVersion,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(schemaBundles); Objects.requireNonNull(schemaBundles);
Objects.requireNonNull(schemasNotDisplayedBySystem);
Objects.requireNonNull(schemasPackageAccessibleBundles);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size()); List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
for (int i = 0; i < schemaBundles.size(); i++) { for (int i = 0; i < schemaBundles.size(); i++) {
schemas.add(new AppSearchSchema(schemaBundles.get(i))); schemas.add(new AppSearchSchema(schemaBundles.get(i)));
@@ -311,8 +320,8 @@ public class AppSearchManagerService extends SystemService {
} }
schemasPackageAccessible.put(entry.getKey(), packageIdentifiers); schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
} }
AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId); AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
SetSchemaResponse setSchemaResponse = impl.setSchema( SetSchemaResponse setSchemaResponse = impl.setSchema(
packageName, packageName,
databaseName, databaseName,
@@ -356,19 +365,20 @@ public class AppSearchManagerService extends SystemService {
public void getSchema( public void getSchema(
@NonNull String packageName, @NonNull String packageName,
@NonNull String databaseName, @NonNull String databaseName,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
GetSchemaResponse response = impl.getSchema(packageName, databaseName); GetSchemaResponse response = impl.getSchema(packageName, databaseName);
invokeCallbackOnResult( invokeCallbackOnResult(
callback, callback,
@@ -383,19 +393,20 @@ public class AppSearchManagerService extends SystemService {
public void getNamespaces( public void getNamespaces(
@NonNull String packageName, @NonNull String packageName,
@NonNull String databaseName, @NonNull String databaseName,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
List<String> namespaces = impl.getNamespaces(packageName, databaseName); List<String> namespaces = impl.getNamespaces(packageName, databaseName);
invokeCallbackOnResult(callback, invokeCallbackOnResult(callback,
AppSearchResult.newSuccessfulResult(namespaces)); AppSearchResult.newSuccessfulResult(namespaces));
@@ -410,29 +421,30 @@ public class AppSearchManagerService extends SystemService {
@NonNull String packageName, @NonNull String packageName,
@NonNull String databaseName, @NonNull String databaseName,
@NonNull List<Bundle> documentBundles, @NonNull List<Bundle> documentBundles,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchBatchResultCallback callback) { @NonNull IAppSearchBatchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(documentBundles); Objects.requireNonNull(documentBundles);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchBatchResult.Builder<String, Void> resultBuilder = AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
for (int i = 0; i < documentBundles.size(); i++) { for (int i = 0; i < documentBundles.size(); i++) {
GenericDocument document = new GenericDocument(documentBundles.get(i)); GenericDocument document = new GenericDocument(documentBundles.get(i));
try { try {
@@ -488,30 +500,32 @@ public class AppSearchManagerService extends SystemService {
@NonNull String namespace, @NonNull String namespace,
@NonNull List<String> ids, @NonNull List<String> ids,
@NonNull Map<String, List<String>> typePropertyPaths, @NonNull Map<String, List<String>> typePropertyPaths,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchBatchResultCallback callback) { @NonNull IAppSearchBatchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(namespace); Objects.requireNonNull(namespace);
Objects.requireNonNull(ids); Objects.requireNonNull(ids);
Objects.requireNonNull(typePropertyPaths);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchBatchResult.Builder<String, Bundle> resultBuilder = AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
for (int i = 0; i < ids.size(); i++) { for (int i = 0; i < ids.size(); i++) {
String id = ids.get(i); String id = ids.get(i);
try { try {
@@ -568,28 +582,29 @@ public class AppSearchManagerService extends SystemService {
@NonNull String databaseName, @NonNull String databaseName,
@NonNull String queryExpression, @NonNull String queryExpression,
@NonNull Bundle searchSpecBundle, @NonNull Bundle searchSpecBundle,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(queryExpression); Objects.requireNonNull(queryExpression);
Objects.requireNonNull(searchSpecBundle); Objects.requireNonNull(searchSpecBundle);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
SearchResultPage searchResultPage = SearchResultPage searchResultPage =
impl.query( impl.query(
packageName, packageName,
@@ -634,27 +649,28 @@ public class AppSearchManagerService extends SystemService {
@NonNull String packageName, @NonNull String packageName,
@NonNull String queryExpression, @NonNull String queryExpression,
@NonNull Bundle searchSpecBundle, @NonNull Bundle searchSpecBundle,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(queryExpression); Objects.requireNonNull(queryExpression);
Objects.requireNonNull(searchSpecBundle); Objects.requireNonNull(searchSpecBundle);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
SearchResultPage searchResultPage = SearchResultPage searchResultPage =
impl.globalQuery( impl.globalQuery(
queryExpression, queryExpression,
@@ -698,18 +714,19 @@ public class AppSearchManagerService extends SystemService {
@Override @Override
public void getNextPage( public void getNextPage(
long nextPageToken, long nextPageToken,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
// TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
// opened it // opened it
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
SearchResultPage searchResultPage = impl.getNextPage(nextPageToken); SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
invokeCallbackOnResult( invokeCallbackOnResult(
callback, callback,
@@ -721,14 +738,15 @@ public class AppSearchManagerService extends SystemService {
} }
@Override @Override
public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) { public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
impl.invalidateNextPageToken(nextPageToken); impl.invalidateNextPageToken(nextPageToken);
} catch (Throwable t) { } catch (Throwable t) {
Log.e(TAG, "Unable to invalidate the query page token", t); Log.e(TAG, "Unable to invalidate the query page token", t);
@@ -743,15 +761,22 @@ public class AppSearchManagerService extends SystemService {
@NonNull ParcelFileDescriptor fileDescriptor, @NonNull ParcelFileDescriptor fileDescriptor,
@NonNull String queryExpression, @NonNull String queryExpression,
@NonNull Bundle searchSpecBundle, @NonNull Bundle searchSpecBundle,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
Objects.requireNonNull(fileDescriptor);
Objects.requireNonNull(queryExpression);
Objects.requireNonNull(searchSpecBundle);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
// we don't need to append the file. The file is always brand new. // we don't need to append the file. The file is always brand new.
try (DataOutputStream outputStream = new DataOutputStream( try (DataOutputStream outputStream = new DataOutputStream(
new FileOutputStream(fileDescriptor.getFileDescriptor()))) { new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
@@ -783,15 +808,20 @@ public class AppSearchManagerService extends SystemService {
@NonNull String packageName, @NonNull String packageName,
@NonNull String databaseName, @NonNull String databaseName,
@NonNull ParcelFileDescriptor fileDescriptor, @NonNull ParcelFileDescriptor fileDescriptor,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
Objects.requireNonNull(fileDescriptor);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
GenericDocument document; GenericDocument document;
ArrayList<Bundle> migrationFailureBundles = new ArrayList<>(); ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
@@ -835,24 +865,26 @@ public class AppSearchManagerService extends SystemService {
@NonNull String documentId, @NonNull String documentId,
long usageTimeMillis, long usageTimeMillis,
boolean systemUsage, boolean systemUsage,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(namespace); Objects.requireNonNull(namespace);
Objects.requireNonNull(documentId); Objects.requireNonNull(documentId);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
if (systemUsage) { if (systemUsage) {
// TODO(b/183031844): Validate that the call comes from the system // TODO(b/183031844): Validate that the call comes from the system
} }
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
impl.reportUsage( impl.reportUsage(
packageName, databaseName, namespace, documentId, packageName, databaseName, namespace, documentId,
usageTimeMillis, systemUsage); usageTimeMillis, systemUsage);
@@ -870,29 +902,31 @@ public class AppSearchManagerService extends SystemService {
@NonNull String databaseName, @NonNull String databaseName,
@NonNull String namespace, @NonNull String namespace,
@NonNull List<String> ids, @NonNull List<String> ids,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchBatchResultCallback callback) { @NonNull IAppSearchBatchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(namespace);
Objects.requireNonNull(ids); Objects.requireNonNull(ids);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchBatchResult.Builder<String, Void> resultBuilder = AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
for (int i = 0; i < ids.size(); i++) { for (int i = 0; i < ids.size(); i++) {
String id = ids.get(i); String id = ids.get(i);
try { try {
@@ -945,7 +979,7 @@ public class AppSearchManagerService extends SystemService {
@NonNull String databaseName, @NonNull String databaseName,
@NonNull String queryExpression, @NonNull String queryExpression,
@NonNull Bundle searchSpecBundle, @NonNull Bundle searchSpecBundle,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
// TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
@@ -953,21 +987,22 @@ public class AppSearchManagerService extends SystemService {
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(queryExpression); Objects.requireNonNull(queryExpression);
Objects.requireNonNull(searchSpecBundle); Objects.requireNonNull(searchSpecBundle);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
impl.removeByQuery( impl.removeByQuery(
packageName, packageName,
databaseName, databaseName,
@@ -1009,19 +1044,20 @@ public class AppSearchManagerService extends SystemService {
public void getStorageInfo( public void getStorageInfo(
@NonNull String packageName, @NonNull String packageName,
@NonNull String databaseName, @NonNull String databaseName,
@UserIdInt int userId, @NonNull UserHandle userHandle,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName); Objects.requireNonNull(databaseName);
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUser, callingUid, packageName);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId);
StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName, StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
databaseName); databaseName);
Bundle storageInfoBundle = storageInfo.getBundle(); Bundle storageInfoBundle = storageInfo.getBundle();
@@ -1034,21 +1070,23 @@ public class AppSearchManagerService extends SystemService {
} }
@Override @Override
public void persistToDisk(@UserIdInt int userId, public void persistToDisk(
@NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis) { @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Objects.requireNonNull(userHandle);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
AppSearchImpl impl = AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
mImplInstanceManager.getAppSearchImpl(callingUserId); logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
impl.persistToDisk(PersistType.Code.FULL); impl.persistToDisk(PersistType.Code.FULL);
++operationSuccessCount; ++operationSuccessCount;
} catch (Throwable t) { } catch (Throwable t) {
@@ -1080,23 +1118,26 @@ public class AppSearchManagerService extends SystemService {
} }
@Override @Override
public void initialize(@UserIdInt int userId, public void initialize(
@NonNull UserHandle userHandle,
@ElapsedRealtimeLong long binderCallStartTimeMillis, @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchResultCallback callback) { @NonNull IAppSearchResultCallback callback) {
Objects.requireNonNull(userHandle);
Objects.requireNonNull(callback); Objects.requireNonNull(callback);
long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
int callingUid = Binder.getCallingUid(); int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid); UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
EXECUTOR.execute(() -> { EXECUTOR.execute(() -> {
@AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
PlatformLogger logger = null; PlatformLogger logger = null;
int operationSuccessCount = 0; int operationSuccessCount = 0;
int operationFailureCount = 0; int operationFailureCount = 0;
try { try {
verifyUserUnlocked(callingUserId); verifyUserUnlocked(callingUser);
logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
callingUserId); mContext, callingUser);
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId, logger); mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
++operationSuccessCount; ++operationSuccessCount;
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
} catch (Throwable t) { } catch (Throwable t) {
@@ -1129,16 +1170,29 @@ public class AppSearchManagerService extends SystemService {
}); });
} }
private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) { private void verifyCallingPackage(
Objects.requireNonNull(callingPackage); @NonNull UserHandle actualCallingUser,
if (mPackageManagerInternal.getPackageUid( int actualCallingUid,
callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid)) @NonNull String claimedCallingPackage) {
!= callingUid) { Objects.requireNonNull(actualCallingUser);
Objects.requireNonNull(claimedCallingPackage);
int claimedCallingUid;
try {
Context claimedCallingContext =
mContext.createContextAsUser(actualCallingUser, /*flags=*/ 0);
claimedCallingUid = claimedCallingContext.getPackageManager().getPackageUid(
claimedCallingPackage, /*flags=*/ 0);
} catch (PackageManager.NameNotFoundException e) {
throw new SecurityException(
"Specified calling package [" + claimedCallingPackage + "] not found");
}
if (claimedCallingUid != actualCallingUid) {
throw new SecurityException( throw new SecurityException(
"Specified calling package [" "Specified calling package ["
+ callingPackage + claimedCallingPackage
+ "] does not match the calling uid " + "] does not match the calling uid "
+ callingUid); + actualCallingUid);
} }
} }
@@ -1192,19 +1246,28 @@ public class AppSearchManagerService extends SystemService {
} }
} }
/**
* Helper for dealing with incoming user arguments to system service calls.
*
* <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
*
* @return the user handle that the call should run as. Will always be a concrete user.
*/
// TODO(b/173553485) verifying that the caller has permission to access target user's data // TODO(b/173553485) verifying that the caller has permission to access target user's data
// TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
// TODO(b/173553485) Implement SystemService.onUserStopping() // TODO(b/173553485) Implement SystemService.onUserStopping()
private static int handleIncomingUser(@UserIdInt int userId, int callingUid) { @NonNull
private static UserHandle handleIncomingUser(@NonNull UserHandle userHandle, int callingUid) {
int callingPid = Binder.getCallingPid(); int callingPid = Binder.getCallingPid();
return ActivityManager.handleIncomingUser( int finalUserId = ActivityManager.handleIncomingUser(
callingPid, callingPid,
callingUid, callingUid,
userId, userHandle.getIdentifier(),
/*allowAll=*/ false, /*allowAll=*/ false,
/*requireFull=*/ false, /*requireFull=*/ false,
/*name=*/ null, /*name=*/ null,
/*callerPackage=*/ null); /*callerPackage=*/ null);
return UserHandle.of(finalUserId);
} }
// TODO(b/179160886): Cache the previous storage stats. // TODO(b/179160886): Cache the previous storage stats.
@@ -1218,19 +1281,19 @@ public class AppSearchManagerService extends SystemService {
Objects.requireNonNull(stats); Objects.requireNonNull(stats);
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
int userId = userHandle.getIdentifier();
try { try {
verifyUserUnlocked(userId); verifyUserUnlocked(userHandle);
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
userId); mContext, userHandle);
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
userId, logger); mContext, userHandle, logger);
stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes(); stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
} catch (Throwable t) { } catch (Throwable t) {
Log.e( Log.e(
TAG, TAG,
"Unable to augment storage stats for userId " "Unable to augment storage stats for "
+ userId + userHandle
+ " packageName " + " packageName "
+ packageName, + packageName,
t); t);
@@ -1241,17 +1304,18 @@ public class AppSearchManagerService extends SystemService {
public void augmentStatsForUid( public void augmentStatsForUid(
@NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) { @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
Objects.requireNonNull(stats); Objects.requireNonNull(stats);
int userId = UserHandle.getUserId(uid);
UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
try { try {
verifyUserUnlocked(userId); verifyUserUnlocked(userHandle);
String[] packagesForUid = mPackageManager.getPackagesForUid(uid); String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
if (packagesForUid == null) { if (packagesForUid == null) {
return; return;
} }
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
userId); mContext, userHandle);
AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
userId, logger); mContext, userHandle, logger);
for (int i = 0; i < packagesForUid.length; i++) { for (int i = 0; i < packagesForUid.length; i++) {
stats.dataSize += stats.dataSize +=
impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes(); impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
@@ -1269,24 +1333,24 @@ public class AppSearchManagerService extends SystemService {
// size of the icing dir (or use the overall StorageInfo without interpolating it). // size of the icing dir (or use the overall StorageInfo without interpolating it).
Objects.requireNonNull(stats); Objects.requireNonNull(stats);
Objects.requireNonNull(userHandle); Objects.requireNonNull(userHandle);
int userId = userHandle.getIdentifier();
try { try {
verifyUserUnlocked(userId); verifyUserUnlocked(userHandle);
List<PackageInfo> packagesForUser = List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
mPackageManager.getInstalledPackagesAsUser(/*flags=*/0, userId); /*flags=*/0, userHandle.getIdentifier());
if (packagesForUser == null) { if (packagesForUser == null) {
return; return;
} }
PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
userId); mContext, userHandle);
AppSearchImpl impl = AppSearchImpl impl =
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userId, logger); mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
for (int i = 0; i < packagesForUser.size(); i++) { for (int i = 0; i < packagesForUser.size(); i++) {
String packageName = packagesForUser.get(i).packageName; String packageName = packagesForUser.get(i).packageName;
stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes(); stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
} }
} catch (Throwable t) { } catch (Throwable t) {
Log.e(TAG, "Unable to augment storage stats for user " + userId, t); Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
} }
} }
} }

View File

@@ -20,13 +20,12 @@ import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.appsearch.exceptions.AppSearchException; import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Environment; import android.os.Environment;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.SparseArray; import android.util.ArrayMap;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
@@ -34,6 +33,8 @@ import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.AppSearchLogger; import com.android.server.appsearch.external.localstorage.AppSearchLogger;
import java.io.File; import java.io.File;
import java.util.Map;
import java.util.Objects;
/** /**
* Manages the lifecycle of instances of {@link AppSearchImpl}. * Manages the lifecycle of instances of {@link AppSearchImpl}.
@@ -46,7 +47,7 @@ public final class ImplInstanceManager {
private static ImplInstanceManager sImplInstanceManager; private static ImplInstanceManager sImplInstanceManager;
@GuardedBy("mInstancesLocked") @GuardedBy("mInstancesLocked")
private final SparseArray<AppSearchImpl> mInstancesLocked = new SparseArray<>(); private final Map<UserHandle, AppSearchImpl> mInstancesLocked = new ArrayMap<>();
private final String mGlobalQuerierPackage; private final String mGlobalQuerierPackage;
@@ -79,8 +80,9 @@ public final class ImplInstanceManager {
* *
* <p>This folder should only be accessed after unlock. * <p>This folder should only be accessed after unlock.
*/ */
public static File getAppSearchDir(@UserIdInt int userId) { public static File getAppSearchDir(@NonNull UserHandle userHandle) {
return new File(Environment.getDataSystemCeDirectory(userId), APP_SEARCH_DIR); return new File(
Environment.getDataSystemCeDirectory(userHandle.getIdentifier()), APP_SEARCH_DIR);
} }
/** /**
@@ -90,18 +92,22 @@ public final class ImplInstanceManager {
* one will be created. * one will be created.
* *
* @param context The context * @param context The context
* @param userId The multi-user userId of the device user calling AppSearch * @param userHandle The multi-user handle of the device user calling AppSearch
* @return An initialized {@link AppSearchImpl} for this user * @return An initialized {@link AppSearchImpl} for this user
*/ */
@NonNull @NonNull
public AppSearchImpl getOrCreateAppSearchImpl( public AppSearchImpl getOrCreateAppSearchImpl(
@NonNull Context context, @UserIdInt int userId, @Nullable AppSearchLogger logger) @NonNull Context context,
throws AppSearchException { @NonNull UserHandle userHandle,
@Nullable AppSearchLogger logger) throws AppSearchException {
Objects.requireNonNull(context);
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
AppSearchImpl instance = mInstancesLocked.get(userId); AppSearchImpl instance = mInstancesLocked.get(userHandle);
if (instance == null) { if (instance == null) {
instance = createImpl(context, userId, logger); instance = createImpl(context, userHandle, logger);
mInstancesLocked.put(userId, instance); mInstancesLocked.put(userHandle, instance);
} }
return instance; return instance;
} }
@@ -116,12 +122,13 @@ public final class ImplInstanceManager {
* <p>If the user is removed, the "credential encrypted" system directory where icing lives will * <p>If the user is removed, the "credential encrypted" system directory where icing lives will
* be auto-deleted. So we shouldn't worry about persist data or close the AppSearchImpl. * be auto-deleted. So we shouldn't worry about persist data or close the AppSearchImpl.
* *
* @param userId The multi-user userId of the user that need to be removed. * @param userHandle The multi-user user handle of the user that need to be removed.
*/ */
public void removeAppSearchImplForUser(@UserIdInt int userId) { public void removeAppSearchImplForUser(@NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
// no need to close and persist data to disk since we are removing them now. // no need to close and persist data to disk since we are removing them now.
mInstancesLocked.remove(userId); mInstancesLocked.remove(userHandle);
} }
} }
@@ -130,14 +137,15 @@ public final class ImplInstanceManager {
* *
* <p>All mutation apply to this {@link AppSearchImpl} will be persisted to disk. * <p>All mutation apply to this {@link AppSearchImpl} will be persisted to disk.
* *
* @param userId The multi-user userId of the user that need to be removed. * @param userHandle The multi-user user handle of the user that need to be removed.
*/ */
public void closeAndRemoveAppSearchImplForUser(@UserIdInt int userId) { public void closeAndRemoveAppSearchImplForUser(@NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
AppSearchImpl appSearchImpl = mInstancesLocked.get(userId); AppSearchImpl appSearchImpl = mInstancesLocked.get(userHandle);
if (appSearchImpl != null) { if (appSearchImpl != null) {
appSearchImpl.close(); appSearchImpl.close();
mInstancesLocked.remove(userId); mInstancesLocked.remove(userHandle);
} }
} }
} }
@@ -148,31 +156,39 @@ public final class ImplInstanceManager {
* <p>This method should only be called by an initialized SearchSession, which has been already * <p>This method should only be called by an initialized SearchSession, which has been already
* created the AppSearchImpl instance for the given user. * created the AppSearchImpl instance for the given user.
* *
* @param userId The multi-user userId of the device user calling AppSearch * @param userHandle The multi-user handle of the device user calling AppSearch
* @return An initialized {@link AppSearchImpl} for this user * @return An initialized {@link AppSearchImpl} for this user
* @throws IllegalStateException if {@link AppSearchImpl} haven't created for the given user. * @throws IllegalStateException if {@link AppSearchImpl} haven't created for the given user.
*/ */
@NonNull @NonNull
public AppSearchImpl getAppSearchImpl(@UserIdInt int userId) { public AppSearchImpl getAppSearchImpl(@NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
AppSearchImpl instance = mInstancesLocked.get(userId); AppSearchImpl instance = mInstancesLocked.get(userHandle);
if (instance == null) { if (instance == null) {
// Impossible scenario, user cannot call an uninitialized SearchSession, // Impossible scenario, user cannot call an uninitialized SearchSession,
// getInstance should always find the instance for the given user and never try to // getInstance should always find the instance for the given user and never try to
// create an instance for this user again. // create an instance for this user again.
throw new IllegalStateException( throw new IllegalStateException(
"AppSearchImpl has never been created for this user: " + userId); "AppSearchImpl has never been created for: " + userHandle);
} }
return instance; return instance;
} }
} }
private AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId, private AppSearchImpl createImpl(
@NonNull Context context,
@NonNull UserHandle userHandle,
@Nullable AppSearchLogger logger) @Nullable AppSearchLogger logger)
throws AppSearchException { throws AppSearchException {
File appSearchDir = getAppSearchDir(userId); File appSearchDir = getAppSearchDir(userHandle);
// TODO(b/181787682): Swap AppSearchImpl and VisibilityStore to accept a UserHandle too
return AppSearchImpl.create( return AppSearchImpl.create(
appSearchDir, context, userId, mGlobalQuerierPackage, logger); appSearchDir,
context,
userHandle.getIdentifier(),
mGlobalQuerierPackage,
/*logger=*/ null);
} }
/** /**

View File

@@ -17,14 +17,17 @@
package com.android.server.appsearch.stats; package com.android.server.appsearch.stats;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.Context; import android.content.Context;
import android.util.SparseArray; import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.server.appsearch.AppSearchManagerService; import com.android.server.appsearch.AppSearchManagerService;
import java.util.Map;
import java.util.Objects;
/** /**
* Manages the lifecycle of instances of {@link PlatformLogger}. * Manages the lifecycle of instances of {@link PlatformLogger}.
* *
@@ -40,7 +43,7 @@ public final class LoggerInstanceManager {
private static volatile LoggerInstanceManager sLoggerInstanceManager; private static volatile LoggerInstanceManager sLoggerInstanceManager;
@GuardedBy("mInstancesLocked") @GuardedBy("mInstancesLocked")
private final SparseArray<PlatformLogger> mInstancesLocked = new SparseArray<>(); private final Map<UserHandle, PlatformLogger> mInstancesLocked = new ArrayMap<>();
private LoggerInstanceManager() { private LoggerInstanceManager() {
} }
@@ -68,48 +71,49 @@ public final class LoggerInstanceManager {
* Gets an instance of PlatformLogger for the given user, or creates one if none exists. * Gets an instance of PlatformLogger for the given user, or creates one if none exists.
* *
* @param context The context * @param context The context
* @param userId The multi-user userId of the device user calling AppSearch * @param userHandle The multi-user handle of the device user calling AppSearch
* @return An initialized {@link PlatformLogger} for this user * @return An initialized {@link PlatformLogger} for this user
*/ */
@NonNull @NonNull
public PlatformLogger getOrCreatePlatformLogger( public PlatformLogger getOrCreatePlatformLogger(
@NonNull Context context, @UserIdInt int userId) { @NonNull Context context, @NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
PlatformLogger instance = mInstancesLocked.get(userId); PlatformLogger instance = mInstancesLocked.get(userHandle);
if (instance == null) { if (instance == null) {
instance = new PlatformLogger(context, userId, new PlatformLogger.Config( instance = new PlatformLogger(context, userHandle, new PlatformLogger.Config(
MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
DEFAULT_SAMPLING_RATIO, DEFAULT_SAMPLING_RATIO,
// TODO(b/173532925) re-enable sampling ratios for different stats types // TODO(b/173532925) re-enable sampling ratios for different stats types
// once we have P/H flag manager setup in ag/13977824 // once we have P/H flag manager setup in ag/13977824
/*samplingRatios=*/ new SparseIntArray())); /*samplingRatios=*/ new SparseIntArray()));
mInstancesLocked.put(userId, instance); mInstancesLocked.put(userHandle, instance);
} }
return instance; return instance;
} }
} }
/** /**
* Gets an instance of PlatformLogger for the given user. * Gets an instance of PlatformLogger for the given user.
* *
* <p>This method should only be called by an initialized SearchSession, which has been already * <p>This method should only be called by an initialized SearchSession, which has been already
* created the PlatformLogger instance for the given user. * created the PlatformLogger instance for the given user.
* *
* @param userId The multi-user userId of the device user calling AppSearch * @param userHandle The multi-user handle of the device user calling AppSearch
* @return An initialized {@link PlatformLogger} for this user * @return An initialized {@link PlatformLogger} for this user
* @throws IllegalStateException if {@link PlatformLogger} haven't created for the given user. * @throws IllegalStateException if {@link PlatformLogger} haven't created for the given user.
*/ */
@NonNull @NonNull
public PlatformLogger getPlatformLogger(@UserIdInt int userId) { public PlatformLogger getPlatformLogger(@NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
PlatformLogger instance = mInstancesLocked.get(userId); PlatformLogger instance = mInstancesLocked.get(userHandle);
if (instance == null) { if (instance == null) {
// Impossible scenario, user cannot call an uninitialized SearchSession, // Impossible scenario, user cannot call an uninitialized SearchSession,
// getInstance should always find the instance for the given user and never try to // getInstance should always find the instance for the given user and never try to
// create an instance for this user again. // create an instance for this user again.
throw new IllegalStateException( throw new IllegalStateException(
"PlatformLogger has never been created for this user: " + userId); "PlatformLogger has never been created for: " + userHandle);
} }
return instance; return instance;
} }
@@ -121,11 +125,12 @@ public final class LoggerInstanceManager {
* <p>This method should only be called if {@link AppSearchManagerService} receives an * <p>This method should only be called if {@link AppSearchManagerService} receives an
* ACTION_USER_REMOVED, which the logger instance of given user should be removed. * ACTION_USER_REMOVED, which the logger instance of given user should be removed.
* *
* @param userId The multi-user userId of the user that need to be removed. * @param userHandle The multi-user handle of the user that need to be removed.
*/ */
public void removePlatformLoggerForUser(@UserIdInt int userId) { public void removePlatformLoggerForUser(@NonNull UserHandle userHandle) {
Objects.requireNonNull(userHandle);
synchronized (mInstancesLocked) { synchronized (mInstancesLocked) {
mInstancesLocked.remove(userId); mInstancesLocked.remove(userHandle);
} }
} }
} }

View File

@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Process; import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import android.util.SparseIntArray; import android.util.SparseIntArray;
@@ -56,8 +57,8 @@ public final class PlatformLogger implements AppSearchLogger {
// Context of the system service. // Context of the system service.
private final Context mContext; private final Context mContext;
// User ID of the caller who we're logging for. // User we're logging for.
private final int mUserId; private final UserHandle mUserHandle;
// Configuration for the logger // Configuration for the logger
private final Config mConfig; private final Config mConfig;
@@ -164,10 +165,11 @@ public final class PlatformLogger implements AppSearchLogger {
/** /**
* Westworld constructor * Westworld constructor
*/ */
public PlatformLogger(@NonNull Context context, int userId, @NonNull Config config) { public PlatformLogger(
@NonNull Context context, @NonNull UserHandle userHandle, @NonNull Config config) {
mContext = Objects.requireNonNull(context); mContext = Objects.requireNonNull(context);
mUserHandle = Objects.requireNonNull(userHandle);
mConfig = Objects.requireNonNull(config); mConfig = Objects.requireNonNull(config);
mUserId = userId;
} }
/** Logs {@link CallStats}. */ /** Logs {@link CallStats}. */
@@ -493,7 +495,8 @@ public final class PlatformLogger implements AppSearchLogger {
// TODO(b/173532925) since VisibilityStore has the same method, we can make this a // TODO(b/173532925) since VisibilityStore has the same method, we can make this a
// utility function // utility function
try { try {
packageUid = mContext.getPackageManager().getPackageUidAsUser(packageName, mUserId); packageUid = mContext.getPackageManager().getPackageUidAsUser(
packageName, mUserHandle.getIdentifier());
mPackageUidCacheLocked.put(packageName, packageUid); mPackageUidCacheLocked.put(packageName, packageUid);
return packageUid; return packageUid;
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {

View File

@@ -75,7 +75,7 @@ public class PlatformLoggerTest {
public void testCreateExtraStatsLocked_nullSamplingRatioMap_returnsDefaultSamplingRatio() { public void testCreateExtraStatsLocked_nullSamplingRatioMap_returnsDefaultSamplingRatio() {
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL, UserHandle.of(UserHandle.USER_NULL),
new PlatformLogger.Config( new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
TEST_DEFAULT_SAMPLING_RATIO, TEST_DEFAULT_SAMPLING_RATIO,
@@ -106,7 +106,7 @@ public class PlatformLoggerTest {
samplingRatios.put(CallStats.CALL_TYPE_SEARCH, querySamplingRatio); samplingRatios.put(CallStats.CALL_TYPE_SEARCH, querySamplingRatio);
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL, UserHandle.of(UserHandle.USER_NULL),
new PlatformLogger.Config( new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
TEST_DEFAULT_SAMPLING_RATIO, TEST_DEFAULT_SAMPLING_RATIO,
@@ -207,7 +207,7 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL, UserHandle.of(UserHandle.USER_NULL),
new PlatformLogger.Config( new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
samplingRatio, samplingRatio,
@@ -225,7 +225,7 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL, UserHandle.of(UserHandle.USER_NULL),
new PlatformLogger.Config( new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
samplingRatio, samplingRatio,
@@ -247,7 +247,7 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL, UserHandle.of(UserHandle.USER_NULL),
new PlatformLogger.Config( new PlatformLogger.Config(
minTimeIntervalBetweenSamplesMillis, minTimeIntervalBetweenSamplesMillis,
samplingRatio, samplingRatio,
@@ -269,7 +269,7 @@ public class PlatformLoggerTest {
final String testPackageName = "packageName"; final String testPackageName = "packageName";
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL, UserHandle.of(UserHandle.USER_NULL),
new PlatformLogger.Config( new PlatformLogger.Config(
minTimeIntervalBetweenSamplesMillis, minTimeIntervalBetweenSamplesMillis,
samplingRatio, samplingRatio,
@@ -289,7 +289,7 @@ public class PlatformLoggerTest {
final int testUid = 1234; final int testUid = 1234;
PlatformLogger logger = new PlatformLogger( PlatformLogger logger = new PlatformLogger(
mContext, mContext,
mContext.getUserId(), mContext.getUser(),
new PlatformLogger.Config( new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
TEST_DEFAULT_SAMPLING_RATIO, TEST_DEFAULT_SAMPLING_RATIO,

View File

@@ -653,15 +653,15 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
new ArrayMap<>(1); new ArrayMap<>(1);
private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1); private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1);
private String getKey(int userId, String databaseName) { private String getKey(UserHandle userHandle, String databaseName) {
return new StringBuilder().append(userId).append("@").append(databaseName).toString(); return userHandle.getIdentifier() + "@" + databaseName;
} }
@Override @Override
public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles, public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles,
List<String> schemasNotPlatformSurfaceable, List<String> schemasNotPlatformSurfaceable,
Map<String, List<Bundle>> schemasPackageAccessibleBundles, boolean forceOverride, Map<String, List<Bundle>> schemasPackageAccessibleBundles, boolean forceOverride,
int userId, int version, long binderCallStartTimeMillis, int version, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchResultCallback callback) throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
for (Map.Entry<String, List<Bundle>> entry : for (Map.Entry<String, List<Bundle>> entry :
schemasPackageAccessibleBundles.entrySet()) { schemasPackageAccessibleBundles.entrySet()) {
@@ -684,20 +684,20 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
@Override @Override
public void getSchema(String packageName, String databaseName, int userId, public void getSchema(String packageName, String databaseName, UserHandle userHandle,
IAppSearchResultCallback callback) throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
ignore(callback); ignore(callback);
} }
@Override @Override
public void getNamespaces(String packageName, String databaseName, int userId, public void getNamespaces(String packageName, String databaseName, UserHandle userHandle,
IAppSearchResultCallback callback) throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
ignore(callback); ignore(callback);
} }
@Override @Override
public void putDocuments(String packageName, String databaseName, public void putDocuments(String packageName, String databaseName,
List<Bundle> documentBundles, int userId, long binderCallStartTimeMillis, List<Bundle> documentBundles, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchBatchResultCallback callback) IAppSearchBatchResultCallback callback)
throws RemoteException { throws RemoteException {
final List<GenericDocument> docs = new ArrayList<>(documentBundles.size()); final List<GenericDocument> docs = new ArrayList<>(documentBundles.size());
@@ -706,7 +706,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
final AppSearchBatchResult.Builder<String, Void> builder = final AppSearchBatchResult.Builder<String, Void> builder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
final String key = getKey(userId, databaseName); final String key = getKey(userHandle, databaseName);
Map<String, GenericDocument> docMap = mDocumentMap.get(key); Map<String, GenericDocument> docMap = mDocumentMap.get(key);
for (GenericDocument doc : docs) { for (GenericDocument doc : docs) {
builder.setSuccess(doc.getId(), null); builder.setSuccess(doc.getId(), null);
@@ -721,12 +721,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override @Override
public void getDocuments(String packageName, String databaseName, String namespace, public void getDocuments(String packageName, String databaseName, String namespace,
List<String> ids, Map<String, List<String>> typePropertyPaths, int userId, List<String> ids, Map<String, List<String>> typePropertyPaths,
long binderCallStartTimeMillis, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchBatchResultCallback callback) throws RemoteException { IAppSearchBatchResultCallback callback) throws RemoteException {
final AppSearchBatchResult.Builder<String, Bundle> builder = final AppSearchBatchResult.Builder<String, Bundle> builder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
final String key = getKey(userId, databaseName); final String key = getKey(userHandle, databaseName);
if (!mDocumentMap.containsKey(key)) { if (!mDocumentMap.containsKey(key)) {
for (String id : ids) { for (String id : ids) {
builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND, builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND,
@@ -748,10 +748,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override @Override
public void query(String packageName, String databaseName, String queryExpression, public void query(String packageName, String databaseName, String queryExpression,
Bundle searchSpecBundle, int userId, long binderCallStartTimeMillis, Bundle searchSpecBundle, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchResultCallback callback) IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
final String key = getKey(userId, databaseName); final String key = getKey(userHandle, databaseName);
if (!mDocumentMap.containsKey(key)) { if (!mDocumentMap.containsKey(key)) {
final Bundle page = new Bundle(); final Bundle page = new Bundle();
page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1);
@@ -779,14 +779,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override @Override
public void globalQuery(String packageName, String queryExpression, Bundle searchSpecBundle, public void globalQuery(String packageName, String queryExpression, Bundle searchSpecBundle,
int userId, long binderCallStartTimeMillis, IAppSearchResultCallback callback) UserHandle userHandle, long binderCallStartTimeMillis,
throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
ignore(callback); ignore(callback);
} }
@Override @Override
public void getNextPage(long nextPageToken, int userId, IAppSearchResultCallback callback) public void getNextPage(long nextPageToken, UserHandle userHandle,
throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
final Bundle page = new Bundle(); final Bundle page = new Bundle();
page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1);
page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>()); page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>());
@@ -795,28 +795,30 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
@Override @Override
public void invalidateNextPageToken(long nextPageToken, int userId) throws RemoteException { public void invalidateNextPageToken(long nextPageToken, UserHandle userHandle)
throws RemoteException {
} }
@Override @Override
public void writeQueryResultsToFile(String packageName, String databaseName, public void writeQueryResultsToFile(String packageName, String databaseName,
ParcelFileDescriptor fileDescriptor, String queryExpression, ParcelFileDescriptor fileDescriptor, String queryExpression,
Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) Bundle searchSpecBundle, UserHandle userHandle, IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
ignore(callback); ignore(callback);
} }
@Override @Override
public void putDocumentsFromFile(String packageName, String databaseName, public void putDocumentsFromFile(String packageName, String databaseName,
ParcelFileDescriptor fileDescriptor, int userId, IAppSearchResultCallback callback) ParcelFileDescriptor fileDescriptor, UserHandle userHandle,
IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
ignore(callback); ignore(callback);
} }
@Override @Override
public void reportUsage(String packageName, String databaseName, String namespace, public void reportUsage(String packageName, String databaseName, String namespace,
String documentId, long usageTimestampMillis, boolean systemUsage, int userId, String documentId, long usageTimestampMillis, boolean systemUsage,
UserHandle userHandle,
IAppSearchResultCallback callback) IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
ignore(callback); ignore(callback);
@@ -824,12 +826,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override @Override
public void removeByDocumentId(String packageName, String databaseName, String namespace, public void removeByDocumentId(String packageName, String databaseName, String namespace,
List<String> ids, int userId, long binderCallStartTimeMillis, List<String> ids, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchBatchResultCallback callback) IAppSearchBatchResultCallback callback)
throws RemoteException { throws RemoteException {
final AppSearchBatchResult.Builder<String, Void> builder = final AppSearchBatchResult.Builder<String, Void> builder =
new AppSearchBatchResult.Builder<>(); new AppSearchBatchResult.Builder<>();
final String key = getKey(userId, databaseName); final String key = getKey(userHandle, databaseName);
if (!mDocumentMap.containsKey(key)) { if (!mDocumentMap.containsKey(key)) {
for (String id : ids) { for (String id : ids) {
builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND, builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND,
@@ -852,10 +854,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override @Override
public void removeByQuery(String packageName, String databaseName, String queryExpression, public void removeByQuery(String packageName, String databaseName, String queryExpression,
Bundle searchSpecBundle, int userId, long binderCallStartTimeMillis, Bundle searchSpecBundle, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchResultCallback callback) IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
final String key = getKey(userId, databaseName); final String key = getKey(userHandle, databaseName);
if (!mDocumentMap.containsKey(key)) { if (!mDocumentMap.containsKey(key)) {
callback.onResult( callback.onResult(
new AppSearchResultParcel<>(AppSearchResult.newSuccessfulResult(null))); new AppSearchResultParcel<>(AppSearchResult.newSuccessfulResult(null)));
@@ -867,19 +869,18 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
} }
@Override @Override
public void getStorageInfo(String packageName, String databaseName, int userId, public void getStorageInfo(String packageName, String databaseName, UserHandle userHandle,
IAppSearchResultCallback callback) throws RemoteException { IAppSearchResultCallback callback) throws RemoteException {
ignore(callback); ignore(callback);
} }
@Override @Override
public void persistToDisk(int userId, long binderCallStartTimeMillis) public void persistToDisk(UserHandle userHandle, long binderCallStartTimeMillis)
throws RemoteException { throws RemoteException {
} }
@Override @Override
public void initialize(int userId, long binderCallStartTimeMillis, public void initialize(UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchResultCallback callback) IAppSearchResultCallback callback)
throws RemoteException { throws RemoteException {
ignore(callback); ignore(callback);