Sync AppSearch from framework.
Contains changes:
* 37a4e9: Split indexing configs into per-type configs.
* 69d6e3: Add projection to the Get api.
Bug: 175039682
Bug: 177572431
Bug: 171857731
Test: Presubmit
Change-Id: Ida457b2d617be6e85557023bfb4716ad78c8db6c
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 401624f..ebb0070 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -43,6 +43,15 @@
method @IntRange(from=0) public int getVersion();
}
+ public static final class AppSearchSchema.BooleanPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ }
+
+ public static final class AppSearchSchema.BooleanPropertyConfig.Builder {
+ ctor public AppSearchSchema.BooleanPropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.BooleanPropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.BooleanPropertyConfig.Builder setCardinality(int);
+ }
+
public static final class AppSearchSchema.Builder {
ctor public AppSearchSchema.Builder(@NonNull String);
method @NonNull public android.app.appsearch.AppSearchSchema.Builder addProperty(@NonNull android.app.appsearch.AppSearchSchema.PropertyConfig);
@@ -50,22 +59,58 @@
method @NonNull public android.app.appsearch.AppSearchSchema.Builder setVersion(@IntRange(from=0) int);
}
- public static final class AppSearchSchema.PropertyConfig {
+ public static final class AppSearchSchema.BytesPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ }
+
+ public static final class AppSearchSchema.BytesPropertyConfig.Builder {
+ ctor public AppSearchSchema.BytesPropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.BytesPropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.BytesPropertyConfig.Builder setCardinality(int);
+ }
+
+ public static final class AppSearchSchema.DocumentPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ method @NonNull public String getSchemaType();
+ method public boolean isIndexNestedProperties();
+ }
+
+ public static final class AppSearchSchema.DocumentPropertyConfig.Builder {
+ ctor public AppSearchSchema.DocumentPropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setCardinality(int);
+ method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setIndexNestedProperties(boolean);
+ method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setSchemaType(@NonNull String);
+ }
+
+ public static final class AppSearchSchema.DoublePropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ }
+
+ public static final class AppSearchSchema.DoublePropertyConfig.Builder {
+ ctor public AppSearchSchema.DoublePropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig.Builder setCardinality(int);
+ }
+
+ public static final class AppSearchSchema.Int64PropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ }
+
+ public static final class AppSearchSchema.Int64PropertyConfig.Builder {
+ ctor public AppSearchSchema.Int64PropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig.Builder setCardinality(int);
+ }
+
+ public abstract static class AppSearchSchema.PropertyConfig {
method public int getCardinality();
method public int getDataType();
- method public int getIndexingType();
method @NonNull public String getName();
- method @Nullable public String getSchemaType();
- method public int getTokenizerType();
field public static final int CARDINALITY_OPTIONAL = 2; // 0x2
field public static final int CARDINALITY_REPEATED = 1; // 0x1
field public static final int CARDINALITY_REQUIRED = 3; // 0x3
- field public static final int DATA_TYPE_BOOLEAN = 4; // 0x4
- field public static final int DATA_TYPE_BYTES = 5; // 0x5
- field public static final int DATA_TYPE_DOCUMENT = 6; // 0x6
- field public static final int DATA_TYPE_DOUBLE = 3; // 0x3
- field public static final int DATA_TYPE_INT64 = 2; // 0x2
- field public static final int DATA_TYPE_STRING = 1; // 0x1
+ }
+
+ public static final class AppSearchSchema.StringPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ method public int getIndexingType();
+ method public int getTokenizerType();
field public static final int INDEXING_TYPE_EXACT_TERMS = 1; // 0x1
field public static final int INDEXING_TYPE_NONE = 0; // 0x0
field public static final int INDEXING_TYPE_PREFIXES = 2; // 0x2
@@ -73,14 +118,12 @@
field public static final int TOKENIZER_TYPE_PLAIN = 1; // 0x1
}
- public static final class AppSearchSchema.PropertyConfig.Builder {
- ctor public AppSearchSchema.PropertyConfig.Builder(@NonNull String);
- method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig build();
- method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setCardinality(int);
- method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setDataType(int);
- method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setIndexingType(int);
- method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setSchemaType(@NonNull String);
- method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setTokenizerType(int);
+ public static final class AppSearchSchema.StringPropertyConfig.Builder {
+ ctor public AppSearchSchema.StringPropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setCardinality(int);
+ method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setIndexingType(int);
+ method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setTokenizerType(int);
}
public final class AppSearchSession implements java.io.Closeable {
@@ -143,11 +186,15 @@
public final class GetByUriRequest {
method @NonNull public String getNamespace();
+ method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
method @NonNull public java.util.Set<java.lang.String> getUris();
+ field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
}
public static final class GetByUriRequest.Builder {
ctor public GetByUriRequest.Builder();
+ method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.lang.String...);
+ method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.lang.String...);
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.GetByUriRequest build();
diff --git a/framework/java/android/app/appsearch/AppSearchManager.java b/framework/java/android/app/appsearch/AppSearchManager.java
index ed4e034..814800e 100644
--- a/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/framework/java/android/app/appsearch/AppSearchManager.java
@@ -330,6 +330,7 @@
DEFAULT_DATABASE_NAME,
request.getNamespace(),
uris,
+ request.getProjectionsVisibleToPackagesInternal(),
mContext.getUserId(),
new IAppSearchBatchResultCallback.Stub() {
public void onResult(AppSearchBatchResult result) {
diff --git a/framework/java/android/app/appsearch/AppSearchSession.java b/framework/java/android/app/appsearch/AppSearchSession.java
index 928bf7d..c4c123c 100644
--- a/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/framework/java/android/app/appsearch/AppSearchSession.java
@@ -311,8 +311,13 @@
Objects.requireNonNull(callback);
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
try {
- mService.getDocuments(mPackageName, mDatabaseName, request.getNamespace(),
- new ArrayList<>(request.getUris()), mUserId,
+ mService.getDocuments(
+ mPackageName,
+ mDatabaseName,
+ request.getNamespace(),
+ new ArrayList<>(request.getUris()),
+ request.getProjectionsVisibleToPackagesInternal(),
+ mUserId,
new IAppSearchBatchResultCallback.Stub() {
public void onResult(AppSearchBatchResult result) {
executor.execute(() -> {
diff --git a/framework/java/android/app/appsearch/IAppSearchManager.aidl b/framework/java/android/app/appsearch/IAppSearchManager.aidl
index be76f42..68ae23f 100644
--- a/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -97,6 +97,8 @@
* @param databaseName The databaseName this document resides in.
* @param namespace The namespace this document resides in.
* @param uris The URIs of the documents to retrieve
+ * @param typePropertyPaths A map of schema type to a list of property paths to return in the
+ * result.
* @param userId Id of the calling user
* @param callback
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
@@ -110,6 +112,7 @@
in String databaseName,
in String namespace,
in List<String> uris,
+ in Map<String, List<String>> typePropertyPaths,
in int userId,
in IAppSearchBatchResultCallback callback);
diff --git a/framework/java/external/android/app/appsearch/AppSearchEmail.java b/framework/java/external/android/app/appsearch/AppSearchEmail.java
index 9ca363e..d394904 100644
--- a/framework/java/external/android/app/appsearch/AppSearchEmail.java
+++ b/framework/java/external/android/app/appsearch/AppSearchEmail.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.appsearch.AppSearchSchema.PropertyConfig;
+import android.app.appsearch.AppSearchSchema.StringPropertyConfig;
/**
* Encapsulates a {@link GenericDocument} that represent an email.
@@ -41,46 +42,40 @@
public static final AppSearchSchema SCHEMA =
new AppSearchSchema.Builder(SCHEMA_TYPE)
.addProperty(
- new PropertyConfig.Builder(KEY_FROM)
- .setDataType(PropertyConfig.DATA_TYPE_STRING)
+ new StringPropertyConfig.Builder(KEY_FROM)
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build())
.addProperty(
- new PropertyConfig.Builder(KEY_TO)
- .setDataType(PropertyConfig.DATA_TYPE_STRING)
+ new StringPropertyConfig.Builder(KEY_TO)
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
- .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build())
.addProperty(
- new PropertyConfig.Builder(KEY_CC)
- .setDataType(PropertyConfig.DATA_TYPE_STRING)
+ new StringPropertyConfig.Builder(KEY_CC)
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
- .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build())
.addProperty(
- new PropertyConfig.Builder(KEY_BCC)
- .setDataType(PropertyConfig.DATA_TYPE_STRING)
+ new StringPropertyConfig.Builder(KEY_BCC)
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
- .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build())
.addProperty(
- new PropertyConfig.Builder(KEY_SUBJECT)
- .setDataType(PropertyConfig.DATA_TYPE_STRING)
+ new StringPropertyConfig.Builder(KEY_SUBJECT)
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build())
.addProperty(
- new PropertyConfig.Builder(KEY_BODY)
- .setDataType(PropertyConfig.DATA_TYPE_STRING)
+ new StringPropertyConfig.Builder(KEY_BODY)
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build())
.build();
diff --git a/framework/java/external/android/app/appsearch/AppSearchSchema.java b/framework/java/external/android/app/appsearch/AppSearchSchema.java
index 1f882ec..7f5d202 100644
--- a/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -98,7 +98,7 @@
}
List<PropertyConfig> ret = new ArrayList<>(propertyBundles.size());
for (int i = 0; i < propertyBundles.size(); i++) {
- ret.add(new PropertyConfig(propertyBundles.get(i)));
+ ret.add(PropertyConfig.fromBundle(propertyBundles.get(i)));
}
return ret;
}
@@ -210,18 +210,15 @@
}
/**
- * Configuration for a single property (field) of a document type.
+ * Common configuration for a single property (field) in a Document.
*
* <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be a
* property.
*/
- public static final class PropertyConfig {
- private static final String NAME_FIELD = "name";
- private static final String DATA_TYPE_FIELD = "dataType";
- private static final String SCHEMA_TYPE_FIELD = "schemaType";
- private static final String CARDINALITY_FIELD = "cardinality";
- private static final String INDEXING_TYPE_FIELD = "indexingType";
- private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
+ public abstract static class PropertyConfig {
+ static final String NAME_FIELD = "name";
+ static final String DATA_TYPE_FIELD = "dataType";
+ static final String CARDINALITY_FIELD = "cardinality";
/**
* Physical data-types of the contents of the property.
@@ -242,18 +239,31 @@
@Retention(RetentionPolicy.SOURCE)
public @interface DataType {}
+ /** @hide */
public static final int DATA_TYPE_STRING = 1;
+
+ /** @hide */
public static final int DATA_TYPE_INT64 = 2;
+
+ /** @hide */
public static final int DATA_TYPE_DOUBLE = 3;
+
+ /** @hide */
public static final int DATA_TYPE_BOOLEAN = 4;
- /** Unstructured BLOB. */
+ /**
+ * Unstructured BLOB.
+ *
+ * @hide
+ */
public static final int DATA_TYPE_BYTES = 5;
/**
* Indicates that the property is itself a {@link GenericDocument}, making it part of a
* hierarchical schema. Any property using this DataType MUST have a valid {@link
* PropertyConfig#getSchemaType}.
+ *
+ * @hide
*/
public static final int DATA_TYPE_DOCUMENT = 6;
@@ -282,6 +292,97 @@
/** Exactly one value [1]. */
public static final int CARDINALITY_REQUIRED = 3;
+ final Bundle mBundle;
+
+ @Nullable private Integer mHashCode;
+
+ PropertyConfig(@NonNull Bundle bundle) {
+ mBundle = Preconditions.checkNotNull(bundle);
+ }
+
+ @Override
+ public String toString() {
+ return mBundle.toString();
+ }
+
+ /** Returns the name of this property. */
+ @NonNull
+ public String getName() {
+ return mBundle.getString(NAME_FIELD, "");
+ }
+
+ /** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
+ public @DataType int getDataType() {
+ return mBundle.getInt(DATA_TYPE_FIELD, -1);
+ }
+
+ /**
+ * Returns the cardinality of the property (whether it is optional, required or repeated).
+ */
+ public @Cardinality int getCardinality() {
+ return mBundle.getInt(CARDINALITY_FIELD, -1);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof PropertyConfig)) {
+ return false;
+ }
+ PropertyConfig otherProperty = (PropertyConfig) other;
+ return BundleUtil.deepEquals(this.mBundle, otherProperty.mBundle);
+ }
+
+ @Override
+ public int hashCode() {
+ if (mHashCode == null) {
+ mHashCode = BundleUtil.deepHashCode(mBundle);
+ }
+ return mHashCode;
+ }
+
+ /**
+ * Converts a {@link Bundle} into a {@link PropertyConfig} depending on its internal data
+ * type.
+ *
+ * <p>The bundle is not cloned.
+ *
+ * @throws IllegalArgumentException if the bundle does no contain a recognized value in its
+ * {@code DATA_TYPE_FIELD}.
+ * @hide
+ */
+ @NonNull
+ public static PropertyConfig fromBundle(@NonNull Bundle propertyBundle) {
+ switch (propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)) {
+ case PropertyConfig.DATA_TYPE_STRING:
+ return new StringPropertyConfig(propertyBundle);
+ case PropertyConfig.DATA_TYPE_INT64:
+ return new Int64PropertyConfig(propertyBundle);
+ case PropertyConfig.DATA_TYPE_DOUBLE:
+ return new DoublePropertyConfig(propertyBundle);
+ case PropertyConfig.DATA_TYPE_BOOLEAN:
+ return new BooleanPropertyConfig(propertyBundle);
+ case PropertyConfig.DATA_TYPE_BYTES:
+ return new BytesPropertyConfig(propertyBundle);
+ case PropertyConfig.DATA_TYPE_DOCUMENT:
+ return new DocumentPropertyConfig(propertyBundle);
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported property bundle of type "
+ + propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)
+ + "; contents: "
+ + propertyBundle);
+ }
+ }
+ }
+
+ /** Configuration for a property of type String in a Document. */
+ public static final class StringPropertyConfig extends PropertyConfig {
+ private static final String INDEXING_TYPE_FIELD = "indexingType";
+ private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
+
/**
* Encapsulates the configurations on how AppSearch should query/index these terms.
*
@@ -296,14 +397,7 @@
@Retention(RetentionPolicy.SOURCE)
public @interface IndexingType {}
- /**
- * Content in this property will not be tokenized or indexed.
- *
- * <p>Useful if the data type is not made up of terms (e.g. {@link
- * PropertyConfig#DATA_TYPE_DOCUMENT} or {@link PropertyConfig#DATA_TYPE_BYTES} type). None
- * of the properties inside the nested property will be indexed regardless of the value of
- * {@code indexingType} for the nested properties.
- */
+ /** Content in this property will not be tokenized or indexed. */
public static final int INDEXING_TYPE_NONE = 0;
/**
@@ -338,54 +432,16 @@
public @interface TokenizerType {}
/**
- * It is only valid for tokenizer_type to be 'NONE' if the data type is {@link
- * PropertyConfig#DATA_TYPE_DOCUMENT}.
+ * It is only valid for tokenizer_type to be 'NONE' if {@link #getIndexingType} is {@link
+ * #INDEXING_TYPE_NONE}.
*/
public static final int TOKENIZER_TYPE_NONE = 0;
/** Tokenization for plain text. */
public static final int TOKENIZER_TYPE_PLAIN = 1;
- final Bundle mBundle;
-
- @Nullable private Integer mHashCode;
-
- PropertyConfig(@NonNull Bundle bundle) {
- mBundle = Preconditions.checkNotNull(bundle);
- }
-
- @Override
- public String toString() {
- return mBundle.toString();
- }
-
- /** Returns the name of this property. */
- @NonNull
- public String getName() {
- return mBundle.getString(NAME_FIELD, "");
- }
-
- /** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
- public @DataType int getDataType() {
- return mBundle.getInt(DATA_TYPE_FIELD, -1);
- }
-
- /**
- * Returns the logical schema-type of the contents of this property.
- *
- * <p>Only set when {@link #getDataType} is set to {@link #DATA_TYPE_DOCUMENT}. Otherwise,
- * it is {@code null}.
- */
- @Nullable
- public String getSchemaType() {
- return mBundle.getString(SCHEMA_TYPE_FIELD);
- }
-
- /**
- * Returns the cardinality of the property (whether it is optional, required or repeated).
- */
- public @Cardinality int getCardinality() {
- return mBundle.getInt(CARDINALITY_FIELD, -1);
+ StringPropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
}
/** Returns how the property is indexed. */
@@ -398,75 +454,19 @@
return mBundle.getInt(TOKENIZER_TYPE_FIELD);
}
- @Override
- public boolean equals(@Nullable Object other) {
- if (this == other) {
- return true;
- }
- if (!(other instanceof PropertyConfig)) {
- return false;
- }
- PropertyConfig otherProperty = (PropertyConfig) other;
- return BundleUtil.deepEquals(this.mBundle, otherProperty.mBundle);
- }
-
- @Override
- public int hashCode() {
- if (mHashCode == null) {
- mHashCode = BundleUtil.deepHashCode(mBundle);
- }
- return mHashCode;
- }
-
/**
- * Builder for {@link PropertyConfig}.
+ * Builder for {@link StringPropertyConfig}.
*
- * <p>The following properties must be set, or {@link PropertyConfig} construction will
- * fail:
- *
- * <ul>
- * <li>dataType
- * <li>cardinality
- * </ul>
- *
- * <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType}
- * is also required.
+ * <p>{@link #setCardinality} must be called or {@link #build} will fail.
*/
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
- /** Creates a new {@link PropertyConfig.Builder}. */
+ /** Creates a new {@link StringPropertyConfig.Builder}. */
public Builder(@NonNull String propertyName) {
mBundle.putString(NAME_FIELD, propertyName);
- }
-
- /**
- * Type of data the property contains (e.g. string, int, bytes, etc).
- *
- * <p>This property must be set.
- */
- @NonNull
- public PropertyConfig.Builder setDataType(@DataType int dataType) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- Preconditions.checkArgumentInRange(
- dataType, DATA_TYPE_STRING, DATA_TYPE_DOCUMENT, "dataType");
- mBundle.putInt(DATA_TYPE_FIELD, dataType);
- return this;
- }
-
- /**
- * The logical schema-type of the contents of this property.
- *
- * <p>Only required when {@link #setDataType} is set to {@link #DATA_TYPE_DOCUMENT}.
- * Otherwise, it is ignored.
- */
- @NonNull
- public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
- Preconditions.checkState(!mBuilt, "Builder has already been used");
- Preconditions.checkNotNull(schemaType);
- mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
- return this;
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
}
/**
@@ -474,8 +474,9 @@
*
* <p>This property must be set.
*/
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
- public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ public StringPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkArgumentInRange(
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
@@ -487,7 +488,7 @@
* Configures how a property should be indexed so that it can be retrieved by queries.
*/
@NonNull
- public PropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
+ public StringPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkArgumentInRange(
indexingType, INDEXING_TYPE_NONE, INDEXING_TYPE_PREFIXES, "indexingType");
@@ -497,7 +498,7 @@
/** Configures how this property should be tokenized (split into words). */
@NonNull
- public PropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
+ public StringPropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkArgumentInRange(
tokenizerType, TOKENIZER_TYPE_NONE, TOKENIZER_TYPE_PLAIN, "tokenizerType");
@@ -506,6 +507,337 @@
}
/**
+ * Constructs a new {@link StringPropertyConfig} from the contents of this builder.
+ *
+ * <p>After calling this method, the builder must no longer be used.
+ *
+ * @throws IllegalSchemaException if the property is not correctly populated
+ */
+ @NonNull
+ public StringPropertyConfig build() {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
+ // of partially reimplementing some of the validation Icing does here.
+ if (!mBundle.containsKey(CARDINALITY_FIELD)) {
+ throw new IllegalSchemaException("Missing field: cardinality");
+ }
+ mBuilt = true;
+ return new StringPropertyConfig(mBundle);
+ }
+ }
+ }
+
+ /** Configuration for a property containing a 64-bit integer. */
+ public static final class Int64PropertyConfig extends PropertyConfig {
+ Int64PropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
+ }
+
+ /**
+ * Builder for {@link Int64PropertyConfig}.
+ *
+ * <p>{@link #setCardinality} must be called or {@link #build} will fail.
+ */
+ public static final class Builder {
+ private final Bundle mBundle = new Bundle();
+ private boolean mBuilt = false;
+
+ /** Creates a new {@link Int64PropertyConfig.Builder}. */
+ public Builder(@NonNull String propertyName) {
+ mBundle.putString(NAME_FIELD, propertyName);
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_INT64);
+ }
+
+ /**
+ * The cardinality of the property (whether it is optional, required or repeated).
+ *
+ * <p>This property must be set.
+ */
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
+ @NonNull
+ public Int64PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkArgumentInRange(
+ cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+ mBundle.putInt(CARDINALITY_FIELD, cardinality);
+ return this;
+ }
+
+ /**
+ * Constructs a new {@link Int64PropertyConfig} from the contents of this builder.
+ *
+ * <p>After calling this method, the builder must no longer be used.
+ *
+ * @throws IllegalSchemaException if the property is not correctly populated
+ */
+ @NonNull
+ public Int64PropertyConfig build() {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ if (!mBundle.containsKey(CARDINALITY_FIELD)) {
+ throw new IllegalSchemaException("Missing field: cardinality");
+ }
+ mBuilt = true;
+ return new Int64PropertyConfig(mBundle);
+ }
+ }
+ }
+
+ /** Configuration for a property containing a double-precision decimal number. */
+ public static final class DoublePropertyConfig extends PropertyConfig {
+ DoublePropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
+ }
+
+ /**
+ * Builder for {@link DoublePropertyConfig}.
+ *
+ * <p>{@link #setCardinality} must be called or {@link #build} will fail.
+ */
+ public static final class Builder {
+ private final Bundle mBundle = new Bundle();
+ private boolean mBuilt = false;
+
+ /** Creates a new {@link DoublePropertyConfig.Builder}. */
+ public Builder(@NonNull String propertyName) {
+ mBundle.putString(NAME_FIELD, propertyName);
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOUBLE);
+ }
+
+ /**
+ * The cardinality of the property (whether it is optional, required or repeated).
+ *
+ * <p>This property must be set.
+ */
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
+ @NonNull
+ public DoublePropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkArgumentInRange(
+ cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+ mBundle.putInt(CARDINALITY_FIELD, cardinality);
+ return this;
+ }
+
+ /**
+ * Constructs a new {@link DoublePropertyConfig} from the contents of this builder.
+ *
+ * <p>After calling this method, the builder must no longer be used.
+ *
+ * @throws IllegalSchemaException if the property is not correctly populated
+ */
+ @NonNull
+ public DoublePropertyConfig build() {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ if (!mBundle.containsKey(CARDINALITY_FIELD)) {
+ throw new IllegalSchemaException("Missing field: cardinality");
+ }
+ mBuilt = true;
+ return new DoublePropertyConfig(mBundle);
+ }
+ }
+ }
+
+ /** Configuration for a property containing a boolean. */
+ public static final class BooleanPropertyConfig extends PropertyConfig {
+ BooleanPropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
+ }
+
+ /**
+ * Builder for {@link BooleanPropertyConfig}.
+ *
+ * <p>{@link #setCardinality} must be called or {@link #build} will fail.
+ */
+ public static final class Builder {
+ private final Bundle mBundle = new Bundle();
+ private boolean mBuilt = false;
+
+ /** Creates a new {@link BooleanPropertyConfig.Builder}. */
+ public Builder(@NonNull String propertyName) {
+ mBundle.putString(NAME_FIELD, propertyName);
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BOOLEAN);
+ }
+
+ /**
+ * The cardinality of the property (whether it is optional, required or repeated).
+ *
+ * <p>This property must be set.
+ */
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
+ @NonNull
+ public BooleanPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkArgumentInRange(
+ cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+ mBundle.putInt(CARDINALITY_FIELD, cardinality);
+ return this;
+ }
+
+ /**
+ * Constructs a new {@link BooleanPropertyConfig} from the contents of this builder.
+ *
+ * <p>After calling this method, the builder must no longer be used.
+ *
+ * @throws IllegalSchemaException if the property is not correctly populated
+ */
+ @NonNull
+ public BooleanPropertyConfig build() {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ if (!mBundle.containsKey(CARDINALITY_FIELD)) {
+ throw new IllegalSchemaException("Missing field: cardinality");
+ }
+ mBuilt = true;
+ return new BooleanPropertyConfig(mBundle);
+ }
+ }
+ }
+
+ /** Configuration for a property containing a byte array. */
+ public static final class BytesPropertyConfig extends PropertyConfig {
+ BytesPropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
+ }
+
+ /**
+ * Builder for {@link BytesPropertyConfig}.
+ *
+ * <p>{@link #setCardinality} must be called or {@link #build} will fail.
+ */
+ public static final class Builder {
+ private final Bundle mBundle = new Bundle();
+ private boolean mBuilt = false;
+
+ /** Creates a new {@link BytesPropertyConfig.Builder}. */
+ public Builder(@NonNull String propertyName) {
+ mBundle.putString(NAME_FIELD, propertyName);
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BYTES);
+ }
+
+ /**
+ * The cardinality of the property (whether it is optional, required or repeated).
+ *
+ * <p>This property must be set.
+ */
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
+ @NonNull
+ public BytesPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkArgumentInRange(
+ cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+ mBundle.putInt(CARDINALITY_FIELD, cardinality);
+ return this;
+ }
+
+ /**
+ * Constructs a new {@link BytesPropertyConfig} from the contents of this builder.
+ *
+ * <p>After calling this method, the builder must no longer be used.
+ *
+ * @throws IllegalSchemaException if the property is not correctly populated
+ */
+ @NonNull
+ public BytesPropertyConfig build() {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ if (!mBundle.containsKey(CARDINALITY_FIELD)) {
+ throw new IllegalSchemaException("Missing field: cardinality");
+ }
+ mBuilt = true;
+ return new BytesPropertyConfig(mBundle);
+ }
+ }
+ }
+
+ /** Configuration for a property containing another Document. */
+ public static final class DocumentPropertyConfig extends PropertyConfig {
+ private static final String SCHEMA_TYPE_FIELD = "schemaType";
+ private static final String INDEX_NESTED_PROPERTIES_FIELD = "indexNestedProperties";
+
+ DocumentPropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
+ }
+
+ /** Returns the logical schema-type of the contents of this document property. */
+ @NonNull
+ public String getSchemaType() {
+ return Preconditions.checkNotNull(mBundle.getString(SCHEMA_TYPE_FIELD));
+ }
+
+ /**
+ * Returns whether fields in the nested document should be indexed according to that
+ * document's schema.
+ *
+ * <p>If false, the nested document's properties are not indexed regardless of its own
+ * schema.
+ */
+ public boolean isIndexNestedProperties() {
+ return mBundle.getBoolean(INDEX_NESTED_PROPERTIES_FIELD);
+ }
+
+ /**
+ * Builder for {@link DocumentPropertyConfig}.
+ *
+ * <p>The following properties must be set, or {@link DocumentPropertyConfig} construction
+ * will fail:
+ *
+ * <ul>
+ * <li>cardinality
+ * <li>schemaType
+ * </ul>
+ */
+ public static final class Builder {
+ private final Bundle mBundle = new Bundle();
+ private boolean mBuilt = false;
+
+ /** Creates a new {@link DocumentPropertyConfig.Builder}. */
+ public Builder(@NonNull String propertyName) {
+ mBundle.putString(NAME_FIELD, propertyName);
+ mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
+ }
+
+ /**
+ * The logical schema-type of the contents of this property.
+ *
+ * <p>This property must be set.
+ */
+ @NonNull
+ public DocumentPropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkNotNull(schemaType);
+ mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
+ return this;
+ }
+
+ /**
+ * The cardinality of the property (whether it is optional, required or repeated).
+ *
+ * <p>This property must be set.
+ */
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
+ @NonNull
+ public DocumentPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkArgumentInRange(
+ cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+ mBundle.putInt(CARDINALITY_FIELD, cardinality);
+ return this;
+ }
+
+ /**
+ * Configures whether fields in the nested document should be indexed according to that
+ * document's schema.
+ *
+ * <p>If false, the nested document's properties are not indexed regardless of its own
+ * schema.
+ */
+ @NonNull
+ public DocumentPropertyConfig.Builder setIndexNestedProperties(
+ boolean indexNestedProperties) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, indexNestedProperties);
+ return this;
+ }
+
+ /**
* Constructs a new {@link PropertyConfig} from the contents of this builder.
*
* <p>After calling this method, the builder must no longer be used.
@@ -514,24 +846,16 @@
* missing {@code dataType}).
*/
@NonNull
- public PropertyConfig build() {
+ public DocumentPropertyConfig build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
- // of partially reimplementing some of the validation Icing does here.
- if (!mBundle.containsKey(DATA_TYPE_FIELD)) {
- throw new IllegalSchemaException("Missing field: dataType");
- }
- if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()
- && mBundle.getInt(DATA_TYPE_FIELD) == DATA_TYPE_DOCUMENT) {
- throw new IllegalSchemaException(
- "Missing field: schemaType (required for configs with "
- + "dataType = DOCUMENT)");
+ if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()) {
+ throw new IllegalSchemaException("Missing field: schemaType");
}
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
throw new IllegalSchemaException("Missing field: cardinality");
}
mBuilt = true;
- return new PropertyConfig(mBundle);
+ return new DocumentPropertyConfig(mBundle);
}
}
}
diff --git a/framework/java/external/android/app/appsearch/GenericDocument.java b/framework/java/external/android/app/appsearch/GenericDocument.java
index 11e7fab..2f02808 100644
--- a/framework/java/external/android/app/appsearch/GenericDocument.java
+++ b/framework/java/external/android/app/appsearch/GenericDocument.java
@@ -80,9 +80,9 @@
/**
* The maximum number of indexed properties a document can have.
*
- * <p>Indexed properties are properties where the {@link
- * AppSearchSchema.PropertyConfig#getIndexingType()} constant is anything other than {@link
- * AppSearchSchema.PropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
+ * <p>Indexed properties are properties which are strings where the {@link
+ * AppSearchSchema.StringPropertyConfig#getIndexingType} value is anything other than {@link
+ * AppSearchSchema.StringPropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
*/
public static int getMaxIndexedProperties() {
return MAX_INDEXED_PROPERTIES;
diff --git a/framework/java/external/android/app/appsearch/GetByUriRequest.java b/framework/java/external/android/app/appsearch/GetByUriRequest.java
index 74afdd2..38e0046 100644
--- a/framework/java/external/android/app/appsearch/GetByUriRequest.java
+++ b/framework/java/external/android/app/appsearch/GetByUriRequest.java
@@ -17,13 +17,17 @@
package android.app.appsearch;
import android.annotation.NonNull;
+import android.util.ArrayMap;
import android.util.ArraySet;
import com.android.internal.util.Preconditions;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
/**
@@ -32,12 +36,24 @@
* @see AppSearchSession#getByUri
*/
public final class GetByUriRequest {
+ /**
+ * Schema type to be used in {@link android.app.appsearch.GetByUriRequest.Builder#addProjection}
+ * to apply property paths to all results, excepting any types that have had their own, specific
+ * property paths set.
+ */
+ public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
+
private final String mNamespace;
private final Set<String> mUris;
+ private final Map<String, List<String>> mTypePropertyPathsMap;
- GetByUriRequest(@NonNull String namespace, @NonNull Set<String> uris) {
- mNamespace = namespace;
- mUris = uris;
+ GetByUriRequest(
+ @NonNull String namespace,
+ @NonNull Set<String> uris,
+ @NonNull Map<String, List<String>> typePropertyPathsMap) {
+ mNamespace = Preconditions.checkNotNull(namespace);
+ mUris = Preconditions.checkNotNull(uris);
+ mTypePropertyPathsMap = Preconditions.checkNotNull(typePropertyPathsMap);
}
/** Returns the namespace to get documents from. */
@@ -52,10 +68,43 @@
return Collections.unmodifiableSet(mUris);
}
+ /**
+ * Returns a map from schema type to property paths to be used for projection.
+ *
+ * <p>If the map is empty, then all properties will be retrieved for all results.
+ *
+ * <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned by this
+ * function, rather than calling it multiple times.
+ */
+ @NonNull
+ public Map<String, List<String>> getProjections() {
+ Map<String, List<String>> copy = new ArrayMap<>();
+ for (String key : mTypePropertyPathsMap.keySet()) {
+ copy.put(key, new ArrayList<>(mTypePropertyPathsMap.get(key)));
+ }
+ return copy;
+ }
+
+ /**
+ * Returns a map from schema type to property paths to be used for projection.
+ *
+ * <p>If the map is empty, then all properties will be retrieved for all results.
+ *
+ * <p>A more efficient version of {@link #getProjections}, but it returns a modifiable map. This
+ * is not meant to be unhidden and should only be used by internal classes.
+ *
+ * @hide
+ */
+ @NonNull
+ public Map<String, List<String>> getProjectionsVisibleToPackagesInternal() {
+ return mTypePropertyPathsMap;
+ }
+
/** Builder for {@link GetByUriRequest} objects. */
public static final class Builder {
private String mNamespace = GenericDocument.DEFAULT_NAMESPACE;
private final Set<String> mUris = new ArraySet<>();
+ private final Map<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
private boolean mBuilt = false;
/**
@@ -87,12 +136,63 @@
return this;
}
+ /**
+ * Adds property paths for the specified type to be used for projection. If property paths
+ * are added for a type, then only the properties referred to will be retrieved for results
+ * of that type. If a property path that is specified isn't present in a result, it will be
+ * ignored for that result. Property paths cannot be null.
+ *
+ * <p>If no property paths are added for a particular type, then all properties of results
+ * of that type will be retrieved.
+ *
+ * <p>If property path is added for the {@link
+ * GetByUriRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will apply to
+ * all results, excepting any types that have their own, specific property paths set.
+ *
+ * <p>{@see SearchSpec.Builder#addProjection(String, String...)}
+ */
+ @NonNull
+ public Builder addProjection(@NonNull String schemaType, @NonNull String... propertyPaths) {
+ Preconditions.checkNotNull(propertyPaths);
+ return addProjection(schemaType, Arrays.asList(propertyPaths));
+ }
+
+ /**
+ * Adds property paths for the specified type to be used for projection. If property paths
+ * are added for a type, then only the properties referred to will be retrieved for results
+ * of that type. If a property path that is specified isn't present in a result, it will be
+ * ignored for that result. Property paths cannot be null.
+ *
+ * <p>If no property paths are added for a particular type, then all properties of results
+ * of that type will be retrieved.
+ *
+ * <p>If property path is added for the {@link
+ * GetByUriRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will apply to
+ * all results, excepting any types that have their own, specific property paths set.
+ *
+ * <p>{@see SearchSpec.Builder#addProjection(String, String...)}
+ */
+ @NonNull
+ public Builder addProjection(
+ @NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Preconditions.checkNotNull(schemaType);
+ Preconditions.checkNotNull(propertyPaths);
+ List<String> propertyPathsList = new ArrayList<>(propertyPaths.size());
+ for (String propertyPath : propertyPaths) {
+ Preconditions.checkNotNull(propertyPath);
+ propertyPathsList.add(propertyPath);
+ }
+ mProjectionTypePropertyPaths.put(schemaType, propertyPathsList);
+ return this;
+ }
+
/** Builds a new {@link GetByUriRequest}. */
@NonNull
public GetByUriRequest build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBuilt = true;
- return new GetByUriRequest(mNamespace, mUris);
+ return new GetByUriRequest(mNamespace, mUris, mProjectionTypePropertyPaths);
}
}
}
diff --git a/service/java/com/android/server/appsearch/AppSearchManagerService.java b/service/java/com/android/server/appsearch/AppSearchManagerService.java
index cfee7a4..ec41353 100644
--- a/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -190,6 +190,7 @@
@NonNull String databaseName,
@NonNull String namespace,
@NonNull List<String> uris,
+ @NonNull Map<String, List<String>> typePropertyPaths,
@UserIdInt int userId,
@NonNull IAppSearchBatchResultCallback callback) {
Preconditions.checkNotNull(packageName);
@@ -208,8 +209,8 @@
for (int i = 0; i < uris.size(); i++) {
String uri = uris.get(i);
try {
- GenericDocument document =
- impl.getDocument(packageName, databaseName, namespace, uri);
+ GenericDocument document = impl.getDocument(packageName, databaseName,
+ namespace, uri, typePropertyPaths);
resultBuilder.setSuccess(uri, document.getBundle());
} catch (Throwable t) {
resultBuilder.setResult(uri, throwableToFailedResult(t));
diff --git a/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 1581847..1665b1c 100644
--- a/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -21,6 +21,7 @@
import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
+import android.app.appsearch.GetByUriRequest;
import android.app.appsearch.PackageIdentifier;
import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
@@ -38,6 +39,7 @@
import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
+import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
import com.google.android.icing.IcingSearchEngine;
import com.google.android.icing.proto.DeleteByQueryResultProto;
@@ -428,6 +430,8 @@
* @param databaseName The databaseName this document resides in.
* @param namespace The namespace this document resides in.
* @param uri The URI of the document to get.
+ * @param typePropertyPaths A map of schema type to a list of property paths to return in the
+ * result.
* @return The Document contents
* @throws AppSearchException on IcingSearchEngine error.
*/
@@ -436,16 +440,35 @@
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String namespace,
- @NonNull String uri)
+ @NonNull String uri,
+ @NonNull Map<String, List<String>> typePropertyPaths)
throws AppSearchException {
GetResultProto getResultProto;
+ List<TypePropertyMask> nonPrefixedPropertyMasks =
+ TypePropertyPathToProtoConverter.toTypePropertyMaskList(typePropertyPaths);
+ List<TypePropertyMask> prefixedPropertyMasks =
+ new ArrayList<>(nonPrefixedPropertyMasks.size());
+ for (int i = 0; i < nonPrefixedPropertyMasks.size(); ++i) {
+ TypePropertyMask typePropertyMask = nonPrefixedPropertyMasks.get(i);
+ String nonPrefixedType = typePropertyMask.getSchemaType();
+ String prefixedType =
+ nonPrefixedType.equals(GetByUriRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
+ ? nonPrefixedType
+ : createPrefix(packageName, databaseName) + nonPrefixedType;
+ prefixedPropertyMasks.add(
+ typePropertyMask.toBuilder().setSchemaType(prefixedType).build());
+ }
+ GetResultSpecProto getResultSpec =
+ GetResultSpecProto.newBuilder()
+ .addAllTypePropertyMasks(prefixedPropertyMasks)
+ .build();
mReadWriteLock.readLock().lock();
try {
getResultProto =
mIcingSearchEngineLocked.get(
createPrefix(packageName, databaseName) + namespace,
uri,
- GetResultSpecProto.getDefaultInstance());
+ getResultSpec);
} finally {
mReadWriteLock.readLock().unlock();
}
diff --git a/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java b/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java
index 1c86cd6..24d64a0 100644
--- a/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java
@@ -85,15 +85,14 @@
private static final AppSearchSchema VISIBILITY_SCHEMA =
new AppSearchSchema.Builder(VISIBILITY_TYPE)
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder(
+ new AppSearchSchema.StringPropertyConfig.Builder(
NOT_PLATFORM_SURFACEABLE_PROPERTY)
- .setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder(PACKAGE_ACCESSIBLE_PROPERTY)
- .setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT)
+ new AppSearchSchema.DocumentPropertyConfig.Builder(
+ PACKAGE_ACCESSIBLE_PROPERTY)
.setSchemaType(PACKAGE_ACCESSIBLE_TYPE)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
@@ -107,22 +106,20 @@
private static final AppSearchSchema PACKAGE_ACCESSIBLE_SCHEMA =
new AppSearchSchema.Builder(PACKAGE_ACCESSIBLE_TYPE)
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
+ new AppSearchSchema.StringPropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
.build())
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder(SHA_256_CERT_PROPERTY)
+ new AppSearchSchema.BytesPropertyConfig.Builder(SHA_256_CERT_PROPERTY)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES)
.build())
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder(ACCESSIBLE_SCHEMA_PROPERTY)
+ new AppSearchSchema.StringPropertyConfig.Builder(
+ ACCESSIBLE_SCHEMA_PROPERTY)
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
.build())
.build();
@@ -238,7 +235,8 @@
PACKAGE_NAME,
DATABASE_NAME,
NAMESPACE,
- /*uri=*/ addUriPrefix(prefix));
+ /*uri=*/ addUriPrefix(prefix),
+ /*typePropertyPaths=*/ Collections.emptyMap());
// Update platform visibility settings
String[] schemas =
diff --git a/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index 69bf3d7..ce1c9f4 100644
--- a/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -22,6 +22,7 @@
import com.android.internal.util.Preconditions;
+import com.google.android.icing.proto.DocumentIndexingConfig;
import com.google.android.icing.proto.PropertyConfigProto;
import com.google.android.icing.proto.SchemaTypeConfigProto;
import com.google.android.icing.proto.SchemaTypeConfigProtoOrBuilder;
@@ -65,7 +66,6 @@
Preconditions.checkNotNull(property);
PropertyConfigProto.Builder builder =
PropertyConfigProto.newBuilder().setPropertyName(property.getName());
- StringIndexingConfig.Builder indexingConfig = StringIndexingConfig.newBuilder();
// Set dataType
@AppSearchSchema.PropertyConfig.DataType int dataType = property.getDataType();
@@ -76,12 +76,6 @@
}
builder.setDataType(dataTypeProto);
- // Set schemaType
- String schemaType = property.getSchemaType();
- if (schemaType != null) {
- builder.setSchemaType(schemaType);
- }
-
// Set cardinality
@AppSearchSchema.PropertyConfig.Cardinality int cardinality = property.getCardinality();
PropertyConfigProto.Cardinality.Code cardinalityProto =
@@ -91,36 +85,27 @@
}
builder.setCardinality(cardinalityProto);
- // Set indexingType
- @AppSearchSchema.PropertyConfig.IndexingType int indexingType = property.getIndexingType();
- TermMatchType.Code termMatchTypeProto;
- switch (indexingType) {
- case AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE:
- termMatchTypeProto = TermMatchType.Code.UNKNOWN;
- break;
- case AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS:
- termMatchTypeProto = TermMatchType.Code.EXACT_ONLY;
- break;
- case AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES:
- termMatchTypeProto = TermMatchType.Code.PREFIX;
- break;
- default:
- throw new IllegalArgumentException("Invalid indexingType: " + indexingType);
- }
- indexingConfig.setTermMatchType(termMatchTypeProto);
+ if (property instanceof AppSearchSchema.StringPropertyConfig) {
+ AppSearchSchema.StringPropertyConfig stringProperty =
+ (AppSearchSchema.StringPropertyConfig) property;
+ StringIndexingConfig stringIndexingConfig =
+ StringIndexingConfig.newBuilder()
+ .setTermMatchType(
+ convertTermMatchTypeToProto(stringProperty.getIndexingType()))
+ .setTokenizerType(
+ convertTokenizerTypeToProto(stringProperty.getTokenizerType()))
+ .build();
+ builder.setStringIndexingConfig(stringIndexingConfig);
- // Set tokenizerType
- @AppSearchSchema.PropertyConfig.TokenizerType
- int tokenizerType = property.getTokenizerType();
- StringIndexingConfig.TokenizerType.Code tokenizerTypeProto =
- StringIndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
- if (tokenizerTypeProto == null) {
- throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType);
+ } else if (property instanceof AppSearchSchema.DocumentPropertyConfig) {
+ AppSearchSchema.DocumentPropertyConfig documentProperty =
+ (AppSearchSchema.DocumentPropertyConfig) property;
+ builder.setSchemaType(documentProperty.getSchemaType())
+ .setDocumentIndexingConfig(
+ DocumentIndexingConfig.newBuilder()
+ .setIndexNestedProperties(
+ documentProperty.isIndexNestedProperties()));
}
- indexingConfig.setTokenizerType(tokenizerTypeProto);
-
- // Build!
- builder.setStringIndexingConfig(indexingConfig);
return builder.build();
}
@@ -145,39 +130,99 @@
private static AppSearchSchema.PropertyConfig toPropertyConfig(
@NonNull PropertyConfigProto proto) {
Preconditions.checkNotNull(proto);
- AppSearchSchema.PropertyConfig.Builder builder =
- new AppSearchSchema.PropertyConfig.Builder(proto.getPropertyName())
- .setDataType(proto.getDataType().getNumber())
+ switch (proto.getDataType()) {
+ case STRING:
+ return toStringPropertyConfig(proto);
+ case INT64:
+ return new AppSearchSchema.Int64PropertyConfig.Builder(proto.getPropertyName())
+ .setCardinality(proto.getCardinality().getNumber())
+ .build();
+ case DOUBLE:
+ return new AppSearchSchema.DoublePropertyConfig.Builder(proto.getPropertyName())
+ .setCardinality(proto.getCardinality().getNumber())
+ .build();
+ case BOOLEAN:
+ return new AppSearchSchema.BooleanPropertyConfig.Builder(proto.getPropertyName())
+ .setCardinality(proto.getCardinality().getNumber())
+ .build();
+ case BYTES:
+ return new AppSearchSchema.BytesPropertyConfig.Builder(proto.getPropertyName())
+ .setCardinality(proto.getCardinality().getNumber())
+ .build();
+ case DOCUMENT:
+ return toDocumentPropertyConfig(proto);
+ default:
+ throw new IllegalArgumentException("Invalid dataType: " + proto.getDataType());
+ }
+ }
+
+ @NonNull
+ private static AppSearchSchema.StringPropertyConfig toStringPropertyConfig(
+ @NonNull PropertyConfigProto proto) {
+ AppSearchSchema.StringPropertyConfig.Builder builder =
+ new AppSearchSchema.StringPropertyConfig.Builder(proto.getPropertyName())
.setCardinality(proto.getCardinality().getNumber())
.setTokenizerType(
proto.getStringIndexingConfig().getTokenizerType().getNumber());
- // Set schema
- if (!proto.getSchemaType().isEmpty()) {
- builder.setSchemaType(proto.getSchemaType());
- }
-
// Set indexingType
- @AppSearchSchema.PropertyConfig.IndexingType int indexingType;
TermMatchType.Code termMatchTypeProto = proto.getStringIndexingConfig().getTermMatchType();
- switch (termMatchTypeProto) {
+ builder.setIndexingType(convertTermMatchTypeFromProto(termMatchTypeProto));
+
+ return builder.build();
+ }
+
+ @NonNull
+ private static AppSearchSchema.DocumentPropertyConfig toDocumentPropertyConfig(
+ @NonNull PropertyConfigProto proto) {
+ return new AppSearchSchema.DocumentPropertyConfig.Builder(proto.getPropertyName())
+ .setCardinality(proto.getCardinality().getNumber())
+ .setSchemaType(proto.getSchemaType())
+ .setIndexNestedProperties(
+ proto.getDocumentIndexingConfig().getIndexNestedProperties())
+ .build();
+ }
+
+ @NonNull
+ private static TermMatchType.Code convertTermMatchTypeToProto(
+ @AppSearchSchema.StringPropertyConfig.IndexingType int indexingType) {
+ switch (indexingType) {
+ case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE:
+ return TermMatchType.Code.UNKNOWN;
+ case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS:
+ return TermMatchType.Code.EXACT_ONLY;
+ case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES:
+ return TermMatchType.Code.PREFIX;
+ default:
+ throw new IllegalArgumentException("Invalid indexingType: " + indexingType);
+ }
+ }
+
+ @AppSearchSchema.StringPropertyConfig.IndexingType
+ private static int convertTermMatchTypeFromProto(@NonNull TermMatchType.Code termMatchType) {
+ switch (termMatchType) {
case UNKNOWN:
- indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE;
- break;
+ return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
case EXACT_ONLY:
- indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS;
- break;
+ return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS;
case PREFIX:
- indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES;
- break;
+ return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES;
default:
// Avoid crashing in the 'read' path; we should try to interpret the document to the
// extent possible.
- Log.w(TAG, "Invalid indexingType: " + termMatchTypeProto.getNumber());
- indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE;
+ Log.w(TAG, "Invalid indexingType: " + termMatchType.getNumber());
+ return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
}
- builder.setIndexingType(indexingType);
+ }
- return builder.build();
+ @NonNull
+ private static StringIndexingConfig.TokenizerType.Code convertTokenizerTypeToProto(
+ @AppSearchSchema.StringPropertyConfig.TokenizerType int tokenizerType) {
+ StringIndexingConfig.TokenizerType.Code tokenizerTypeProto =
+ StringIndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
+ if (tokenizerTypeProto == null) {
+ throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType);
+ }
+ return tokenizerTypeProto;
}
}
diff --git a/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
index 417ea24..07d50ae 100644
--- a/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
@@ -25,10 +25,6 @@
import com.google.android.icing.proto.ScoringSpecProto;
import com.google.android.icing.proto.SearchSpecProto;
import com.google.android.icing.proto.TermMatchType;
-import com.google.android.icing.proto.TypePropertyMask;
-
-import java.util.List;
-import java.util.Map;
/**
* Translates a {@link SearchSpec} into icing search protos.
@@ -61,22 +57,17 @@
@NonNull
public static ResultSpecProto toResultSpecProto(@NonNull SearchSpec spec) {
Preconditions.checkNotNull(spec);
- ResultSpecProto.Builder builder =
- ResultSpecProto.newBuilder()
- .setNumPerPage(spec.getResultCountPerPage())
- .setSnippetSpec(
- ResultSpecProto.SnippetSpecProto.newBuilder()
- .setNumToSnippet(spec.getSnippetCount())
- .setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
- .setMaxWindowBytes(spec.getMaxSnippetSize()));
- Map<String, List<String>> projectionTypePropertyPaths = spec.getProjections();
- for (Map.Entry<String, List<String>> e : projectionTypePropertyPaths.entrySet()) {
- builder.addTypePropertyMasks(
- TypePropertyMask.newBuilder()
- .setSchemaType(e.getKey())
- .addAllPaths(e.getValue()));
- }
- return builder.build();
+ return ResultSpecProto.newBuilder()
+ .setNumPerPage(spec.getResultCountPerPage())
+ .setSnippetSpec(
+ ResultSpecProto.SnippetSpecProto.newBuilder()
+ .setNumToSnippet(spec.getSnippetCount())
+ .setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
+ .setMaxWindowBytes(spec.getMaxSnippetSize()))
+ .addAllTypePropertyMasks(
+ TypePropertyPathToProtoConverter.toTypePropertyMaskList(
+ spec.getProjections()))
+ .build();
}
/** Extracts {@link ScoringSpecProto} information from a {@link SearchSpec}. */
diff --git a/service/java/com/android/server/appsearch/external/localstorage/converter/TypePropertyPathToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/TypePropertyPathToProtoConverter.java
new file mode 100644
index 0000000..6f6dad2
--- /dev/null
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/TypePropertyPathToProtoConverter.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appsearch.external.localstorage.converter;
+
+import android.annotation.NonNull;
+
+import com.android.internal.util.Preconditions;
+
+import com.google.android.icing.proto.TypePropertyMask;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Translates a <code>Map<String, List<String>></code> into <code>List<TypePropertyMask></code>.
+ *
+ * @hide
+ */
+public final class TypePropertyPathToProtoConverter {
+ private TypePropertyPathToProtoConverter() {}
+
+ /** Extracts {@link TypePropertyMask} information from a {@link Map}. */
+ @NonNull
+ public static List<TypePropertyMask> toTypePropertyMaskList(
+ @NonNull Map<String, List<String>> typePropertyPaths) {
+ Preconditions.checkNotNull(typePropertyPaths);
+ List<TypePropertyMask> typePropertyMasks = new ArrayList<>(typePropertyPaths.size());
+ for (Map.Entry<String, List<String>> e : typePropertyPaths.entrySet()) {
+ typePropertyMasks.add(
+ TypePropertyMask.newBuilder()
+ .setSchemaType(e.getKey())
+ .addAllPaths(e.getValue())
+ .build());
+ }
+ return typePropertyMasks;
+ }
+}
diff --git a/synced_jetpack_changeid.txt b/synced_jetpack_changeid.txt
index bca9424..5ab3450 100644
--- a/synced_jetpack_changeid.txt
+++ b/synced_jetpack_changeid.txt
@@ -1 +1 @@
-I87d10a6c5f7b8e22a633fa910385061fbca0db24
+Iff96eae150c7cdd281c9ecb5d93f4ef697e89f1a
diff --git a/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java b/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
index 459fd15..13858a3 100644
--- a/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
+++ b/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
@@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.Future;
public class AppSearchTestUtils {
@@ -59,6 +60,20 @@
return list;
}
+ public static List<GenericDocument> doGet(AppSearchSessionShim session, GetByUriRequest request)
+ throws Exception {
+ AppSearchBatchResult<String, GenericDocument> result =
+ checkIsBatchResultSuccess(session.getByUri(request));
+ Set<String> uris = request.getUris();
+ assertThat(result.getSuccesses()).hasSize(uris.size());
+ assertThat(result.getFailures()).isEmpty();
+ List<GenericDocument> list = new ArrayList<>(uris.size());
+ for (String uri : uris) {
+ list.add(result.getSuccesses().get(uri));
+ }
+ return list;
+ }
+
public static List<GenericDocument> convertSearchResultsToDocuments(
SearchResultsShim searchResults) throws Exception {
List<SearchResult> results = searchResults.getNextPage().get();
diff --git a/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
index 7fcf877..dc225f1 100644
--- a/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
+++ b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
@@ -34,28 +34,26 @@
new AppSearchSchema.Builder("Email")
.setVersion(12345)
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder("subject")
- .setDataType(
- AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
+ new AppSearchSchema.StringPropertyConfig.Builder("subject")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
- AppSearchSchema.PropertyConfig
+ AppSearchSchema.StringPropertyConfig
.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
- AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
+ AppSearchSchema.StringPropertyConfig
+ .TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder("body")
- .setDataType(
- AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
+ new AppSearchSchema.StringPropertyConfig.Builder("body")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
- AppSearchSchema.PropertyConfig
+ AppSearchSchema.StringPropertyConfig
.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
- AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
+ AppSearchSchema.StringPropertyConfig
+ .TOKENIZER_TYPE_PLAIN)
.build())
.build();
@@ -102,26 +100,20 @@
AppSearchSchema musicRecordingSchema =
new AppSearchSchema.Builder("MusicRecording")
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder("artist")
- .setDataType(
- AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
+ new AppSearchSchema.StringPropertyConfig.Builder("artist")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.setIndexingType(
- AppSearchSchema.PropertyConfig
+ AppSearchSchema.StringPropertyConfig
.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
- AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
+ AppSearchSchema.StringPropertyConfig
+ .TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
- new AppSearchSchema.PropertyConfig.Builder("pubDate")
- .setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_INT64)
+ new AppSearchSchema.Int64PropertyConfig.Builder("pubDate")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setIndexingType(
- AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
- .setTokenizerType(
- AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
.build())
.build();
@@ -147,14 +139,7 @@
.setPropertyName("pubDate")
.setDataType(PropertyConfigProto.DataType.Code.INT64)
.setCardinality(
- PropertyConfigProto.Cardinality.Code.OPTIONAL)
- .setStringIndexingConfig(
- StringIndexingConfig.newBuilder()
- .setTokenizerType(
- StringIndexingConfig.TokenizerType
- .Code.NONE)
- .setTermMatchType(
- TermMatchType.Code.UNKNOWN)))
+ PropertyConfigProto.Cardinality.Code.OPTIONAL))
.build();
assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(musicRecordingSchema))