Merge frontend changes from Jetpack into Framework.

Includes new APIs to comply with MissingGetterForSetter.

Bug: 162450968
Test: AppSearchManagerTest
Change-Id: I14fb2c815f2393968a06155c326f68562d066361
diff --git a/framework/java/android/app/appsearch/AppSearchEmail.java b/framework/java/android/app/appsearch/AppSearchEmail.java
index 5f2fabe..beb9ad3 100644
--- a/framework/java/android/app/appsearch/AppSearchEmail.java
+++ b/framework/java/android/app/appsearch/AppSearchEmail.java
@@ -27,8 +27,6 @@
  *
  * <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 @@
     }
 
     /**
-     * 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 @@
     }
 
     /**
-     * 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 @@
     }
 
     /**
-     * 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 @@
     }
 
     /**
-     * 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 @@
     }
 
     /**
-     * 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 @@
     }
 
     /**
-     * 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 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 @@
         }
 
         /**
-         * 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;
         }
 
diff --git a/framework/java/android/app/appsearch/AppSearchSchema.java b/framework/java/android/app/appsearch/AppSearchSchema.java
index 90e4df6..3933726 100644
--- a/framework/java/android/app/appsearch/AppSearchSchema.java
+++ b/framework/java/android/app/appsearch/AppSearchSchema.java
@@ -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 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 @@
  * @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 @@
         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 @@
         }
 
         /** 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 @@
             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 @@
      * 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 @@
         /** 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 @@
             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 @@
          * 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 @@
                     throw new IllegalSchemaException("Missing field: cardinality");
                 }
                 mBuilt = true;
-                return new PropertyConfig(mName, mBundle);
+                return new PropertyConfig(mBundle);
             }
         }
     }
diff --git a/framework/java/android/app/appsearch/GenericDocument.java b/framework/java/android/app/appsearch/GenericDocument.java
index 9fe2c67..48d3ac0 100644
--- a/framework/java/android/app/appsearch/GenericDocument.java
+++ b/framework/java/android/app/appsearch/GenericDocument.java
@@ -30,6 +30,7 @@
 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 @@
     /** 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 @@
         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 @@
 
     @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 @@
     }
 
     /**
-     * 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 @@
                 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 @@
 
     /**
      * 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 @@
     /**
      * 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 @@
          *
          * @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 @@
         }
 
         /**
-         * 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 @@
         }
 
         /**
-         * 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 @@
         }
 
         /**
-         * 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 @@
          * @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 @@
          * @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 @@
          * @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 @@
          * @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 @@
          * @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 @@
          * @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);
diff --git a/framework/java/android/app/appsearch/GetByUriRequest.java b/framework/java/android/app/appsearch/GetByUriRequest.java
index 3c0e746..e1e0eda 100644
--- a/framework/java/android/app/appsearch/GetByUriRequest.java
+++ b/framework/java/android/app/appsearch/GetByUriRequest.java
@@ -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 @@
         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 @@
 
         /** 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);
diff --git a/framework/java/android/app/appsearch/PutDocumentsRequest.java b/framework/java/android/app/appsearch/PutDocumentsRequest.java
index 7e97542..1f90bc1 100644
--- a/framework/java/android/app/appsearch/PutDocumentsRequest.java
+++ b/framework/java/android/app/appsearch/PutDocumentsRequest.java
@@ -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 @@
         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 @@
         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 @@
         }
 
         /** 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");
diff --git a/framework/java/android/app/appsearch/RemoveByUriRequest.java b/framework/java/android/app/appsearch/RemoveByUriRequest.java
index a047041..486857f 100644
--- a/framework/java/android/app/appsearch/RemoveByUriRequest.java
+++ b/framework/java/android/app/appsearch/RemoveByUriRequest.java
@@ -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 @@
         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 @@
 
         /** 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);
diff --git a/framework/java/android/app/appsearch/SearchResult.java b/framework/java/android/app/appsearch/SearchResult.java
index 758280b..99cb2f1 100644
--- a/framework/java/android/app/appsearch/SearchResult.java
+++ b/framework/java/android/app/appsearch/SearchResult.java
@@ -49,19 +49,22 @@
     @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 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 @@
     }
 
     /**
-     * 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 @@
      * 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:
diff --git a/framework/java/android/app/appsearch/SearchSpec.java b/framework/java/android/app/appsearch/SearchSpec.java
index c871905..15acf10 100644
--- a/framework/java/android/app/appsearch/SearchSpec.java
+++ b/framework/java/android/app/appsearch/SearchSpec.java
@@ -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 @@
  */
 // 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 @@
             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 @@
      * @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 @@
      * @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 @@
          * 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 @@
         /**
          * 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 @@
          * <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 @@
 
         /** 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 @@
          * <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 @@
         }
 
         /**
-         * 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 @@
          * {@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 @@
             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);
         }
diff --git a/framework/java/android/app/appsearch/SetSchemaRequest.java b/framework/java/android/app/appsearch/SetSchemaRequest.java
index b2e9d46..f2c8156 100644
--- a/framework/java/android/app/appsearch/SetSchemaRequest.java
+++ b/framework/java/android/app/appsearch/SetSchemaRequest.java
@@ -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 @@
         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;
     }
diff --git a/framework/java/android/app/appsearch/exceptions/AppSearchException.java b/framework/java/android/app/appsearch/exceptions/AppSearchException.java
index d490469..15d0992 100644
--- a/framework/java/android/app/appsearch/exceptions/AppSearchException.java
+++ b/framework/java/android/app/appsearch/exceptions/AppSearchException.java
@@ -54,6 +54,7 @@
         mResultCode = resultCode;
     }
 
+    /** Returns the result code this exception was constructed with. */
     public @AppSearchResult.ResultCode int getResultCode() {
         return mResultCode;
     }
