Merge "Merge frontend changes from Jetpack into Framework."
This commit is contained in:
committed by
Android (Google) Code Review
commit
dbf6f13897
@@ -27,8 +27,6 @@ import android.app.appsearch.AppSearchSchema.PropertyConfig;
|
||||
*
|
||||
* <p>This class is a higher level implement of {@link GenericDocument}.
|
||||
*
|
||||
* <p>This class will eventually migrate to Jetpack, where it will become public API.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -99,10 +97,9 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the from address of {@link AppSearchEmail}.
|
||||
* Gets the from address of {@link AppSearchEmail}.
|
||||
*
|
||||
* @return Returns the subject of {@link AppSearchEmail} or {@code null} if it's not been set
|
||||
* yet.
|
||||
* @return The subject of {@link AppSearchEmail} or {@code null} if it's not been set yet.
|
||||
*/
|
||||
@Nullable
|
||||
public String getFrom() {
|
||||
@@ -110,10 +107,10 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the destination addresses of {@link AppSearchEmail}.
|
||||
* Gets the destination addresses of {@link AppSearchEmail}.
|
||||
*
|
||||
* @return Returns the destination addresses of {@link AppSearchEmail} or {@code null} if it's
|
||||
* not been set yet.
|
||||
* @return The destination addresses of {@link AppSearchEmail} or {@code null} if it's not
|
||||
* been set yet.
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getTo() {
|
||||
@@ -121,10 +118,9 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CC list of {@link AppSearchEmail}.
|
||||
* Gets the CC list of {@link AppSearchEmail}.
|
||||
*
|
||||
* @return Returns the CC list of {@link AppSearchEmail} or {@code null} if it's not been set
|
||||
* yet.
|
||||
* @return The CC list of {@link AppSearchEmail} or {@code null} if it's not been set yet.
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getCc() {
|
||||
@@ -132,10 +128,9 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BCC list of {@link AppSearchEmail}.
|
||||
* Gets the BCC list of {@link AppSearchEmail}.
|
||||
*
|
||||
* @return Returns the BCC list of {@link AppSearchEmail} or {@code null} if it's not been set
|
||||
* yet.
|
||||
* @return The BCC list of {@link AppSearchEmail} or {@code null} if it's not been set yet.
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getBcc() {
|
||||
@@ -143,10 +138,9 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subject of {@link AppSearchEmail}.
|
||||
* Gets the subject of {@link AppSearchEmail}.
|
||||
*
|
||||
* @return Returns the value subject of {@link AppSearchEmail} or {@code null} if it's not been
|
||||
* set yet.
|
||||
* @return The value subject of {@link AppSearchEmail} or {@code null} if it's not been set yet.
|
||||
*/
|
||||
@Nullable
|
||||
public String getSubject() {
|
||||
@@ -154,9 +148,9 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the body of {@link AppSearchEmail}.
|
||||
* Gets the body of {@link AppSearchEmail}.
|
||||
*
|
||||
* @return Returns the body of {@link AppSearchEmail} or {@code null} if it's not been set yet.
|
||||
* @return The body of {@link AppSearchEmail} or {@code null} if it's not been set yet.
|
||||
*/
|
||||
@Nullable
|
||||
public String getBody() {
|
||||
@@ -169,7 +163,8 @@ public class AppSearchEmail extends GenericDocument {
|
||||
public static class Builder extends GenericDocument.Builder<AppSearchEmail.Builder> {
|
||||
|
||||
/**
|
||||
* Create a new {@link AppSearchEmail.Builder}
|
||||
* Creates a new {@link AppSearchEmail.Builder}
|
||||
*
|
||||
* @param uri The Uri of the Email.
|
||||
*/
|
||||
public Builder(@NonNull String uri) {
|
||||
@@ -177,56 +172,56 @@ public class AppSearchEmail extends GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the from address of {@link AppSearchEmail}
|
||||
* Sets the from address of {@link AppSearchEmail}
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchEmail.Builder setFrom(@NonNull String from) {
|
||||
setProperty(KEY_FROM, from);
|
||||
setPropertyString(KEY_FROM, from);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the destination address of {@link AppSearchEmail}
|
||||
* Sets the destination address of {@link AppSearchEmail}
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchEmail.Builder setTo(@NonNull String... to) {
|
||||
setProperty(KEY_TO, to);
|
||||
setPropertyString(KEY_TO, to);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CC list of {@link AppSearchEmail}
|
||||
* Sets the CC list of {@link AppSearchEmail}
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchEmail.Builder setCc(@NonNull String... cc) {
|
||||
setProperty(KEY_CC, cc);
|
||||
setPropertyString(KEY_CC, cc);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BCC list of {@link AppSearchEmail}
|
||||
* Sets the BCC list of {@link AppSearchEmail}
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchEmail.Builder setBcc(@NonNull String... bcc) {
|
||||
setProperty(KEY_BCC, bcc);
|
||||
setPropertyString(KEY_BCC, bcc);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subject of {@link AppSearchEmail}
|
||||
* Sets the subject of {@link AppSearchEmail}
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchEmail.Builder setSubject(@NonNull String subject) {
|
||||
setProperty(KEY_SUBJECT, subject);
|
||||
setPropertyString(KEY_SUBJECT, subject);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the body of {@link AppSearchEmail}
|
||||
* Sets the body of {@link AppSearchEmail}
|
||||
*/
|
||||
@NonNull
|
||||
public AppSearchEmail.Builder setBody(@NonNull String body) {
|
||||
setProperty(KEY_BODY, body);
|
||||
setPropertyString(KEY_BODY, body);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import android.app.appsearch.exceptions.IllegalSchemaException;
|
||||
import android.util.ArraySet;
|
||||
@@ -28,6 +30,8 @@ import com.android.internal.util.Preconditions;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -39,13 +43,8 @@ import java.util.Set;
|
||||
* @hide
|
||||
*/
|
||||
public final class AppSearchSchema {
|
||||
/** @hide */
|
||||
|
||||
public static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String PROPERTIES_FIELD = "properties";
|
||||
private static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
private static final String PROPERTIES_FIELD = "properties";
|
||||
|
||||
private final Bundle mBundle;
|
||||
|
||||
@@ -71,10 +70,35 @@ public final class AppSearchSchema {
|
||||
return mBundle.toString();
|
||||
}
|
||||
|
||||
/** Returns the name of this schema type, e.g. Email. */
|
||||
@NonNull
|
||||
public String getSchemaTypeName() {
|
||||
return mBundle.getString(SCHEMA_TYPE_FIELD, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of {@link PropertyConfig}s that are part of this schema.
|
||||
*
|
||||
* <p>This method creates a new list when called.
|
||||
*/
|
||||
@NonNull
|
||||
public List<PropertyConfig> getProperties() {
|
||||
ArrayList<Bundle> propertyBundles =
|
||||
mBundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
|
||||
if (propertyBundles.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<PropertyConfig> ret = new ArrayList<>(propertyBundles.size());
|
||||
for (int i = 0; i < propertyBundles.size(); i++) {
|
||||
ret.add(new PropertyConfig(propertyBundles.get(i)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Builder for {@link AppSearchSchema objects}. */
|
||||
public static final class Builder {
|
||||
private final String mTypeName;
|
||||
private final ArrayList<Bundle> mProperties = new ArrayList<>();
|
||||
private final ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
|
||||
private final Set<String> mPropertyNames = new ArraySet<>();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
@@ -85,15 +109,19 @@ public final class AppSearchSchema {
|
||||
}
|
||||
|
||||
/** Adds a property to the given type. */
|
||||
// TODO(b/171360120): MissingGetterMatchingBuilder expects a method called getPropertys, but
|
||||
// we provide the (correct) method getProperties. Once the bug referenced in this TODO is
|
||||
// fixed, remove this SuppressLint.
|
||||
@SuppressLint("MissingGetterMatchingBuilder")
|
||||
@NonNull
|
||||
public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(propertyConfig);
|
||||
if (!mPropertyNames.add(propertyConfig.mName)) {
|
||||
throw new IllegalSchemaException(
|
||||
"Property defined more than once: " + propertyConfig.mName);
|
||||
String name = propertyConfig.getName();
|
||||
if (!mPropertyNames.add(name)) {
|
||||
throw new IllegalSchemaException("Property defined more than once: " + name);
|
||||
}
|
||||
mProperties.add(propertyConfig.mBundle);
|
||||
mPropertyBundles.add(propertyConfig.mBundle);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -107,7 +135,7 @@ public final class AppSearchSchema {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mTypeName);
|
||||
bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mProperties);
|
||||
bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
|
||||
mBuilt = true;
|
||||
return new AppSearchSchema(bundle);
|
||||
}
|
||||
@@ -120,29 +148,12 @@ public final class AppSearchSchema {
|
||||
* a property.
|
||||
*/
|
||||
public static final class PropertyConfig {
|
||||
/** @hide */
|
||||
|
||||
public static final String NAME_FIELD = "name";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String DATA_TYPE_FIELD = "dataType";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String CARDINALITY_FIELD = "cardinality";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String INDEXING_TYPE_FIELD = "indexingType";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
|
||||
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";
|
||||
|
||||
/**
|
||||
* Physical data-types of the contents of the property.
|
||||
@@ -259,11 +270,9 @@ public final class AppSearchSchema {
|
||||
/** Tokenization for plain text. */
|
||||
public static final int TOKENIZER_TYPE_PLAIN = 1;
|
||||
|
||||
final String mName;
|
||||
final Bundle mBundle;
|
||||
|
||||
PropertyConfig(@NonNull String name, @NonNull Bundle bundle) {
|
||||
mName = Preconditions.checkNotNull(name);
|
||||
PropertyConfig(@NonNull Bundle bundle) {
|
||||
mBundle = Preconditions.checkNotNull(bundle);
|
||||
}
|
||||
|
||||
@@ -272,6 +281,45 @@ public final class AppSearchSchema {
|
||||
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);
|
||||
}
|
||||
|
||||
/** Returns how the property is indexed. */
|
||||
public @IndexingType int getIndexingType() {
|
||||
return mBundle.getInt(INDEXING_TYPE_FIELD);
|
||||
}
|
||||
|
||||
/** Returns how this property is tokenized (split into words). */
|
||||
public @TokenizerType int getTokenizerType() {
|
||||
return mBundle.getInt(TOKENIZER_TYPE_FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link PropertyConfig}.
|
||||
*
|
||||
@@ -286,13 +334,11 @@ public final class AppSearchSchema {
|
||||
* is also required.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final String mName;
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link PropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mName = Preconditions.checkNotNull(propertyName);
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
}
|
||||
|
||||
@@ -386,7 +432,7 @@ public final class AppSearchSchema {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new PropertyConfig(mName, mBundle);
|
||||
return new PropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.android.internal.util.Preconditions;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -65,20 +66,14 @@ public class GenericDocument {
|
||||
/** The default time-to-live in millisecond of a document, which is infinity. */
|
||||
private static final long DEFAULT_TTL_MILLIS = 0L;
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String PROPERTIES_FIELD = "properties";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String BYTE_ARRAY_FIELD = "byteArray";
|
||||
|
||||
static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
static final String URI_FIELD = "uri";
|
||||
static final String SCORE_FIELD = "score";
|
||||
static final String TTL_MILLIS_FIELD = "ttlMillis";
|
||||
static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
|
||||
static final String NAMESPACE_FIELD = "namespace";
|
||||
private static final String PROPERTIES_FIELD = "properties";
|
||||
private static final String BYTE_ARRAY_FIELD = "byteArray";
|
||||
private static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
private static final String URI_FIELD = "uri";
|
||||
private static final String SCORE_FIELD = "score";
|
||||
private static final String TTL_MILLIS_FIELD = "ttlMillis";
|
||||
private static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
|
||||
private static final String NAMESPACE_FIELD = "namespace";
|
||||
|
||||
/**
|
||||
* The maximum number of indexed properties a document can have.
|
||||
@@ -190,6 +185,12 @@ public class GenericDocument {
|
||||
return mBundle.getInt(SCORE_FIELD, DEFAULT_SCORE);
|
||||
}
|
||||
|
||||
/** Returns the names of all properties defined in this document. */
|
||||
@NonNull
|
||||
public Set<String> getPropertyNames() {
|
||||
return Collections.unmodifiableSet(mProperties.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a {@link String} value by key.
|
||||
*
|
||||
@@ -437,8 +438,6 @@ public class GenericDocument {
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
// Check only proto's equality is sufficient here since all properties in
|
||||
// mProperties are ordered by keys and stored in proto.
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
@@ -450,8 +449,8 @@ public class GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deeply checks two bundle is equally or not.
|
||||
* <p> Two bundle will be considered equally if they contains same content.
|
||||
* Deeply checks two bundles are equally or not.
|
||||
* <p> Two bundles will be considered equally if they contain same content.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static boolean bundleEquals(Bundle one, Bundle two) {
|
||||
@@ -472,7 +471,7 @@ public class GenericDocument {
|
||||
return false;
|
||||
} else if (valueOne == null && (valueTwo != null || !two.containsKey(key))) {
|
||||
// If we call bundle.get(key) when the 'key' doesn't actually exist in the
|
||||
// bundle, we'll get back a null. So make sure that both values are null and
|
||||
// bundle, we'll get back a null. So make sure that both values are null and
|
||||
// both keys exist in the bundle.
|
||||
return false;
|
||||
} else if (valueOne instanceof boolean[]) {
|
||||
@@ -538,8 +537,8 @@ public class GenericDocument {
|
||||
|
||||
/**
|
||||
* Calculates the hash code for a bundle.
|
||||
* <p> The hash code is only effected by the content in the bundle. Bundles will get
|
||||
* consistent hash code if they have same content.
|
||||
* <p> The hash code is only effected by the contents in the bundle. Bundles will get
|
||||
* consistent hash code if they have same contents.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static int bundleHashCode(Bundle bundle) {
|
||||
@@ -648,8 +647,11 @@ public class GenericDocument {
|
||||
/**
|
||||
* The builder class for {@link GenericDocument}.
|
||||
*
|
||||
* @param <BuilderType> Type of subclass who extend this.
|
||||
* @param <BuilderType> Type of subclass who extends this.
|
||||
*/
|
||||
// This builder is specifically designed to be extended by classes deriving from
|
||||
// GenericDocument.
|
||||
@SuppressLint("StaticFinalBuilder")
|
||||
public static class Builder<BuilderType extends Builder> {
|
||||
|
||||
private final Bundle mProperties = new Bundle();
|
||||
@@ -662,12 +664,11 @@ public class GenericDocument {
|
||||
*
|
||||
* @param uri The uri of {@link GenericDocument}.
|
||||
* @param schemaType The schema type of the {@link GenericDocument}. The passed-in
|
||||
* {@code schemaType} must be defined using {@code AppSearchManager#setSchema} prior
|
||||
* {@code schemaType} must be defined using {@link AppSearchSession#setSchema} prior
|
||||
* to inserting a document of this {@code schemaType} into the AppSearch index using
|
||||
* {@code AppSearchManager#putDocuments}. Otherwise, the document will be
|
||||
* rejected by {@code AppSearchManager#putDocuments}.
|
||||
* {@link AppSearchSession#putDocuments}. Otherwise, the document will be
|
||||
* rejected by {@link AppSearchSession#putDocuments}.
|
||||
*/
|
||||
//TODO(b/157082794) Linkify AppSearchManager once that API is public.
|
||||
@SuppressWarnings("unchecked")
|
||||
public Builder(@NonNull String uri, @NonNull String schemaType) {
|
||||
Preconditions.checkNotNull(uri);
|
||||
@@ -685,9 +686,12 @@ public class GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the app-defined namespace this Document resides in. No special values are
|
||||
* reserved or understood by the infrastructure. URIs are unique within a namespace. The
|
||||
* number of namespaces per app should be kept small for efficiency reasons.
|
||||
* Sets the app-defined namespace this Document resides in. No special values are
|
||||
* reserved or understood by the infrastructure.
|
||||
*
|
||||
* <p>URIs are unique within a namespace.
|
||||
*
|
||||
* <p>The number of namespaces per app should be kept small for efficiency reasons.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setNamespace(@NonNull String namespace) {
|
||||
@@ -714,7 +718,7 @@ public class GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the creation timestamp in milliseconds of the {@link GenericDocument}. Should be
|
||||
* Sets the creation timestamp of the {@link GenericDocument}, in milliseconds. Should be
|
||||
* set using a value obtained from the {@link System#currentTimeMillis()} time base.
|
||||
*/
|
||||
@NonNull
|
||||
@@ -726,7 +730,7 @@ public class GenericDocument {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
|
||||
* Sets the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
|
||||
*
|
||||
* <p>After this many milliseconds since the {@link #setCreationTimestampMillis creation
|
||||
* timestamp}, the document is deleted.
|
||||
@@ -752,7 +756,7 @@ public class GenericDocument {
|
||||
* @param values The {@code String} values of the property.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setProperty(@NonNull String key, @NonNull String... values) {
|
||||
public BuilderType setPropertyString(@NonNull String key, @NonNull String... values) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(values);
|
||||
@@ -768,7 +772,7 @@ public class GenericDocument {
|
||||
* @param values The {@code boolean} values of the property.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setProperty(@NonNull String key, @NonNull boolean... values) {
|
||||
public BuilderType setPropertyBoolean(@NonNull String key, @NonNull boolean... values) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(values);
|
||||
@@ -784,7 +788,7 @@ public class GenericDocument {
|
||||
* @param values The {@code long} values of the property.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setProperty(@NonNull String key, @NonNull long... values) {
|
||||
public BuilderType setPropertyLong(@NonNull String key, @NonNull long... values) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(values);
|
||||
@@ -800,7 +804,7 @@ public class GenericDocument {
|
||||
* @param values The {@code double} values of the property.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setProperty(@NonNull String key, @NonNull double... values) {
|
||||
public BuilderType setPropertyDouble(@NonNull String key, @NonNull double... values) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(values);
|
||||
@@ -815,7 +819,7 @@ public class GenericDocument {
|
||||
* @param values The {@code byte[]} of the property.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setProperty(@NonNull String key, @NonNull byte[]... values) {
|
||||
public BuilderType setPropertyBytes(@NonNull String key, @NonNull byte[]... values) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(values);
|
||||
@@ -831,7 +835,8 @@ public class GenericDocument {
|
||||
* @param values The {@link GenericDocument} values of the property.
|
||||
*/
|
||||
@NonNull
|
||||
public BuilderType setProperty(@NonNull String key, @NonNull GenericDocument... values) {
|
||||
public BuilderType setPropertyDocument(
|
||||
@NonNull String key, @NonNull GenericDocument... values) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(values);
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import android.util.ArraySet;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -40,18 +40,16 @@ public final class GetByUriRequest {
|
||||
mUris = uris;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns the namespace to get documents from. */
|
||||
@NonNull
|
||||
public String getNamespace() {
|
||||
return mNamespace;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns the URIs to get from the namespace. */
|
||||
@NonNull
|
||||
public Set<String> getUris() {
|
||||
return mUris;
|
||||
return Collections.unmodifiableSet(mUris);
|
||||
}
|
||||
|
||||
/** Builder for {@link GetByUriRequest} objects. */
|
||||
@@ -75,14 +73,14 @@ public final class GetByUriRequest {
|
||||
|
||||
/** Adds one or more URIs to the request. */
|
||||
@NonNull
|
||||
public Builder addUris(@NonNull String... uris) {
|
||||
public Builder addUri(@NonNull String... uris) {
|
||||
Preconditions.checkNotNull(uris);
|
||||
return addUris(Arrays.asList(uris));
|
||||
return addUri(Arrays.asList(uris));
|
||||
}
|
||||
|
||||
/** Adds one or more URIs to the request. */
|
||||
@NonNull
|
||||
public Builder addUris(@NonNull Collection<String> uris) {
|
||||
public Builder addUri(@NonNull Collection<String> uris) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(uris);
|
||||
mUris.addAll(uris);
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -38,11 +41,10 @@ public final class PutDocumentsRequest {
|
||||
mDocuments = documents;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns the documents that are part of this request. */
|
||||
@NonNull
|
||||
public List<GenericDocument> getDocuments() {
|
||||
return mDocuments;
|
||||
return Collections.unmodifiableList(mDocuments);
|
||||
}
|
||||
|
||||
/** Builder for {@link PutDocumentsRequest} objects. */
|
||||
@@ -51,6 +53,7 @@ public final class PutDocumentsRequest {
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Adds one or more documents to the request. */
|
||||
@SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
|
||||
@NonNull
|
||||
public Builder addGenericDocument(@NonNull GenericDocument... documents) {
|
||||
Preconditions.checkNotNull(documents);
|
||||
@@ -58,6 +61,7 @@ public final class PutDocumentsRequest {
|
||||
}
|
||||
|
||||
/** Adds one or more documents to the request. */
|
||||
@SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
|
||||
@NonNull
|
||||
public Builder addGenericDocument(@NonNull Collection<GenericDocument> documents) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import android.util.ArraySet;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -40,18 +40,16 @@ public final class RemoveByUriRequest {
|
||||
mUris = uris;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns the namespace to remove documents from. */
|
||||
@NonNull
|
||||
public String getNamespace() {
|
||||
return mNamespace;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns the URIs to remove from the namespace. */
|
||||
@NonNull
|
||||
public Set<String> getUris() {
|
||||
return mUris;
|
||||
return Collections.unmodifiableSet(mUris);
|
||||
}
|
||||
|
||||
/** Builder for {@link RemoveByUriRequest} objects. */
|
||||
@@ -75,14 +73,14 @@ public final class RemoveByUriRequest {
|
||||
|
||||
/** Adds one or more URIs to the request. */
|
||||
@NonNull
|
||||
public Builder addUris(@NonNull String... uris) {
|
||||
public Builder addUri(@NonNull String... uris) {
|
||||
Preconditions.checkNotNull(uris);
|
||||
return addUris(Arrays.asList(uris));
|
||||
return addUri(Arrays.asList(uris));
|
||||
}
|
||||
|
||||
/** Adds one or more URIs to the request. */
|
||||
@NonNull
|
||||
public Builder addUris(@NonNull Collection<String> uris) {
|
||||
public Builder addUri(@NonNull Collection<String> uris) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(uris);
|
||||
mUris.addAll(uris);
|
||||
|
||||
@@ -49,19 +49,22 @@ public final class SearchResult {
|
||||
@NonNull
|
||||
private final Bundle mDocumentBundle;
|
||||
|
||||
/** Cache of the inflated document. Comes from inflating mDocumentBundle at first use. */
|
||||
@Nullable
|
||||
private GenericDocument mDocument;
|
||||
|
||||
@Nullable
|
||||
private final List<Bundle> mMatchBundles;
|
||||
|
||||
/**
|
||||
* Contains a list of Snippets that matched the request. Only populated when requested in
|
||||
* both {@link SearchSpec.Builder#setSnippetCount(int)}
|
||||
* and {@link SearchSpec.Builder#setSnippetCountPerProperty(int)}.
|
||||
* Contains a list of MatchInfo bundles that matched the request.
|
||||
*
|
||||
* Only populated when requested in both {@link SearchSpec.Builder#setSnippetCount} and
|
||||
* {@link SearchSpec.Builder#setSnippetCountPerProperty}.
|
||||
*
|
||||
* @see #getMatches()
|
||||
*/
|
||||
@NonNull
|
||||
private final List<Bundle> mMatchBundles;
|
||||
|
||||
/** Cache of the inflated matches. Comes from inflating mMatchBundles at first use. */
|
||||
@Nullable
|
||||
private List<MatchInfo> mMatches;
|
||||
|
||||
@@ -70,7 +73,7 @@ public final class SearchResult {
|
||||
public SearchResult(@NonNull Bundle bundle) {
|
||||
mBundle = Preconditions.checkNotNull(bundle);
|
||||
mDocumentBundle = Preconditions.checkNotNull(bundle.getBundle(DOCUMENT_FIELD));
|
||||
mMatchBundles = bundle.getParcelableArrayList(MATCHES_FIELD);
|
||||
mMatchBundles = Preconditions.checkNotNull(bundle.getParcelableArrayList(MATCHES_FIELD));
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -93,19 +96,16 @@ public final class SearchResult {
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains a list of Snippets that matched the request. Only populated when requested in
|
||||
* both {@link SearchSpec.Builder#setSnippetCount(int)}
|
||||
* and {@link SearchSpec.Builder#setSnippetCountPerProperty(int)}.
|
||||
* Contains a list of Snippets that matched the request.
|
||||
*
|
||||
* @return List of matches based on {@link SearchSpec}, if snippeting is disabled and this
|
||||
* method is called it will return {@code null}. Users can also restrict snippet population
|
||||
* using {@link SearchSpec.Builder#setSnippetCount} and
|
||||
* {@link SearchSpec.Builder#setSnippetCountPerProperty(int)}, for all results after that
|
||||
* value this method will return {@code null}.
|
||||
* @return List of matches based on {@link SearchSpec}. If snippeting is disabled using
|
||||
* {@link SearchSpec.Builder#setSnippetCount} or
|
||||
* {@link SearchSpec.Builder#setSnippetCountPerProperty}, for all results after that
|
||||
* value, this method returns an empty list.
|
||||
*/
|
||||
@Nullable
|
||||
@NonNull
|
||||
public List<MatchInfo> getMatches() {
|
||||
if (mMatchBundles != null && mMatches == null) {
|
||||
if (mMatches == null) {
|
||||
mMatches = new ArrayList<>(mMatchBundles.size());
|
||||
for (int i = 0; i < mMatchBundles.size(); i++) {
|
||||
MatchInfo matchInfo = new MatchInfo(getDocument(), mMatchBundles.get(i));
|
||||
@@ -119,8 +119,8 @@ public final class SearchResult {
|
||||
* Snippet: It refers to a substring of text from the content of document that is returned as a
|
||||
* part of search result.
|
||||
* This class represents a match objects for any Snippets that might be present in
|
||||
* {@link SearchResults} from query. Using this class user can get the full text, exact matches
|
||||
* and Snippets of document content for a given match.
|
||||
* {@link SearchResults} from query. Using this class
|
||||
* user can get the full text, exact matches and Snippets of document content for a given match.
|
||||
*
|
||||
* <p>Class Example 1:
|
||||
* A document contains following text in property subject:
|
||||
|
||||
@@ -16,16 +16,23 @@
|
||||
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
import android.app.appsearch.exceptions.IllegalSearchSpecException;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class represents the specification logic for AppSearch. It can be used to set the type of
|
||||
@@ -34,69 +41,26 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
// TODO(sidchhabra) : AddResultSpec fields for Snippets etc.
|
||||
public final class SearchSpec {
|
||||
/** @hide */
|
||||
|
||||
public static final String TERM_MATCH_TYPE_FIELD = "termMatchType";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String SCHEMA_TYPES_FIELD = "schemaType";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String NAMESPACE_FIELD = "namespace";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String NUM_PER_PAGE_FIELD = "numPerPage";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String RANKING_STRATEGY_FIELD = "rankingStrategy";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String ORDER_FIELD = "order";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String SNIPPET_COUNT_FIELD = "snippetCount";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String SNIPPET_COUNT_PER_PROPERTY_FIELD = "snippetCountPerProperty";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final String MAX_SNIPPET_FIELD = "maxSnippet";
|
||||
static final String TERM_MATCH_TYPE_FIELD = "termMatchType";
|
||||
static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
static final String NAMESPACE_FIELD = "namespace";
|
||||
static final String NUM_PER_PAGE_FIELD = "numPerPage";
|
||||
static final String RANKING_STRATEGY_FIELD = "rankingStrategy";
|
||||
static final String ORDER_FIELD = "order";
|
||||
static final String SNIPPET_COUNT_FIELD = "snippetCount";
|
||||
static final String SNIPPET_COUNT_PER_PROPERTY_FIELD = "snippetCountPerProperty";
|
||||
static final String MAX_SNIPPET_FIELD = "maxSnippet";
|
||||
|
||||
/** @hide */
|
||||
|
||||
public static final int DEFAULT_NUM_PER_PAGE = 10;
|
||||
|
||||
// TODO(b/170371356): In framework, we may want these limits might be flag controlled.
|
||||
private static final int MAX_NUM_PER_PAGE = 10_000;
|
||||
private static final int MAX_SNIPPET_COUNT = 10_000;
|
||||
private static final int MAX_SNIPPET_PER_PROPERTY_COUNT = 10_000;
|
||||
private static final int MAX_SNIPPET_SIZE_LIMIT = 10_000;
|
||||
|
||||
private final Bundle mBundle;
|
||||
|
||||
/** @hide */
|
||||
|
||||
public SearchSpec(@NonNull Bundle bundle) {
|
||||
Preconditions.checkNotNull(bundle);
|
||||
mBundle = bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Bundle} populated by this builder.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getBundle() {
|
||||
return mBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Term Match Type for the query.
|
||||
* @hide
|
||||
@@ -108,7 +72,7 @@ public final class SearchSpec {
|
||||
TERM_MATCH_PREFIX
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface TermMatchCode {}
|
||||
public @interface TermMatch {}
|
||||
|
||||
/**
|
||||
* Query terms will only match exact tokens in the index.
|
||||
@@ -126,14 +90,14 @@ public final class SearchSpec {
|
||||
* @hide
|
||||
*/
|
||||
// NOTE: The integer values of these constants must match the proto enum constants in
|
||||
// {@link ScoringSpecProto.RankingStrategy.Code }
|
||||
// {@link ScoringSpecProto.RankingStrategy.Code}
|
||||
@IntDef(value = {
|
||||
RANKING_STRATEGY_NONE,
|
||||
RANKING_STRATEGY_DOCUMENT_SCORE,
|
||||
RANKING_STRATEGY_CREATION_TIMESTAMP
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface RankingStrategyCode {}
|
||||
public @interface RankingStrategy {}
|
||||
|
||||
/** No Ranking, results are returned in arbitrary order.*/
|
||||
public static final int RANKING_STRATEGY_NONE = 0;
|
||||
@@ -147,23 +111,109 @@ public final class SearchSpec {
|
||||
* @hide
|
||||
*/
|
||||
// NOTE: The integer values of these constants must match the proto enum constants in
|
||||
// {@link ScoringSpecProto.Order.Code }
|
||||
// {@link ScoringSpecProto.Order.Code}
|
||||
@IntDef(value = {
|
||||
ORDER_DESCENDING,
|
||||
ORDER_ASCENDING
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface OrderCode {}
|
||||
public @interface Order {}
|
||||
|
||||
/** Search results will be returned in a descending order. */
|
||||
public static final int ORDER_DESCENDING = 0;
|
||||
/** Search results will be returned in an ascending order. */
|
||||
public static final int ORDER_ASCENDING = 1;
|
||||
|
||||
private final Bundle mBundle;
|
||||
|
||||
/** @hide */
|
||||
|
||||
public SearchSpec(@NonNull Bundle bundle) {
|
||||
Preconditions.checkNotNull(bundle);
|
||||
mBundle = bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Bundle} populated by this builder.
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@NonNull
|
||||
public Bundle getBundle() {
|
||||
return mBundle;
|
||||
}
|
||||
|
||||
/** Returns how the query terms should match terms in the index. */
|
||||
public @TermMatch int getTermMatch() {
|
||||
return mBundle.getInt(TERM_MATCH_TYPE_FIELD, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of schema types to search for.
|
||||
*
|
||||
* <p>If empty, the query will search over all schema types.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getSchemas() {
|
||||
List<String> schemas = mBundle.getStringArrayList(SCHEMA_TYPE_FIELD);
|
||||
if (schemas == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(schemas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of namespaces to search for.
|
||||
*
|
||||
* <p>If empty, the query will search over all namespaces.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getNamespaces() {
|
||||
List<String> namespaces = mBundle.getStringArrayList(NAMESPACE_FIELD);
|
||||
if (namespaces == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(namespaces);
|
||||
}
|
||||
|
||||
/** Returns the number of results per page in the returned object. */
|
||||
public int getNumPerPage() {
|
||||
return mBundle.getInt(NUM_PER_PAGE_FIELD, DEFAULT_NUM_PER_PAGE);
|
||||
}
|
||||
|
||||
/** Returns the ranking strategy. */
|
||||
public @RankingStrategy int getRankingStrategy() {
|
||||
return mBundle.getInt(RANKING_STRATEGY_FIELD);
|
||||
}
|
||||
|
||||
/** Returns the order of returned search results (descending or ascending). */
|
||||
public @Order int getOrder() {
|
||||
return mBundle.getInt(ORDER_FIELD);
|
||||
}
|
||||
|
||||
/** Returns how many documents to generate snippets for. */
|
||||
public int getSnippetCount() {
|
||||
return mBundle.getInt(SNIPPET_COUNT_FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many matches for each property of a matching document to generate snippets for.
|
||||
*/
|
||||
public int getSnippetCountPerProperty() {
|
||||
return mBundle.getInt(SNIPPET_COUNT_PER_PROPERTY_FIELD);
|
||||
}
|
||||
|
||||
/** Returns the maximum size of a snippet in characters. */
|
||||
public int getMaxSnippetSize() {
|
||||
return mBundle.getInt(MAX_SNIPPET_FIELD);
|
||||
}
|
||||
|
||||
/** Builder for {@link SearchSpec objects}. */
|
||||
public static final class Builder {
|
||||
|
||||
private final Bundle mBundle;
|
||||
private final ArrayList<String> mSchemaTypes = new ArrayList<>();
|
||||
private final ArrayList<String> mNamespaces = new ArrayList<>();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link SearchSpec.Builder}. */
|
||||
@@ -176,7 +226,7 @@ public final class SearchSpec {
|
||||
* Indicates how the query terms should match {@code TermMatchCode} in the index.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTermMatch(@TermMatchCode int termMatchTypeCode) {
|
||||
public Builder setTermMatch(@TermMatch int termMatchTypeCode) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(termMatchTypeCode, TERM_MATCH_EXACT_ONLY,
|
||||
TERM_MATCH_PREFIX, "Term match type");
|
||||
@@ -187,13 +237,27 @@ public final class SearchSpec {
|
||||
/**
|
||||
* Adds a Schema type filter to {@link SearchSpec} Entry. Only search for documents that
|
||||
* have the specified schema types.
|
||||
*
|
||||
* <p>If unset, the query will search over all schema types.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setSchemaTypes(@NonNull String... schemaTypes) {
|
||||
public Builder addSchema(@NonNull String... schemaTypes) {
|
||||
Preconditions.checkNotNull(schemaTypes);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mBundle.putStringArray(SCHEMA_TYPES_FIELD, schemaTypes);
|
||||
return addSchema(Arrays.asList(schemaTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Schema type filter to {@link SearchSpec} Entry. Only search for documents that
|
||||
* have the specified schema types.
|
||||
*
|
||||
* <p>If unset, the query will search over all schema types.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addSchema(@NonNull Collection<String> schemaTypes) {
|
||||
Preconditions.checkNotNull(schemaTypes);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mSchemaTypes.addAll(schemaTypes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -203,10 +267,22 @@ public final class SearchSpec {
|
||||
* <p>If unset, the query will search over all namespaces.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setNamespaces(@NonNull String... namespaces) {
|
||||
public Builder addNamespace(@NonNull String... namespaces) {
|
||||
Preconditions.checkNotNull(namespaces);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mBundle.putStringArray(NAMESPACE_FIELD, namespaces);
|
||||
return addNamespace(Arrays.asList(namespaces));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a namespace filter to {@link SearchSpec} Entry. Only search for documents that
|
||||
* have the specified namespaces.
|
||||
* <p>If unset, the query will search over all namespaces.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addNamespace(@NonNull Collection<String> namespaces) {
|
||||
Preconditions.checkNotNull(namespaces);
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mNamespaces.addAll(namespaces);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -224,7 +300,7 @@ public final class SearchSpec {
|
||||
|
||||
/** Sets ranking strategy for AppSearch results.*/
|
||||
@NonNull
|
||||
public Builder setRankingStrategy(@RankingStrategyCode int rankingStrategy) {
|
||||
public Builder setRankingStrategy(@RankingStrategy int rankingStrategy) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(rankingStrategy, RANKING_STRATEGY_NONE,
|
||||
RANKING_STRATEGY_CREATION_TIMESTAMP, "Result ranking strategy");
|
||||
@@ -238,7 +314,7 @@ public final class SearchSpec {
|
||||
* <p>This order field will be ignored if RankingStrategy = {@code RANKING_STRATEGY_NONE}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setOrder(@OrderCode int order) {
|
||||
public Builder setOrder(@Order int order) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(order, ORDER_DESCENDING, ORDER_ASCENDING,
|
||||
"Result ranking order");
|
||||
@@ -264,11 +340,12 @@ public final class SearchSpec {
|
||||
}
|
||||
|
||||
/**
|
||||
* Only the first {@code matchesCountPerProperty} matches for a every property of
|
||||
* {@link GenericDocument} will contain snippet information.
|
||||
* Sets {@code snippetCountPerProperty}. Only the first {@code snippetCountPerProperty}
|
||||
* snippets for a every property of {@link GenericDocument} will contain snippet
|
||||
* information.
|
||||
*
|
||||
* <p>If set to 0, snippeting is disabled and {@link SearchResult#getMatches} will return
|
||||
* {@code null} for that result.
|
||||
* <p>If set to 0, snippeting is disabled and {@link SearchResult#getMatches}
|
||||
* will return {@code null} for that result.
|
||||
*
|
||||
* <p>The value should be set in range[0, 10k].
|
||||
*/
|
||||
@@ -286,10 +363,13 @@ public final class SearchSpec {
|
||||
* {@code maxSnippetSize/2} bytes before the middle of the matching token and end at
|
||||
* {@code maxSnippetSize/2} bytes after the middle of the matching token. It respects
|
||||
* token boundaries, therefore the returned window may be smaller than requested.
|
||||
*
|
||||
* <p> Setting {@code maxSnippetSize} to 0 will disable windowing and an empty string will
|
||||
* be returned. If matches enabled is also set to false, then snippeting is disabled.
|
||||
*
|
||||
* <p>Ex. {@code maxSnippetSize} = 16. "foo bar baz bat rat" with a query of "baz" will
|
||||
* return a window of "bar baz bat" which is only 11 bytes long.
|
||||
*
|
||||
* <p>The value should be in range[0, 10k].
|
||||
*/
|
||||
@NonNull
|
||||
@@ -312,6 +392,8 @@ public final class SearchSpec {
|
||||
if (!mBundle.containsKey(TERM_MATCH_TYPE_FIELD)) {
|
||||
throw new IllegalSearchSpecException("Missing termMatchType field.");
|
||||
}
|
||||
mBundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
|
||||
mBundle.putStringArrayList(SCHEMA_TYPE_FIELD, mSchemaTypes);
|
||||
mBuilt = true;
|
||||
return new SearchSpec(mBundle);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,17 @@
|
||||
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.ArraySet;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
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.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -40,15 +44,13 @@ public final class SetSchemaRequest {
|
||||
mForceOverride = forceOverride;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns the schemas that are part of this request. */
|
||||
@NonNull
|
||||
public Set<AppSearchSchema> getSchemas() {
|
||||
return mSchemas;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
/** Returns whether this request will force the schema to be overridden. */
|
||||
public boolean isForceOverride() {
|
||||
return mForceOverride;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ public class AppSearchException extends Exception {
|
||||
mResultCode = resultCode;
|
||||
}
|
||||
|
||||
/** Returns the result code this exception was constructed with. */
|
||||
public @AppSearchResult.ResultCode int getResultCode() {
|
||||
return mResultCode;
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ import android.os.UserHandle;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.appsearch.external.localbackend.AppSearchImpl;
|
||||
import com.android.server.appsearch.external.localbackend.converter.GenericDocumentToProtoConverter;
|
||||
import com.android.server.appsearch.external.localbackend.converter.SchemaToProtoConverter;
|
||||
import com.android.server.appsearch.external.localbackend.converter.SearchResultToProtoConverter;
|
||||
import com.android.server.appsearch.external.localbackend.converter.SearchSpecToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
||||
import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
|
||||
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.google.android.icing.proto.DocumentProto;
|
||||
import com.google.android.icing.proto.SchemaProto;
|
||||
@@ -46,6 +46,7 @@ import com.google.android.icing.proto.SearchResultProto;
|
||||
import com.google.android.icing.proto.SearchSpecProto;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -193,7 +194,12 @@ public class AppSearchManagerService extends SystemService {
|
||||
SearchSpecToProtoConverter.toResultSpecProto(searchSpec),
|
||||
SearchSpecToProtoConverter.toScoringSpecProto(searchSpec));
|
||||
List<SearchResult> searchResultList =
|
||||
SearchResultToProtoConverter.convert(searchResultProto);
|
||||
new ArrayList<>(searchResultProto.getResultsCount());
|
||||
for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
|
||||
SearchResult result = SearchResultToProtoConverter.convertSearchResult(
|
||||
searchResultProto.getResults(i));
|
||||
searchResultList.add(result);
|
||||
}
|
||||
SearchResults searchResults =
|
||||
new SearchResults(searchResultList, searchResultProto.getNextPageToken());
|
||||
callback.complete(AppSearchResult.newSuccessfulResult(searchResults));
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.os.Environment;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.server.appsearch.external.localbackend.AppSearchImpl;
|
||||
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend;
|
||||
package com.android.server.appsearch.external.localstorage;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
|
||||
import android.os.Bundle;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
@@ -43,7 +41,6 @@ public final class GenericDocumentToProtoConverter {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static DocumentProto convert(@NonNull GenericDocument document) {
|
||||
Preconditions.checkNotNull(document);
|
||||
Bundle properties = document.getBundle().getBundle(GenericDocument.PROPERTIES_FIELD);
|
||||
DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder();
|
||||
mProtoBuilder.setUri(document.getUri())
|
||||
.setSchema(document.getSchemaType())
|
||||
@@ -51,42 +48,45 @@ public final class GenericDocumentToProtoConverter {
|
||||
.setScore(document.getScore())
|
||||
.setTtlMs(document.getTtlMillis())
|
||||
.setCreationTimestampMs(document.getCreationTimestampMillis());
|
||||
ArrayList<String> keys = new ArrayList<>(properties.keySet());
|
||||
ArrayList<String> keys = new ArrayList<>(document.getPropertyNames());
|
||||
Collections.sort(keys);
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
String name = keys.get(i);
|
||||
Object values = properties.get(name);
|
||||
PropertyProto.Builder propertyProto = PropertyProto.newBuilder().setName(name);
|
||||
if (values instanceof boolean[]) {
|
||||
for (boolean value : (boolean[]) values) {
|
||||
propertyProto.addBooleanValues(value);
|
||||
String[] stringValues = document.getPropertyStringArray(name);
|
||||
long[] longValues = document.getPropertyLongArray(name);
|
||||
double[] doubleValues = document.getPropertyDoubleArray(name);
|
||||
boolean[] booleanValues = document.getPropertyBooleanArray(name);
|
||||
byte[][] bytesValues = document.getPropertyBytesArray(name);
|
||||
GenericDocument[] documentValues = document.getPropertyDocumentArray(name);
|
||||
if (stringValues != null) {
|
||||
for (int j = 0; j < stringValues.length; j++) {
|
||||
propertyProto.addStringValues(stringValues[j]);
|
||||
}
|
||||
} else if (values instanceof long[]) {
|
||||
for (long value : (long[]) values) {
|
||||
propertyProto.addInt64Values(value);
|
||||
} else if (longValues != null) {
|
||||
for (int j = 0; j < longValues.length; j++) {
|
||||
propertyProto.addInt64Values(longValues[j]);
|
||||
}
|
||||
} else if (values instanceof double[]) {
|
||||
for (double value : (double[]) values) {
|
||||
propertyProto.addDoubleValues(value);
|
||||
} else if (doubleValues != null) {
|
||||
for (int j = 0; j < doubleValues.length; j++) {
|
||||
propertyProto.addDoubleValues(doubleValues[j]);
|
||||
}
|
||||
} else if (values instanceof String[]) {
|
||||
for (String value : (String[]) values) {
|
||||
propertyProto.addStringValues(value);
|
||||
} else if (booleanValues != null) {
|
||||
for (int j = 0; j < booleanValues.length; j++) {
|
||||
propertyProto.addBooleanValues(booleanValues[j]);
|
||||
}
|
||||
} else if (values instanceof ArrayList) {
|
||||
for (Bundle bundle : (ArrayList<Bundle>) values) {
|
||||
byte[] value = bundle.getByteArray(GenericDocument.BYTE_ARRAY_FIELD);
|
||||
propertyProto.addBytesValues(ByteString.copyFrom(value));
|
||||
} else if (bytesValues != null) {
|
||||
for (int j = 0; j < bytesValues.length; j++) {
|
||||
propertyProto.addBytesValues(ByteString.copyFrom(bytesValues[j]));
|
||||
}
|
||||
} else if (values instanceof Bundle[]) {
|
||||
for (Bundle bundle : (Bundle[]) values) {
|
||||
GenericDocument value = new GenericDocument(bundle);
|
||||
propertyProto.addDocumentValues(convert(value));
|
||||
} else if (documentValues != null) {
|
||||
for (int j = 0; j < documentValues.length; j++) {
|
||||
DocumentProto proto = convert(documentValues[j]);
|
||||
propertyProto.addDocumentValues(proto);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Property \"" + name + "\" has unsupported value type \""
|
||||
+ values.getClass().getSimpleName() + "\"");
|
||||
"Property \"" + name + "\" has unsupported value type");
|
||||
}
|
||||
mProtoBuilder.addProperties(propertyProto);
|
||||
}
|
||||
@@ -107,42 +107,42 @@ public final class GenericDocumentToProtoConverter {
|
||||
for (int i = 0; i < proto.getPropertiesCount(); i++) {
|
||||
PropertyProto property = proto.getProperties(i);
|
||||
String name = property.getName();
|
||||
if (property.getBooleanValuesCount() > 0) {
|
||||
boolean[] values = new boolean[property.getBooleanValuesCount()];
|
||||
if (property.getStringValuesCount() > 0) {
|
||||
String[] values = new String[property.getStringValuesCount()];
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
values[j] = property.getBooleanValues(j);
|
||||
values[j] = property.getStringValues(j);
|
||||
}
|
||||
documentBuilder.setProperty(name, values);
|
||||
documentBuilder.setPropertyString(name, values);
|
||||
} else if (property.getInt64ValuesCount() > 0) {
|
||||
long[] values = new long[property.getInt64ValuesCount()];
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
values[j] = property.getInt64Values(j);
|
||||
}
|
||||
documentBuilder.setProperty(name, values);
|
||||
documentBuilder.setPropertyLong(name, values);
|
||||
} else if (property.getDoubleValuesCount() > 0) {
|
||||
double[] values = new double[property.getDoubleValuesCount()];
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
values[j] = property.getDoubleValues(j);
|
||||
}
|
||||
documentBuilder.setProperty(name, values);
|
||||
} else if (property.getStringValuesCount() > 0) {
|
||||
String[] values = new String[property.getStringValuesCount()];
|
||||
documentBuilder.setPropertyDouble(name, values);
|
||||
} else if (property.getBooleanValuesCount() > 0) {
|
||||
boolean[] values = new boolean[property.getBooleanValuesCount()];
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
values[j] = property.getStringValues(j);
|
||||
values[j] = property.getBooleanValues(j);
|
||||
}
|
||||
documentBuilder.setProperty(name, values);
|
||||
documentBuilder.setPropertyBoolean(name, values);
|
||||
} else if (property.getBytesValuesCount() > 0) {
|
||||
byte[][] values = new byte[property.getBytesValuesCount()][];
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
values[j] = property.getBytesValues(j).toByteArray();
|
||||
}
|
||||
documentBuilder.setProperty(name, values);
|
||||
documentBuilder.setPropertyBytes(name, values);
|
||||
} else if (property.getDocumentValuesCount() > 0) {
|
||||
GenericDocument[] values = new GenericDocument[property.getDocumentValuesCount()];
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
values[j] = convert(property.getDocumentValues(j));
|
||||
}
|
||||
documentBuilder.setProperty(name, values);
|
||||
documentBuilder.setPropertyDocument(name, values);
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown type of value: " + name);
|
||||
}
|
||||
@@ -14,9 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
|
||||
import android.os.Bundle;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
@@ -28,7 +26,7 @@ import com.google.android.icing.proto.PropertyConfigProto;
|
||||
import com.google.android.icing.proto.SchemaTypeConfigProto;
|
||||
import com.google.android.icing.proto.TermMatchType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Translates an {@link AppSearchSchema} into a {@link SchemaTypeConfigProto}.
|
||||
@@ -45,31 +43,26 @@ public final class SchemaToProtoConverter {
|
||||
@NonNull
|
||||
public static SchemaTypeConfigProto convert(@NonNull AppSearchSchema schema) {
|
||||
Preconditions.checkNotNull(schema);
|
||||
Bundle bundle = schema.getBundle();
|
||||
SchemaTypeConfigProto.Builder protoBuilder =
|
||||
SchemaTypeConfigProto.newBuilder()
|
||||
.setSchemaType(bundle.getString(AppSearchSchema.SCHEMA_TYPE_FIELD, ""));
|
||||
ArrayList<Bundle> properties =
|
||||
bundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
|
||||
if (properties != null) {
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
PropertyConfigProto propertyProto = convertProperty(properties.get(i));
|
||||
protoBuilder.addProperties(propertyProto);
|
||||
}
|
||||
SchemaTypeConfigProto.newBuilder().setSchemaType(schema.getSchemaTypeName());
|
||||
List<AppSearchSchema.PropertyConfig> properties = schema.getProperties();
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
PropertyConfigProto propertyProto = convertProperty(properties.get(i));
|
||||
protoBuilder.addProperties(propertyProto);
|
||||
}
|
||||
return protoBuilder.build();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static PropertyConfigProto convertProperty(@NonNull Bundle bundle) {
|
||||
Preconditions.checkNotNull(bundle);
|
||||
private static PropertyConfigProto convertProperty(
|
||||
@NonNull AppSearchSchema.PropertyConfig property) {
|
||||
Preconditions.checkNotNull(property);
|
||||
PropertyConfigProto.Builder propertyConfigProto = PropertyConfigProto.newBuilder()
|
||||
.setPropertyName(bundle.getString(AppSearchSchema.PropertyConfig.NAME_FIELD, ""));
|
||||
.setPropertyName(property.getName());
|
||||
IndexingConfig.Builder indexingConfig = IndexingConfig.newBuilder();
|
||||
|
||||
// Set dataType
|
||||
@AppSearchSchema.PropertyConfig.DataType int dataType =
|
||||
bundle.getInt(AppSearchSchema.PropertyConfig.DATA_TYPE_FIELD);
|
||||
@AppSearchSchema.PropertyConfig.DataType int dataType = property.getDataType();
|
||||
PropertyConfigProto.DataType.Code dataTypeProto =
|
||||
PropertyConfigProto.DataType.Code.forNumber(dataType);
|
||||
if (dataTypeProto == null) {
|
||||
@@ -78,12 +71,13 @@ public final class SchemaToProtoConverter {
|
||||
propertyConfigProto.setDataType(dataTypeProto);
|
||||
|
||||
// Set schemaType
|
||||
propertyConfigProto.setSchemaType(
|
||||
bundle.getString(AppSearchSchema.PropertyConfig.SCHEMA_TYPE_FIELD, ""));
|
||||
String schemaType = property.getSchemaType();
|
||||
if (schemaType != null) {
|
||||
propertyConfigProto.setSchemaType(schemaType);
|
||||
}
|
||||
|
||||
// Set cardinality
|
||||
@AppSearchSchema.PropertyConfig.Cardinality int cardinality =
|
||||
bundle.getInt(AppSearchSchema.PropertyConfig.CARDINALITY_FIELD);
|
||||
@AppSearchSchema.PropertyConfig.Cardinality int cardinality = property.getCardinality();
|
||||
PropertyConfigProto.Cardinality.Code cardinalityProto =
|
||||
PropertyConfigProto.Cardinality.Code.forNumber(cardinality);
|
||||
if (cardinalityProto == null) {
|
||||
@@ -92,8 +86,7 @@ public final class SchemaToProtoConverter {
|
||||
propertyConfigProto.setCardinality(cardinalityProto);
|
||||
|
||||
// Set indexingType
|
||||
@AppSearchSchema.PropertyConfig.IndexingType int indexingType =
|
||||
bundle.getInt(AppSearchSchema.PropertyConfig.INDEXING_TYPE_FIELD);
|
||||
@AppSearchSchema.PropertyConfig.IndexingType int indexingType = property.getIndexingType();
|
||||
TermMatchType.Code termMatchTypeProto;
|
||||
switch (indexingType) {
|
||||
case AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE:
|
||||
@@ -112,7 +105,7 @@ public final class SchemaToProtoConverter {
|
||||
|
||||
// Set tokenizerType
|
||||
@AppSearchSchema.PropertyConfig.TokenizerType int tokenizerType =
|
||||
bundle.getInt(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_FIELD);
|
||||
property.getTokenizerType();
|
||||
IndexingConfig.TokenizerType.Code tokenizerTypeProto =
|
||||
IndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
|
||||
if (tokenizerTypeProto == null) {
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
@@ -22,43 +22,32 @@ import android.annotation.NonNull;
|
||||
|
||||
import android.app.appsearch.GenericDocument;
|
||||
import android.app.appsearch.SearchResult;
|
||||
import android.app.appsearch.SearchResults;
|
||||
|
||||
import com.google.android.icing.proto.SearchResultProto;
|
||||
import com.google.android.icing.proto.SnippetMatchProto;
|
||||
import com.google.android.icing.proto.SnippetProto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Translates a {@link SearchResultProto} into {@link SearchResults}.
|
||||
* Translates a {@link SearchResultProto} into {@link SearchResult}s.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public class SearchResultToProtoConverter {
|
||||
private SearchResultToProtoConverter() {}
|
||||
|
||||
/** Translates a {@link SearchResultProto} into a list of {@link SearchResult}. */
|
||||
@NonNull
|
||||
public static List<SearchResult> convert(@NonNull SearchResultProto searchResultProto) {
|
||||
List<SearchResult> results = new ArrayList<>(searchResultProto.getResultsCount());
|
||||
for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
|
||||
results.add(convertSearchResult(searchResultProto.getResults(i)));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Translate a {@link SearchResultProto.ResultProto} into {@link SearchResult}. */
|
||||
@NonNull
|
||||
static SearchResult convertSearchResult(@NonNull SearchResultProto.ResultProto proto) {
|
||||
public static SearchResult convertSearchResult(
|
||||
@NonNull SearchResultProto.ResultProtoOrBuilder proto) {
|
||||
Bundle bundle = new Bundle();
|
||||
GenericDocument document = GenericDocumentToProtoConverter.convert(proto.getDocument());
|
||||
bundle.putBundle(SearchResult.DOCUMENT_FIELD, document.getBundle());
|
||||
|
||||
ArrayList<Bundle> matchList = null;
|
||||
ArrayList<Bundle> matchList = new ArrayList<>();
|
||||
if (proto.hasSnippet()) {
|
||||
matchList = new ArrayList<>();
|
||||
for (int i = 0; i < proto.getSnippet().getEntriesCount(); i++) {
|
||||
SnippetProto.EntryProto entry = proto.getSnippet().getEntries(i);
|
||||
for (int j = 0; j < entry.getSnippetMatchesCount(); j++) {
|
||||
@@ -14,9 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
|
||||
import android.os.Bundle;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
@@ -28,8 +26,6 @@ import com.google.android.icing.proto.ScoringSpecProto;
|
||||
import com.google.android.icing.proto.SearchSpecProto;
|
||||
import com.google.android.icing.proto.TermMatchType;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Translates a {@link SearchSpec} into icing search protos.
|
||||
* @hide
|
||||
@@ -42,25 +38,17 @@ public final class SearchSpecToProtoConverter {
|
||||
@NonNull
|
||||
public static SearchSpecProto toSearchSpecProto(@NonNull SearchSpec spec) {
|
||||
Preconditions.checkNotNull(spec);
|
||||
Bundle bundle = spec.getBundle();
|
||||
SearchSpecProto.Builder protoBuilder = SearchSpecProto.newBuilder();
|
||||
SearchSpecProto.Builder protoBuilder = SearchSpecProto.newBuilder()
|
||||
.addAllSchemaTypeFilters(spec.getSchemas())
|
||||
.addAllNamespaceFilters(spec.getNamespaces());
|
||||
|
||||
@SearchSpec.TermMatchCode int termMatchCode =
|
||||
bundle.getInt(SearchSpec.TERM_MATCH_TYPE_FIELD);
|
||||
@SearchSpec.TermMatch int termMatchCode = spec.getTermMatch();
|
||||
TermMatchType.Code termMatchCodeProto = TermMatchType.Code.forNumber(termMatchCode);
|
||||
if (termMatchCodeProto == null || termMatchCodeProto.equals(TermMatchType.Code.UNKNOWN)) {
|
||||
throw new IllegalArgumentException("Invalid term match type: " + termMatchCode);
|
||||
}
|
||||
protoBuilder.setTermMatchType(termMatchCodeProto);
|
||||
|
||||
String[] schemaTypes = bundle.getStringArray(SearchSpec.SCHEMA_TYPES_FIELD);
|
||||
if (schemaTypes != null) {
|
||||
protoBuilder.addAllSchemaTypeFilters(Arrays.asList(schemaTypes));
|
||||
}
|
||||
String[] namespaces = bundle.getStringArray(SearchSpec.NAMESPACE_FIELD);
|
||||
if (namespaces != null) {
|
||||
protoBuilder.addAllNamespaceFilters(Arrays.asList(namespaces));
|
||||
}
|
||||
return protoBuilder.build();
|
||||
}
|
||||
|
||||
@@ -68,27 +56,23 @@ public final class SearchSpecToProtoConverter {
|
||||
@NonNull
|
||||
public static ResultSpecProto toResultSpecProto(@NonNull SearchSpec spec) {
|
||||
Preconditions.checkNotNull(spec);
|
||||
Bundle bundle = spec.getBundle();
|
||||
return ResultSpecProto.newBuilder()
|
||||
.setNumPerPage(bundle.getInt(
|
||||
SearchSpec.NUM_PER_PAGE_FIELD, SearchSpec.DEFAULT_NUM_PER_PAGE))
|
||||
.setSnippetSpec(ResultSpecProto.SnippetSpecProto.newBuilder()
|
||||
.setNumToSnippet(bundle.getInt(SearchSpec.SNIPPET_COUNT_FIELD))
|
||||
.setNumMatchesPerProperty(
|
||||
bundle.getInt(SearchSpec.SNIPPET_COUNT_PER_PROPERTY_FIELD))
|
||||
.setMaxWindowBytes(bundle.getInt(SearchSpec.MAX_SNIPPET_FIELD)))
|
||||
.setNumPerPage(spec.getNumPerPage())
|
||||
.setSnippetSpec(
|
||||
ResultSpecProto.SnippetSpecProto.newBuilder()
|
||||
.setNumToSnippet(spec.getSnippetCount())
|
||||
.setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
|
||||
.setMaxWindowBytes(spec.getMaxSnippetSize()))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
/** Extracts {@link ScoringSpecProto} information from a {@link SearchSpec}. */
|
||||
@NonNull
|
||||
public static ScoringSpecProto toScoringSpecProto(@NonNull SearchSpec spec) {
|
||||
Preconditions.checkNotNull(spec);
|
||||
Bundle bundle = spec.getBundle();
|
||||
ScoringSpecProto.Builder protoBuilder = ScoringSpecProto.newBuilder();
|
||||
|
||||
@SearchSpec.OrderCode int orderCode = bundle.getInt(SearchSpec.ORDER_FIELD);
|
||||
@SearchSpec.Order int orderCode = spec.getOrder();
|
||||
ScoringSpecProto.Order.Code orderCodeProto =
|
||||
ScoringSpecProto.Order.Code.forNumber(orderCode);
|
||||
if (orderCodeProto == null) {
|
||||
@@ -96,8 +80,7 @@ public final class SearchSpecToProtoConverter {
|
||||
}
|
||||
protoBuilder.setOrderBy(orderCodeProto);
|
||||
|
||||
@SearchSpec.RankingStrategyCode int rankingStrategyCode =
|
||||
bundle.getInt(SearchSpec.RANKING_STRATEGY_FIELD);
|
||||
@SearchSpec.RankingStrategy int rankingStrategyCode = spec.getRankingStrategy();
|
||||
ScoringSpecProto.RankingStrategy.Code rankingStrategyCodeProto =
|
||||
ScoringSpecProto.RankingStrategy.Code.forNumber(rankingStrategyCode);
|
||||
if (rankingStrategyCodeProto == null) {
|
||||
@@ -30,7 +30,7 @@ public class AppSearchEmailTest {
|
||||
// Score and Property are mixed into the middle to make sure DocumentBuilder's
|
||||
// methods can be interleaved with EmailBuilder's methods.
|
||||
.setScore(1)
|
||||
.setProperty("propertyKey", "propertyValue1", "propertyValue2")
|
||||
.setPropertyString("propertyKey", "propertyValue1", "propertyValue2")
|
||||
.setSubject("subject")
|
||||
.setBody("EmailBody")
|
||||
.build();
|
||||
|
||||
@@ -39,22 +39,22 @@ public class GenericDocumentTest {
|
||||
GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setTtlMillis(1L)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.build();
|
||||
GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setTtlMillis(1L)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.build();
|
||||
assertThat(document1).isEqualTo(document2);
|
||||
assertThat(document1.hashCode()).isEqualTo(document2.hashCode());
|
||||
@@ -64,23 +64,23 @@ public class GenericDocumentTest {
|
||||
public void testDocumentEquals_DifferentOrder() {
|
||||
GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.build();
|
||||
|
||||
// Create second document with same parameter but different order.
|
||||
GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.build();
|
||||
assertThat(document1).isEqualTo(document2);
|
||||
assertThat(document1.hashCode()).isEqualTo(document2.hashCode());
|
||||
@@ -90,13 +90,13 @@ public class GenericDocumentTest {
|
||||
public void testDocumentEquals_Failure() {
|
||||
GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.build();
|
||||
|
||||
// Create second document with same order but different value.
|
||||
GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("longKey1", 1L, 2L, 4L) // Different
|
||||
.setPropertyLong("longKey1", 1L, 2L, 4L) // Different
|
||||
.build();
|
||||
assertThat(document1).isNotEqualTo(document2);
|
||||
assertThat(document1.hashCode()).isNotEqualTo(document2.hashCode());
|
||||
@@ -106,13 +106,13 @@ public class GenericDocumentTest {
|
||||
public void testDocumentEquals_Failure_RepeatedFieldOrder() {
|
||||
GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.build();
|
||||
|
||||
// Create second document with same order but different value.
|
||||
GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("booleanKey1", true, true, false) // Different
|
||||
.setPropertyBoolean("booleanKey1", true, true, false) // Different
|
||||
.build();
|
||||
assertThat(document1).isNotEqualTo(document2);
|
||||
assertThat(document1.hashCode()).isNotEqualTo(document2.hashCode());
|
||||
@@ -124,12 +124,12 @@ public class GenericDocumentTest {
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setScore(1)
|
||||
.setTtlMillis(1L)
|
||||
.setProperty("longKey1", 1L)
|
||||
.setProperty("doubleKey1", 1.0)
|
||||
.setProperty("booleanKey1", true)
|
||||
.setProperty("stringKey1", "test-value1")
|
||||
.setProperty("byteKey1", sByteArray1)
|
||||
.setProperty("documentKey1", sDocumentProperties1)
|
||||
.setPropertyLong("longKey1", 1L)
|
||||
.setPropertyDouble("doubleKey1", 1.0)
|
||||
.setPropertyBoolean("booleanKey1", true)
|
||||
.setPropertyString("stringKey1", "test-value1")
|
||||
.setPropertyBytes("byteKey1", sByteArray1)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1)
|
||||
.build();
|
||||
assertThat(document.getUri()).isEqualTo("uri1");
|
||||
assertThat(document.getTtlMillis()).isEqualTo(1L);
|
||||
@@ -149,12 +149,12 @@ public class GenericDocumentTest {
|
||||
public void testDocumentGetArrayValues() {
|
||||
GenericDocument document = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.build();
|
||||
|
||||
assertThat(document.getUri()).isEqualTo("uri1");
|
||||
@@ -176,12 +176,12 @@ public class GenericDocumentTest {
|
||||
public void testDocument_ToString() throws Exception {
|
||||
GenericDocument document = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setCreationTimestampMillis(5L)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("stringKey1", "String1", "String2", "String3")
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyString("stringKey1", "String1", "String2", "String3")
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.build();
|
||||
String exceptedString = "{ key: 'creationTimestampMillis' value: 5 } "
|
||||
+ "{ key: 'namespace' value: } "
|
||||
@@ -219,9 +219,9 @@ public class GenericDocumentTest {
|
||||
public void testDocumentGetValues_DifferentTypes() {
|
||||
GenericDocument document = new GenericDocument.Builder("uri1", "schemaType1")
|
||||
.setScore(1)
|
||||
.setProperty("longKey1", 1L)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyLong("longKey1", 1L)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.build();
|
||||
|
||||
// Get a value for a key that doesn't exist
|
||||
@@ -246,6 +246,7 @@ public class GenericDocumentTest {
|
||||
public void testDocumentInvalid() {
|
||||
GenericDocument.Builder builder = new GenericDocument.Builder("uri1", "schemaType1");
|
||||
expectThrows(
|
||||
IllegalArgumentException.class, () -> builder.setProperty("test", new boolean[]{}));
|
||||
IllegalArgumentException.class,
|
||||
() -> builder.setPropertyBoolean("test", new boolean[]{}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 android.app.appsearch;
|
||||
|
||||
import static org.testng.Assert.expectThrows;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class SearchResultsTest {
|
||||
@Test
|
||||
public void buildSearchSpecWithoutTermMatchType() {
|
||||
expectThrows(RuntimeException.class, () -> new SearchSpec.Builder()
|
||||
.setSchemaTypes("testSchemaType")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
92
core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
vendored
Normal file
92
core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2020 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 android.app.appsearch;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.testng.Assert.expectThrows;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class SearchSpecTest {
|
||||
@Test
|
||||
public void buildSearchSpecWithoutTermMatchType() {
|
||||
expectThrows(RuntimeException.class, () -> new SearchSpec.Builder()
|
||||
.addSchema("testSchemaType")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildSearchSpec() {
|
||||
SearchSpec searchSpec = new SearchSpec.Builder()
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||
.addNamespace("namespace1", "namespace2")
|
||||
.addSchema("schemaTypes1", "schemaTypes2")
|
||||
.setSnippetCount(5)
|
||||
.setSnippetCountPerProperty(10)
|
||||
.setMaxSnippetSize(15)
|
||||
.setNumPerPage(42)
|
||||
.setOrder(SearchSpec.ORDER_ASCENDING)
|
||||
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE)
|
||||
.build();
|
||||
|
||||
assertThat(searchSpec.getTermMatch()).isEqualTo(SearchSpec.TERM_MATCH_PREFIX);
|
||||
assertThat(searchSpec.getNamespaces())
|
||||
.containsExactly("namespace1", "namespace2").inOrder();
|
||||
assertThat(searchSpec.getSchemas())
|
||||
.containsExactly("schemaTypes1", "schemaTypes2").inOrder();
|
||||
assertThat(searchSpec.getSnippetCount()).isEqualTo(5);
|
||||
assertThat(searchSpec.getSnippetCountPerProperty()).isEqualTo(10);
|
||||
assertThat(searchSpec.getMaxSnippetSize()).isEqualTo(15);
|
||||
assertThat(searchSpec.getNumPerPage()).isEqualTo(42);
|
||||
assertThat(searchSpec.getOrder()).isEqualTo(SearchSpec.ORDER_ASCENDING);
|
||||
assertThat(searchSpec.getRankingStrategy())
|
||||
.isEqualTo(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBundle() {
|
||||
SearchSpec searchSpec = new SearchSpec.Builder()
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||
.addNamespace("namespace1", "namespace2")
|
||||
.addSchema("schemaTypes1", "schemaTypes2")
|
||||
.setSnippetCount(5)
|
||||
.setSnippetCountPerProperty(10)
|
||||
.setMaxSnippetSize(15)
|
||||
.setNumPerPage(42)
|
||||
.setOrder(SearchSpec.ORDER_ASCENDING)
|
||||
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE)
|
||||
.build();
|
||||
|
||||
Bundle bundle = searchSpec.getBundle();
|
||||
assertThat(bundle.getInt(SearchSpec.TERM_MATCH_TYPE_FIELD))
|
||||
.isEqualTo(SearchSpec.TERM_MATCH_PREFIX);
|
||||
assertThat(bundle.getStringArrayList(SearchSpec.NAMESPACE_FIELD)).containsExactly(
|
||||
"namespace1", "namespace2");
|
||||
assertThat(bundle.getStringArrayList(SearchSpec.SCHEMA_TYPE_FIELD)).containsExactly(
|
||||
"schemaTypes1", "schemaTypes2");
|
||||
assertThat(bundle.getInt(SearchSpec.SNIPPET_COUNT_FIELD)).isEqualTo(5);
|
||||
assertThat(bundle.getInt(SearchSpec.SNIPPET_COUNT_PER_PROPERTY_FIELD)).isEqualTo(10);
|
||||
assertThat(bundle.getInt(SearchSpec.MAX_SNIPPET_FIELD)).isEqualTo(15);
|
||||
assertThat(bundle.getInt(SearchSpec.NUM_PER_PAGE_FIELD)).isEqualTo(42);
|
||||
assertThat(bundle.getInt(SearchSpec.ORDER_FIELD)).isEqualTo(SearchSpec.ORDER_ASCENDING);
|
||||
assertThat(bundle.getInt(SearchSpec.RANKING_STRATEGY_FIELD))
|
||||
.isEqualTo(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE);
|
||||
}
|
||||
}
|
||||
@@ -46,12 +46,12 @@ public class CustomerDocumentTest {
|
||||
CustomerDocument customerDocument = new CustomerDocument.Builder("uri1")
|
||||
.setScore(1)
|
||||
.setCreationTimestampMillis(0)
|
||||
.setProperty("longKey1", 1L, 2L, 3L)
|
||||
.setProperty("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setProperty("booleanKey1", true, false, true)
|
||||
.setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setProperty("byteKey1", sByteArray1, sByteArray2)
|
||||
.setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.setPropertyLong("longKey1", 1L, 2L, 3L)
|
||||
.setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
|
||||
.setPropertyBoolean("booleanKey1", true, false, true)
|
||||
.setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
|
||||
.setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
|
||||
.setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
|
||||
.build();
|
||||
|
||||
assertThat(customerDocument.getUri()).isEqualTo("uri1");
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend;
|
||||
package com.android.server.appsearch.external.localstorage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -53,13 +53,13 @@ public class GenericDocumentToProtoConverterTest {
|
||||
.setScore(1)
|
||||
.setTtlMillis(1L)
|
||||
.setNamespace("namespace")
|
||||
.setProperty("longKey1", 1L)
|
||||
.setProperty("doubleKey1", 1.0)
|
||||
.setProperty("booleanKey1", true)
|
||||
.setProperty("stringKey1", "test-value1")
|
||||
.setProperty("byteKey1", BYTE_ARRAY_1, BYTE_ARRAY_2)
|
||||
.setProperty("documentKey1", DOCUMENT_PROPERTIES_1)
|
||||
.setProperty(GenericDocument.PROPERTIES_FIELD, DOCUMENT_PROPERTIES_2)
|
||||
.setPropertyLong("longKey1", 1L)
|
||||
.setPropertyDouble("doubleKey1", 1.0)
|
||||
.setPropertyBoolean("booleanKey1", true)
|
||||
.setPropertyString("stringKey1", "test-value1")
|
||||
.setPropertyBytes("byteKey1", BYTE_ARRAY_1, BYTE_ARRAY_2)
|
||||
.setPropertyDocument("documentKey1", DOCUMENT_PROPERTIES_1)
|
||||
.setPropertyDocument("documentKey2", DOCUMENT_PROPERTIES_2)
|
||||
.build();
|
||||
|
||||
// Create the Document proto. Need to sort the property order by key.
|
||||
@@ -87,8 +87,8 @@ public class GenericDocumentToProtoConverterTest {
|
||||
PropertyProto.newBuilder().setName("documentKey1")
|
||||
.addDocumentValues(
|
||||
GenericDocumentToProtoConverter.convert(DOCUMENT_PROPERTIES_1)));
|
||||
propertyProtoMap.put(GenericDocument.PROPERTIES_FIELD,
|
||||
PropertyProto.newBuilder().setName(GenericDocument.PROPERTIES_FIELD)
|
||||
propertyProtoMap.put("documentKey2",
|
||||
PropertyProto.newBuilder().setName("documentKey2")
|
||||
.addDocumentValues(
|
||||
GenericDocumentToProtoConverter.convert(DOCUMENT_PROPERTIES_2)));
|
||||
List<String> sortedKey = new ArrayList<>(propertyProtoMap.keySet());
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -50,7 +50,6 @@ public class SchemaToProtoConverterTest {
|
||||
.addProperties(PropertyConfigProto.newBuilder()
|
||||
.setPropertyName("subject")
|
||||
.setDataType(PropertyConfigProto.DataType.Code.STRING)
|
||||
.setSchemaType("")
|
||||
.setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
|
||||
.setIndexingConfig(
|
||||
com.android.server.appsearch.proto.IndexingConfig.newBuilder()
|
||||
@@ -60,7 +59,6 @@ public class SchemaToProtoConverterTest {
|
||||
).addProperties(PropertyConfigProto.newBuilder()
|
||||
.setPropertyName("body")
|
||||
.setDataType(PropertyConfigProto.DataType.Code.STRING)
|
||||
.setSchemaType("")
|
||||
.setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
|
||||
.setIndexingConfig(
|
||||
com.android.server.appsearch.proto.IndexingConfig.newBuilder()
|
||||
@@ -94,7 +92,6 @@ public class SchemaToProtoConverterTest {
|
||||
.addProperties(PropertyConfigProto.newBuilder()
|
||||
.setPropertyName("artist")
|
||||
.setDataType(PropertyConfigProto.DataType.Code.STRING)
|
||||
.setSchemaType("")
|
||||
.setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
|
||||
.setIndexingConfig(
|
||||
com.android.server.appsearch.proto.IndexingConfig.newBuilder()
|
||||
@@ -104,7 +101,6 @@ public class SchemaToProtoConverterTest {
|
||||
).addProperties(PropertyConfigProto.newBuilder()
|
||||
.setPropertyName("pubDate")
|
||||
.setDataType(PropertyConfigProto.DataType.Code.INT64)
|
||||
.setSchemaType("")
|
||||
.setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
|
||||
.setIndexingConfig(
|
||||
com.android.server.appsearch.proto.IndexingConfig.newBuilder()
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.appsearch.external.localbackend.converter;
|
||||
package com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -123,7 +123,7 @@ public class SnippetTest {
|
||||
|
||||
for (SearchResultProto.ResultProto proto : searchResultProto.getResultsList()) {
|
||||
SearchResult result = SearchResultToProtoConverter.convertSearchResult(proto);
|
||||
assertThat(result.getMatches()).isEqualTo(null);
|
||||
assertThat(result.getMatches()).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user