From 1ae91ee03a08a4f0391f0f90e2797fb3c2e02960 Mon Sep 17 00:00:00 2001 From: Alexander Dorokhine Date: Wed, 18 Nov 2020 16:39:25 -0800 Subject: Update Icing from upstream. Change-Id: Ic022a44e876a6060a47e0db991e63b2b73807769 --- .../google/android/icing/IcingSearchEngine.java | 38 +++- .../android/icing/IcingSearchEngineTest.java | 222 +++++++++++---------- 2 files changed, 147 insertions(+), 113 deletions(-) (limited to 'java') diff --git a/java/src/com/google/android/icing/IcingSearchEngine.java b/java/src/com/google/android/icing/IcingSearchEngine.java index 125da12..0902921 100644 --- a/java/src/com/google/android/icing/IcingSearchEngine.java +++ b/java/src/com/google/android/icing/IcingSearchEngine.java @@ -30,6 +30,7 @@ import com.google.android.icing.proto.InitializeResultProto; import com.google.android.icing.proto.OptimizeResultProto; import com.google.android.icing.proto.PersistToDiskResultProto; import com.google.android.icing.proto.PutResultProto; +import com.google.android.icing.proto.ReportUsageResultProto; import com.google.android.icing.proto.ResetResultProto; import com.google.android.icing.proto.ResultSpecProto; import com.google.android.icing.proto.SchemaProto; @@ -38,6 +39,7 @@ import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.proto.SetSchemaResultProto; import com.google.android.icing.proto.StatusProto; +import com.google.android.icing.proto.UsageReport; import com.google.android.icing.protobuf.ExtensionRegistryLite; import com.google.android.icing.protobuf.InvalidProtocolBufferException; @@ -48,7 +50,7 @@ public final class IcingSearchEngine { private static final ExtensionRegistryLite EXTENSION_REGISTRY_LITE = ExtensionRegistryLite.getEmptyRegistry(); - private final long nativePointer; + private long nativePointer; static { // NOTE: This can fail with an UnsatisfiedLinkError @@ -191,6 +193,26 @@ public final class IcingSearchEngine { } } + @NonNull + public ReportUsageResultProto reportUsage(@NonNull UsageReport usageReport) { + byte[] reportUsageResultBytes = nativeReportUsage(nativePointer, usageReport.toByteArray()); + if (reportUsageResultBytes == null) { + Log.e(TAG, "Received null ReportUsageResultProto from native."); + return ReportUsageResultProto.newBuilder() + .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.INTERNAL)) + .build(); + } + + try { + return ReportUsageResultProto.parseFrom(reportUsageResultBytes, EXTENSION_REGISTRY_LITE); + } catch (InvalidProtocolBufferException e) { + Log.e(TAG, "Error parsing ReportUsageResultProto.", e); + return ReportUsageResultProto.newBuilder() + .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.INTERNAL)) + .build(); + } + } + @NonNull public GetAllNamespacesResultProto getAllNamespaces() { byte[] getAllNamespacesResultBytes = nativeGetAllNamespaces(nativePointer); @@ -338,8 +360,7 @@ public final class IcingSearchEngine { } try { - return DeleteResultProto.parseFrom( - deleteResultBytes, EXTENSION_REGISTRY_LITE); + return DeleteResultProto.parseFrom(deleteResultBytes, EXTENSION_REGISTRY_LITE); } catch (InvalidProtocolBufferException e) { Log.e(TAG, "Error parsing DeleteResultProto.", e); return DeleteResultProto.newBuilder() @@ -429,8 +450,17 @@ public final class IcingSearchEngine { } } + public void destroy() { + if (nativePointer != 0) { + nativeDestroy(nativePointer); + } + nativePointer = 0; + } + private static native long nativeCreate(byte[] icingSearchEngineOptionsBytes); + private static native void nativeDestroy(long nativePointer); + private static native byte[] nativeInitialize(long nativePointer); private static native byte[] nativeSetSchema( @@ -444,6 +474,8 @@ public final class IcingSearchEngine { private static native byte[] nativeGet(long nativePointer, String namespace, String uri); + private static native byte[] nativeReportUsage(long nativePointer, byte[] usageReportBytes); + private static native byte[] nativeGetAllNamespaces(long nativePointer); private static native byte[] nativeSearch( diff --git a/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java b/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java index 4c05a7a..ee8ff37 100644 --- a/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java +++ b/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java @@ -33,6 +33,7 @@ import com.google.android.icing.proto.PersistToDiskResultProto; import com.google.android.icing.proto.PropertyConfigProto; import com.google.android.icing.proto.PropertyProto; import com.google.android.icing.proto.PutResultProto; +import com.google.android.icing.proto.ReportUsageResultProto; import com.google.android.icing.proto.ResetResultProto; import com.google.android.icing.proto.ResultSpecProto; import com.google.android.icing.proto.SchemaProto; @@ -45,10 +46,12 @@ import com.google.android.icing.proto.StatusProto; import com.google.android.icing.proto.StringIndexingConfig; import com.google.android.icing.proto.StringIndexingConfig.TokenizerType; import com.google.android.icing.proto.TermMatchType; +import com.google.android.icing.proto.UsageReport; import com.google.android.icing.IcingSearchEngine; import java.io.File; import java.util.HashMap; import java.util.Map; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -68,6 +71,8 @@ public final class IcingSearchEngineTest { private File tempDir; + private IcingSearchEngine icingSearchEngine; + private static SchemaTypeConfigProto createEmailTypeConfig() { return SchemaTypeConfigProto.newBuilder() .setSchemaType(EMAIL_TYPE) @@ -104,77 +109,72 @@ public final class IcingSearchEngineTest { @Before public void setUp() throws Exception { tempDir = temporaryFolder.newFolder(); + IcingSearchEngineOptions options = + IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); + icingSearchEngine = new IcingSearchEngine(options); + } + + @After + public void tearDown() throws Exception { + icingSearchEngine.destroy(); } @Test public void testInitialize() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - - InitializeResultProto initializeResultProto = icing.initialize(); + InitializeResultProto initializeResultProto = icingSearchEngine.initialize(); assertStatusOk(initializeResultProto.getStatus()); } @Test public void testSetAndGetSchema() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); SetSchemaResultProto setSchemaResultProto = - icing.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false); + icingSearchEngine.setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false); assertStatusOk(setSchemaResultProto.getStatus()); - GetSchemaResultProto getSchemaResultProto = icing.getSchema(); + GetSchemaResultProto getSchemaResultProto = icingSearchEngine.getSchema(); assertStatusOk(getSchemaResultProto.getStatus()); assertThat(getSchemaResultProto.getSchema()).isEqualTo(schema); GetSchemaTypeResultProto getSchemaTypeResultProto = - icing.getSchemaType(emailTypeConfig.getSchemaType()); + icingSearchEngine.getSchemaType(emailTypeConfig.getSchemaType()); assertStatusOk(getSchemaTypeResultProto.getStatus()); assertThat(getSchemaTypeResultProto.getSchemaTypeConfig()).isEqualTo(emailTypeConfig); } @Test public void testPutAndGetDocuments() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing + icingSearchEngine .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) .getStatus() .getCode()) .isEqualTo(StatusProto.Code.OK); DocumentProto emailDocument = createEmailDocument("namespace", "uri"); - PutResultProto putResultProto = icing.put(emailDocument); + PutResultProto putResultProto = icingSearchEngine.put(emailDocument); assertStatusOk(putResultProto.getStatus()); - GetResultProto getResultProto = icing.get("namespace", "uri"); + GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri"); assertStatusOk(getResultProto.getStatus()); assertThat(getResultProto.getDocument()).isEqualTo(emailDocument); } @Test public void testSearch() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing + icingSearchEngine .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) .getStatus() .getCode()) @@ -184,7 +184,7 @@ public final class IcingSearchEngineTest { createEmailDocument("namespace", "uri").toBuilder() .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo")) .build(); - assertStatusOk(icing.put(emailDocument).getStatus()); + assertStatusOk(icingSearchEngine.put(emailDocument).getStatus()); SearchSpecProto searchSpec = SearchSpecProto.newBuilder() @@ -193,7 +193,7 @@ public final class IcingSearchEngineTest { .build(); SearchResultProto searchResultProto = - icing.search( + icingSearchEngine.search( searchSpec, ScoringSpecProto.getDefaultInstance(), ResultSpecProto.getDefaultInstance()); @@ -204,15 +204,12 @@ public final class IcingSearchEngineTest { @Test public void testGetNextPage() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing + icingSearchEngine .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) .getStatus() .getCode()) @@ -225,8 +222,8 @@ public final class IcingSearchEngineTest { .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo")) .build(); documents.put("uri:" + i, emailDocument); - assertWithMessage(icing.put(emailDocument).getStatus().getMessage()) - .that(icing.put(emailDocument).getStatus().getCode()) + assertWithMessage(icingSearchEngine.put(emailDocument).getStatus().getMessage()) + .that(icingSearchEngine.put(emailDocument).getStatus().getCode()) .isEqualTo(StatusProto.Code.OK); } @@ -238,7 +235,8 @@ public final class IcingSearchEngineTest { ResultSpecProto resultSpecProto = ResultSpecProto.newBuilder().setNumPerPage(1).build(); SearchResultProto searchResultProto = - icing.search(searchSpec, ScoringSpecProto.getDefaultInstance(), resultSpecProto); + icingSearchEngine.search( + searchSpec, ScoringSpecProto.getDefaultInstance(), resultSpecProto); assertStatusOk(searchResultProto.getStatus()); assertThat(searchResultProto.getResultsCount()).isEqualTo(1); DocumentProto resultDocument = searchResultProto.getResults(0).getDocument(); @@ -246,7 +244,7 @@ public final class IcingSearchEngineTest { // fetch rest pages for (int i = 1; i < 5; i++) { - searchResultProto = icing.getNextPage(searchResultProto.getNextPageToken()); + searchResultProto = icingSearchEngine.getNextPage(searchResultProto.getNextPageToken()); assertWithMessage(searchResultProto.getStatus().getMessage()) .that(searchResultProto.getStatus().getCode()) .isEqualTo(StatusProto.Code.OK); @@ -256,120 +254,109 @@ public final class IcingSearchEngineTest { } // invalidate rest result - icing.invalidateNextPageToken(searchResultProto.getNextPageToken()); + icingSearchEngine.invalidateNextPageToken(searchResultProto.getNextPageToken()); - searchResultProto = icing.getNextPage(searchResultProto.getNextPageToken()); + searchResultProto = icingSearchEngine.getNextPage(searchResultProto.getNextPageToken()); assertStatusOk(searchResultProto.getStatus()); assertThat(searchResultProto.getResultsCount()).isEqualTo(0); } @Test public void testDelete() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing + icingSearchEngine .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) .getStatus() .getCode()) .isEqualTo(StatusProto.Code.OK); DocumentProto emailDocument = createEmailDocument("namespace", "uri"); - assertStatusOk(icing.put(emailDocument).getStatus()); + assertStatusOk(icingSearchEngine.put(emailDocument).getStatus()); - DeleteResultProto deleteResultProto = icing.delete("namespace", "uri"); + DeleteResultProto deleteResultProto = icingSearchEngine.delete("namespace", "uri"); assertStatusOk(deleteResultProto.getStatus()); - GetResultProto getResultProto = icing.get("namespace", "uri"); + GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri"); assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND); } @Test public void testDeleteByNamespace() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing + icingSearchEngine .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) .getStatus() .getCode()) .isEqualTo(StatusProto.Code.OK); DocumentProto emailDocument = createEmailDocument("namespace", "uri"); - assertStatusOk(icing.put(emailDocument).getStatus()); + assertStatusOk(icingSearchEngine.put(emailDocument).getStatus()); DeleteByNamespaceResultProto deleteByNamespaceResultProto = - icing.deleteByNamespace("namespace"); + icingSearchEngine.deleteByNamespace("namespace"); assertStatusOk(deleteByNamespaceResultProto.getStatus()); - GetResultProto getResultProto = icing.get("namespace", "uri"); + GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri"); assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND); } @Test public void testDeleteBySchemaType() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing + icingSearchEngine .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) .getStatus() .getCode()) .isEqualTo(StatusProto.Code.OK); DocumentProto emailDocument = createEmailDocument("namespace", "uri"); - assertStatusOk(icing.put(emailDocument).getStatus()); + assertStatusOk(icingSearchEngine.put(emailDocument).getStatus()); DeleteBySchemaTypeResultProto deleteBySchemaTypeResultProto = - icing.deleteBySchemaType(EMAIL_TYPE); + icingSearchEngine.deleteBySchemaType(EMAIL_TYPE); assertStatusOk(deleteBySchemaTypeResultProto.getStatus()); - GetResultProto getResultProto = icing.get("namespace", "uri"); + GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri"); assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND); } - @Test public void testDeleteByQuery() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing - .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) - .getStatus() - .getCode()) + icingSearchEngine + .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) + .getStatus() + .getCode()) .isEqualTo(StatusProto.Code.OK); DocumentProto emailDocument1 = createEmailDocument("namespace", "uri1").toBuilder() - .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo")) - .build();; - assertStatusOk(icing.put(emailDocument1).getStatus()); + .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("foo")) + .build(); + + assertStatusOk(icingSearchEngine.put(emailDocument1).getStatus()); DocumentProto emailDocument2 = createEmailDocument("namespace", "uri2").toBuilder() - .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("bar")) - .build();; - assertStatusOk(icing.put(emailDocument2).getStatus()); + .addProperties(PropertyProto.newBuilder().setName("subject").addStringValues("bar")) + .build(); + + assertStatusOk(icingSearchEngine.put(emailDocument2).getStatus()); SearchSpecProto searchSpec = SearchSpecProto.newBuilder() @@ -378,7 +365,7 @@ public final class IcingSearchEngineTest { .build(); SearchResultProto searchResultProto = - icing.search( + icingSearchEngine.search( searchSpec, ScoringSpecProto.getDefaultInstance(), ResultSpecProto.getDefaultInstance()); @@ -386,45 +373,36 @@ public final class IcingSearchEngineTest { assertThat(searchResultProto.getResultsCount()).isEqualTo(1); assertThat(searchResultProto.getResults(0).getDocument()).isEqualTo(emailDocument1); - DeleteResultProto deleteResultProto = icing.deleteByQuery(searchSpec); + DeleteResultProto deleteResultProto = icingSearchEngine.deleteByQuery(searchSpec); assertStatusOk(deleteResultProto.getStatus()); - GetResultProto getResultProto = icing.get("namespace", "uri1"); + GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri1"); assertThat(getResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.NOT_FOUND); - getResultProto = icing.get("namespace", "uri2"); + getResultProto = icingSearchEngine.get("namespace", "uri2"); assertStatusOk(getResultProto.getStatus()); } @Test public void testPersistToDisk() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); - PersistToDiskResultProto persistToDiskResultProto = icing.persistToDisk(); + PersistToDiskResultProto persistToDiskResultProto = icingSearchEngine.persistToDisk(); assertStatusOk(persistToDiskResultProto.getStatus()); } @Test public void testOptimize() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); - OptimizeResultProto optimizeResultProto = icing.optimize(); + OptimizeResultProto optimizeResultProto = icingSearchEngine.optimize(); assertStatusOk(optimizeResultProto.getStatus()); } @Test public void testGetOptimizeInfo() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); - GetOptimizeInfoResultProto getOptimizeInfoResultProto = icing.getOptimizeInfo(); + GetOptimizeInfoResultProto getOptimizeInfoResultProto = icingSearchEngine.getOptimizeInfo(); assertStatusOk(getOptimizeInfoResultProto.getStatus()); assertThat(getOptimizeInfoResultProto.getOptimizableDocs()).isEqualTo(0); assertThat(getOptimizeInfoResultProto.getEstimatedOptimizableBytes()).isEqualTo(0); @@ -432,39 +410,63 @@ public final class IcingSearchEngineTest { @Test public void testGetAllNamespaces() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); assertThat( - icing - .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) - .getStatus() - .getCode()) + icingSearchEngine + .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) + .getStatus() + .getCode()) .isEqualTo(StatusProto.Code.OK); DocumentProto emailDocument = createEmailDocument("namespace", "uri"); - assertStatusOk(icing.put(emailDocument).getStatus()); + assertStatusOk(icingSearchEngine.put(emailDocument).getStatus()); - GetAllNamespacesResultProto getAllNamespacesResultProto = icing.getAllNamespaces(); + GetAllNamespacesResultProto getAllNamespacesResultProto = icingSearchEngine.getAllNamespaces(); assertStatusOk(getAllNamespacesResultProto.getStatus()); assertThat(getAllNamespacesResultProto.getNamespacesList()).containsExactly("namespace"); } @Test public void testReset() throws Exception { - IcingSearchEngineOptions options = - IcingSearchEngineOptions.newBuilder().setBaseDir(tempDir.getCanonicalPath()).build(); - IcingSearchEngine icing = new IcingSearchEngine(options); - assertStatusOk(icing.initialize().getStatus()); + assertStatusOk(icingSearchEngine.initialize().getStatus()); - ResetResultProto resetResultProto = icing.reset(); + ResetResultProto resetResultProto = icingSearchEngine.reset(); assertStatusOk(resetResultProto.getStatus()); } + @Test + public void testReportUsage() throws Exception { + assertStatusOk(icingSearchEngine.initialize().getStatus()); + + // Set schema and put a document. + SchemaTypeConfigProto emailTypeConfig = createEmailTypeConfig(); + SchemaProto schema = SchemaProto.newBuilder().addTypes(emailTypeConfig).build(); + assertThat( + icingSearchEngine + .setSchema(schema, /*ignoreErrorsAndDeleteDocuments=*/ false) + .getStatus() + .getCode()) + .isEqualTo(StatusProto.Code.OK); + + DocumentProto emailDocument = createEmailDocument("namespace", "uri"); + PutResultProto putResultProto = icingSearchEngine.put(emailDocument); + assertStatusOk(putResultProto.getStatus()); + + // Report usage + UsageReport usageReport = + UsageReport.newBuilder() + .setDocumentNamespace("namespace") + .setDocumentUri("uri") + .setUsageTimestampMs(1) + .setUsageType(UsageReport.UsageType.USAGE_TYPE1) + .build(); + ReportUsageResultProto reportUsageResultProto = icingSearchEngine.reportUsage(usageReport); + assertStatusOk(reportUsageResultProto.getStatus()); + } + private static void assertStatusOk(StatusProto status) { assertWithMessage(status.getMessage()).that(status.getCode()).isEqualTo(StatusProto.Code.OK); } -- cgit v1.2.3 From 59c2caa38fd8dca3760dad751f4f8e5de8be25f5 Mon Sep 17 00:00:00 2001 From: Tim Barron Date: Tue, 29 Dec 2020 00:23:52 +0000 Subject: Update Icing from upstream. Change-Id: Iff50aebffb83529b0454e7c3a6dc6864e7a85f4a --- .../google/android/icing/IcingSearchEngine.java | 180 ++++++++++++++------- .../android/icing/IcingSearchEngineTest.java | 5 +- 2 files changed, 128 insertions(+), 57 deletions(-) (limited to 'java') diff --git a/java/src/com/google/android/icing/IcingSearchEngine.java b/java/src/com/google/android/icing/IcingSearchEngine.java index 0902921..22c607c 100644 --- a/java/src/com/google/android/icing/IcingSearchEngine.java +++ b/java/src/com/google/android/icing/IcingSearchEngine.java @@ -17,6 +17,7 @@ package com.google.android.icing; import android.util.Log; import androidx.annotation.NonNull; import com.google.android.icing.proto.DeleteByNamespaceResultProto; +import com.google.android.icing.proto.DeleteByQueryResultProto; import com.google.android.icing.proto.DeleteBySchemaTypeResultProto; import com.google.android.icing.proto.DeleteResultProto; import com.google.android.icing.proto.DocumentProto; @@ -42,9 +43,16 @@ import com.google.android.icing.proto.StatusProto; import com.google.android.icing.proto.UsageReport; import com.google.android.icing.protobuf.ExtensionRegistryLite; import com.google.android.icing.protobuf.InvalidProtocolBufferException; +import java.io.Closeable; -/** Java wrapper to access native APIs in external/icing/icing/icing-search-engine.h */ -public final class IcingSearchEngine { +/** + * Java wrapper to access native APIs in external/icing/icing/icing-search-engine.h + * + *

If this instance has been closed, the instance is no longer usable. + * + *

NOTE: This class is NOT thread-safe. + */ +public final class IcingSearchEngine implements Closeable { private static final String TAG = "IcingSearchEngine"; private static final ExtensionRegistryLite EXTENSION_REGISTRY_LITE = @@ -52,6 +60,8 @@ public final class IcingSearchEngine { private long nativePointer; + private boolean closed = false; + static { // NOTE: This can fail with an UnsatisfiedLinkError System.loadLibrary("icing"); @@ -66,9 +76,34 @@ public final class IcingSearchEngine { } } + private void throwIfClosed() { + if (closed) { + throw new IllegalStateException("Trying to use a closed IcingSearchEngine instance."); + } + } + + @Override + public void close() { + throwIfClosed(); + + if (nativePointer != 0) { + nativeDestroy(this); + } + nativePointer = 0; + closed = true; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + close(); + } + @NonNull public InitializeResultProto initialize() { - byte[] initializeResultBytes = nativeInitialize(nativePointer); + throwIfClosed(); + + byte[] initializeResultBytes = nativeInitialize(this); if (initializeResultBytes == null) { Log.e(TAG, "Received null InitializeResult from native."); return InitializeResultProto.newBuilder() @@ -94,8 +129,10 @@ public final class IcingSearchEngine { @NonNull public SetSchemaResultProto setSchema( @NonNull SchemaProto schema, boolean ignoreErrorsAndDeleteDocuments) { + throwIfClosed(); + byte[] setSchemaResultBytes = - nativeSetSchema(nativePointer, schema.toByteArray(), ignoreErrorsAndDeleteDocuments); + nativeSetSchema(this, schema.toByteArray(), ignoreErrorsAndDeleteDocuments); if (setSchemaResultBytes == null) { Log.e(TAG, "Received null SetSchemaResultProto from native."); return SetSchemaResultProto.newBuilder() @@ -115,7 +152,9 @@ public final class IcingSearchEngine { @NonNull public GetSchemaResultProto getSchema() { - byte[] getSchemaResultBytes = nativeGetSchema(nativePointer); + throwIfClosed(); + + byte[] getSchemaResultBytes = nativeGetSchema(this); if (getSchemaResultBytes == null) { Log.e(TAG, "Received null GetSchemaResultProto from native."); return GetSchemaResultProto.newBuilder() @@ -135,7 +174,9 @@ public final class IcingSearchEngine { @NonNull public GetSchemaTypeResultProto getSchemaType(@NonNull String schemaType) { - byte[] getSchemaTypeResultBytes = nativeGetSchemaType(nativePointer, schemaType); + throwIfClosed(); + + byte[] getSchemaTypeResultBytes = nativeGetSchemaType(this, schemaType); if (getSchemaTypeResultBytes == null) { Log.e(TAG, "Received null GetSchemaTypeResultProto from native."); return GetSchemaTypeResultProto.newBuilder() @@ -155,7 +196,9 @@ public final class IcingSearchEngine { @NonNull public PutResultProto put(@NonNull DocumentProto document) { - byte[] putResultBytes = nativePut(nativePointer, document.toByteArray()); + throwIfClosed(); + + byte[] putResultBytes = nativePut(this, document.toByteArray()); if (putResultBytes == null) { Log.e(TAG, "Received null PutResultProto from native."); return PutResultProto.newBuilder() @@ -175,7 +218,9 @@ public final class IcingSearchEngine { @NonNull public GetResultProto get(@NonNull String namespace, @NonNull String uri) { - byte[] getResultBytes = nativeGet(nativePointer, namespace, uri); + throwIfClosed(); + + byte[] getResultBytes = nativeGet(this, namespace, uri); if (getResultBytes == null) { Log.e(TAG, "Received null GetResultProto from native."); return GetResultProto.newBuilder() @@ -195,7 +240,9 @@ public final class IcingSearchEngine { @NonNull public ReportUsageResultProto reportUsage(@NonNull UsageReport usageReport) { - byte[] reportUsageResultBytes = nativeReportUsage(nativePointer, usageReport.toByteArray()); + throwIfClosed(); + + byte[] reportUsageResultBytes = nativeReportUsage(this, usageReport.toByteArray()); if (reportUsageResultBytes == null) { Log.e(TAG, "Received null ReportUsageResultProto from native."); return ReportUsageResultProto.newBuilder() @@ -215,7 +262,9 @@ public final class IcingSearchEngine { @NonNull public GetAllNamespacesResultProto getAllNamespaces() { - byte[] getAllNamespacesResultBytes = nativeGetAllNamespaces(nativePointer); + throwIfClosed(); + + byte[] getAllNamespacesResultBytes = nativeGetAllNamespaces(this); if (getAllNamespacesResultBytes == null) { Log.e(TAG, "Received null GetAllNamespacesResultProto from native."); return GetAllNamespacesResultProto.newBuilder() @@ -239,12 +288,11 @@ public final class IcingSearchEngine { @NonNull SearchSpecProto searchSpec, @NonNull ScoringSpecProto scoringSpec, @NonNull ResultSpecProto resultSpec) { + throwIfClosed(); + byte[] searchResultBytes = nativeSearch( - nativePointer, - searchSpec.toByteArray(), - scoringSpec.toByteArray(), - resultSpec.toByteArray()); + this, searchSpec.toByteArray(), scoringSpec.toByteArray(), resultSpec.toByteArray()); if (searchResultBytes == null) { Log.e(TAG, "Received null SearchResultProto from native."); return SearchResultProto.newBuilder() @@ -264,7 +312,9 @@ public final class IcingSearchEngine { @NonNull public SearchResultProto getNextPage(long nextPageToken) { - byte[] searchResultBytes = nativeGetNextPage(nativePointer, nextPageToken); + throwIfClosed(); + + byte[] searchResultBytes = nativeGetNextPage(this, nextPageToken); if (searchResultBytes == null) { Log.e(TAG, "Received null SearchResultProto from native."); return SearchResultProto.newBuilder() @@ -284,12 +334,16 @@ public final class IcingSearchEngine { @NonNull public void invalidateNextPageToken(long nextPageToken) { - nativeInvalidateNextPageToken(nativePointer, nextPageToken); + throwIfClosed(); + + nativeInvalidateNextPageToken(this, nextPageToken); } @NonNull public DeleteResultProto delete(@NonNull String namespace, @NonNull String uri) { - byte[] deleteResultBytes = nativeDelete(nativePointer, namespace, uri); + throwIfClosed(); + + byte[] deleteResultBytes = nativeDelete(this, namespace, uri); if (deleteResultBytes == null) { Log.e(TAG, "Received null DeleteResultProto from native."); return DeleteResultProto.newBuilder() @@ -309,7 +363,9 @@ public final class IcingSearchEngine { @NonNull public DeleteByNamespaceResultProto deleteByNamespace(@NonNull String namespace) { - byte[] deleteByNamespaceResultBytes = nativeDeleteByNamespace(nativePointer, namespace); + throwIfClosed(); + + byte[] deleteByNamespaceResultBytes = nativeDeleteByNamespace(this, namespace); if (deleteByNamespaceResultBytes == null) { Log.e(TAG, "Received null DeleteByNamespaceResultProto from native."); return DeleteByNamespaceResultProto.newBuilder() @@ -330,7 +386,9 @@ public final class IcingSearchEngine { @NonNull public DeleteBySchemaTypeResultProto deleteBySchemaType(@NonNull String schemaType) { - byte[] deleteBySchemaTypeResultBytes = nativeDeleteBySchemaType(nativePointer, schemaType); + throwIfClosed(); + + byte[] deleteBySchemaTypeResultBytes = nativeDeleteBySchemaType(this, schemaType); if (deleteBySchemaTypeResultBytes == null) { Log.e(TAG, "Received null DeleteBySchemaTypeResultProto from native."); return DeleteBySchemaTypeResultProto.newBuilder() @@ -350,20 +408,22 @@ public final class IcingSearchEngine { } @NonNull - public DeleteResultProto deleteByQuery(@NonNull SearchSpecProto searchSpec) { - byte[] deleteResultBytes = nativeDeleteByQuery(nativePointer, searchSpec.toByteArray()); + public DeleteByQueryResultProto deleteByQuery(@NonNull SearchSpecProto searchSpec) { + throwIfClosed(); + + byte[] deleteResultBytes = nativeDeleteByQuery(this, searchSpec.toByteArray()); if (deleteResultBytes == null) { Log.e(TAG, "Received null DeleteResultProto from native."); - return DeleteResultProto.newBuilder() + return DeleteByQueryResultProto.newBuilder() .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.INTERNAL)) .build(); } try { - return DeleteResultProto.parseFrom(deleteResultBytes, EXTENSION_REGISTRY_LITE); + return DeleteByQueryResultProto.parseFrom(deleteResultBytes, EXTENSION_REGISTRY_LITE); } catch (InvalidProtocolBufferException e) { Log.e(TAG, "Error parsing DeleteResultProto.", e); - return DeleteResultProto.newBuilder() + return DeleteByQueryResultProto.newBuilder() .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.INTERNAL)) .build(); } @@ -371,7 +431,9 @@ public final class IcingSearchEngine { @NonNull public PersistToDiskResultProto persistToDisk() { - byte[] persistToDiskResultBytes = nativePersistToDisk(nativePointer); + throwIfClosed(); + + byte[] persistToDiskResultBytes = nativePersistToDisk(this); if (persistToDiskResultBytes == null) { Log.e(TAG, "Received null PersistToDiskResultProto from native."); return PersistToDiskResultProto.newBuilder() @@ -391,7 +453,9 @@ public final class IcingSearchEngine { @NonNull public OptimizeResultProto optimize() { - byte[] optimizeResultBytes = nativeOptimize(nativePointer); + throwIfClosed(); + + byte[] optimizeResultBytes = nativeOptimize(this); if (optimizeResultBytes == null) { Log.e(TAG, "Received null OptimizeResultProto from native."); return OptimizeResultProto.newBuilder() @@ -411,7 +475,9 @@ public final class IcingSearchEngine { @NonNull public GetOptimizeInfoResultProto getOptimizeInfo() { - byte[] getOptimizeInfoResultBytes = nativeGetOptimizeInfo(nativePointer); + throwIfClosed(); + + byte[] getOptimizeInfoResultBytes = nativeGetOptimizeInfo(this); if (getOptimizeInfoResultBytes == null) { Log.e(TAG, "Received null GetOptimizeInfoResultProto from native."); return GetOptimizeInfoResultProto.newBuilder() @@ -432,7 +498,9 @@ public final class IcingSearchEngine { @NonNull public ResetResultProto reset() { - byte[] resetResultBytes = nativeReset(nativePointer); + throwIfClosed(); + + byte[] resetResultBytes = nativeReset(this); if (resetResultBytes == null) { Log.e(TAG, "Received null ResetResultProto from native."); return ResetResultProto.newBuilder() @@ -450,54 +518,56 @@ public final class IcingSearchEngine { } } - public void destroy() { - if (nativePointer != 0) { - nativeDestroy(nativePointer); - } - nativePointer = 0; - } - private static native long nativeCreate(byte[] icingSearchEngineOptionsBytes); - private static native void nativeDestroy(long nativePointer); + private static native void nativeDestroy(IcingSearchEngine instance); - private static native byte[] nativeInitialize(long nativePointer); + private static native byte[] nativeInitialize(IcingSearchEngine instance); private static native byte[] nativeSetSchema( - long nativePointer, byte[] schemaBytes, boolean ignoreErrorsAndDeleteDocuments); + IcingSearchEngine instance, byte[] schemaBytes, boolean ignoreErrorsAndDeleteDocuments); - private static native byte[] nativeGetSchema(long nativePointer); + private static native byte[] nativeGetSchema(IcingSearchEngine instance); - private static native byte[] nativeGetSchemaType(long nativePointer, String schemaType); + private static native byte[] nativeGetSchemaType(IcingSearchEngine instance, String schemaType); - private static native byte[] nativePut(long nativePointer, byte[] documentBytes); + private static native byte[] nativePut(IcingSearchEngine instance, byte[] documentBytes); - private static native byte[] nativeGet(long nativePointer, String namespace, String uri); + private static native byte[] nativeGet(IcingSearchEngine instance, String namespace, String uri); - private static native byte[] nativeReportUsage(long nativePointer, byte[] usageReportBytes); + private static native byte[] nativeReportUsage( + IcingSearchEngine instance, byte[] usageReportBytes); - private static native byte[] nativeGetAllNamespaces(long nativePointer); + private static native byte[] nativeGetAllNamespaces(IcingSearchEngine instance); private static native byte[] nativeSearch( - long nativePointer, byte[] searchSpecBytes, byte[] scoringSpecBytes, byte[] resultSpecBytes); + IcingSearchEngine instance, + byte[] searchSpecBytes, + byte[] scoringSpecBytes, + byte[] resultSpecBytes); - private static native byte[] nativeGetNextPage(long nativePointer, long nextPageToken); + private static native byte[] nativeGetNextPage(IcingSearchEngine instance, long nextPageToken); - private static native void nativeInvalidateNextPageToken(long nativePointer, long nextPageToken); + private static native void nativeInvalidateNextPageToken( + IcingSearchEngine instance, long nextPageToken); - private static native byte[] nativeDelete(long nativePointer, String namespace, String uri); + private static native byte[] nativeDelete( + IcingSearchEngine instance, String namespace, String uri); - private static native byte[] nativeDeleteByNamespace(long nativePointer, String namespace); + private static native byte[] nativeDeleteByNamespace( + IcingSearchEngine instance, String namespace); - private static native byte[] nativeDeleteBySchemaType(long nativePointer, String schemaType); + private static native byte[] nativeDeleteBySchemaType( + IcingSearchEngine instance, String schemaType); - private static native byte[] nativeDeleteByQuery(long nativePointer, byte[] searchSpecBytes); + private static native byte[] nativeDeleteByQuery( + IcingSearchEngine instance, byte[] searchSpecBytes); - private static native byte[] nativePersistToDisk(long nativePointer); + private static native byte[] nativePersistToDisk(IcingSearchEngine instance); - private static native byte[] nativeOptimize(long nativePointer); + private static native byte[] nativeOptimize(IcingSearchEngine instance); - private static native byte[] nativeGetOptimizeInfo(long nativePointer); + private static native byte[] nativeGetOptimizeInfo(IcingSearchEngine instance); - private static native byte[] nativeReset(long nativePointer); + private static native byte[] nativeReset(IcingSearchEngine instance); } diff --git a/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java b/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java index ee8ff37..6f07e1a 100644 --- a/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java +++ b/java/tests/instrumentation/src/com/google/android/icing/IcingSearchEngineTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import com.google.android.icing.proto.DeleteByNamespaceResultProto; +import com.google.android.icing.proto.DeleteByQueryResultProto; import com.google.android.icing.proto.DeleteBySchemaTypeResultProto; import com.google.android.icing.proto.DeleteResultProto; import com.google.android.icing.proto.DocumentProto; @@ -116,7 +117,7 @@ public final class IcingSearchEngineTest { @After public void tearDown() throws Exception { - icingSearchEngine.destroy(); + icingSearchEngine.close(); } @Test @@ -373,7 +374,7 @@ public final class IcingSearchEngineTest { assertThat(searchResultProto.getResultsCount()).isEqualTo(1); assertThat(searchResultProto.getResults(0).getDocument()).isEqualTo(emailDocument1); - DeleteResultProto deleteResultProto = icingSearchEngine.deleteByQuery(searchSpec); + DeleteByQueryResultProto deleteResultProto = icingSearchEngine.deleteByQuery(searchSpec); assertStatusOk(deleteResultProto.getStatus()); GetResultProto getResultProto = icingSearchEngine.get("namespace", "uri1"); -- cgit v1.2.3