diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java index 59b940a460d38..3c70276cd5050 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java @@ -205,7 +205,7 @@ public class AppSearchManager { AppSearchSession.createSearchSession( searchContext, mService, - mContext.getUser().getIdentifier(), + mContext.getUser(), getPackageName(), executor, callback); @@ -228,7 +228,7 @@ public class AppSearchManager { Objects.requireNonNull(executor); Objects.requireNonNull(callback); 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. */ diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java index 353051c9423b4..c7385047a6eaa 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java @@ -21,7 +21,6 @@ import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; import android.annotation.NonNull; -import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.IAppSearchManager; @@ -31,6 +30,7 @@ import android.os.Bundle; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.os.UserHandle; import android.util.ArraySet; import java.io.Closeable; @@ -57,20 +57,20 @@ public class AppSearchMigrationHelper implements Closeable { private final IAppSearchManager mService; private final String mPackageName; private final String mDatabaseName; - private final int mUserId; + private final UserHandle mUserHandle; private final File mMigratedFile; private final Set mDestinationTypes; private boolean mAreDocumentsMigrated = false; AppSearchMigrationHelper(@NonNull IAppSearchManager service, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull String packageName, @NonNull String databaseName, @NonNull Set newSchemas) throws IOException { mService = Objects.requireNonNull(service); + mUserHandle = Objects.requireNonNull(userHandle); mPackageName = Objects.requireNonNull(packageName); mDatabaseName = Objects.requireNonNull(databaseName); - mUserId = userId; mMigratedFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null); mDestinationTypes = new ArraySet<>(newSchemas.size()); for (AppSearchSchema newSchema : newSchemas) { @@ -105,7 +105,7 @@ public class AppSearchMigrationHelper implements Closeable { .addFilterSchemas(schemaType) .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY) .build().getBundle(), - mUserId, + mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { @@ -145,7 +145,7 @@ public class AppSearchMigrationHelper implements Closeable { try (ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(mMigratedFile, MODE_READ_ONLY)) { CompletableFuture>> future = new CompletableFuture<>(); - mService.putDocumentsFromFile(mPackageName, mDatabaseName, fileDescriptor, mUserId, + mService.putDocumentsFromFile(mPackageName, mDatabaseName, fileDescriptor, mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java index 43bf08d5c6604..4ef91b5e3bc11 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java @@ -18,7 +18,6 @@ package android.app.appsearch; import android.annotation.CallbackExecutor; import android.annotation.NonNull; -import android.annotation.UserIdInt; import android.app.appsearch.aidl.AppSearchBatchResultParcel; import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.IAppSearchBatchResultCallback; @@ -30,6 +29,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; @@ -61,26 +61,25 @@ public final class AppSearchSession implements Closeable { private final String mPackageName; private final String mDatabaseName; - @UserIdInt - private final int mUserId; + private final UserHandle mUserHandle; private final IAppSearchManager mService; private boolean mIsMutated = 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}. */ static void createSearchSession( @NonNull AppSearchManager.SearchContext searchContext, @NonNull IAppSearchManager service, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull String packageName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer> callback) { AppSearchSession searchSession = - new AppSearchSession(service, userId, packageName, searchContext.mDatabaseName); + new AppSearchSession(service, userHandle, packageName, searchContext.mDatabaseName); searchSession.initialize(executor, callback); } @@ -90,7 +89,8 @@ public final class AppSearchSession implements Closeable { @NonNull @CallbackExecutor Executor executor, @NonNull Consumer> callback) { try { - mService.initialize(mUserId, + mService.initialize( + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @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) { mService = service; - mUserId = userId; + mUserHandle = userHandle; mPackageName = packageName; mDatabaseName = databaseName; } @@ -199,7 +199,7 @@ public final class AppSearchSession implements Closeable { mService.getSchema( mPackageName, mDatabaseName, - mUserId, + mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { @@ -236,7 +236,7 @@ public final class AppSearchSession implements Closeable { mService.getNamespaces( mPackageName, mDatabaseName, - mUserId, + mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { @@ -289,7 +289,7 @@ public final class AppSearchSession implements Closeable { documentBundles.add(documents.get(i).getBundle()); } try { - mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserId, + mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchBatchResultCallback.Stub() { @Override @@ -352,7 +352,7 @@ public final class AppSearchSession implements Closeable { request.getNamespace(), new ArrayList<>(request.getIds()), request.getProjectionsInternal(), - mUserId, + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchBatchResultCallback.Stub() { @Override @@ -472,7 +472,7 @@ public final class AppSearchSession implements Closeable { Objects.requireNonNull(searchSpec); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); return new SearchResults(mService, mPackageName, mDatabaseName, queryExpression, - searchSpec, mUserId); + searchSpec, mUserHandle); } /** @@ -508,7 +508,7 @@ public final class AppSearchSession implements Closeable { request.getDocumentId(), request.getUsageTimestampMillis(), /*systemUsage=*/ false, - mUserId, + mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { @@ -565,8 +565,12 @@ public final class AppSearchSession implements Closeable { Objects.requireNonNull(callback); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); try { - mService.removeByDocumentId(mPackageName, mDatabaseName, request.getNamespace(), - new ArrayList<>(request.getIds()), mUserId, + mService.removeByDocumentId( + mPackageName, + mDatabaseName, + request.getNamespace(), + new ArrayList<>(request.getIds()), + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchBatchResultCallback.Stub() { @Override @@ -616,8 +620,12 @@ public final class AppSearchSession implements Closeable { Objects.requireNonNull(callback); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); try { - mService.removeByQuery(mPackageName, mDatabaseName, queryExpression, - searchSpec.getBundle(), mUserId, + mService.removeByQuery( + mPackageName, + mDatabaseName, + queryExpression, + searchSpec.getBundle(), + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @Override @@ -650,7 +658,7 @@ public final class AppSearchSession implements Closeable { mService.getStorageInfo( mPackageName, mDatabaseName, - mUserId, + mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { @@ -678,8 +686,8 @@ public final class AppSearchSession implements Closeable { public void close() { if (mIsMutated && !mIsClosed) { try { - mService.persistToDisk(mUserId, - /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); + mService.persistToDisk( + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mIsClosed = true; } catch (RemoteException e) { Log.e(TAG, "Unable to close the AppSearchSession", e); @@ -708,7 +716,7 @@ public final class AppSearchSession implements Closeable { schemasPackageAccessibleBundles, request.isForceOverride(), request.getVersion(), - mUserId, + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @Override @@ -796,7 +804,7 @@ public final class AppSearchSession implements Closeable { schemasPackageAccessibleBundles, /*forceOverride=*/ false, request.getVersion(), - mUserId, + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @Override @@ -822,7 +830,7 @@ public final class AppSearchSession implements Closeable { } try (AppSearchMigrationHelper migrationHelper = new AppSearchMigrationHelper( - mService, mUserId, mPackageName, mDatabaseName, request.getSchemas())) { + mService, mUserHandle, mPackageName, mDatabaseName, request.getSchemas())) { // 4. Trigger migration for all migrators. // TODO(b/177266929) trigger migration for all types together rather than @@ -848,7 +856,7 @@ public final class AppSearchSession implements Closeable { schemasPackageAccessibleBundles, /*forceOverride=*/ true, request.getVersion(), - mUserId, + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @Override diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java index bb8d565caf521..247eb08d698a1 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java +++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java @@ -18,12 +18,12 @@ package android.app.appsearch; import android.annotation.CallbackExecutor; import android.annotation.NonNull; -import android.annotation.UserIdInt; import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.IAppSearchManager; import android.app.appsearch.aidl.IAppSearchResultCallback; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserHandle; import android.util.Log; import com.android.internal.util.Preconditions; @@ -45,24 +45,23 @@ public class GlobalSearchSession implements Closeable { private static final String TAG = "AppSearchGlobalSearchSe"; private final String mPackageName; - @UserIdInt - private final int mUserId; + private final UserHandle mUserHandle; private final IAppSearchManager mService; private boolean mIsMutated = 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}. */ static void createGlobalSearchSession( @NonNull IAppSearchManager service, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull String packageName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer> callback) { - GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userId, + GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userHandle, packageName); globalSearchSession.initialize(executor, callback); } @@ -73,7 +72,8 @@ public class GlobalSearchSession implements Closeable { @NonNull @CallbackExecutor Executor executor, @NonNull Consumer> callback) { try { - mService.initialize(mUserId, + mService.initialize( + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @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) { mService = service; - mUserId = userId; + mUserHandle = userHandle; mPackageName = packageName; } @@ -127,7 +127,7 @@ public class GlobalSearchSession implements Closeable { Objects.requireNonNull(searchSpec); Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed"); return new SearchResults(mService, mPackageName, /*databaseName=*/null, queryExpression, - searchSpec, mUserId); + searchSpec, mUserHandle); } /** @@ -165,7 +165,7 @@ public class GlobalSearchSession implements Closeable { request.getDocumentId(), request.getUsageTimestampMillis(), /*systemUsage=*/ true, - mUserId, + mUserHandle, new IAppSearchResultCallback.Stub() { @Override public void onResult(AppSearchResultParcel resultParcel) { @@ -186,8 +186,8 @@ public class GlobalSearchSession implements Closeable { public void close() { if (mIsMutated && !mIsClosed) { try { - mService.persistToDisk(mUserId, - /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); + mService.persistToDisk( + mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mIsClosed = true; } catch (RemoteException e) { Log.e(TAG, "Unable to close the GlobalSearchSession", e); diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java index 0106b0f3c1b65..eb5d22eaaea0c 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java +++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java @@ -19,13 +19,13 @@ package android.app.appsearch; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UserIdInt; import android.app.appsearch.aidl.AppSearchResultParcel; import android.app.appsearch.aidl.IAppSearchManager; import android.app.appsearch.aidl.IAppSearchResultCallback; import android.os.Bundle; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserHandle; import android.util.Log; import com.android.internal.util.Preconditions; @@ -66,8 +66,7 @@ public class SearchResults implements Closeable { private final SearchSpec mSearchSpec; - @UserIdInt - private final int mUserId; + private final UserHandle mUserHandle; private long mNextPageToken; @@ -81,13 +80,13 @@ public class SearchResults implements Closeable { @Nullable String databaseName, @NonNull String queryExpression, @NonNull SearchSpec searchSpec, - @UserIdInt int userId) { + @NonNull UserHandle userHandle) { mService = Objects.requireNonNull(service); mPackageName = packageName; mDatabaseName = databaseName; mQueryExpression = Objects.requireNonNull(queryExpression); mSearchSpec = Objects.requireNonNull(searchSpec); - mUserId = userId; + mUserHandle = Objects.requireNonNull(userHandle); } /** @@ -114,18 +113,18 @@ public class SearchResults implements Closeable { if (mDatabaseName == null) { // Global query, there's no one package-database combination to check. mService.globalQuery(mPackageName, mQueryExpression, - mSearchSpec.getBundle(), mUserId, + mSearchSpec.getBundle(), mUserHandle, binderCallStartTimeMillis, wrapCallback(executor, callback)); } else { // Normal local query, pass in specified database. mService.query(mPackageName, mDatabaseName, mQueryExpression, - mSearchSpec.getBundle(), mUserId, + mSearchSpec.getBundle(), mUserHandle, binderCallStartTimeMillis, wrapCallback(executor, callback)); } } else { - mService.getNextPage(mNextPageToken, mUserId, wrapCallback(executor, callback)); + mService.getNextPage(mNextPageToken, mUserHandle, wrapCallback(executor, callback)); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -136,7 +135,7 @@ public class SearchResults implements Closeable { public void close() { if (!mIsClosed) { try { - mService.invalidateNextPageToken(mNextPageToken, mUserId); + mService.invalidateNextPageToken(mNextPageToken, mUserHandle); mIsClosed = true; } catch (RemoteException e) { Log.e(TAG, "Unable to close the SearchResults", e); diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl index 18ebddc6727c3..0b26e146a7a44 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl +++ b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl @@ -16,6 +16,7 @@ package android.app.appsearch.aidl; import android.os.Bundle; +import android.os.UserHandle; import android.app.appsearch.aidl.IAppSearchBatchResultCallback; 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 * incompatible documents will be deleted. * @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 callback {@link IAppSearchResultCallback#onResult} will be called with an * {@link AppSearchResult}<{@link Bundle}>, where the value are @@ -50,7 +51,7 @@ interface IAppSearchManager { in Map> schemasPackageAccessibleBundles, boolean forceOverride, in int schemaVersion, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchResultCallback callback); @@ -59,14 +60,14 @@ interface IAppSearchManager { * * @param packageName The name of the package that owns the schema. * @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 * {@link AppSearchResult}<{@link Bundle}> where the bundle is a GetSchemaResponse. */ void getSchema( in String packageName, in String databaseName, - in int userId, + in UserHandle userHandle, in IAppSearchResultCallback callback); /** @@ -74,14 +75,14 @@ interface IAppSearchManager { * * @param packageName The name of the package that owns the schema. * @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 * {@link AppSearchResult}<{@link List}<{@link String}>>. */ void getNamespaces( in String packageName, in String databaseName, - in int userId, + in UserHandle userHandle, in IAppSearchResultCallback callback); /** @@ -90,7 +91,7 @@ interface IAppSearchManager { * @param packageName The name of the package that owns this document. * @param databaseName The name of the database where this document lives. * @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 callback * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} @@ -103,7 +104,7 @@ interface IAppSearchManager { in String packageName, in String databaseName, in List documentBundles, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchBatchResultCallback callback); @@ -116,7 +117,7 @@ interface IAppSearchManager { * @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 * 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 callback * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} @@ -131,7 +132,7 @@ interface IAppSearchManager { in String namespace, in List ids, in Map> typePropertyPaths, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchBatchResultCallback callback); @@ -142,7 +143,7 @@ interface IAppSearchManager { * @param databaseName The databaseName this query for. * @param queryExpression String to search for * @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 callback {@link AppSearchResult}<{@link Bundle}> of performing this * operation. @@ -152,7 +153,7 @@ interface IAppSearchManager { in String databaseName, in String queryExpression, in Bundle searchSpecBundle, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchResultCallback callback); @@ -163,7 +164,7 @@ interface IAppSearchManager { * @param packageName The name of the package making the query. * @param queryExpression String to search for * @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 callback {@link AppSearchResult}<{@link Bundle}> of performing this * operation. @@ -172,7 +173,7 @@ interface IAppSearchManager { in String packageName, in String queryExpression, in Bundle searchSpecBundle, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchResultCallback callback); @@ -181,20 +182,20 @@ interface IAppSearchManager { * next-page token is invalid or all pages have been returned. * * @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}<{@link Bundle}> of performing this * 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. * * @param nextPageToken The token of pre-loaded results of previously executed query to be * 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. @@ -206,7 +207,7 @@ interface IAppSearchManager { * @param fileDescriptor The ParcelFileDescriptor where documents should be written to. * @param queryExpression String to search for. * @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 * {@link AppSearchResult}<{@code Void}>. */ @@ -216,7 +217,7 @@ interface IAppSearchManager { in ParcelFileDescriptor fileDescriptor, in String queryExpression, in Bundle searchSpecBundle, - in int userId, + in UserHandle userHandle, in IAppSearchResultCallback callback); /** @@ -225,7 +226,7 @@ interface IAppSearchManager { * @param packageName The name of the package that owns this document. * @param databaseName The name of the database where this document lives. * @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 * {@link AppSearchResult}<{@link List}<{@link Bundle}>>, where the value are * MigrationFailure bundles. @@ -234,7 +235,7 @@ interface IAppSearchManager { in String packageName, in String databaseName, in ParcelFileDescriptor fileDescriptor, - in int userId, + in UserHandle userHandle, in IAppSearchResultCallback callback); /** @@ -255,7 +256,7 @@ interface IAppSearchManager { * @param id ID of the document being 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 userId Id of the calling user + * @param userHandle Handle of the calling user * @param callback {@link IAppSearchResultCallback#onResult} will be called with an * {@link AppSearchResult}<{@link Void}>. */ @@ -266,7 +267,7 @@ interface IAppSearchManager { in String id, in long usageTimestampMillis, in boolean systemUsage, - in int userId, + in UserHandle userHandle, in IAppSearchResultCallback callback); /** @@ -276,7 +277,7 @@ interface IAppSearchManager { * @param databaseName The databaseName the document is in. * @param namespace Namespace of the document to remove. * @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 callback * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} @@ -291,7 +292,7 @@ interface IAppSearchManager { in String databaseName, in String namespace, in List ids, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchBatchResultCallback callback); @@ -302,7 +303,7 @@ interface IAppSearchManager { * @param databaseName The databaseName this query for. * @param queryExpression String to search for * @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 callback {@link IAppSearchResultCallback#onResult} will be called with an * {@link AppSearchResult}<{@link Void}>. @@ -312,7 +313,7 @@ interface IAppSearchManager { in String databaseName, in String queryExpression, in Bundle searchSpecBundle, - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchResultCallback callback); @@ -321,7 +322,7 @@ interface IAppSearchManager { * * @param packageName The name of the package 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 * {@link AppSearchResult}<{@link Bundle}>, where the value is a * {@link StorageInfo}. @@ -329,27 +330,27 @@ interface IAppSearchManager { void getStorageInfo( in String packageName, in String databaseName, - in int userId, + in UserHandle userHandle, in IAppSearchResultCallback callback); /** * 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 */ - void persistToDisk(in int userId, in long binderCallStartTimeMillis); + void persistToDisk(in UserHandle userHandle, in long binderCallStartTimeMillis); /** * 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 callback {@link IAppSearchResultCallback#onResult} will be called with an * {@link AppSearchResult}<{@link Void}>. */ void initialize( - in int userId, + in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchResultCallback callback); } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java index 61ac63e6600db..754cc41960fc0 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java @@ -21,7 +21,6 @@ import static android.os.UserHandle.USER_NULL; import android.annotation.ElapsedRealtimeLong; import android.annotation.NonNull; -import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.appsearch.AppSearchBatchResult; import android.app.appsearch.AppSearchMigrationHelper; @@ -45,7 +44,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageStats; import android.os.Binder; import android.os.Bundle; @@ -60,7 +58,6 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.server.LocalManagerRegistry; -import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.appsearch.external.localstorage.AppSearchImpl; 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 final Context mContext; private PackageManager mPackageManager; - private PackageManagerInternal mPackageManagerInternal; private ImplInstanceManager mImplInstanceManager; private UserManager mUserManager; private LoggerInstanceManager mLoggerInstanceManager; @@ -104,11 +100,11 @@ public class AppSearchManagerService extends SystemService { Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); - // Cache of unlocked user ids so we don't have to query UserManager service each time. The - // "locked" suffix refers to the fact that access to the field should be locked; unrelated to - // the unlocked status of user ids. - @GuardedBy("mUnlockedUserIdsLocked") - private final Set mUnlockedUserIdsLocked = new ArraySet<>(); + // Cache of unlocked users so we don't have to query UserManager service each time. The "locked" + // suffix refers to the fact that access to the field should be locked; unrelated to the + // unlocked status of users. + @GuardedBy("mUnlockedUsersLocked") + private final Set mUnlockedUsersLocked = new ArraySet<>(); public AppSearchManagerService(Context context) { super(context); @@ -119,7 +115,6 @@ public class AppSearchManagerService extends SystemService { public void onStart() { publishBinderService(Context.APP_SEARCH_SERVICE, new Stub()); mPackageManager = getContext().getPackageManager(); - mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mImplInstanceManager = ImplInstanceManager.getInstance(mContext); mUserManager = mContext.getSystemService(UserManager.class); mLoggerInstanceManager = LoggerInstanceManager.getInstance(); @@ -148,6 +143,9 @@ public class AppSearchManagerService extends SystemService { private class UserActionReceiver extends BroadcastReceiver { @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { + Objects.requireNonNull(context); + Objects.requireNonNull(intent); + switch (intent.getAction()) { case Intent.ACTION_USER_REMOVED: 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); return; } - handleUserRemoved(userId); + handleUserRemoved(UserHandle.of(userId)); break; default: 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 * 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 */ - private void handleUserRemoved(@UserIdInt int userId) { + private void handleUserRemoved(@NonNull UserHandle userHandle) { try { - mImplInstanceManager.removeAppSearchImplForUser(userId); - mLoggerInstanceManager.removePlatformLoggerForUser(userId); - Log.i(TAG, "Removed AppSearchImpl instance for user: " + userId); + mImplInstanceManager.removeAppSearchImplForUser(userHandle); + mLoggerInstanceManager.removePlatformLoggerForUser(userHandle); + Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle); } 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 { @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { + Objects.requireNonNull(context); + Objects.requireNonNull(intent); + switch (intent.getAction()) { case Intent.ACTION_PACKAGE_FULLY_REMOVED: case Intent.ACTION_PACKAGE_DATA_CLEARED: @@ -208,19 +209,19 @@ public class AppSearchManagerService extends SystemService { } } - private void handlePackageRemoved(String packageName, int uid) { - int userId = UserHandle.getUserId(uid); + private void handlePackageRemoved(@NonNull String packageName, int uid) { + UserHandle userHandle = UserHandle.getUserHandleForUid(uid); try { - if (isUserLocked(userId)) { + if (isUserLocked(userHandle)) { //TODO(b/186151459) clear the uninstalled package data when user is unlocked. return; } - if (ImplInstanceManager.getAppSearchDir(userId).exists()) { + if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) { // Only clear the package's data if AppSearch exists for this user. PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, - userId); + userHandle); AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, - userId, logger); + userHandle, logger); //TODO(b/145759910) clear visibility setting for package. impl.clearPackageData(packageName); logger.removeCachedUidForPackage(packageName); @@ -232,38 +233,42 @@ public class AppSearchManagerService extends SystemService { @Override public void onUserUnlocking(@NonNull TargetUser user) { - synchronized (mUnlockedUserIdsLocked) { - mUnlockedUserIdsLocked.add(user.getUserIdentifier()); + Objects.requireNonNull(user); + synchronized (mUnlockedUsersLocked) { + mUnlockedUsersLocked.add(user.getUserHandle()); } } @Override public void onUserStopping(@NonNull TargetUser user) { - synchronized (mUnlockedUserIdsLocked) { - mUnlockedUserIdsLocked.remove(user.getUserIdentifier()); + Objects.requireNonNull(user); + + synchronized (mUnlockedUsersLocked) { + UserHandle userHandle = user.getUserHandle(); + mUnlockedUsersLocked.remove(userHandle); try { - mImplInstanceManager.closeAndRemoveAppSearchImplForUser(user.getUserIdentifier()); + mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle); } catch (Throwable t) { Log.e(TAG, "Error handling user stopping.", t); } } } - private void verifyUserUnlocked(int callingUserId) { - if (isUserLocked(callingUserId)) { - throw new IllegalStateException("User " + callingUserId + " is locked or not running."); + private void verifyUserUnlocked(@NonNull UserHandle callingUser) { + if (isUserLocked(callingUser)) { + throw new IllegalStateException(callingUser + " is locked or not running."); } } - private boolean isUserLocked(int callingUserId) { - synchronized (mUnlockedUserIdsLocked) { + private boolean isUserLocked(@NonNull UserHandle callingUser) { + synchronized (mUnlockedUsersLocked) { // First, check the local copy. - if (mUnlockedUserIdsLocked.contains(callingUserId)) { + if (mUnlockedUsersLocked.contains(callingUser)) { return false; } // If the local copy says the user is locked, check with UM for the actual state, // 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> schemasPackageAccessibleBundles, boolean forceOverride, int schemaVersion, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); Objects.requireNonNull(schemaBundles); + Objects.requireNonNull(schemasNotDisplayedBySystem); + Objects.requireNonNull(schemasPackageAccessibleBundles); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); List schemas = new ArrayList<>(schemaBundles.size()); for (int i = 0; i < schemaBundles.size(); i++) { schemas.add(new AppSearchSchema(schemaBundles.get(i))); @@ -311,8 +320,8 @@ public class AppSearchManagerService extends SystemService { } schemasPackageAccessible.put(entry.getKey(), packageIdentifiers); } - AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); SetSchemaResponse setSchemaResponse = impl.setSchema( packageName, databaseName, @@ -356,19 +365,20 @@ public class AppSearchManagerService extends SystemService { public void getSchema( @NonNull String packageName, @NonNull String databaseName, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); GetSchemaResponse response = impl.getSchema(packageName, databaseName); invokeCallbackOnResult( callback, @@ -383,19 +393,20 @@ public class AppSearchManagerService extends SystemService { public void getNamespaces( @NonNull String packageName, @NonNull String databaseName, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); List namespaces = impl.getNamespaces(packageName, databaseName); invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(namespaces)); @@ -410,29 +421,30 @@ public class AppSearchManagerService extends SystemService { @NonNull String packageName, @NonNull String databaseName, @NonNull List documentBundles, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchBatchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); Objects.requireNonNull(documentBundles); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); AppSearchBatchResult.Builder resultBuilder = new AppSearchBatchResult.Builder<>(); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); for (int i = 0; i < documentBundles.size(); i++) { GenericDocument document = new GenericDocument(documentBundles.get(i)); try { @@ -488,30 +500,32 @@ public class AppSearchManagerService extends SystemService { @NonNull String namespace, @NonNull List ids, @NonNull Map> typePropertyPaths, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchBatchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); Objects.requireNonNull(namespace); Objects.requireNonNull(ids); + Objects.requireNonNull(typePropertyPaths); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); AppSearchBatchResult.Builder resultBuilder = new AppSearchBatchResult.Builder<>(); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); for (int i = 0; i < ids.size(); i++) { String id = ids.get(i); try { @@ -568,28 +582,29 @@ public class AppSearchManagerService extends SystemService { @NonNull String databaseName, @NonNull String queryExpression, @NonNull Bundle searchSpecBundle, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); Objects.requireNonNull(queryExpression); Objects.requireNonNull(searchSpecBundle); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); SearchResultPage searchResultPage = impl.query( packageName, @@ -634,27 +649,28 @@ public class AppSearchManagerService extends SystemService { @NonNull String packageName, @NonNull String queryExpression, @NonNull Bundle searchSpecBundle, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(queryExpression); Objects.requireNonNull(searchSpecBundle); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); SearchResultPage searchResultPage = impl.globalQuery( queryExpression, @@ -698,18 +714,19 @@ public class AppSearchManagerService extends SystemService { @Override public void getNextPage( long nextPageToken, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + 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 // opened it EXECUTOR.execute(() -> { try { - verifyUserUnlocked(callingUserId); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyUserUnlocked(callingUser); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); SearchResultPage searchResultPage = impl.getNextPage(nextPageToken); invokeCallbackOnResult( callback, @@ -721,14 +738,15 @@ public class AppSearchManagerService extends SystemService { } @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 callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyUserUnlocked(callingUserId); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyUserUnlocked(callingUser); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); impl.invalidateNextPageToken(nextPageToken); } catch (Throwable 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 String queryExpression, @NonNull Bundle searchSpecBundle, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @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 callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); // we don't need to append the file. The file is always brand new. try (DataOutputStream outputStream = new DataOutputStream( new FileOutputStream(fileDescriptor.getFileDescriptor()))) { @@ -783,15 +808,20 @@ public class AppSearchManagerService extends SystemService { @NonNull String packageName, @NonNull String databaseName, @NonNull ParcelFileDescriptor fileDescriptor, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { + Objects.requireNonNull(packageName); + Objects.requireNonNull(databaseName); + Objects.requireNonNull(fileDescriptor); + Objects.requireNonNull(userHandle); + Objects.requireNonNull(callback); + int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); GenericDocument document; ArrayList migrationFailureBundles = new ArrayList<>(); @@ -835,24 +865,26 @@ public class AppSearchManagerService extends SystemService { @NonNull String documentId, long usageTimeMillis, boolean systemUsage, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { + Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); Objects.requireNonNull(namespace); Objects.requireNonNull(documentId); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyUserUnlocked(callingUserId); + verifyUserUnlocked(callingUser); if (systemUsage) { // TODO(b/183031844): Validate that the call comes from the system } - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); impl.reportUsage( packageName, databaseName, namespace, documentId, usageTimeMillis, systemUsage); @@ -870,29 +902,31 @@ public class AppSearchManagerService extends SystemService { @NonNull String databaseName, @NonNull String namespace, @NonNull List ids, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchBatchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); + Objects.requireNonNull(namespace); Objects.requireNonNull(ids); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); AppSearchBatchResult.Builder resultBuilder = new AppSearchBatchResult.Builder<>(); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); for (int i = 0; i < ids.size(); i++) { String id = ids.get(i); try { @@ -945,7 +979,7 @@ public class AppSearchManagerService extends SystemService { @NonNull String databaseName, @NonNull String queryExpression, @NonNull Bundle searchSpecBundle, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchResultCallback callback) { // 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(queryExpression); Objects.requireNonNull(searchSpecBundle); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); impl.removeByQuery( packageName, databaseName, @@ -1009,19 +1044,20 @@ public class AppSearchManagerService extends SystemService { public void getStorageInfo( @NonNull String packageName, @NonNull String databaseName, - @UserIdInt int userId, + @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { Objects.requireNonNull(packageName); Objects.requireNonNull(databaseName); + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyUserUnlocked(callingUserId); - verifyCallingPackage(callingUid, packageName); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); + verifyUserUnlocked(callingUser); + verifyCallingPackage(callingUser, callingUid, packageName); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName, databaseName); Bundle storageInfoBundle = storageInfo.getBundle(); @@ -1034,21 +1070,23 @@ public class AppSearchManagerService extends SystemService { } @Override - public void persistToDisk(@UserIdInt int userId, + public void persistToDisk( + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis) { + Objects.requireNonNull(userHandle); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - AppSearchImpl impl = - mImplInstanceManager.getAppSearchImpl(callingUserId); - logger = mLoggerInstanceManager.getPlatformLogger(callingUserId); + verifyUserUnlocked(callingUser); + AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser); + logger = mLoggerInstanceManager.getPlatformLogger(callingUser); impl.persistToDisk(PersistType.Code.FULL); ++operationSuccessCount; } catch (Throwable t) { @@ -1080,23 +1118,26 @@ public class AppSearchManagerService extends SystemService { } @Override - public void initialize(@UserIdInt int userId, + public void initialize( + @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchResultCallback callback) { + Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); + long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - int callingUserId = handleIncomingUser(userId, callingUid); + UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; PlatformLogger logger = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - verifyUserUnlocked(callingUserId); - logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, - callingUserId); - mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId, logger); + verifyUserUnlocked(callingUser); + logger = mLoggerInstanceManager.getOrCreatePlatformLogger( + mContext, callingUser); + mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger); ++operationSuccessCount; invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); } catch (Throwable t) { @@ -1129,16 +1170,29 @@ public class AppSearchManagerService extends SystemService { }); } - private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) { - Objects.requireNonNull(callingPackage); - if (mPackageManagerInternal.getPackageUid( - callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid)) - != callingUid) { + private void verifyCallingPackage( + @NonNull UserHandle actualCallingUser, + int actualCallingUid, + @NonNull String claimedCallingPackage) { + 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( "Specified calling package [" - + callingPackage + + claimedCallingPackage + "] 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. + * + *

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) Handle ACTION_USER_REMOVED broadcast // 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(); - return ActivityManager.handleIncomingUser( + int finalUserId = ActivityManager.handleIncomingUser( callingPid, callingUid, - userId, + userHandle.getIdentifier(), /*allowAll=*/ false, /*requireFull=*/ false, /*name=*/ null, /*callerPackage=*/ null); + return UserHandle.of(finalUserId); } // TODO(b/179160886): Cache the previous storage stats. @@ -1218,19 +1281,19 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(stats); Objects.requireNonNull(packageName); Objects.requireNonNull(userHandle); - int userId = userHandle.getIdentifier(); + try { - verifyUserUnlocked(userId); - PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, - userId); - AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, - userId, logger); + verifyUserUnlocked(userHandle); + PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger( + mContext, userHandle); + AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl( + mContext, userHandle, logger); stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes(); } catch (Throwable t) { Log.e( TAG, - "Unable to augment storage stats for userId " - + userId + "Unable to augment storage stats for " + + userHandle + " packageName " + packageName, t); @@ -1241,17 +1304,18 @@ public class AppSearchManagerService extends SystemService { public void augmentStatsForUid( @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) { Objects.requireNonNull(stats); - int userId = UserHandle.getUserId(uid); + + UserHandle userHandle = UserHandle.getUserHandleForUid(uid); try { - verifyUserUnlocked(userId); + verifyUserUnlocked(userHandle); String[] packagesForUid = mPackageManager.getPackagesForUid(uid); if (packagesForUid == null) { return; } - PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, - userId); - AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, - userId, logger); + PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger( + mContext, userHandle); + AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl( + mContext, userHandle, logger); for (int i = 0; i < packagesForUid.length; i++) { stats.dataSize += 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). Objects.requireNonNull(stats); Objects.requireNonNull(userHandle); - int userId = userHandle.getIdentifier(); + try { - verifyUserUnlocked(userId); - List packagesForUser = - mPackageManager.getInstalledPackagesAsUser(/*flags=*/0, userId); + verifyUserUnlocked(userHandle); + List packagesForUser = mPackageManager.getInstalledPackagesAsUser( + /*flags=*/0, userHandle.getIdentifier()); if (packagesForUser == null) { return; } - PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext, - userId); + PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger( + mContext, userHandle); AppSearchImpl impl = - mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userId, logger); + mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger); for (int i = 0; i < packagesForUser.size(); i++) { String packageName = packagesForUser.get(i).packageName; stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes(); } } 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); } } } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java index f8bc473cd2a58..6477489859488 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java @@ -20,13 +20,12 @@ import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UserIdInt; import android.app.appsearch.exceptions.AppSearchException; import android.content.Context; import android.content.pm.PackageManager; import android.os.Environment; import android.os.UserHandle; -import android.util.SparseArray; +import android.util.ArrayMap; import com.android.internal.R; 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 java.io.File; +import java.util.Map; +import java.util.Objects; /** * Manages the lifecycle of instances of {@link AppSearchImpl}. @@ -46,7 +47,7 @@ public final class ImplInstanceManager { private static ImplInstanceManager sImplInstanceManager; @GuardedBy("mInstancesLocked") - private final SparseArray mInstancesLocked = new SparseArray<>(); + private final Map mInstancesLocked = new ArrayMap<>(); private final String mGlobalQuerierPackage; @@ -79,8 +80,9 @@ public final class ImplInstanceManager { * *

This folder should only be accessed after unlock. */ - public static File getAppSearchDir(@UserIdInt int userId) { - return new File(Environment.getDataSystemCeDirectory(userId), APP_SEARCH_DIR); + public static File getAppSearchDir(@NonNull UserHandle userHandle) { + return new File( + Environment.getDataSystemCeDirectory(userHandle.getIdentifier()), APP_SEARCH_DIR); } /** @@ -90,18 +92,22 @@ public final class ImplInstanceManager { * one will be created. * * @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 */ @NonNull public AppSearchImpl getOrCreateAppSearchImpl( - @NonNull Context context, @UserIdInt int userId, @Nullable AppSearchLogger logger) - throws AppSearchException { + @NonNull Context context, + @NonNull UserHandle userHandle, + @Nullable AppSearchLogger logger) throws AppSearchException { + Objects.requireNonNull(context); + Objects.requireNonNull(userHandle); + synchronized (mInstancesLocked) { - AppSearchImpl instance = mInstancesLocked.get(userId); + AppSearchImpl instance = mInstancesLocked.get(userHandle); if (instance == null) { - instance = createImpl(context, userId, logger); - mInstancesLocked.put(userId, instance); + instance = createImpl(context, userHandle, logger); + mInstancesLocked.put(userHandle, instance); } return instance; } @@ -116,12 +122,13 @@ public final class ImplInstanceManager { *

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. * - * @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) { // 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 { * *

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) { - AppSearchImpl appSearchImpl = mInstancesLocked.get(userId); + AppSearchImpl appSearchImpl = mInstancesLocked.get(userHandle); if (appSearchImpl != null) { appSearchImpl.close(); - mInstancesLocked.remove(userId); + mInstancesLocked.remove(userHandle); } } } @@ -148,31 +156,39 @@ public final class ImplInstanceManager { *

This method should only be called by an initialized SearchSession, which has been already * 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 * @throws IllegalStateException if {@link AppSearchImpl} haven't created for the given user. */ @NonNull - public AppSearchImpl getAppSearchImpl(@UserIdInt int userId) { + public AppSearchImpl getAppSearchImpl(@NonNull UserHandle userHandle) { + Objects.requireNonNull(userHandle); synchronized (mInstancesLocked) { - AppSearchImpl instance = mInstancesLocked.get(userId); + AppSearchImpl instance = mInstancesLocked.get(userHandle); if (instance == null) { // Impossible scenario, user cannot call an uninitialized SearchSession, // getInstance should always find the instance for the given user and never try to // create an instance for this user again. throw new IllegalStateException( - "AppSearchImpl has never been created for this user: " + userId); + "AppSearchImpl has never been created for: " + userHandle); } return instance; } } - private AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId, + private AppSearchImpl createImpl( + @NonNull Context context, + @NonNull UserHandle userHandle, @Nullable AppSearchLogger logger) 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( - appSearchDir, context, userId, mGlobalQuerierPackage, logger); + appSearchDir, + context, + userHandle.getIdentifier(), + mGlobalQuerierPackage, + /*logger=*/ null); } /** diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java index 45440633cff45..cb65e42696d14 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java @@ -17,14 +17,17 @@ package com.android.server.appsearch.stats; import android.annotation.NonNull; -import android.annotation.UserIdInt; import android.content.Context; -import android.util.SparseArray; +import android.os.UserHandle; +import android.util.ArrayMap; import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.server.appsearch.AppSearchManagerService; +import java.util.Map; +import java.util.Objects; + /** * Manages the lifecycle of instances of {@link PlatformLogger}. * @@ -40,7 +43,7 @@ public final class LoggerInstanceManager { private static volatile LoggerInstanceManager sLoggerInstanceManager; @GuardedBy("mInstancesLocked") - private final SparseArray mInstancesLocked = new SparseArray<>(); + private final Map mInstancesLocked = new ArrayMap<>(); 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. * * @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 */ @NonNull public PlatformLogger getOrCreatePlatformLogger( - @NonNull Context context, @UserIdInt int userId) { + @NonNull Context context, @NonNull UserHandle userHandle) { + Objects.requireNonNull(userHandle); synchronized (mInstancesLocked) { - PlatformLogger instance = mInstancesLocked.get(userId); + PlatformLogger instance = mInstancesLocked.get(userHandle); 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, DEFAULT_SAMPLING_RATIO, // TODO(b/173532925) re-enable sampling ratios for different stats types // once we have P/H flag manager setup in ag/13977824 /*samplingRatios=*/ new SparseIntArray())); - mInstancesLocked.put(userId, instance); + mInstancesLocked.put(userHandle, instance); } return instance; } } - /** * Gets an instance of PlatformLogger for the given user. * *

This method should only be called by an initialized SearchSession, which has been already * 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 * @throws IllegalStateException if {@link PlatformLogger} haven't created for the given user. */ @NonNull - public PlatformLogger getPlatformLogger(@UserIdInt int userId) { + public PlatformLogger getPlatformLogger(@NonNull UserHandle userHandle) { + Objects.requireNonNull(userHandle); synchronized (mInstancesLocked) { - PlatformLogger instance = mInstancesLocked.get(userId); + PlatformLogger instance = mInstancesLocked.get(userHandle); if (instance == null) { // Impossible scenario, user cannot call an uninitialized SearchSession, // getInstance should always find the instance for the given user and never try to // create an instance for this user again. throw new IllegalStateException( - "PlatformLogger has never been created for this user: " + userId); + "PlatformLogger has never been created for: " + userHandle); } return instance; } @@ -121,11 +125,12 @@ public final class LoggerInstanceManager { *

This method should only be called if {@link AppSearchManagerService} receives an * 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) { - mInstancesLocked.remove(userId); + mInstancesLocked.remove(userHandle); } } } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java index df59306f6ebed..74aedbdf9056d 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Process; import android.os.SystemClock; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import android.util.SparseIntArray; @@ -56,8 +57,8 @@ public final class PlatformLogger implements AppSearchLogger { // Context of the system service. private final Context mContext; - // User ID of the caller who we're logging for. - private final int mUserId; + // User we're logging for. + private final UserHandle mUserHandle; // Configuration for the logger private final Config mConfig; @@ -164,10 +165,11 @@ public final class PlatformLogger implements AppSearchLogger { /** * 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); + mUserHandle = Objects.requireNonNull(userHandle); mConfig = Objects.requireNonNull(config); - mUserId = userId; } /** 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 // utility function try { - packageUid = mContext.getPackageManager().getPackageUidAsUser(packageName, mUserId); + packageUid = mContext.getPackageManager().getPackageUidAsUser( + packageName, mUserHandle.getIdentifier()); mPackageUidCacheLocked.put(packageName, packageUid); return packageUid; } catch (PackageManager.NameNotFoundException e) { diff --git a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java index e5bdafd693743..747dd1df1869a 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java @@ -75,7 +75,7 @@ public class PlatformLoggerTest { public void testCreateExtraStatsLocked_nullSamplingRatioMap_returnsDefaultSamplingRatio() { PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.USER_NULL, + UserHandle.of(UserHandle.USER_NULL), new PlatformLogger.Config( TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_DEFAULT_SAMPLING_RATIO, @@ -106,7 +106,7 @@ public class PlatformLoggerTest { samplingRatios.put(CallStats.CALL_TYPE_SEARCH, querySamplingRatio); PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.USER_NULL, + UserHandle.of(UserHandle.USER_NULL), new PlatformLogger.Config( TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_DEFAULT_SAMPLING_RATIO, @@ -207,7 +207,7 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.USER_NULL, + UserHandle.of(UserHandle.USER_NULL), new PlatformLogger.Config( TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, samplingRatio, @@ -225,7 +225,7 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.USER_NULL, + UserHandle.of(UserHandle.USER_NULL), new PlatformLogger.Config( TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, samplingRatio, @@ -247,7 +247,7 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.USER_NULL, + UserHandle.of(UserHandle.USER_NULL), new PlatformLogger.Config( minTimeIntervalBetweenSamplesMillis, samplingRatio, @@ -269,7 +269,7 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.USER_NULL, + UserHandle.of(UserHandle.USER_NULL), new PlatformLogger.Config( minTimeIntervalBetweenSamplesMillis, samplingRatio, @@ -289,7 +289,7 @@ public class PlatformLoggerTest { final int testUid = 1234; PlatformLogger logger = new PlatformLogger( mContext, - mContext.getUserId(), + mContext.getUser(), new PlatformLogger.Config( TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, TEST_DEFAULT_SAMPLING_RATIO, diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index b2ddbf024a31d..f6baa6bb1596d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -653,15 +653,15 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { new ArrayMap<>(1); private Map> mDocumentMap = new ArrayMap<>(1); - private String getKey(int userId, String databaseName) { - return new StringBuilder().append(userId).append("@").append(databaseName).toString(); + private String getKey(UserHandle userHandle, String databaseName) { + return userHandle.getIdentifier() + "@" + databaseName; } @Override public void setSchema(String packageName, String databaseName, List schemaBundles, List schemasNotPlatformSurfaceable, Map> schemasPackageAccessibleBundles, boolean forceOverride, - int userId, int version, long binderCallStartTimeMillis, + int version, UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchResultCallback callback) throws RemoteException { for (Map.Entry> entry : schemasPackageAccessibleBundles.entrySet()) { @@ -684,20 +684,20 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override - public void getSchema(String packageName, String databaseName, int userId, + public void getSchema(String packageName, String databaseName, UserHandle userHandle, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } @Override - public void getNamespaces(String packageName, String databaseName, int userId, + public void getNamespaces(String packageName, String databaseName, UserHandle userHandle, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } @Override public void putDocuments(String packageName, String databaseName, - List documentBundles, int userId, long binderCallStartTimeMillis, + List documentBundles, UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchBatchResultCallback callback) throws RemoteException { final List docs = new ArrayList<>(documentBundles.size()); @@ -706,7 +706,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } final AppSearchBatchResult.Builder builder = new AppSearchBatchResult.Builder<>(); - final String key = getKey(userId, databaseName); + final String key = getKey(userHandle, databaseName); Map docMap = mDocumentMap.get(key); for (GenericDocument doc : docs) { builder.setSuccess(doc.getId(), null); @@ -721,12 +721,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void getDocuments(String packageName, String databaseName, String namespace, - List ids, Map> typePropertyPaths, int userId, - long binderCallStartTimeMillis, + List ids, Map> typePropertyPaths, + UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchBatchResultCallback callback) throws RemoteException { final AppSearchBatchResult.Builder builder = new AppSearchBatchResult.Builder<>(); - final String key = getKey(userId, databaseName); + final String key = getKey(userHandle, databaseName); if (!mDocumentMap.containsKey(key)) { for (String id : ids) { builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND, @@ -748,10 +748,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void query(String packageName, String databaseName, String queryExpression, - Bundle searchSpecBundle, int userId, long binderCallStartTimeMillis, + Bundle searchSpecBundle, UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchResultCallback callback) throws RemoteException { - final String key = getKey(userId, databaseName); + final String key = getKey(userHandle, databaseName); if (!mDocumentMap.containsKey(key)) { final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); @@ -779,14 +779,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void globalQuery(String packageName, String queryExpression, Bundle searchSpecBundle, - int userId, long binderCallStartTimeMillis, IAppSearchResultCallback callback) - throws RemoteException { + UserHandle userHandle, long binderCallStartTimeMillis, + IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } @Override - public void getNextPage(long nextPageToken, int userId, IAppSearchResultCallback callback) - throws RemoteException { + public void getNextPage(long nextPageToken, UserHandle userHandle, + IAppSearchResultCallback callback) throws RemoteException { final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); page.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, new ArrayList<>()); @@ -795,28 +795,30 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override - public void invalidateNextPageToken(long nextPageToken, int userId) throws RemoteException { - + public void invalidateNextPageToken(long nextPageToken, UserHandle userHandle) + throws RemoteException { } @Override public void writeQueryResultsToFile(String packageName, String databaseName, ParcelFileDescriptor fileDescriptor, String queryExpression, - Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) + Bundle searchSpecBundle, UserHandle userHandle, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } @Override public void putDocumentsFromFile(String packageName, String databaseName, - ParcelFileDescriptor fileDescriptor, int userId, IAppSearchResultCallback callback) + ParcelFileDescriptor fileDescriptor, UserHandle userHandle, + IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } @Override 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) throws RemoteException { ignore(callback); @@ -824,12 +826,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void removeByDocumentId(String packageName, String databaseName, String namespace, - List ids, int userId, long binderCallStartTimeMillis, + List ids, UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchBatchResultCallback callback) throws RemoteException { final AppSearchBatchResult.Builder builder = new AppSearchBatchResult.Builder<>(); - final String key = getKey(userId, databaseName); + final String key = getKey(userHandle, databaseName); if (!mDocumentMap.containsKey(key)) { for (String id : ids) { builder.setFailure(id, AppSearchResult.RESULT_NOT_FOUND, @@ -852,10 +854,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { @Override public void removeByQuery(String packageName, String databaseName, String queryExpression, - Bundle searchSpecBundle, int userId, long binderCallStartTimeMillis, + Bundle searchSpecBundle, UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchResultCallback callback) throws RemoteException { - final String key = getKey(userId, databaseName); + final String key = getKey(userHandle, databaseName); if (!mDocumentMap.containsKey(key)) { callback.onResult( new AppSearchResultParcel<>(AppSearchResult.newSuccessfulResult(null))); @@ -867,19 +869,18 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override - public void getStorageInfo(String packageName, String databaseName, int userId, + public void getStorageInfo(String packageName, String databaseName, UserHandle userHandle, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } @Override - public void persistToDisk(int userId, long binderCallStartTimeMillis) + public void persistToDisk(UserHandle userHandle, long binderCallStartTimeMillis) throws RemoteException { - } @Override - public void initialize(int userId, long binderCallStartTimeMillis, + public void initialize(UserHandle userHandle, long binderCallStartTimeMillis, IAppSearchResultCallback callback) throws RemoteException { ignore(callback);