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 6477489859488..beb4d24cf17ea 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java @@ -16,18 +16,15 @@ package com.android.server.appsearch; -import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; import android.annotation.NonNull; import android.annotation.Nullable; 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.ArrayMap; -import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.AppSearchLogger; @@ -49,12 +46,6 @@ public final class ImplInstanceManager { @GuardedBy("mInstancesLocked") private final Map mInstancesLocked = new ArrayMap<>(); - private final String mGlobalQuerierPackage; - - private ImplInstanceManager(@NonNull String globalQuerierPackage) { - mGlobalQuerierPackage = globalQuerierPackage; - } - /** * Gets an instance of ImplInstanceManager to be used. * @@ -66,9 +57,7 @@ public final class ImplInstanceManager { if (sImplInstanceManager == null) { synchronized (ImplInstanceManager.class) { if (sImplInstanceManager == null) { - sImplInstanceManager = - new ImplInstanceManager( - getGlobalAppSearchDataQuerierPackageName(context)); + sImplInstanceManager = new ImplInstanceManager(); } } } @@ -91,7 +80,7 @@ public final class ImplInstanceManager { *

If no AppSearchImpl instance exists for the unlocked user, Icing will be initialized and * one will be created. * - * @param context The context + * @param context The system context * @param userHandle The multi-user handle of the device user calling AppSearch * @return An initialized {@link AppSearchImpl} for this user */ @@ -106,7 +95,8 @@ public final class ImplInstanceManager { synchronized (mInstancesLocked) { AppSearchImpl instance = mInstancesLocked.get(userHandle); if (instance == null) { - instance = createImpl(context, userHandle, logger); + Context userContext = context.createContextAsUser(userHandle, /*flags=*/ 0); + instance = createImpl(userContext, userHandle, logger); mInstancesLocked.put(userHandle, instance); } return instance; @@ -177,7 +167,7 @@ public final class ImplInstanceManager { } private AppSearchImpl createImpl( - @NonNull Context context, + @NonNull Context userContext, @NonNull UserHandle userHandle, @Nullable AppSearchLogger logger) throws AppSearchException { @@ -185,33 +175,8 @@ public final class ImplInstanceManager { // TODO(b/181787682): Swap AppSearchImpl and VisibilityStore to accept a UserHandle too return AppSearchImpl.create( appSearchDir, - context, + userContext, userHandle.getIdentifier(), - mGlobalQuerierPackage, /*logger=*/ null); } - - /** - * Returns the global querier package if it's a system package. Otherwise, empty string. - * - * @param context Context of the system service. - */ - @NonNull - private static String getGlobalAppSearchDataQuerierPackageName(@NonNull Context context) { - String globalAppSearchDataQuerierPackage = - context.getString(R.string.config_globalAppSearchDataQuerierPackage); - try { - if (context.getPackageManager() - .getPackageInfoAsUser( - globalAppSearchDataQuerierPackage, - MATCH_FACTORY_ONLY, - UserHandle.USER_SYSTEM) - == null) { - return ""; - } - } catch (PackageManager.NameNotFoundException e) { - return ""; - } - return globalAppSearchDataQuerierPackage; - } } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java index d008f3b43a00f..a940dde69f76a 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java @@ -17,7 +17,6 @@ package com.android.server.appsearch.external.localstorage; import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.addPrefixToDocument; -import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.createPackagePrefix; import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.createPrefix; import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.getDatabaseName; import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.getPackageName; @@ -60,6 +59,7 @@ import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats; import com.android.server.appsearch.external.localstorage.stats.RemoveStats; import com.android.server.appsearch.external.localstorage.stats.SearchStats; +import com.android.server.appsearch.visibilitystore.VisibilityStore; import com.google.android.icing.IcingSearchEngine; import com.google.android.icing.proto.DeleteByQueryResultProto; @@ -98,6 +98,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -199,14 +200,12 @@ public final class AppSearchImpl implements Closeable { @NonNull public static AppSearchImpl create( @NonNull File icingDir, - @NonNull Context context, + @NonNull Context userContext, int userId, - @NonNull String globalQuerierPackage, @Nullable AppSearchLogger logger) throws AppSearchException { Objects.requireNonNull(icingDir); - Objects.requireNonNull(context); - Objects.requireNonNull(globalQuerierPackage); + Objects.requireNonNull(userContext); long totalLatencyStartMillis = SystemClock.elapsedRealtime(); InitializeStats.Builder initStatsBuilder = null; @@ -215,8 +214,7 @@ public final class AppSearchImpl implements Closeable { } AppSearchImpl appSearchImpl = - new AppSearchImpl( - icingDir, context, userId, globalQuerierPackage, initStatsBuilder); + new AppSearchImpl(icingDir, userContext, userId, initStatsBuilder); long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime(); appSearchImpl.initializeVisibilityStore(); @@ -239,9 +237,8 @@ public final class AppSearchImpl implements Closeable { /** @param initStatsBuilder collects stats for initialization if provided. */ private AppSearchImpl( @NonNull File icingDir, - @NonNull Context context, + @NonNull Context userContext, int userId, - @NonNull String globalQuerierPackage, @Nullable InitializeStats.Builder initStatsBuilder) throws AppSearchException { mReadWriteLock.writeLock().lock(); @@ -259,8 +256,7 @@ public final class AppSearchImpl implements Closeable { "Constructing IcingSearchEngine, response", Objects.hashCode(mIcingSearchEngineLocked)); - mVisibilityStoreLocked = - new VisibilityStore(this, context, userId, globalQuerierPackage); + mVisibilityStoreLocked = new VisibilityStore(this, userContext, userId); // The core initialization procedure. If any part of this fails, we bail into // resetLocked(), deleting all data (but hopefully allowing AppSearchImpl to come up). @@ -495,7 +491,8 @@ public final class AppSearchImpl implements Closeable { } mVisibilityStoreLocked.setVisibility( - prefix, + packageName, + databaseName, prefixedSchemasNotPlatformSurfaceable, prefixedSchemasPackageAccessible); @@ -844,17 +841,17 @@ public final class AppSearchImpl implements Closeable { try { throwIfClosedLocked(); + // Convert package filters to prefix filters Set packageFilters = new ArraySet<>(searchSpec.getFilterPackageNames()); Set prefixFilters = new ArraySet<>(); - Set allPrefixes = mNamespaceMapLocked.keySet(); if (packageFilters.isEmpty()) { // Client didn't restrict their search over packages. Try to query over all // packages/prefixes - prefixFilters = allPrefixes; + prefixFilters = mNamespaceMapLocked.keySet(); } else { // Client did restrict their search over packages. Only include the prefixes that // belong to the specified packages. - for (String prefix : allPrefixes) { + for (String prefix : mNamespaceMapLocked.keySet()) { String packageName = getPackageName(prefix); if (packageFilters.contains(packageName)) { prefixFilters.add(prefix); @@ -862,41 +859,50 @@ public final class AppSearchImpl implements Closeable { } } - // Find which schemas the client is allowed to query over. - Set allowedPrefixedSchemas = new ArraySet<>(); - List schemaFilters = searchSpec.getFilterSchemas(); + // Convert schema filters to prefixed schema filters + ArraySet prefixedSchemaFilters = new ArraySet<>(); for (String prefix : prefixFilters) { - String packageName = getPackageName(prefix); - - if (!schemaFilters.isEmpty()) { - for (String schema : schemaFilters) { - // Client specified some schemas to search over, check each one - String prefixedSchema = prefix + schema; - if (packageName.equals(callerPackageName) - || mVisibilityStoreLocked.isSchemaSearchableByCaller( - prefix, prefixedSchema, callerUid)) { - allowedPrefixedSchemas.add(prefixedSchema); - } - } - } else { + List schemaFilters = searchSpec.getFilterSchemas(); + if (schemaFilters.isEmpty()) { // Client didn't specify certain schemas to search over, check all schemas - Map prefixedSchemas = - mSchemaMapLocked.get(prefix); - if (prefixedSchemas != null) { - for (String prefixedSchema : prefixedSchemas.keySet()) { - if (packageName.equals(callerPackageName) - || mVisibilityStoreLocked.isSchemaSearchableByCaller( - prefix, prefixedSchema, callerUid)) { - allowedPrefixedSchemas.add(prefixedSchema); - } - } + prefixedSchemaFilters.addAll(mSchemaMapLocked.get(prefix).keySet()); + } else { + // Client specified some schemas to search over, check each one + for (int i = 0; i < schemaFilters.size(); i++) { + prefixedSchemaFilters.add(prefix + schemaFilters.get(i)); } } } + // Remove the schemas the client is not allowed to search over + Iterator prefixedSchemaIt = prefixedSchemaFilters.iterator(); + while (prefixedSchemaIt.hasNext()) { + String prefixedSchema = prefixedSchemaIt.next(); + String packageName = getPackageName(prefixedSchema); + + boolean allow; + if (packageName.equals(callerPackageName)) { + // Callers can always retrieve their own data + allow = true; + } else { + String databaseName = getDatabaseName(prefixedSchema); + allow = + mVisibilityStoreLocked.isSchemaSearchableByCaller( + packageName, + databaseName, + prefixedSchema, + callerPackageName, + callerUid); + } + + if (!allow) { + prefixedSchemaIt.remove(); + } + } + return doQueryLocked( prefixFilters, - allowedPrefixedSchemas, + prefixedSchemaFilters, queryExpression, searchSpec, sStatsBuilder); @@ -1404,20 +1410,47 @@ public final class AppSearchImpl implements Closeable { mReadWriteLock.writeLock().lock(); try { throwIfClosedLocked(); + Set existingPackages = getPackageToDatabases().keySet(); + if (existingPackages.contains(packageName)) { + existingPackages.remove(packageName); + prunePackageData(existingPackages); + } + } finally { + mReadWriteLock.writeLock().unlock(); + } + } + /** + * Remove all {@link AppSearchSchema}s and {@link GenericDocument}s that doesn't belong to any + * of the given installed packages + * + * @param installedPackages The name of all installed package. + * @throws AppSearchException if we cannot remove the data. + */ + public void prunePackageData(@NonNull Set installedPackages) throws AppSearchException { + mReadWriteLock.writeLock().lock(); + try { + throwIfClosedLocked(); + Map> packageToDatabases = getPackageToDatabases(); + if (installedPackages.containsAll(packageToDatabases.keySet())) { + // No package got removed. We are good. + return; + } + + // Prune schema proto SchemaProto existingSchema = getSchemaProtoLocked(); SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder(); - - String prefix = createPackagePrefix(packageName); for (int i = 0; i < existingSchema.getTypesCount(); i++) { - if (!existingSchema.getTypes(i).getSchemaType().startsWith(prefix)) { + String packageName = getPackageName(existingSchema.getTypes(i).getSchemaType()); + if (installedPackages.contains(packageName)) { newSchemaBuilder.addTypes(existingSchema.getTypes(i)); } } + SchemaProto finalSchema = newSchemaBuilder.build(); - // Apply schema, set force override to true to remove all schemas and documents under - // that package. + // Apply schema, set force override to true to remove all schemas and documents that + // doesn't belong to any of these installed packages. mLogUtil.piiTrace( "clearPackageData.setSchema, request", finalSchema.getTypesCount(), @@ -1432,6 +1465,20 @@ public final class AppSearchImpl implements Closeable { // Determine whether it succeeded. checkSuccess(setSchemaResultProto.getStatus()); + + // Prune cached maps + for (Map.Entry> entry : packageToDatabases.entrySet()) { + String packageName = entry.getKey(); + Set databaseNames = entry.getValue(); + if (!installedPackages.contains(packageName) && databaseNames != null) { + for (String databaseName : databaseNames) { + String removedPrefix = createPrefix(packageName, databaseName); + mSchemaMapLocked.remove(removedPrefix); + mNamespaceMapLocked.remove(removedPrefix); + } + } + } + // TODO(b/145759910) clear visibility setting for package. } finally { mReadWriteLock.writeLock().unlock(); } @@ -1857,14 +1904,6 @@ public final class AppSearchImpl implements Closeable { return schemaProto.getSchema(); } - /** Returns a set of all prefixes AppSearchImpl knows about. */ - // TODO(b/180058203): Remove this method once platform has switched away from using this method. - @GuardedBy("mReadWriteLock") - @NonNull - Set getPrefixesLocked() { - return mSchemaMapLocked.keySet(); - } - private static void addToMap( Map> map, String prefix, String prefixedValue) { Set values = map.get(prefix); diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java index 5afdda280c352..5ad4276d93185 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java @@ -26,36 +26,52 @@ import java.util.Set; * {@link android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem} API. * * This object is not thread safe. - * @hide */ -public class NotPlatformSurfaceableMap { +class NotPlatformSurfaceableMap { /** - * Maps prefixes to the set of prefixed schemas that are platform-hidden within that prefix. + * Maps packages to databases to the set of prefixed schemas that are platform-hidden within + * that database. */ - private final Map> mMap = new ArrayMap<>(); + private final Map>> mMap = new ArrayMap<>(); /** - * Sets the prefixed schemas that are opted out of platform surfacing for the prefix. + * Sets the prefixed schemas that are opted out of platform surfacing for the database. * *

Any existing mappings for this prefix are overwritten. */ - public void setNotPlatformSurfaceable(@NonNull String prefix, @NonNull Set schemas) { - mMap.put(prefix, schemas); + public void setNotPlatformSurfaceable( + @NonNull String packageName, + @NonNull String databaseName, + @NonNull Set prefixedSchemas) { + Map> databaseToSchemas = mMap.get(packageName); + if (databaseToSchemas == null) { + databaseToSchemas = new ArrayMap<>(); + mMap.put(packageName, databaseToSchemas); + } + databaseToSchemas.put(databaseName, prefixedSchemas); } /** * Returns whether the given prefixed schema is platform surfaceable (has not opted out) in the - * given prefix. + * given database. */ - public boolean isSchemaPlatformSurfaceable(@NonNull String prefix, @NonNull String schemaType) { - Set schemaTypes = mMap.get(prefix); + public boolean isSchemaPlatformSurfaceable( + @NonNull String packageName, + @NonNull String databaseName, + @NonNull String prefixedSchema) { + Map> databaseToSchemaType = mMap.get(packageName); + if (databaseToSchemaType == null) { + // No opt-outs for this package + return true; + } + Set schemaTypes = databaseToSchemaType.get(databaseName); if (schemaTypes == null) { - // No opt-outs for this prefix + // No opt-outs for this database return true; } // Some schemas were opted out of being platform-surfaced. As long as this schema // isn't one of those opt-outs, it's surfaceable. - return !schemaTypes.contains(schemaType); + return !schemaTypes.contains(prefixedSchema); } /** Discards all data in the map. */ diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java index 5601ef93490d5..bf8051b42acde 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java @@ -26,9 +26,8 @@ import androidx.annotation.Nullable; * Holds configuration about a package+cert that can access a schema. * * @see android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage - * @hide */ -public class PackageAccessibleDocument extends GenericDocument { +class PackageAccessibleDocument extends GenericDocument { /** Schema type for nested documents that hold package accessible information. */ public static final String SCHEMA_TYPE = "PackageAccessibleType"; diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java index e90e8bf3f1182..2b3934718aed2 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java @@ -28,23 +28,31 @@ import java.util.Set; * {@link android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage} API. * * This object is not thread safe. - * @hide */ -public class PackageAccessibleMap { +class PackageAccessibleMap { /** - * Maps prefixes to prefixed schema types to PackageIdentifiers that have access to that schema. + * Maps packages to databases to prefixed schemas to PackageIdentifiers that have access to that + * schema. */ - private final Map>> mMap = new ArrayMap<>(); + private final Map>>> mMap = + new ArrayMap<>(); /** - * Sets the prefixed schemas that have package visibility in the given prefix. + * Sets the prefixed schemas that have package visibility in the given database. * *

Any existing mappings for this prefix are overwritten. */ public void setPackageAccessible( - @NonNull String prefix, + @NonNull String packageName, + @NonNull String databaseName, @NonNull Map> schemaToPackageIdentifier) { - mMap.put(prefix, schemaToPackageIdentifier); + Map>> databaseToSchemaTypeToVisibility = + mMap.get(packageName); + if (databaseToSchemaTypeToVisibility == null) { + databaseToSchemaTypeToVisibility = new ArrayMap<>(); + mMap.put(packageName, databaseToSchemaTypeToVisibility); + } + databaseToSchemaTypeToVisibility.put(databaseName, schemaToPackageIdentifier); } /** @@ -55,12 +63,20 @@ public class PackageAccessibleMap { */ @NonNull public Set getAccessiblePackages( - @NonNull String prefix, @NonNull String schemaType) { - Map> schemaTypeToVisibility = mMap.get(prefix); + @NonNull String packageName, + @NonNull String databaseName, + @NonNull String prefixedSchema) { + Map>> databaseToSchemaTypeToVisibility = + mMap.get(packageName); + if (databaseToSchemaTypeToVisibility == null) { + return Collections.emptySet(); + } + Map> schemaTypeToVisibility = + databaseToSchemaTypeToVisibility.get(databaseName); if (schemaTypeToVisibility == null) { return Collections.emptySet(); } - Set accessiblePackages = schemaTypeToVisibility.get(schemaType); + Set accessiblePackages = schemaTypeToVisibility.get(prefixedSchema); if (accessiblePackages == null) { return Collections.emptySet(); } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java index 327ce854fc5b1..f2b2621b22b85 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java @@ -21,11 +21,8 @@ import android.app.appsearch.GenericDocument; import androidx.annotation.Nullable; -/** - * Holds the visibility settings that apply to a package's databases. - * @hide - */ -public class VisibilityDocument extends GenericDocument { +/** Holds the visibility settings that apply to a package's databases. */ +class VisibilityDocument extends GenericDocument { /** Schema type for documents that hold AppSearch's metadata, e.g. visibility settings */ public static final String SCHEMA_TYPE = "VisibilityType"; diff --git a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java similarity index 66% rename from apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java rename to apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java index b7e21591a86cf..acff792f1e6c3 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java @@ -13,11 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.android.server.appsearch.visibilitystore; -// TODO(b/169883602): This is purposely a different package from the path so that it can access -// AppSearchImpl's methods without having to make them public. This should be moved into a proper -// package once AppSearchImpl-VisibilityStore's dependencies are refactored. -package com.android.server.appsearch.external.localstorage; +import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA; import android.annotation.NonNull; import android.annotation.UserIdInt; @@ -33,13 +31,10 @@ import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; -import com.android.server.appsearch.visibilitystore.NotPlatformSurfaceableMap; -import com.android.server.appsearch.visibilitystore.PackageAccessibleDocument; -import com.android.server.appsearch.visibilitystore.PackageAccessibleMap; -import com.android.server.appsearch.visibilitystore.VisibilityDocument; import com.google.android.icing.proto.PersistType; @@ -85,38 +80,24 @@ public class VisibilityStore { * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}. */ - static final String PACKAGE_NAME = "VS#Pkg"; + @VisibleForTesting public static final String PACKAGE_NAME = "VS#Pkg"; - static final String DATABASE_NAME = "VS#Db"; - - /** - * Prefix that AppSearchImpl creates for the VisibilityStore based on our package name and - * database name. Tracked here to tell when we're looking at our own prefix when looking through - * AppSearchImpl. - */ - static final String VISIBILITY_STORE_PREFIX = - PrefixUtil.createPrefix(PACKAGE_NAME, DATABASE_NAME); + @VisibleForTesting public static final String DATABASE_NAME = "VS#Db"; /** Namespace of documents that contain visibility settings */ private static final String NAMESPACE = ""; - /** - * Prefix to add to all visibility document ids. IcingSearchEngine doesn't allow empty ids. - */ + /** Prefix to add to all visibility document ids. IcingSearchEngine doesn't allow empty ids. */ private static final String ID_PREFIX = "uri:"; private final AppSearchImpl mAppSearchImpl; - // Context of the system service. - private final Context mContext; + // Context of the user that the call is being made as. + private final Context mUserContext; // User ID of the caller who we're checking visibility settings for. private final int mUserId; - // UID of the package that has platform-query privileges, i.e. can query for all - // platform-surfaceable content. - private int mGlobalQuerierUid; - /** Stores the schemas that are platform-hidden. All values are prefixed. */ private final NotPlatformSurfaceableMap mNotPlatformSurfaceableMap = new NotPlatformSurfaceableMap(); @@ -129,16 +110,15 @@ public class VisibilityStore { * before using the object. * * @param appSearchImpl AppSearchImpl instance + * @param userContext Context of the user that the call is being made as */ public VisibilityStore( @NonNull AppSearchImpl appSearchImpl, - @NonNull Context context, - @UserIdInt int userId, - @NonNull String globalQuerierPackage) { + @NonNull Context userContext, + @UserIdInt int userId) { mAppSearchImpl = appSearchImpl; - mContext = context; + mUserContext = userContext; mUserId = userId; - mGlobalQuerierUid = getGlobalQuerierUid(globalQuerierPackage); } /** @@ -181,28 +161,44 @@ public class VisibilityStore { // Populate visibility settings set mNotPlatformSurfaceableMap.clear(); - for (String prefix : mAppSearchImpl.getPrefixesLocked()) { - if (prefix.equals(VISIBILITY_STORE_PREFIX)) { - // Our own prefix. Skip - continue; + for (Map.Entry> entry : + mAppSearchImpl.getPackageToDatabases().entrySet()) { + String packageName = entry.getKey(); + if (packageName.equals(PACKAGE_NAME)) { + continue; // Our own package. Skip. } - try { - // Note: We use the other clients' prefixed names as ids - VisibilityDocument visibilityDocument = new VisibilityDocument( - mAppSearchImpl.getDocument( - PACKAGE_NAME, - DATABASE_NAME, - NAMESPACE, - /*id=*/ addIdPrefix(prefix), - /*typePropertyPaths=*/ Collections.emptyMap())); + for (String databaseName : entry.getValue()) { + VisibilityDocument visibilityDocument; + try { + // Note: We use the other clients' prefixed names as ids + visibilityDocument = + new VisibilityDocument( + mAppSearchImpl.getDocument( + PACKAGE_NAME, + DATABASE_NAME, + NAMESPACE, + /*id=*/ getVisibilityDocumentId( + packageName, databaseName), + /*typePropertyPaths=*/ Collections.emptyMap())); + } catch (AppSearchException e) { + if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) { + // TODO(b/172068212): This indicates some desync error. We were expecting a + // document, but didn't find one. Should probably reset AppSearch instead + // of ignoring it. + continue; + } + // Otherwise, this is some other error we should pass up. + throw e; + } // Update platform visibility settings String[] notPlatformSurfaceableSchemas = visibilityDocument.getNotPlatformSurfaceableSchemas(); if (notPlatformSurfaceableSchemas != null) { mNotPlatformSurfaceableMap.setNotPlatformSurfaceable( - prefix, + packageName, + databaseName, new ArraySet<>(notPlatformSurfaceableSchemas)); } @@ -226,25 +222,18 @@ public class VisibilityStore { schemaToPackageIdentifierMap.put(prefixedSchema, packageIdentifiers); } } - mPackageAccessibleMap.setPackageAccessible(prefix, schemaToPackageIdentifierMap); - } catch (AppSearchException e) { - if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) { - // TODO(b/172068212): This indicates some desync error. We were expecting a - // document, but didn't find one. Should probably reset AppSearch instead of - // ignoring it. - continue; - } - // Otherwise, this is some other error we should pass up. - throw e; + mPackageAccessibleMap.setPackageAccessible( + packageName, databaseName, schemaToPackageIdentifierMap); } } } /** - * Sets visibility settings for {@code prefix}. Any previous visibility settings will be + * Sets visibility settings for the given database. Any previous visibility settings will be * overwritten. * - * @param prefix Prefix that identifies who owns the {@code schemasNotPlatformSurfaceable}. + * @param packageName Package of app that owns the {@code schemasNotPlatformSurfaceable}. + * @param databaseName Database that owns the {@code schemasNotPlatformSurfaceable}. * @param schemasNotPlatformSurfaceable Set of prefixed schemas that should be hidden from the * platform. * @param schemasPackageAccessible Map of prefixed schemas to a list of package identifiers that @@ -252,17 +241,20 @@ public class VisibilityStore { * @throws AppSearchException on AppSearchImpl error. */ public void setVisibility( - @NonNull String prefix, + @NonNull String packageName, + @NonNull String databaseName, @NonNull Set schemasNotPlatformSurfaceable, @NonNull Map> schemasPackageAccessible) throws AppSearchException { - Objects.requireNonNull(prefix); + Objects.requireNonNull(packageName); + Objects.requireNonNull(databaseName); Objects.requireNonNull(schemasNotPlatformSurfaceable); Objects.requireNonNull(schemasPackageAccessible); // Persist the document VisibilityDocument.Builder visibilityDocument = - new VisibilityDocument.Builder(NAMESPACE, /*id=*/ addIdPrefix(prefix)); + new VisibilityDocument.Builder( + NAMESPACE, /*id=*/ getVisibilityDocumentId(packageName, databaseName)); if (!schemasNotPlatformSurfaceable.isEmpty()) { visibilityDocument.setSchemasNotPlatformSurfaceable( schemasNotPlatformSurfaceable.toArray(new String[0])); @@ -293,29 +285,50 @@ public class VisibilityStore { mAppSearchImpl.persistToDisk(PersistType.Code.LITE); // Update derived data structures. - mNotPlatformSurfaceableMap.setNotPlatformSurfaceable(prefix, schemasNotPlatformSurfaceable); - mPackageAccessibleMap.setPackageAccessible(prefix, schemaToPackageIdentifierMap); + mNotPlatformSurfaceableMap.setNotPlatformSurfaceable( + packageName, databaseName, schemasNotPlatformSurfaceable); + mPackageAccessibleMap.setPackageAccessible( + packageName, databaseName, schemaToPackageIdentifierMap); } - /** Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}. */ + /** + * Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}. + * + * @param packageName Package that owns the schema. + * @param databaseName Database within the package that owns the schema. + * @param prefixedSchema Prefixed schema type the caller is trying to access. + * @param callerPackageName Package name of the caller. + * @param callerUid Uid of the caller. + */ public boolean isSchemaSearchableByCaller( - @NonNull String prefix, @NonNull String prefixedSchema, int callerUid) { - Objects.requireNonNull(prefix); + @NonNull String packageName, + @NonNull String databaseName, + @NonNull String prefixedSchema, + @NonNull String callerPackageName, + int callerUid) { + Objects.requireNonNull(packageName); + Objects.requireNonNull(databaseName); Objects.requireNonNull(prefixedSchema); + Objects.requireNonNull(callerPackageName); - if (prefix.equals(VISIBILITY_STORE_PREFIX)) { + if (packageName.equals(PACKAGE_NAME)) { return false; // VisibilityStore schemas are for internal bookkeeping. } - // We compare appIds here rather than direct uids because the package's uid may change based - // on the user that's running. - if (UserHandle.isSameApp(mGlobalQuerierUid, callerUid) - && mNotPlatformSurfaceableMap.isSchemaPlatformSurfaceable(prefix, prefixedSchema)) { + // TODO(b/180058203): If we can cache or pass in that a caller has the + // READ_GLOBAL_SEARCH_DATA permission, then we can save this package manager lookup for + // each schema we may check in the loop. + if (mNotPlatformSurfaceableMap.isSchemaPlatformSurfaceable( + packageName, databaseName, prefixedSchema) + && mUserContext + .getPackageManager() + .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, callerPackageName) + == PackageManager.PERMISSION_GRANTED) { return true; } // May not be platform surfaceable, but might still be accessible through 3p access. - return isSchemaPackageAccessible(prefix, prefixedSchema, callerUid); + return isSchemaPackageAccessible(packageName, databaseName, prefixedSchema, callerUid); } /** @@ -328,20 +341,32 @@ public class VisibilityStore { * does not handle packages that have been signed by multiple certificates. */ private boolean isSchemaPackageAccessible( - @NonNull String prefix, @NonNull String prefixedSchema, int callerUid) { + @NonNull String packageName, + @NonNull String databaseName, + @NonNull String prefixedSchema, + int callerUid) { Set packageIdentifiers = - mPackageAccessibleMap.getAccessiblePackages(prefix, prefixedSchema); + mPackageAccessibleMap.getAccessiblePackages( + packageName, databaseName, prefixedSchema); for (PackageIdentifier packageIdentifier : packageIdentifiers) { - // Check that the caller uid matches this allowlisted PackageIdentifier. // TODO(b/169883602): Consider caching the UIDs of packages. Looking this up in the // package manager could be costly. We would also need to update the cache on // package-removals. - if (getPackageUidAsUser(packageIdentifier.getPackageName()) != callerUid) { + + // 'callerUid' is the uid of the caller. The 'user' doesn't have to be the same one as + // the callerUid since clients can createContextAsUser with some other user, and then + // make calls to us. So just check if the appId portion of the uid is the same. This is + // essentially UserHandle.isSameApp, but that's not a system API for us to use. + int callerAppId = UserHandle.getAppId((callerUid)); + int userAppId = + UserHandle.getAppId(getPackageUidAsUser(packageIdentifier.getPackageName())); + if (callerAppId != userAppId) { continue; } // Check that the package also has the matching certificate - if (mContext.getPackageManager() + if (mUserContext + .getPackageManager() .hasSigningCertificate( packageIdentifier.getPackageName(), packageIdentifier.getSha256Certificate(), @@ -367,36 +392,14 @@ public class VisibilityStore { /** * Adds a prefix to create a visibility store document's id. * - * @param id Non-prefixed id + * @param packageName Package to which the visibility doc refers + * @param databaseName Database to which the visibility doc refers * @return Prefixed id */ - private static String addIdPrefix(String id) { - return ID_PREFIX + id; - } - - /** - * Finds the uid of the {@code globalQuerierPackage}. {@code globalQuerierPackage} must be a - * pre-installed, system app. Returns {@link Process#INVALID_UID} if unable to find the UID. - */ - private int getGlobalQuerierUid(@NonNull String globalQuerierPackage) { - try { - int flags = - PackageManager.MATCH_DISABLED_COMPONENTS - | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS - | PackageManager.MATCH_SYSTEM_ONLY; - // It doesn't matter that we're using the caller's userId here. We'll eventually check - // that the two uids in question belong to the same appId. - return mContext.getPackageManager() - .getPackageUidAsUser(globalQuerierPackage, flags, mUserId); - } catch (PackageManager.NameNotFoundException e) { - // Global querier doesn't exist. - Log.i( - TAG, - "AppSearch global querier package not found on device: '" - + globalQuerierPackage - + "'"); - } - return Process.INVALID_UID; + @NonNull + private static String getVisibilityDocumentId( + @NonNull String packageName, @NonNull String databaseName) { + return ID_PREFIX + PrefixUtil.createPrefix(packageName, databaseName); } /** @@ -405,7 +408,7 @@ public class VisibilityStore { */ private int getPackageUidAsUser(@NonNull String packageName) { try { - return mContext.getPackageManager().getPackageUidAsUser(packageName, mUserId); + return mUserContext.getPackageManager().getPackageUidAsUser(packageName, mUserId); } catch (PackageManager.NameNotFoundException e) { // Package doesn't exist, continue } diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt index fe9117b8fc597..395292df120a9 100644 --- a/apex/appsearch/synced_jetpack_changeid.txt +++ b/apex/appsearch/synced_jetpack_changeid.txt @@ -1 +1 @@ -be6d5138cbd64d3fd401a83d30bf9ad22a6c2d17 +c35ced970a63a6c7b1d17f9706160579540850d6 diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java index 79e5865abd82e..755795db184b9 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java @@ -19,19 +19,21 @@ // global query integration tests that can test AppSearchImpl-VisibilityStore integration logic. package com.android.server.appsearch.external.localstorage; +import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA; +import static android.content.pm.PackageManager.PERMISSION_DENIED; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import static com.google.common.truth.Truth.assertThat; import android.app.appsearch.AppSearchSchema; -import android.app.appsearch.GenericDocument; import android.app.appsearch.PackageIdentifier; -import android.app.appsearch.SearchResultPage; -import android.app.appsearch.SearchSpec; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.PackageManager; import androidx.test.core.app.ApplicationProvider; +import com.android.compatibility.common.util.SystemUtil; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; import com.google.common.collect.ImmutableList; @@ -43,7 +45,6 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.util.Collections; -import java.util.List; /** This tests AppSearchImpl when it's running with a platform-backed VisibilityStore. */ public class AppSearchImplPlatformTest { @@ -70,126 +71,11 @@ public class AppSearchImplPlatformTest { mTemporaryFolder.newFolder(), mContext, mContext.getUserId(), - mContext.getPackageName(), /*logger=*/ null); + mGlobalQuerierUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0); } - /** - * TODO(b/169883602): This should be an integration test at the cts-level. This is a short-term - * test until we have official support for multiple-apps indexing at once. - */ - @Test - public void testGlobalQueryWithMultiplePackages_noPackageFilters() throws Exception { - // Insert package1 schema - List schema1 = - ImmutableList.of(new AppSearchSchema.Builder("schema1").build()); - mAppSearchImpl.setSchema( - "package1", - "database1", - schema1, - /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), - /*schemasPackageAccessible=*/ Collections.emptyMap(), - /*forceOverride=*/ false, - /*schemaVersion=*/ 0); - - // Insert package2 schema - List schema2 = - ImmutableList.of(new AppSearchSchema.Builder("schema2").build()); - mAppSearchImpl.setSchema( - "package2", - "database2", - schema2, - /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), - /*schemasPackageAccessible=*/ Collections.emptyMap(), - /*forceOverride=*/ false, - /*schemaVersion=*/ 0); - - // Insert package1 document - GenericDocument document1 = - new GenericDocument.Builder<>("namespace", "uri", "schema1").build(); - mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null); - - // Insert package2 document - GenericDocument document2 = - new GenericDocument.Builder<>("namespace", "uri", "schema2").build(); - mAppSearchImpl.putDocument("package2", "database2", document2, /*logger=*/ null); - - // No query filters specified, global query can retrieve all documents. - SearchSpec searchSpec = - new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY).build(); - SearchResultPage searchResultPage = mAppSearchImpl.globalQuery( - "", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null); - assertThat(searchResultPage.getResults()).hasSize(2); - - // Document2 will be first since it got indexed later and has a "better", aka more recent - // score. - assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2); - assertThat(searchResultPage.getResults().get(1).getGenericDocument()).isEqualTo(document1); - } - - /** - * TODO(b/169883602): This should be an integration test at the cts-level. This is a short-term - * test until we have official support for multiple-apps indexing at once. - */ - @Test - public void testGlobalQueryWithMultiplePackages_withPackageFilters() throws Exception { - // Insert package1 schema - List schema1 = - ImmutableList.of(new AppSearchSchema.Builder("schema1").build()); - mAppSearchImpl.setSchema( - "package1", - "database1", - schema1, - /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), - /*schemasPackageAccessible=*/ Collections.emptyMap(), - /*forceOverride=*/ false, - /*schemaVersion=*/ 0); - - // Insert package2 schema - List schema2 = - ImmutableList.of(new AppSearchSchema.Builder("schema2").build()); - mAppSearchImpl.setSchema( - "package2", - "database2", - schema2, - /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), - /*schemasPackageAccessible=*/ Collections.emptyMap(), - /*forceOverride=*/ false, - /*schemaVersion=*/ 0); - - // Insert package1 document - GenericDocument document1 = - new GenericDocument.Builder<>("namespace", "uri", "schema1").build(); - mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null); - - // Insert package2 document - GenericDocument document2 = - new GenericDocument.Builder<>("namespace", "uri", "schema2").build(); - mAppSearchImpl.putDocument("package2", "database2", document2, /*logger=*/ null); - - // "package1" filter specified - SearchSpec searchSpec = - new SearchSpec.Builder() - .setTermMatch(SearchSpec.TERM_MATCH_PREFIX) - .addFilterPackageNames("package1") - .build(); - SearchResultPage searchResultPage = mAppSearchImpl.globalQuery( - "", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null); - assertThat(searchResultPage.getResults()).hasSize(1); - assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1); - - // "package2" filter specified - searchSpec = - new SearchSpec.Builder() - .setTermMatch(SearchSpec.TERM_MATCH_PREFIX) - .addFilterPackageNames("package2") - .build(); - searchResultPage = mAppSearchImpl.globalQuery( - "", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null); - assertThat(searchResultPage.getResults()).hasSize(1); - assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2); - } @Test public void testSetSchema_existingSchemaRetainsVisibilitySetting() throws Exception { @@ -202,6 +88,12 @@ public class AppSearchImplPlatformTest { mMockPackageManager.mockGetPackageUidAsUser(packageNameFoo, mContext.getUserId(), uidFoo); mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); + // Make sure we have global query privileges and "foo" doesn't + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName(), PERMISSION_GRANTED); + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo, PERMISSION_DENIED); + // Set schema1 String prefix = PrefixUtil.createPrefix("package", "database"); mAppSearchImpl.setSchema( @@ -220,12 +112,22 @@ public class AppSearchImplPlatformTest { mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "schema1", mGlobalQuerierUid)) + "package", + "database", + prefix + "schema1", + mContext.getPackageName(), + mGlobalQuerierUid)) .isFalse(); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "schema1", uidFoo)) + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "schema1", + packageNameFoo, + uidFoo)) .isTrue(); // Add a new schema, and include the already-existing "schema1" @@ -243,29 +145,57 @@ public class AppSearchImplPlatformTest { /*schemaVersion=*/ 0); // Check that "schema1" still has the same visibility settings + SystemUtil.runWithShellPermissionIdentity( + () -> { + assertThat( + mAppSearchImpl + .getVisibilityStoreLocked() + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "schema1", + mContext.getPackageName(), + mGlobalQuerierUid)) + .isFalse(); + }, + READ_GLOBAL_APP_SEARCH_DATA); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "schema1", mGlobalQuerierUid)) - .isFalse(); - assertThat( - mAppSearchImpl - .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "schema1", uidFoo)) + "package", + "database", + prefix + "schema1", + packageNameFoo, + uidFoo)) .isTrue(); // "schema2" has default visibility settings + SystemUtil.runWithShellPermissionIdentity( + () -> { + assertThat( + mAppSearchImpl + .getVisibilityStoreLocked() + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "schema2", + mContext.getPackageName(), + mGlobalQuerierUid)) + .isTrue(); + }, + READ_GLOBAL_APP_SEARCH_DATA); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "schema2", mGlobalQuerierUid)) - .isTrue(); - assertThat( - mAppSearchImpl - .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "schema2", uidFoo)) + "package", + "database", + prefix + "schema2", + packageNameFoo, + uidFoo)) .isFalse(); } @@ -280,6 +210,12 @@ public class AppSearchImplPlatformTest { mMockPackageManager.mockGetPackageUidAsUser(packageNameFoo, mContext.getUserId(), uidFoo); mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); + // Make sure we have global query privileges and "foo" doesn't + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName(), PERMISSION_GRANTED); + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo, PERMISSION_DENIED); + String prefix = PrefixUtil.createPrefix("package", "database"); mAppSearchImpl.setSchema( "package", @@ -297,12 +233,22 @@ public class AppSearchImplPlatformTest { mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "schema1", mGlobalQuerierUid)) + "package", + "database", + prefix + "schema1", + mContext.getPackageName(), + mGlobalQuerierUid)) .isFalse(); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "schema1", uidFoo)) + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "schema1", + packageNameFoo, + uidFoo)) .isTrue(); // Remove "schema1" by force overriding @@ -320,12 +266,22 @@ public class AppSearchImplPlatformTest { mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "schema1", mGlobalQuerierUid)) + "package", + "database", + prefix + "schema1", + mContext.getPackageName(), + mGlobalQuerierUid)) .isTrue(); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "schema1", uidFoo)) + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "schema1", + packageNameFoo, + uidFoo)) .isFalse(); // Add "schema1" back, it gets default visibility settings which means it's not platform @@ -338,21 +294,35 @@ public class AppSearchImplPlatformTest { /*schemasPackageAccessible=*/ Collections.emptyMap(), /*forceOverride=*/ false, /*schemaVersion=*/ 0); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "schema1", mGlobalQuerierUid)) + "package", + "database", + prefix + "schema1", + mContext.getPackageName(), + mGlobalQuerierUid)) .isTrue(); assertThat( mAppSearchImpl .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "schema1", uidFoo)) + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "schema1", + packageNameFoo, + uidFoo)) .isFalse(); } @Test public void testSetSchema_defaultPlatformVisible() throws Exception { + // Make sure we have global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName(), PERMISSION_GRANTED); + String prefix = PrefixUtil.createPrefix("package", "database"); mAppSearchImpl.setSchema( "package", @@ -362,16 +332,25 @@ public class AppSearchImplPlatformTest { /*schemasPackageAccessible=*/ Collections.emptyMap(), /*forceOverride=*/ false, /*schemaVersion=*/ 0); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "Schema", mGlobalQuerierUid)) + "package", + "database", + prefix + "Schema", + mContext.getPackageName(), + mGlobalQuerierUid)) .isTrue(); } @Test public void testSetSchema_platformHidden() throws Exception { + // Make sure we have global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName(), PERMISSION_GRANTED); + String prefix = PrefixUtil.createPrefix("package", "database"); mAppSearchImpl.setSchema( "package", @@ -381,16 +360,27 @@ public class AppSearchImplPlatformTest { /*schemasPackageAccessible=*/ Collections.emptyMap(), /*forceOverride=*/ false, /*schemaVersion=*/ 0); + assertThat( mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "Schema", mGlobalQuerierUid)) + "package", + "database", + prefix + "Schema", + mContext.getPackageName(), + mGlobalQuerierUid)) .isFalse(); } @Test public void testSetSchema_defaultNotPackageAccessible() throws Exception { + String packageName = "com.package"; + + // Make sure package doesn't global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageName, PERMISSION_DENIED); + String prefix = PrefixUtil.createPrefix("package", "database"); mAppSearchImpl.setSchema( "package", @@ -404,7 +394,11 @@ public class AppSearchImplPlatformTest { mAppSearchImpl .getVisibilityStoreLocked() .isSchemaSearchableByCaller( - prefix, prefix + "Schema", /*callerUid=*/ 42)) + "package", + "database", + prefix + "Schema", + packageName, + /*callerUid=*/ 42)) .isFalse(); } @@ -419,6 +413,10 @@ public class AppSearchImplPlatformTest { mMockPackageManager.mockGetPackageUidAsUser(packageNameFoo, mContext.getUserId(), uidFoo); mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); + // Make sure foo doesn't have global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo, PERMISSION_DENIED); + String prefix = PrefixUtil.createPrefix("package", "database"); mAppSearchImpl.setSchema( "package", @@ -433,7 +431,12 @@ public class AppSearchImplPlatformTest { assertThat( mAppSearchImpl .getVisibilityStoreLocked() - .isSchemaSearchableByCaller(prefix, prefix + "Schema", uidFoo)) + .isSchemaSearchableByCaller( + "package", + "database", + prefix + "Schema", + packageNameFoo, + uidFoo)) .isTrue(); } } diff --git a/services/tests/servicestests/src/com/android/server/appsearch/MockPackageManager.java b/services/tests/servicestests/src/com/android/server/appsearch/MockPackageManager.java index 459fc53dcc08f..60e1a8f1212b2 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/MockPackageManager.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/MockPackageManager.java @@ -44,6 +44,12 @@ public class MockPackageManager { return mMockPackageManager; } + /** Mock a checkPermission call. */ + public void mockCheckPermission(String permission, String packageName, int permissionResult) { + when(mMockPackageManager.checkPermission(permission, packageName)) + .thenReturn(permissionResult); + } + /** Mock a NameNotFoundException if the package name isn't installed. */ public void mockThrowsNameNotFoundException(String packageName) { try { diff --git a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java index 28955d6e727f7..d9cfc54fd186e 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java @@ -15,10 +15,14 @@ */ // TODO(b/169883602): This is purposely a different package from the path so that it can access -// AppSearchImpl and VisibilityStore methods without having to make methods public. This should be -// moved into a proper package once AppSearchImpl-VisibilityStore's dependencies are refactored. +// AppSearchImpl methods without having to make methods public. This should be moved into a proper +// package once AppSearchImpl-VisibilityStore's dependencies are refactored. package com.android.server.appsearch.external.localstorage; +import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA; +import static android.content.pm.PackageManager.PERMISSION_DENIED; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import static com.google.common.truth.Truth.assertThat; import android.app.appsearch.PackageIdentifier; @@ -29,6 +33,7 @@ import android.content.pm.PackageManager; import androidx.test.core.app.ApplicationProvider; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; +import com.android.server.appsearch.visibilitystore.VisibilityStore; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -48,7 +53,7 @@ public class VisibilityStoreTest { private Context mContext; private AppSearchImpl mAppSearchImpl; private VisibilityStore mVisibilityStore; - private int mGlobalQuerierUid; + private int mUid; @Before public void setUp() throws Exception { @@ -67,11 +72,9 @@ public class VisibilityStoreTest { mTemporaryFolder.newFolder(), mContext, mContext.getUserId(), - /*globalQuerierPackage=*/ mContext.getPackageName(), /*logger=*/ null); - mGlobalQuerierUid = - mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0); + mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0); mVisibilityStore = mAppSearchImpl.getVisibilityStoreLocked(); } @@ -99,83 +102,98 @@ public class VisibilityStoreTest { @Test public void testSetVisibility_platformSurfaceable() throws Exception { + // Make sure we have global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName(), PERMISSION_GRANTED); + mVisibilityStore.setVisibility( - "prefix", + "package", + "database", /*schemasNotPlatformSurfaceable=*/ ImmutableSet.of( "prefix/schema1", "prefix/schema2"), /*schemasPackageAccessible=*/ Collections.emptyMap()); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema1", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema1", + mContext.getPackageName(), + mUid)) .isFalse(); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema2", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema2", + mContext.getPackageName(), + mUid)) .isFalse(); - // New .setVisibility() call completely overrides previous visibility settings. So - // "schema2" isn't preserved. + // New .setVisibility() call completely overrides previous visibility settings. + // So "schema2" isn't preserved. mVisibilityStore.setVisibility( - "prefix", + "package", + "database", /*schemasNotPlatformSurfaceable=*/ ImmutableSet.of( "prefix/schema1", "prefix/schema3"), /*schemasPackageAccessible=*/ Collections.emptyMap()); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema1", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema1", + mContext.getPackageName(), + mUid)) .isFalse(); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema2", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema2", + mContext.getPackageName(), + mUid)) .isTrue(); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema3", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema3", + mContext.getPackageName(), + mUid)) .isFalse(); // Everything defaults to visible again. mVisibilityStore.setVisibility( - "prefix", + "package", + "database", /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(), /*schemasPackageAccessible=*/ Collections.emptyMap()); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema1", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema1", + mContext.getPackageName(), + mUid)) .isTrue(); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema2", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema2", + mContext.getPackageName(), + mUid)) .isTrue(); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schema3", mGlobalQuerierUid)) + "package", + "database", + "prefix/schema3", + mContext.getPackageName(), + mUid)) .isTrue(); } - @Test - public void testIsSchemaSearchableByCaller_platformQuerierHandlesNameNotFoundException() - throws Exception { - // Initialized the VisibilityStore with this context's package name as the global querier. - mMockPackageManager.mockThrowsNameNotFoundException(mContext.getPackageName()); - - // Create a new VisibilityStore instance since we look up the UID on initialization - AppSearchImpl appSearchImpl = - AppSearchImpl.create( - mTemporaryFolder.newFolder(), - mContext, - mContext.getUserId(), - /*globalQuerierPackage=*/ mContext.getPackageName(), - /*logger=*/ null); - VisibilityStore visibilityStore = appSearchImpl.getVisibilityStoreLocked(); - - // Use some arbitrary callerUid. If we can't find the global querier's uid though, - // nothing should be platform surfaceable. - assertThat( - visibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", /*callerUid=*/ 0)) - .isFalse(); - } - @Test public void testSetVisibility_packageAccessible() throws Exception { // Values for a "foo" client @@ -191,19 +209,26 @@ public class VisibilityStoreTest { // Can't be the same value as uidFoo nor uidBar int uidNotFooOrBar = 3; + // Make sure none of them have global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo, PERMISSION_DENIED); + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameBar, PERMISSION_DENIED); + // By default, a schema isn't package accessible. assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", uidFoo)) + "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo)) .isFalse(); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaBar", uidBar)) + "package", "database", "prefix/schemaBar", packageNameBar, uidBar)) .isFalse(); // Grant package access mVisibilityStore.setVisibility( - "prefix", + "package", + "database", /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(), /*schemasPackageAccessible=*/ ImmutableMap.of( "prefix/schemaFoo", @@ -216,7 +241,7 @@ public class VisibilityStoreTest { mMockPackageManager.mockRemoveSigningCertificate(packageNameFoo, sha256CertFoo); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", uidFoo)) + "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo)) .isFalse(); // Should fail if PackageManager doesn't think the package belongs to the uid @@ -225,7 +250,7 @@ public class VisibilityStoreTest { mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", uidFoo)) + "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo)) .isFalse(); // But if uid and certificate match, then we should have access @@ -233,20 +258,21 @@ public class VisibilityStoreTest { mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", uidFoo)) + "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo)) .isTrue(); mMockPackageManager.mockGetPackageUidAsUser(packageNameBar, mContext.getUserId(), uidBar); mMockPackageManager.mockAddSigningCertificate(packageNameBar, sha256CertBar); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaBar", uidBar)) + "package", "database", "prefix/schemaBar", packageNameBar, uidBar)) .isTrue(); // New .setVisibility() call completely overrides previous visibility settings. So // "schemaBar" settings aren't preserved. mVisibilityStore.setVisibility( - "prefix", + "package", + "database", /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(), /*schemasPackageAccessible=*/ ImmutableMap.of( "prefix/schemaFoo", @@ -256,14 +282,14 @@ public class VisibilityStoreTest { mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", uidFoo)) + "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo)) .isTrue(); mMockPackageManager.mockGetPackageUidAsUser(packageNameBar, mContext.getUserId(), uidBar); mMockPackageManager.mockAddSigningCertificate(packageNameBar, sha256CertBar); assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaBar", uidBar)) + "package", "database", "prefix/schemaBar", packageNameBar, uidBar)) .isFalse(); } @@ -278,9 +304,14 @@ public class VisibilityStoreTest { // Pretend we can't find the Foo package. mMockPackageManager.mockThrowsNameNotFoundException(packageNameFoo); + // Make sure "foo" doesn't have global query privileges + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo, PERMISSION_DENIED); + // Grant package access mVisibilityStore.setVisibility( - "prefix", + "package", + "database", /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(), /*schemasPackageAccessible=*/ ImmutableMap.of( "prefix/schemaFoo", @@ -289,7 +320,7 @@ public class VisibilityStoreTest { // If we can't verify the Foo package that has access, assume it doesn't have access. assertThat( mVisibilityStore.isSchemaSearchableByCaller( - "prefix", "prefix/schemaFoo", uidFoo)) + "package", "database", "prefix/schemaFoo", packageNameFoo, uidFoo)) .isFalse(); } @@ -300,8 +331,15 @@ public class VisibilityStoreTest { byte[] sha256CertFoo = new byte[] {10}; int uidFoo = 1; + // Set it up such that the test package has global query privileges, but "foo" doesn't. + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName(), PERMISSION_GRANTED); + mMockPackageManager.mockCheckPermission( + READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo, PERMISSION_DENIED); + mVisibilityStore.setVisibility( - /*prefix=*/ "", + /*packageName=*/ "", + /*databaseName=*/ "", /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(), /*schemasPackageAccessible=*/ ImmutableMap.of( "schema", @@ -309,12 +347,22 @@ public class VisibilityStoreTest { assertThat( mVisibilityStore.isSchemaSearchableByCaller( - /*prefix=*/ "", "schema", mGlobalQuerierUid)) + /*packageName=*/ "", + /*databaseName=*/ "", + "schema", + mContext.getPackageName(), + mUid)) .isTrue(); mMockPackageManager.mockGetPackageUidAsUser(packageNameFoo, mContext.getUserId(), uidFoo); mMockPackageManager.mockAddSigningCertificate(packageNameFoo, sha256CertFoo); - assertThat(mVisibilityStore.isSchemaSearchableByCaller(/*prefix=*/ "", "schema", uidFoo)) + assertThat( + mVisibilityStore.isSchemaSearchableByCaller( + /*packageName=*/ "", + /*databaseName=*/ "", + "schema", + packageNameFoo, + uidFoo)) .isTrue(); } } diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java index 4cac5233f3460..031532bc03ff8 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java @@ -55,6 +55,7 @@ import com.android.server.appsearch.proto.SearchSpecProto; import com.android.server.appsearch.proto.StatusProto; import com.android.server.appsearch.proto.StringIndexingConfig; import com.android.server.appsearch.proto.TermMatchType; +import com.android.server.appsearch.visibilitystore.VisibilityStore; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -86,7 +87,6 @@ public class AppSearchImplTest { mTemporaryFolder.newFolder(), context, VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ context.getPackageName(), /*logger=*/ null); } @@ -496,11 +496,7 @@ public class AppSearchImplTest { File appsearchDir = mTemporaryFolder.newFolder(); AppSearchImpl appSearchImpl = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); // Insert schema List schemas = @@ -563,11 +559,7 @@ public class AppSearchImplTest { appSearchImpl.close(); appSearchImpl = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ context.getPackageName(), - testLogger); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, testLogger); // Check recovery state InitializeStats initStats = testLogger.mInitializeStats; @@ -1163,6 +1155,7 @@ public class AppSearchImplTest { public void testClearPackageData() throws AppSearchException { List existingSchemas = mAppSearchImpl.getSchemaProtoLocked().getTypesList(); + Map> existingDatabases = mAppSearchImpl.getPackageToDatabases(); // Insert package schema List schema = @@ -1210,6 +1203,67 @@ public class AppSearchImplTest { // Verify the schema is cleared. assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList()) .containsExactlyElementsIn(existingSchemas); + assertThat(mAppSearchImpl.getPackageToDatabases()) + .containsExactlyEntriesIn(existingDatabases); + } + + @Test + public void testPrunePackageData() throws AppSearchException { + List existingSchemas = + mAppSearchImpl.getSchemaProtoLocked().getTypesList(); + Map> existingDatabases = mAppSearchImpl.getPackageToDatabases(); + + Set existingPackages = new ArraySet<>(existingSchemas.size()); + for (int i = 0; i < existingSchemas.size(); i++) { + existingPackages.add(PrefixUtil.getPackageName(existingSchemas.get(i).getSchemaType())); + } + + // Insert schema for package A and B. + List schema = + ImmutableList.of(new AppSearchSchema.Builder("schema").build()); + mAppSearchImpl.setSchema( + "packageA", + "database", + schema, + /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), + /*schemasPackageAccessible=*/ Collections.emptyMap(), + /*forceOverride=*/ false, + /*version=*/ 0); + mAppSearchImpl.setSchema( + "packageB", + "database", + schema, + /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), + /*schemasPackageAccessible=*/ Collections.emptyMap(), + /*forceOverride=*/ false, + /*version=*/ 0); + + // Verify these two packages is stored in AppSearch + SchemaProto expectedProto = + SchemaProto.newBuilder() + .addTypes( + SchemaTypeConfigProto.newBuilder() + .setSchemaType("packageA$database/schema") + .setVersion(0)) + .addTypes( + SchemaTypeConfigProto.newBuilder() + .setSchemaType("packageB$database/schema") + .setVersion(0)) + .build(); + List expectedTypes = new ArrayList<>(); + expectedTypes.addAll(existingSchemas); + expectedTypes.addAll(expectedProto.getTypesList()); + assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList()) + .containsExactlyElementsIn(expectedTypes); + + // Prune packages + mAppSearchImpl.prunePackageData(existingPackages); + + // Verify the schema is same as beginning. + assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList()) + .containsExactlyElementsIn(existingSchemas); + assertThat(mAppSearchImpl.getPackageToDatabases()) + .containsExactlyEntriesIn(existingDatabases); } @Test @@ -1258,36 +1312,6 @@ public class AppSearchImplTest { .containsExactlyEntriesIn(expectedMapping); } - @Test - public void testGetPrefixes() throws Exception { - Set existingPrefixes = mAppSearchImpl.getPrefixesLocked(); - - // Has database1 - Set expectedPrefixes = new ArraySet<>(existingPrefixes); - expectedPrefixes.add(createPrefix("package", "database1")); - mAppSearchImpl.setSchema( - "package", - "database1", - Collections.singletonList(new AppSearchSchema.Builder("schema").build()), - /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), - /*schemasPackageAccessible=*/ Collections.emptyMap(), - /*forceOverride=*/ false, - /*version=*/ 0); - assertThat(mAppSearchImpl.getPrefixesLocked()).containsExactlyElementsIn(expectedPrefixes); - - // Has both databases - expectedPrefixes.add(createPrefix("package", "database2")); - mAppSearchImpl.setSchema( - "package", - "database2", - Collections.singletonList(new AppSearchSchema.Builder("schema").build()), - /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), - /*schemasPackageAccessible=*/ Collections.emptyMap(), - /*forceOverride=*/ false, - /*version=*/ 0); - assertThat(mAppSearchImpl.getPrefixesLocked()).containsExactlyElementsIn(expectedPrefixes); - } - @Test public void testRewriteSearchResultProto() throws Exception { final String prefix = @@ -1665,7 +1689,6 @@ public class AppSearchImplTest { mTemporaryFolder.newFolder(), context, VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", /*logger=*/ null); // Initial check that we could do something at first. @@ -1815,11 +1838,7 @@ public class AppSearchImplTest { File appsearchDir = mTemporaryFolder.newFolder(); AppSearchImpl appSearchImpl = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); List schemas = Collections.singletonList(new AppSearchSchema.Builder("type").build()); @@ -1846,11 +1865,7 @@ public class AppSearchImplTest { // That document should be visible even from another instance. AppSearchImpl appSearchImpl2 = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); getResult = appSearchImpl2.getDocument( "package", "database", "namespace1", "id1", Collections.emptyMap()); @@ -1864,11 +1879,7 @@ public class AppSearchImplTest { File appsearchDir = mTemporaryFolder.newFolder(); AppSearchImpl appSearchImpl = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); List schemas = Collections.singletonList(new AppSearchSchema.Builder("type").build()); @@ -1919,11 +1930,7 @@ public class AppSearchImplTest { // Only the second document should be retrievable from another instance. AppSearchImpl appSearchImpl2 = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); expectThrows( AppSearchException.class, () -> @@ -1946,11 +1953,7 @@ public class AppSearchImplTest { File appsearchDir = mTemporaryFolder.newFolder(); AppSearchImpl appSearchImpl = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); List schemas = Collections.singletonList(new AppSearchSchema.Builder("type").build()); @@ -2009,11 +2012,7 @@ public class AppSearchImplTest { // Only the second document should be retrievable from another instance. AppSearchImpl appSearchImpl2 = AppSearchImpl.create( - appsearchDir, - context, - VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ "", - /*logger=*/ null); + appsearchDir, context, VisibilityStore.NO_OP_USER_ID, /*logger=*/ null); expectThrows( AppSearchException.class, () -> diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java index 190e173b6dcc5..d1ca7596964bb 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java @@ -40,6 +40,7 @@ import com.android.server.appsearch.proto.PutDocumentStatsProto; import com.android.server.appsearch.proto.QueryStatsProto; import com.android.server.appsearch.proto.ScoringSpecProto; import com.android.server.appsearch.proto.TermMatchType; +import com.android.server.appsearch.visibilitystore.VisibilityStore; import org.junit.Before; import org.junit.Rule; @@ -64,7 +65,6 @@ public class AppSearchLoggerTest { mTemporaryFolder.newFolder(), context, VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ context.getPackageName(), /*logger=*/ null); mLogger = new TestLogger(); } @@ -293,7 +293,6 @@ public class AppSearchLoggerTest { mTemporaryFolder.newFolder(), context, VisibilityStore.NO_OP_USER_ID, - /*globalQuerierPackage=*/ context.getPackageName(), mLogger); InitializeStats iStats = mLogger.mInitializeStats;