diff --git a/service/java/com/android/server/appsearch/AppSearchManagerService.java b/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 7cd6ee2..f2830e5 100644
--- a/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -33,11 +33,11 @@
 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.SearchSpecProto;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -193,7 +194,12 @@
                         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));
diff --git a/service/java/com/android/server/appsearch/ImplInstanceManager.java b/service/java/com/android/server/appsearch/ImplInstanceManager.java
index 60f7005..2871eb6 100644
--- a/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -24,7 +24,7 @@
 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;
 
diff --git a/service/java/com/android/server/appsearch/external/localbackend/AppSearchImpl.java b/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
similarity index 99%
rename from service/java/com/android/server/appsearch/external/localbackend/AppSearchImpl.java
rename to service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 642378d..b1a79f8 100644
--- a/service/java/com/android/server/appsearch/external/localbackend/AppSearchImpl.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -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;
 
diff --git a/service/java/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
similarity index 69%
rename from service/java/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverter.java
rename to service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
index fdeb90d..60684f0 100644
--- a/service/java/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverter.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -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 @@
     @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 @@
                 .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 @@
         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);
             }
diff --git a/service/java/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
similarity index 73%
rename from service/java/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverter.java
rename to service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index ca0d2ee..403711f 100644
--- a/service/java/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverter.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -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.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 @@
     @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 @@
         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 @@
         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 @@
 
         // 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) {
diff --git a/service/java/com/android/server/appsearch/external/localbackend/converter/SearchResultToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
similarity index 79%
rename from service/java/com/android/server/appsearch/external/localbackend/converter/SearchResultToProtoConverter.java
rename to service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
index 524c80d..9f7c696 100644
--- a/service/java/com/android/server/appsearch/external/localbackend/converter/SearchResultToProtoConverter.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
@@ -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.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++) {
diff --git a/service/java/com/android/server/appsearch/external/localbackend/converter/SearchSpecToProtoConverter.java b/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
similarity index 67%
rename from service/java/com/android/server/appsearch/external/localbackend/converter/SearchSpecToProtoConverter.java
rename to service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
index a5d913a..14822dc 100644
--- a/service/java/com/android/server/appsearch/external/localbackend/converter/SearchSpecToProtoConverter.java
+++ b/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
@@ -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.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 @@
     @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 @@
     @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 @@
         }
         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) {
diff --git a/testing/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java b/testing/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
index ac2d4b5..2f2bef8 100644
--- a/testing/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
+++ b/testing/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
@@ -30,7 +30,7 @@
                 // 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();
diff --git a/testing/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java b/testing/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
index 1f2c12b..9c29943 100644
--- a/testing/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
+++ b/testing/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
@@ -39,22 +39,22 @@
         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 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 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 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 @@
                 .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 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 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 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 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[]{}));
     }
 }
diff --git a/testing/coretests/src/android/app/appsearch/external/app/SearchResultsTest.java b/testing/coretests/src/android/app/appsearch/external/app/SearchResultsTest.java
deleted file mode 100644
index acbf11a..0000000
--- a/testing/coretests/src/android/app/appsearch/external/app/SearchResultsTest.java
+++ /dev/null
@@ -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());
-    }
-}
diff --git a/testing/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java b/testing/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
new file mode 100644
index 0000000..d4635fd
--- /dev/null
+++ b/testing/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
@@ -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);
+    }
+}
diff --git a/testing/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java b/testing/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java
index 2c7c35f..d56d0c3 100644
--- a/testing/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java
+++ b/testing/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java
@@ -46,12 +46,12 @@
         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");
diff --git a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/AppSearchImplTest.java b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
similarity index 99%
rename from testing/servicestests/src/com/android/server/appsearch/external/localbackend/AppSearchImplTest.java
rename to testing/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index 081bfb5..0d0ac6d 100644
--- a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/AppSearchImplTest.java
+++ b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -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;
 
diff --git a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverterTest.java b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
similarity index 86%
rename from testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverterTest.java
rename to testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
index a95290d..85d4f01 100644
--- a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverterTest.java
+++ b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
@@ -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 @@
                         .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 @@
                 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());
diff --git a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverterTest.java b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
similarity index 96%
rename from testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverterTest.java
rename to testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
index 8b2fd1c..7336c3c 100644
--- a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverterTest.java
+++ b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
@@ -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 @@
                 .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 @@
                 ).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 @@
                 .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 @@
                 ).addProperties(PropertyConfigProto.newBuilder()
                         .setPropertyName("pubDate")
                         .setDataType(PropertyConfigProto.DataType.Code.INT64)
-                        .setSchemaType("")
                         .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
                         .setIndexingConfig(
                                 com.android.server.appsearch.proto.IndexingConfig.newBuilder()
diff --git a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SnippetTest.java b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
similarity index 98%
rename from testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SnippetTest.java
rename to testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
index e9357aa..d5762a1 100644
--- a/testing/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SnippetTest.java
+++ b/testing/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
@@ -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 @@
 
         for (SearchResultProto.ResultProto proto : searchResultProto.getResultsList()) {
             SearchResult result = SearchResultToProtoConverter.convertSearchResult(proto);
-            assertThat(result.getMatches()).isEqualTo(null);
+            assertThat(result.getMatches()).isEmpty();
         }
     }