Loading apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java +36 −6 Original line number Diff line number Diff line Loading @@ -297,11 +297,26 @@ public final class SetSchemaRequest { } /** * Sets the {@link Migrator}. * Sets the {@link Migrator} associated with the given SchemaType. * * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type * from the current version number stored in AppSearch to the final version set via {@link * #setVersion}. * * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch * is different from the final version set via {@link #setVersion} and {@link * Migrator#shouldMigrate} returns {@code true}. * * <p>The target schema type of the output {@link GenericDocument} of {@link * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link * SetSchemaRequest}. * * @param schemaType The schema type to set migrator on. * @param migrator The migrator translate a document from it's old version to a new * incompatible version. * @param migrator The migrator translates a document from its current version to the final * version set via {@link #setVersion}. * @see SetSchemaRequest.Builder#setVersion * @see SetSchemaRequest.Builder#addSchemas * @see AppSearchSession#setSchema */ @NonNull @SuppressLint("MissingGetterMatchingBuilder") // Getter return plural objects. Loading @@ -313,10 +328,25 @@ public final class SetSchemaRequest { } /** * Sets {@link Migrator}s. * Sets a Map of {@link Migrator}s. * * @param migrators A {@link Map} of migrators that translate a document from its old * version to a new incompatible version. * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type * from the current version number stored in AppSearch to the final version set via {@link * #setVersion}. * * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch * is different from the final version set via {@link #setVersion} and {@link * Migrator#shouldMigrate} returns {@code true}. * * <p>The target schema type of the output {@link GenericDocument} of {@link * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link * SetSchemaRequest}. * * @param migrators A {@link Map} of migrators that translate a document from it's current * version to the final version set via {@link #setVersion}. * @see SetSchemaRequest.Builder#setVersion * @see SetSchemaRequest.Builder#addSchemas * @see AppSearchSession#setSchema */ @NonNull public Builder setMigrators(@NonNull Map<String, Migrator> migrators) { Loading apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +40 −1 Original line number Diff line number Diff line Loading @@ -1126,6 +1126,40 @@ public final class AppSearchImpl implements Closeable { } } /** * Remove all {@link AppSearchSchema}s and {@link GenericDocument}s under the given package. * * @param packageName The name of package to be removed. * @throws AppSearchException if we cannot remove the data. */ public void clearPackageData(@NonNull String packageName) throws AppSearchException { mReadWriteLock.writeLock().lock(); try { throwIfClosedLocked(); 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)) { newSchemaBuilder.addTypes(existingSchema.getTypes(i)); } } // Apply schema, set force override to true to remove all schemas and documents under // that package. SetSchemaResultProto setSchemaResultProto = mIcingSearchEngineLocked.setSchema( newSchemaBuilder.build(), /*ignoreErrorsAndDeleteDocuments=*/ true); // Determine whether it succeeded. checkSuccess(setSchemaResultProto.getStatus()); } finally { mReadWriteLock.writeLock().unlock(); } } /** * Clears documents and schema across all packages and databaseNames. * Loading Loading @@ -1624,7 +1658,12 @@ public final class AppSearchImpl implements Closeable { @NonNull static String createPrefix(@NonNull String packageName, @NonNull String databaseName) { return packageName + PACKAGE_DELIMITER + databaseName + DATABASE_DELIMITER; return createPackagePrefix(packageName) + databaseName + DATABASE_DELIMITER; } @NonNull private static String createPackagePrefix(@NonNull String packageName) { return packageName + PACKAGE_DELIMITER; } /** Loading apex/appsearch/synced_jetpack_changeid.txt +1 −1 Original line number Diff line number Diff line Ibbd3a92ad091f6911de652e2ba7e44f555a70a72 I925ec12f4901c7759976c344ba3428210aada8ad services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -987,6 +987,49 @@ public class AppSearchImplTest { .containsExactlyElementsIn(expectedTypes); } @Test public void testClearPackageData() throws AppSearchException { List<SchemaTypeConfigProto> existingSchemas = mAppSearchImpl.getSchemaProtoLocked().getTypesList(); // Insert package schema List<AppSearchSchema> schema = ImmutableList.of(new AppSearchSchema.Builder("schema").build()); mAppSearchImpl.setSchema( "package", "database", schema, /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), /*schemasPackageAccessible=*/ Collections.emptyMap(), /*forceOverride=*/ false, /*version=*/ 0); // Insert package document GenericDocument document = new GenericDocument.Builder<>("namespace", "uri", "schema").build(); mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null); // Verify the document is indexed. SearchSpec searchSpec = new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build(); SearchResultPage searchResultPage = mAppSearchImpl.query("package", "database", /*queryExpression=*/ "", searchSpec); assertThat(searchResultPage.getResults()).hasSize(1); assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document); // Remove the package mAppSearchImpl.clearPackageData("package"); // Verify the document is cleared. searchResultPage = mAppSearchImpl.query("package2", "database2", /*queryExpression=*/ "", searchSpec); assertThat(searchResultPage.getResults()).isEmpty(); // Verify the schema is cleared. assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList()) .containsExactlyElementsIn(existingSchemas); } @Test public void testGetPackageToDatabases() throws Exception { Map<String, Set<String>> existingMapping = mAppSearchImpl.getPackageToDatabases(); Loading Loading
apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java +36 −6 Original line number Diff line number Diff line Loading @@ -297,11 +297,26 @@ public final class SetSchemaRequest { } /** * Sets the {@link Migrator}. * Sets the {@link Migrator} associated with the given SchemaType. * * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type * from the current version number stored in AppSearch to the final version set via {@link * #setVersion}. * * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch * is different from the final version set via {@link #setVersion} and {@link * Migrator#shouldMigrate} returns {@code true}. * * <p>The target schema type of the output {@link GenericDocument} of {@link * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link * SetSchemaRequest}. * * @param schemaType The schema type to set migrator on. * @param migrator The migrator translate a document from it's old version to a new * incompatible version. * @param migrator The migrator translates a document from its current version to the final * version set via {@link #setVersion}. * @see SetSchemaRequest.Builder#setVersion * @see SetSchemaRequest.Builder#addSchemas * @see AppSearchSession#setSchema */ @NonNull @SuppressLint("MissingGetterMatchingBuilder") // Getter return plural objects. Loading @@ -313,10 +328,25 @@ public final class SetSchemaRequest { } /** * Sets {@link Migrator}s. * Sets a Map of {@link Migrator}s. * * @param migrators A {@link Map} of migrators that translate a document from its old * version to a new incompatible version. * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type * from the current version number stored in AppSearch to the final version set via {@link * #setVersion}. * * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch * is different from the final version set via {@link #setVersion} and {@link * Migrator#shouldMigrate} returns {@code true}. * * <p>The target schema type of the output {@link GenericDocument} of {@link * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link * SetSchemaRequest}. * * @param migrators A {@link Map} of migrators that translate a document from it's current * version to the final version set via {@link #setVersion}. * @see SetSchemaRequest.Builder#setVersion * @see SetSchemaRequest.Builder#addSchemas * @see AppSearchSession#setSchema */ @NonNull public Builder setMigrators(@NonNull Map<String, Migrator> migrators) { Loading
apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +40 −1 Original line number Diff line number Diff line Loading @@ -1126,6 +1126,40 @@ public final class AppSearchImpl implements Closeable { } } /** * Remove all {@link AppSearchSchema}s and {@link GenericDocument}s under the given package. * * @param packageName The name of package to be removed. * @throws AppSearchException if we cannot remove the data. */ public void clearPackageData(@NonNull String packageName) throws AppSearchException { mReadWriteLock.writeLock().lock(); try { throwIfClosedLocked(); 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)) { newSchemaBuilder.addTypes(existingSchema.getTypes(i)); } } // Apply schema, set force override to true to remove all schemas and documents under // that package. SetSchemaResultProto setSchemaResultProto = mIcingSearchEngineLocked.setSchema( newSchemaBuilder.build(), /*ignoreErrorsAndDeleteDocuments=*/ true); // Determine whether it succeeded. checkSuccess(setSchemaResultProto.getStatus()); } finally { mReadWriteLock.writeLock().unlock(); } } /** * Clears documents and schema across all packages and databaseNames. * Loading Loading @@ -1624,7 +1658,12 @@ public final class AppSearchImpl implements Closeable { @NonNull static String createPrefix(@NonNull String packageName, @NonNull String databaseName) { return packageName + PACKAGE_DELIMITER + databaseName + DATABASE_DELIMITER; return createPackagePrefix(packageName) + databaseName + DATABASE_DELIMITER; } @NonNull private static String createPackagePrefix(@NonNull String packageName) { return packageName + PACKAGE_DELIMITER; } /** Loading
apex/appsearch/synced_jetpack_changeid.txt +1 −1 Original line number Diff line number Diff line Ibbd3a92ad091f6911de652e2ba7e44f555a70a72 I925ec12f4901c7759976c344ba3428210aada8ad
services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -987,6 +987,49 @@ public class AppSearchImplTest { .containsExactlyElementsIn(expectedTypes); } @Test public void testClearPackageData() throws AppSearchException { List<SchemaTypeConfigProto> existingSchemas = mAppSearchImpl.getSchemaProtoLocked().getTypesList(); // Insert package schema List<AppSearchSchema> schema = ImmutableList.of(new AppSearchSchema.Builder("schema").build()); mAppSearchImpl.setSchema( "package", "database", schema, /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(), /*schemasPackageAccessible=*/ Collections.emptyMap(), /*forceOverride=*/ false, /*version=*/ 0); // Insert package document GenericDocument document = new GenericDocument.Builder<>("namespace", "uri", "schema").build(); mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null); // Verify the document is indexed. SearchSpec searchSpec = new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build(); SearchResultPage searchResultPage = mAppSearchImpl.query("package", "database", /*queryExpression=*/ "", searchSpec); assertThat(searchResultPage.getResults()).hasSize(1); assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document); // Remove the package mAppSearchImpl.clearPackageData("package"); // Verify the document is cleared. searchResultPage = mAppSearchImpl.query("package2", "database2", /*queryExpression=*/ "", searchSpec); assertThat(searchResultPage.getResults()).isEmpty(); // Verify the schema is cleared. assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList()) .containsExactlyElementsIn(existingSchemas); } @Test public void testGetPackageToDatabases() throws Exception { Map<String, Set<String>> existingMapping = mAppSearchImpl.getPackageToDatabases(); Loading