Merge "Revert "Add build rule to merge annotation zips"" into stage-aosp-master
diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp
deleted file mode 100644
index 977e610..0000000
--- a/apex/appsearch/Android.bp
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2019 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-apex {
-    name: "com.android.appsearch",
-    manifest: "apex_manifest.json",
-    bootclasspath_fragments: ["com.android.appsearch-bootclasspath-fragment"],
-    systemserverclasspath_fragments: ["com.android.appsearch-systemserverclasspath-fragment"],
-    key: "com.android.appsearch.key",
-    certificate: ":com.android.appsearch.certificate",
-    updatable: false,
-    jni_libs: ["libicing"],
-    generate_hashtree: false,
-}
-
-apex_key {
-    name: "com.android.appsearch.key",
-    public_key: "com.android.appsearch.avbpubkey",
-    private_key: "com.android.appsearch.pem",
-}
-
-android_app_certificate {
-    name: "com.android.appsearch.certificate",
-    // This will use com.android.appsearch.x509.pem (the cert) and
-    // com.android.appsearch.pk8 (the private key)
-    certificate: "com.android.appsearch",
-}
-
-// Encapsulate the contributions made by the com.android.appsearch to the bootclasspath.
-bootclasspath_fragment {
-    name: "com.android.appsearch-bootclasspath-fragment",
-    contents: ["framework-appsearch"],
-    apex_available: ["com.android.appsearch"],
-
-    // The bootclasspath_fragments that provide APIs on which this depends.
-    fragments: [
-        {
-            apex: "com.android.art",
-            module: "art-bootclasspath-fragment",
-        },
-    ],
-
-    // Additional stubs libraries that this fragment's contents use which are
-    // not provided by another bootclasspath_fragment.
-    additional_stubs: [
-        "android-non-updatable",
-    ],
-}
-
-// Encapsulate the contributions made by the com.android.appsearch to the systemserverclasspath.
-systemserverclasspath_fragment {
-    name: "com.android.appsearch-systemserverclasspath-fragment",
-    contents: ["service-appsearch"],
-    apex_available: ["com.android.appsearch"],
-}
diff --git a/apex/appsearch/OWNERS b/apex/appsearch/OWNERS
deleted file mode 100644
index 1703369..0000000
--- a/apex/appsearch/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-adorokhine@google.com
-sudheersai@google.com
-yamasani@google.com
diff --git a/apex/appsearch/apex_manifest.json b/apex/appsearch/apex_manifest.json
deleted file mode 100644
index 39a2d38..0000000
--- a/apex/appsearch/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.appsearch",
-  "version": 300000000
-}
diff --git a/apex/appsearch/com.android.appsearch.avbpubkey b/apex/appsearch/com.android.appsearch.avbpubkey
deleted file mode 100644
index 4e5acae9..0000000
--- a/apex/appsearch/com.android.appsearch.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/appsearch/com.android.appsearch.pem b/apex/appsearch/com.android.appsearch.pem
deleted file mode 100644
index 4ed5945..0000000
--- a/apex/appsearch/com.android.appsearch.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEAro9f/jvoIsj6ywuRmuUQS8UtprhohJitrovDMfm/T2R/WQvy
-AvUxgetyF4XvBPCDRqCsGxXCJMQOn1furrAeTmWbGHPhA0PI1Ys/qtfNMbh9THyn
-70I2c4X70CUQ+8/Y8BJ8CAB4iER/s9QtD28QLvM2BBUzRoKUSBGUYNMlYobjgRdK
-57V7yg48LkvUIg1fzIW3M5gCgOXa0u1xOadKX3m7tzCboHcXp5anfWX5PH1+okRu
-jzdI8OjtUq23qhoRw5Skz0Vbf4a+8t3kT3slF/Q7O8LoRPwpZsvIcvTyCGAqlra7
-2L2LN4H1p+u2ko3r/QmRbJn2eXW07elkyrggXMyn2rTxibQgk53wYfSavMyNd/E7
-+de/uJ60l2aPa+5KUaR8eYwchXEELdqQ+zRgSZ2711xCaY4glEj7DT6VlEEdr26x
-akX0ra7e2sVGv1um/dvSyVO5aFKKjVvo4LqhWKWO8yvDMxmDDTNatvWhY2Bhd3RA
-0hilYpWQFb9Tv5f4E0tZmfvlddgux7sw++Y/RIimBFoSyf5AezAUIFYYoYvEzytB
-muq1/ecNHr+Z2tZMxN88sJVhzRzD9tKUyXhvxOV2Lg9TIeVTWGwQqgSnHWtIe+1p
-cw8inPfYEhP4Q+3W/RlPvNdu75x8Nj2aG7bxZnhoQDRDw5ddgma27I+a8esCAwEA
-AQKCAgBsNh9I6HRAVBz8kCBkSEnw3rwtFTZdtJQ+lw+bRHpvShqT5g7R/JQDOSTS
-JkoE4uBOgT4P0E45Inz6FLW2/yDacqxR3UwJDRVMI/WFACCJCRhLuR8V+BLvTIjN
-AJ1lrPSL5rmS8E/IEcakgQyp+6ypnkXHBCl0NXCcuKEl4N7VFE+mb/0UZPHnUSnH
-fWR085uGmwH17u7mXxdnGKDPH8DALSPMLUrcj9dPIdqUpwl5kUZWa1uqVphWF98/
-GMe5oE2Q0+3TO+i7xplKz3lAOFPHZLTvmCUK1tMHkZ6ifOwpewwLwB30/5N1BpB1
-126nrWk0xKCtFUixBOHzdnLwJHKSbi7chQU5q39oAJoTfxdmAJlaG0zQHUQZ44MQ
-gemzSA7uJbtoAOAZVF1K14xbIpnfidqTB7N3RCmiJE+/Hpkq6PxgPfu5rqocPbPC
-t0FgJ4NXNmKOAuJllSlrrHATcUOhF4g5pX7tvOc8X4y7bvfwOmtw5ez3INKMF0q6
-/y0vVCi6N1Z7CTa9eY8feZ1PImk/Fkq4NInSPyx7ZE3pLYmsvuJjliFrWo9TRVae
-Dt5vvBKBOpAfhDiHkeXbX7Raj2B6c6adF4no/3SAVlAjIq1iBVjfQWyHAGUoEW1O
-u3LdHTIb6gSTLJ4AfryEKrOE+1VMlYt92GwX692KKXMaJjytSQKCAQEA3pYbl8HD
-Y++UyEN5VzWAQedT3//GDwpDfgdERe2E4smYrkVNJ2WAG2SqY1A35DIl8be3eHvl
-soaL38j48ailfDYY9tI+IlapNh+VOLej+HiOytaPlLhcv2FpSC2qZT4EiU6IBXLo
-+l6FrmD/VQXTjvoktzsDB/n1t4Dfa3Ogf+lLf1Jxr94YpEnDh18V5ofj78SplVLm
-NrzsHxAafE4Ni2a7dyWjcDYIuL7FTShT+0K4W45tRr+CGxThxu7LEe7zw4Z1IagU
-jJNtXjvDD/Zw4UTqI6RwWGZsu6UjPS6LHhOqnWqflWmFRIfMbDkuWvnGZTM9DkVg
-kk1+BNi1PECZXwKCAQEAyMOjbVo6XV3lFN0X8TpHyg/z9ar00/SE7WEJHqPSuzYT
-rSfU4vDDlaPAwkYvGi9ZKi9VM+R3CyBNxnK9Yq6NurHhhrYcAwdS/hGLT1K2o0Y8
-Pgv7gZCFb+SIwLBhlUG9otGULcBzLneqgVUqyMG6IoCjuC2LRyB71Xc2UMyg6n/f
-XpV2RTMb8f+26cgm6nj0SDAfgpr8HV6uNV80c6l1A8gq86nUWwiVAEUdmExSDe7J
-shsfWAj8RSErqDXf1BtEdPLJUSIPX5VXkzAXOXIkengwVno0vv0dBN8uraS8iQSG
-0JsJLLcw9b5kvnh6FEbE7POsIqKyCZV9VADwO6YW9QKCAQBYQsdwNqoGv6KMgozj
-8tgHyfWtVduwbQ50M+dznwpZbzz2pY5Bd/MDabhSpyVyfBwlrAa5ZM+hKc7fDu7/
-zDLKfR0LCjUPIrP4PS/LjK4dQZjFf6zxeOV2EedQcqMlgCEGXTh8iKMvXDm/+sBk
-c2n/QNs8OM8r44b2m8h78B6NefGw6/0ekn/M7V72F9M0VWAh3Cauim+09tbePmFy
-NvUR+MuPJEKZpSNyNltADCS49izqSSC1tAygNniMjHXDh6/rMS7TCLYVRARTIHlp
-o/wAp3X8aiEOPJcTFRlTElihtYSq5POgqHXqxbpek5H5CyALUvT76rCvcsDspQ3A
-dZEbAoIBAQCoLEmP5o8Rev/UdEgECB/uwWJIngYsLp3TAv/SrMRvkiL1X3JTD/+m
-L9/eXVBDjPoR/khPCcg2h77ex2qhaTrL8wnKAG6CkvYQYb3impTnPIRmLT9nDxrX
-2gY78wQrNUCXTRvlH1rcx90KLb+DH9S95ig+tdf/otRYwl27XU5GYQtJfcXuvZth
-IiWku8btjpiCh909WHpsV81yY+faI08j9d8U8WQzRYMbEMpzsyrhBO/rxBCDfDNl
-7R1W8JooYRb9KAs/bVqXZNBROW2a72RjOp6zMfdRLVHLrPC7AE32MNaFk/khfesD
-T5OwgdcxeP6oxo2hDcw5fwHXBlo2fTCpAoIBAQChgjv5AfQ50spqvHy6MNem4tV0
-L0IsxmNLsi8X2a6s4kStwUzOxDA8c/e54XabxQNZ0ERU1q+bgbG7PWC4twDMPR8i
-2DO6rgqSK4MjGOTgAoeDuy3mElFQmCLRs04Wf4jh8kPi217WFlYBynh2HmBKbh42
-JmIrLetbKEK13FXRvMkgZcX4OIDrT5TOvev4VZArU8PTRlWv3sqsKAVXjX0clGHf
-I0/2kSsr2qq1UY7JrYWZsZ9uqz2ZH0pF19a6O/Cq4uqTYoL+sYzFTSeFmChRjV1g
-ancTvTn9lcBqECDMgq5DE/p96Oxg/t8elalR6WDUlysafphVz3nTuyMTh7ka
------END RSA PRIVATE KEY-----
diff --git a/apex/appsearch/com.android.appsearch.pk8 b/apex/appsearch/com.android.appsearch.pk8
deleted file mode 100644
index 77e98b2..0000000
--- a/apex/appsearch/com.android.appsearch.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/appsearch/com.android.appsearch.x509.pem b/apex/appsearch/com.android.appsearch.x509.pem
deleted file mode 100644
index e37c4b9..0000000
--- a/apex/appsearch/com.android.appsearch.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGETCCA/mgAwIBAgIUGl+MIvpEi0+TWzj0ieh6WtjXmP8wDQYJKoZIhvcNAQEL
-BQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMRIwEAYDVQQDDAlhcHBzZWFyY2gxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRA
-YW5kcm9pZC5jb20wIBcNMTkxMTIwMjMxNTM1WhgPNDc1NzEwMTYyMzE1MzVaMIGW
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDES
-MBAGA1UEAwwJYXBwc2VhcmNoMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJv
-aWQuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsyPlp3q3P9Xg
-W1WhIwQiF9em9oqaGQ/3dbIxickAy591qcRbpHb4lDTZusRECfqlV215mV+lv5x4
-EhOnId3uPKBAJ/YDtL7zUW6TWL7to7zEnUqSIKTcoQzNF2EiCeGuRhrtgYvAD3HQ
-dwr4xrbSADbDArF04A49voLpsmq1fyNgl86VISiMRqoSLJnA6eghlduuOt+nf252
-6WgxDs/JrO/eK70q0+RwmWzVJ/tVr+36a65N4EHhfL4t2hdV0k0XFob7hBn7XWzC
-QrSR3jCvE3yAfAr3tq5c19/WWBA7V45nEHzXyAvBUHWubYvDi+vm/yzqU2rQwScC
-bzp4zK4CnhBHqb4gHoy0+kfFIwJ1A3GT2pl3ba/NsIYgliMtPQfkDV5PE5RTNcwH
-21ewH7vm2+spQv5Z/2TEV2lEHlp2vuAliyn2AT4u1ginr6vtBRFLmpPeziFcfB0y
-7h04GctZpX8odz+XI7aMDe47RNu9XyJX0vulntxmlDF76k8Z9DIXg02hY+yc/i7+
-2ztnj1eXL51p+HyhK5VbvJWbKkVaMQijlbuIMYNzMA6L0WHWRc2Cux9UDODMGoiC
-w09JpqudCS/95I/F1xaWJ/Kh3vKeQshHAz0hrL7v7wpjmfeXf6NGsWJGy+giCwZj
-ABtn9nFQoesgi7M1LeazD5Q/4v4AMaUCAwEAAaNTMFEwHQYDVR0OBBYEFJpHCy2Y
-3qaL6cLpE9fe53L61KEEMB8GA1UdIwQYMBaAFJpHCy2Y3qaL6cLpE9fe53L61KEE
-MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAGDYAcOhbOYcDB2K
-WDZka+FCORFFvz4nLQGE7Z9TAn1g7XusM2KbXlb2drIN6CWOFlnKQrUsNsAHrc+s
-tl+A1vC3/NfYKKBVuizPx/kHUgz3k/UIJzbzEu/uCJd86idcJoUTqC/qEJAeeQqM
-XpsNP1Yg7oyzZT8sFlUAKeDeXJ7fIDXR6nduUQ6uJXkee/5JF3VedHdgHAUsC19/
-KHhyVU3MLDUNBdAmM79+DsdVYi2Pw31jojMu95Zz1MYTRBcgQAiEw5nncr38k6ac
-Gy+JffgJR68FzI4QLBSxnDRFD2zXJ09lpP6Sjb1FVcDzk7Bi/EQDLBkrkbeLsk5F
-a0xz9VoJ3kM7Cc4R9MXN4ZWuePjdJwgasnHmllsXn45R9odgJgmfzuUwtgNw/XKQ
-QcQl7Q9QUrBCqIoHijxscUZCBSmIHVNBBDckRAmSXHeWMRlO3uBR4IA/Jfrt//4f
-uc7CNUp+LQ6EzBXJOVFrXRtau6Oj+jM1+fzxKo1uV2+T+GdVEE5jeF/6nB3qna6h
-2NmyLqbqeqp2QxgzBWSGy8Ugs6zg4wItJBqOoRLKKFxTJu5OAzJ4fUA+g7WFXNhR
-kG56SJ863LZoORKHWE72oXYeIW98Tq0qKLH3NzH5L4tfX8DeBTq+APezHetH1ljA
-D0avPy62g0i643bbpwZgezBgRIKL
------END CERTIFICATE-----
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp
deleted file mode 100644
index 8964668..0000000
--- a/apex/appsearch/framework/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (C) 2019 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-filegroup {
-    name: "framework-appsearch-sources",
-    srcs: [
-        ":framework-appsearch-internal-sources",
-        ":framework-appsearch-external-sources",
-    ],
-    visibility: ["//frameworks/base"],
-}
-
-filegroup {
-    name: "framework-appsearch-internal-sources",
-    srcs: [
-        "java/**/*.java",
-        "java/**/*.aidl",
-    ],
-    exclude_srcs: [":framework-appsearch-external-sources"],
-    path: "java",
-}
-
-filegroup {
-    name: "framework-appsearch-external-sources",
-    srcs: [
-        "java/external/**/*.java",
-        "java/external/**/*.aidl",
-    ],
-    path: "java/external",
-}
-
-java_sdk_library {
-    name: "framework-appsearch",
-    srcs: [":framework-appsearch-sources"],
-    sdk_version: "module_current",
-    static_libs: [
-        // This list must be kept in sync with jarjar.txt
-        "modules-utils-preconditions",
-    ],
-    defaults: ["framework-module-defaults"],
-    permitted_packages: ["android.app.appsearch"],
-    jarjar_rules: "jarjar-rules.txt",
-    apex_available: ["com.android.appsearch"],
-    impl_library_visibility: [
-        "//frameworks/base/apex/appsearch/service",
-    ],
-    unsafe_ignore_missing_latest_api: true, // TODO(b/146218515) should be removed
-}
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt
deleted file mode 100644
index 761405c..0000000
--- a/apex/appsearch/framework/api/current.txt
+++ /dev/null
@@ -1,460 +0,0 @@
-// Signature format: 2.0
-package android.app.appsearch {
-
-  public final class AppSearchBatchResult<KeyType, ValueType> {
-    method @NonNull public java.util.Map<KeyType,android.app.appsearch.AppSearchResult<ValueType>> getAll();
-    method @NonNull public java.util.Map<KeyType,android.app.appsearch.AppSearchResult<ValueType>> getFailures();
-    method @NonNull public java.util.Map<KeyType,ValueType> getSuccesses();
-    method public boolean isSuccess();
-  }
-
-  public static final class AppSearchBatchResult.Builder<KeyType, ValueType> {
-    ctor public AppSearchBatchResult.Builder();
-    method @NonNull public android.app.appsearch.AppSearchBatchResult<KeyType,ValueType> build();
-    method @NonNull public android.app.appsearch.AppSearchBatchResult.Builder<KeyType,ValueType> setFailure(@NonNull KeyType, int, @Nullable String);
-    method @NonNull public android.app.appsearch.AppSearchBatchResult.Builder<KeyType,ValueType> setResult(@NonNull KeyType, @NonNull android.app.appsearch.AppSearchResult<ValueType>);
-    method @NonNull public android.app.appsearch.AppSearchBatchResult.Builder<KeyType,ValueType> setSuccess(@NonNull KeyType, @Nullable ValueType);
-  }
-
-  public class AppSearchManager {
-    method public void createGlobalSearchSession(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.GlobalSearchSession>>);
-    method public void createSearchSession(@NonNull android.app.appsearch.AppSearchManager.SearchContext, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.AppSearchSession>>);
-  }
-
-  public static final class AppSearchManager.SearchContext {
-    method @NonNull public String getDatabaseName();
-  }
-
-  public static final class AppSearchManager.SearchContext.Builder {
-    ctor public AppSearchManager.SearchContext.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchManager.SearchContext build();
-  }
-
-  public final class AppSearchResult<ValueType> {
-    method @Nullable public String getErrorMessage();
-    method public int getResultCode();
-    method @Nullable public ValueType getResultValue();
-    method public boolean isSuccess();
-    method @NonNull public static <ValueType> android.app.appsearch.AppSearchResult<ValueType> newFailedResult(int, @Nullable String);
-    method @NonNull public static <ValueType> android.app.appsearch.AppSearchResult<ValueType> newSuccessfulResult(@Nullable ValueType);
-    field public static final int RESULT_INTERNAL_ERROR = 2; // 0x2
-    field public static final int RESULT_INVALID_ARGUMENT = 3; // 0x3
-    field public static final int RESULT_INVALID_SCHEMA = 7; // 0x7
-    field public static final int RESULT_IO_ERROR = 4; // 0x4
-    field public static final int RESULT_NOT_FOUND = 6; // 0x6
-    field public static final int RESULT_OK = 0; // 0x0
-    field public static final int RESULT_OUT_OF_SPACE = 5; // 0x5
-    field public static final int RESULT_SECURITY_ERROR = 8; // 0x8
-    field public static final int RESULT_UNKNOWN_ERROR = 1; // 0x1
-  }
-
-  public final class AppSearchSchema {
-    method @NonNull public java.util.List<android.app.appsearch.AppSearchSchema.PropertyConfig> getProperties();
-    method @NonNull public String getSchemaType();
-  }
-
-  public static final class AppSearchSchema.BooleanPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
-  }
-
-  public static final class AppSearchSchema.BooleanPropertyConfig.Builder {
-    ctor public AppSearchSchema.BooleanPropertyConfig.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.BooleanPropertyConfig build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.BooleanPropertyConfig.Builder setCardinality(int);
-  }
-
-  public static final class AppSearchSchema.Builder {
-    ctor public AppSearchSchema.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.Builder addProperty(@NonNull android.app.appsearch.AppSearchSchema.PropertyConfig);
-    method @NonNull public android.app.appsearch.AppSearchSchema build();
-  }
-
-  public static final class AppSearchSchema.BytesPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
-  }
-
-  public static final class AppSearchSchema.BytesPropertyConfig.Builder {
-    ctor public AppSearchSchema.BytesPropertyConfig.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.BytesPropertyConfig build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.BytesPropertyConfig.Builder setCardinality(int);
-  }
-
-  public static final class AppSearchSchema.DocumentPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
-    method @NonNull public String getSchemaType();
-    method public boolean shouldIndexNestedProperties();
-  }
-
-  public static final class AppSearchSchema.DocumentPropertyConfig.Builder {
-    ctor public AppSearchSchema.DocumentPropertyConfig.Builder(@NonNull String, @NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setCardinality(int);
-    method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setShouldIndexNestedProperties(boolean);
-  }
-
-  public static final class AppSearchSchema.DoublePropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
-  }
-
-  public static final class AppSearchSchema.DoublePropertyConfig.Builder {
-    ctor public AppSearchSchema.DoublePropertyConfig.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig.Builder setCardinality(int);
-  }
-
-  public static final class AppSearchSchema.LongPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
-  }
-
-  public static final class AppSearchSchema.LongPropertyConfig.Builder {
-    ctor public AppSearchSchema.LongPropertyConfig.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.LongPropertyConfig build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.LongPropertyConfig.Builder setCardinality(int);
-  }
-
-  public abstract static class AppSearchSchema.PropertyConfig {
-    method public int getCardinality();
-    method @NonNull public String getName();
-    field public static final int CARDINALITY_OPTIONAL = 2; // 0x2
-    field public static final int CARDINALITY_REPEATED = 1; // 0x1
-    field public static final int CARDINALITY_REQUIRED = 3; // 0x3
-  }
-
-  public static final class AppSearchSchema.StringPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
-    method public int getIndexingType();
-    method public int getTokenizerType();
-    field public static final int INDEXING_TYPE_EXACT_TERMS = 1; // 0x1
-    field public static final int INDEXING_TYPE_NONE = 0; // 0x0
-    field public static final int INDEXING_TYPE_PREFIXES = 2; // 0x2
-    field public static final int TOKENIZER_TYPE_NONE = 0; // 0x0
-    field public static final int TOKENIZER_TYPE_PLAIN = 1; // 0x1
-  }
-
-  public static final class AppSearchSchema.StringPropertyConfig.Builder {
-    ctor public AppSearchSchema.StringPropertyConfig.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig build();
-    method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setCardinality(int);
-    method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setIndexingType(int);
-    method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setTokenizerType(int);
-  }
-
-  public final class AppSearchSession implements java.io.Closeable {
-    method public void close();
-    method public void getByDocumentId(@NonNull android.app.appsearch.GetByDocumentIdRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,android.app.appsearch.GenericDocument>);
-    method public void getNamespaces(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.Set<java.lang.String>>>);
-    method public void getSchema(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.GetSchemaResponse>>);
-    method public void getStorageInfo(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.StorageInfo>>);
-    method public void put(@NonNull android.app.appsearch.PutDocumentsRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
-    method public void remove(@NonNull android.app.appsearch.RemoveByDocumentIdRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>);
-    method public void remove(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
-    method public void reportUsage(@NonNull android.app.appsearch.ReportUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
-    method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec);
-    method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.SetSchemaResponse>>);
-  }
-
-  public interface BatchResultCallback<KeyType, ValueType> {
-    method public void onResult(@NonNull android.app.appsearch.AppSearchBatchResult<KeyType,ValueType>);
-    method public default void onSystemError(@Nullable Throwable);
-  }
-
-  public class GenericDocument {
-    ctor protected GenericDocument(@NonNull android.app.appsearch.GenericDocument);
-    method public long getCreationTimestampMillis();
-    method @NonNull public String getId();
-    method public static int getMaxIndexedProperties();
-    method @NonNull public String getNamespace();
-    method @Nullable public Object getProperty(@NonNull String);
-    method public boolean getPropertyBoolean(@NonNull String);
-    method @Nullable public boolean[] getPropertyBooleanArray(@NonNull String);
-    method @Nullable public byte[] getPropertyBytes(@NonNull String);
-    method @Nullable public byte[][] getPropertyBytesArray(@NonNull String);
-    method @Nullable public android.app.appsearch.GenericDocument getPropertyDocument(@NonNull String);
-    method @Nullable public android.app.appsearch.GenericDocument[] getPropertyDocumentArray(@NonNull String);
-    method public double getPropertyDouble(@NonNull String);
-    method @Nullable public double[] getPropertyDoubleArray(@NonNull String);
-    method public long getPropertyLong(@NonNull String);
-    method @Nullable public long[] getPropertyLongArray(@NonNull String);
-    method @NonNull public java.util.Set<java.lang.String> getPropertyNames();
-    method @Nullable public String getPropertyString(@NonNull String);
-    method @Nullable public String[] getPropertyStringArray(@NonNull String);
-    method @NonNull public String getSchemaType();
-    method public int getScore();
-    method public long getTtlMillis();
-  }
-
-  public static class GenericDocument.Builder<BuilderType extends android.app.appsearch.GenericDocument.Builder> {
-    ctor public GenericDocument.Builder(@NonNull String, @NonNull String, @NonNull String);
-    method @NonNull public android.app.appsearch.GenericDocument build();
-    method @NonNull public BuilderType setCreationTimestampMillis(long);
-    method @NonNull public BuilderType setPropertyBoolean(@NonNull String, @NonNull boolean...);
-    method @NonNull public BuilderType setPropertyBytes(@NonNull String, @NonNull byte[]...);
-    method @NonNull public BuilderType setPropertyDocument(@NonNull String, @NonNull android.app.appsearch.GenericDocument...);
-    method @NonNull public BuilderType setPropertyDouble(@NonNull String, @NonNull double...);
-    method @NonNull public BuilderType setPropertyLong(@NonNull String, @NonNull long...);
-    method @NonNull public BuilderType setPropertyString(@NonNull String, @NonNull java.lang.String...);
-    method @NonNull public BuilderType setScore(@IntRange(from=0, to=java.lang.Integer.MAX_VALUE) int);
-    method @NonNull public BuilderType setTtlMillis(long);
-  }
-
-  public final class GetByDocumentIdRequest {
-    method @NonNull public java.util.Set<java.lang.String> getIds();
-    method @NonNull public String getNamespace();
-    method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
-    field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
-  }
-
-  public static final class GetByDocumentIdRequest.Builder {
-    ctor public GetByDocumentIdRequest.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.GetByDocumentIdRequest.Builder addIds(@NonNull java.lang.String...);
-    method @NonNull public android.app.appsearch.GetByDocumentIdRequest.Builder addIds(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.GetByDocumentIdRequest.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.GetByDocumentIdRequest build();
-  }
-
-  public final class GetSchemaResponse {
-    method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
-    method @IntRange(from=0) public int getVersion();
-  }
-
-  public static final class GetSchemaResponse.Builder {
-    ctor public GetSchemaResponse.Builder();
-    method @NonNull public android.app.appsearch.GetSchemaResponse.Builder addSchema(@NonNull android.app.appsearch.AppSearchSchema);
-    method @NonNull public android.app.appsearch.GetSchemaResponse build();
-    method @NonNull public android.app.appsearch.GetSchemaResponse.Builder setVersion(@IntRange(from=0) int);
-  }
-
-  public class GlobalSearchSession implements java.io.Closeable {
-    method public void close();
-    method public void reportSystemUsage(@NonNull android.app.appsearch.ReportSystemUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>);
-    method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec);
-  }
-
-  public abstract class Migrator {
-    ctor public Migrator();
-    method @NonNull @WorkerThread public abstract android.app.appsearch.GenericDocument onDowngrade(int, int, @NonNull android.app.appsearch.GenericDocument);
-    method @NonNull @WorkerThread public abstract android.app.appsearch.GenericDocument onUpgrade(int, int, @NonNull android.app.appsearch.GenericDocument);
-    method public abstract boolean shouldMigrate(int, int);
-  }
-
-  public class PackageIdentifier {
-    ctor public PackageIdentifier(@NonNull String, @NonNull byte[]);
-    method @NonNull public String getPackageName();
-    method @NonNull public byte[] getSha256Certificate();
-  }
-
-  public final class PutDocumentsRequest {
-    method @NonNull public java.util.List<android.app.appsearch.GenericDocument> getGenericDocuments();
-  }
-
-  public static final class PutDocumentsRequest.Builder {
-    ctor public PutDocumentsRequest.Builder();
-    method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocuments(@NonNull android.app.appsearch.GenericDocument...);
-    method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocuments(@NonNull java.util.Collection<? extends android.app.appsearch.GenericDocument>);
-    method @NonNull public android.app.appsearch.PutDocumentsRequest build();
-  }
-
-  public final class RemoveByDocumentIdRequest {
-    method @NonNull public java.util.Set<java.lang.String> getIds();
-    method @NonNull public String getNamespace();
-  }
-
-  public static final class RemoveByDocumentIdRequest.Builder {
-    ctor public RemoveByDocumentIdRequest.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.RemoveByDocumentIdRequest.Builder addIds(@NonNull java.lang.String...);
-    method @NonNull public android.app.appsearch.RemoveByDocumentIdRequest.Builder addIds(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.RemoveByDocumentIdRequest build();
-  }
-
-  public final class ReportSystemUsageRequest {
-    method @NonNull public String getDatabaseName();
-    method @NonNull public String getDocumentId();
-    method @NonNull public String getNamespace();
-    method @NonNull public String getPackageName();
-    method public long getUsageTimestampMillis();
-  }
-
-  public static final class ReportSystemUsageRequest.Builder {
-    ctor public ReportSystemUsageRequest.Builder(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
-    method @NonNull public android.app.appsearch.ReportSystemUsageRequest build();
-    method @NonNull public android.app.appsearch.ReportSystemUsageRequest.Builder setUsageTimestampMillis(long);
-  }
-
-  public final class ReportUsageRequest {
-    method @NonNull public String getDocumentId();
-    method @NonNull public String getNamespace();
-    method public long getUsageTimestampMillis();
-  }
-
-  public static final class ReportUsageRequest.Builder {
-    ctor public ReportUsageRequest.Builder(@NonNull String, @NonNull String);
-    method @NonNull public android.app.appsearch.ReportUsageRequest build();
-    method @NonNull public android.app.appsearch.ReportUsageRequest.Builder setUsageTimestampMillis(long);
-  }
-
-  public final class SearchResult {
-    method @NonNull public String getDatabaseName();
-    method @NonNull public android.app.appsearch.GenericDocument getGenericDocument();
-    method @NonNull public java.util.List<android.app.appsearch.SearchResult.MatchInfo> getMatchInfos();
-    method @NonNull public String getPackageName();
-    method public double getRankingSignal();
-  }
-
-  public static final class SearchResult.Builder {
-    ctor public SearchResult.Builder(@NonNull String, @NonNull String);
-    method @NonNull public android.app.appsearch.SearchResult.Builder addMatchInfo(@NonNull android.app.appsearch.SearchResult.MatchInfo);
-    method @NonNull public android.app.appsearch.SearchResult build();
-    method @NonNull public android.app.appsearch.SearchResult.Builder setGenericDocument(@NonNull android.app.appsearch.GenericDocument);
-    method @NonNull public android.app.appsearch.SearchResult.Builder setRankingSignal(double);
-  }
-
-  public static final class SearchResult.MatchInfo {
-    method @NonNull public CharSequence getExactMatch();
-    method @NonNull public android.app.appsearch.SearchResult.MatchRange getExactMatchRange();
-    method @NonNull public String getFullText();
-    method @NonNull public String getPropertyPath();
-    method @NonNull public CharSequence getSnippet();
-    method @NonNull public android.app.appsearch.SearchResult.MatchRange getSnippetRange();
-  }
-
-  public static final class SearchResult.MatchInfo.Builder {
-    ctor public SearchResult.MatchInfo.Builder(@NonNull String);
-    method @NonNull public android.app.appsearch.SearchResult.MatchInfo build();
-    method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setExactMatchRange(@NonNull android.app.appsearch.SearchResult.MatchRange);
-    method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setSnippetRange(@NonNull android.app.appsearch.SearchResult.MatchRange);
-  }
-
-  public static final class SearchResult.MatchRange {
-    ctor public SearchResult.MatchRange(int, int);
-    method public int getEnd();
-    method public int getStart();
-  }
-
-  public class SearchResults implements java.io.Closeable {
-    method public void close();
-    method public void getNextPage(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.List<android.app.appsearch.SearchResult>>>);
-  }
-
-  public final class SearchSpec {
-    method @NonNull public java.util.List<java.lang.String> getFilterNamespaces();
-    method @NonNull public java.util.List<java.lang.String> getFilterPackageNames();
-    method @NonNull public java.util.List<java.lang.String> getFilterSchemas();
-    method public int getMaxSnippetSize();
-    method public int getOrder();
-    method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
-    method public int getRankingStrategy();
-    method public int getResultCountPerPage();
-    method public int getResultGroupingLimit();
-    method public int getResultGroupingTypeFlags();
-    method public int getSnippetCount();
-    method public int getSnippetCountPerProperty();
-    method public int getTermMatch();
-    field public static final int GROUPING_TYPE_PER_NAMESPACE = 2; // 0x2
-    field public static final int GROUPING_TYPE_PER_PACKAGE = 1; // 0x1
-    field public static final int ORDER_ASCENDING = 1; // 0x1
-    field public static final int ORDER_DESCENDING = 0; // 0x0
-    field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
-    field public static final int RANKING_STRATEGY_CREATION_TIMESTAMP = 2; // 0x2
-    field public static final int RANKING_STRATEGY_DOCUMENT_SCORE = 1; // 0x1
-    field public static final int RANKING_STRATEGY_NONE = 0; // 0x0
-    field public static final int RANKING_STRATEGY_RELEVANCE_SCORE = 3; // 0x3
-    field public static final int RANKING_STRATEGY_SYSTEM_USAGE_COUNT = 6; // 0x6
-    field public static final int RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP = 7; // 0x7
-    field public static final int RANKING_STRATEGY_USAGE_COUNT = 4; // 0x4
-    field public static final int RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP = 5; // 0x5
-    field public static final int TERM_MATCH_EXACT_ONLY = 1; // 0x1
-    field public static final int TERM_MATCH_PREFIX = 2; // 0x2
-  }
-
-  public static final class SearchSpec.Builder {
-    ctor public SearchSpec.Builder();
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterNamespaces(@NonNull java.lang.String...);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterNamespaces(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterPackageNames(@NonNull java.lang.String...);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterPackageNames(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterSchemas(@NonNull java.lang.String...);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addFilterSchemas(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SearchSpec build();
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setMaxSnippetSize(@IntRange(from=0, to=0x2710) int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setOrder(int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setRankingStrategy(int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setResultCountPerPage(@IntRange(from=0, to=0x2710) int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setResultGrouping(int, int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setSnippetCount(@IntRange(from=0, to=0x2710) int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setSnippetCountPerProperty(@IntRange(from=0, to=0x2710) int);
-    method @NonNull public android.app.appsearch.SearchSpec.Builder setTermMatch(int);
-  }
-
-  public final class SetSchemaRequest {
-    method @NonNull public java.util.Map<java.lang.String,android.app.appsearch.Migrator> getMigrators();
-    method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
-    method @NonNull public java.util.Set<java.lang.String> getSchemasNotDisplayedBySystem();
-    method @NonNull public java.util.Map<java.lang.String,java.util.Set<android.app.appsearch.PackageIdentifier>> getSchemasVisibleToPackages();
-    method @IntRange(from=1) public int getVersion();
-    method public boolean isForceOverride();
-  }
-
-  public static final class SetSchemaRequest.Builder {
-    ctor public SetSchemaRequest.Builder();
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchemas(@NonNull android.app.appsearch.AppSearchSchema...);
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchemas(@NonNull java.util.Collection<android.app.appsearch.AppSearchSchema>);
-    method @NonNull public android.app.appsearch.SetSchemaRequest build();
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setForceOverride(boolean);
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setMigrator(@NonNull String, @NonNull android.app.appsearch.Migrator);
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setMigrators(@NonNull java.util.Map<java.lang.String,android.app.appsearch.Migrator>);
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeDisplayedBySystem(@NonNull String, boolean);
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setSchemaTypeVisibilityForPackage(@NonNull String, boolean, @NonNull android.app.appsearch.PackageIdentifier);
-    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setVersion(@IntRange(from=1) int);
-  }
-
-  public class SetSchemaResponse {
-    method @NonNull public java.util.Set<java.lang.String> getDeletedTypes();
-    method @NonNull public java.util.Set<java.lang.String> getIncompatibleTypes();
-    method @NonNull public java.util.Set<java.lang.String> getMigratedTypes();
-    method @NonNull public java.util.List<android.app.appsearch.SetSchemaResponse.MigrationFailure> getMigrationFailures();
-  }
-
-  public static final class SetSchemaResponse.Builder {
-    ctor public SetSchemaResponse.Builder();
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addDeletedType(@NonNull String);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addDeletedTypes(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addIncompatibleType(@NonNull String);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addIncompatibleTypes(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigratedType(@NonNull String);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigratedTypes(@NonNull java.util.Collection<java.lang.String>);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigrationFailure(@NonNull android.app.appsearch.SetSchemaResponse.MigrationFailure);
-    method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigrationFailures(@NonNull java.util.Collection<android.app.appsearch.SetSchemaResponse.MigrationFailure>);
-    method @NonNull public android.app.appsearch.SetSchemaResponse build();
-  }
-
-  public static class SetSchemaResponse.MigrationFailure {
-    ctor public SetSchemaResponse.MigrationFailure(@NonNull String, @NonNull String, @NonNull String, @NonNull android.app.appsearch.AppSearchResult<?>);
-    method @NonNull public android.app.appsearch.AppSearchResult<java.lang.Void> getAppSearchResult();
-    method @NonNull public String getDocumentId();
-    method @NonNull public String getNamespace();
-    method @NonNull public String getSchemaType();
-  }
-
-  public class StorageInfo {
-    method public int getAliveDocumentsCount();
-    method public int getAliveNamespacesCount();
-    method public long getSizeBytes();
-  }
-
-  public static final class StorageInfo.Builder {
-    ctor public StorageInfo.Builder();
-    method @NonNull public android.app.appsearch.StorageInfo build();
-    method @NonNull public android.app.appsearch.StorageInfo.Builder setAliveDocumentsCount(int);
-    method @NonNull public android.app.appsearch.StorageInfo.Builder setAliveNamespacesCount(int);
-    method @NonNull public android.app.appsearch.StorageInfo.Builder setSizeBytes(long);
-  }
-
-}
-
-package android.app.appsearch.exceptions {
-
-  public class AppSearchException extends java.lang.Exception {
-    ctor public AppSearchException(int);
-    ctor public AppSearchException(int, @Nullable String);
-    ctor public AppSearchException(int, @Nullable String, @Nullable Throwable);
-    method public int getResultCode();
-    method @NonNull public <T> android.app.appsearch.AppSearchResult<T> toAppSearchResult();
-  }
-
-}
-
diff --git a/apex/appsearch/framework/api/module-lib-current.txt b/apex/appsearch/framework/api/module-lib-current.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/appsearch/framework/api/module-lib-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/appsearch/framework/api/module-lib-removed.txt b/apex/appsearch/framework/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/appsearch/framework/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/appsearch/framework/api/removed.txt b/apex/appsearch/framework/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/appsearch/framework/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/appsearch/framework/api/system-current.txt b/apex/appsearch/framework/api/system-current.txt
deleted file mode 100644
index 4a6194e..0000000
--- a/apex/appsearch/framework/api/system-current.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-// Signature format: 2.0
-package android.app.appsearch {
-
-  public class AppSearchManagerFrameworkInitializer {
-    method public static void initialize();
-  }
-
-}
-
diff --git a/apex/appsearch/framework/api/system-removed.txt b/apex/appsearch/framework/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/appsearch/framework/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/appsearch/framework/jarjar-rules.txt b/apex/appsearch/framework/jarjar-rules.txt
deleted file mode 100644
index 50c3ee4..0000000
--- a/apex/appsearch/framework/jarjar-rules.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Rename all com.android.internal.util classes to prevent class name collisions
-# between this module and the other versions of the utility classes linked into
-# the framework.
-
-# These must be kept in sync with the sources of framework-utils-appsearch
-rule com.android.internal.util.Preconditions* android.app.appsearch.internal.util.Preconditions@1
diff --git a/apex/appsearch/framework/java/TEST_MAPPING b/apex/appsearch/framework/java/TEST_MAPPING
deleted file mode 100644
index 12188f8..0000000
--- a/apex/appsearch/framework/java/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "imports": [
-    {
-      "path": "frameworks/base/apex/appsearch/service/java/com/android/server/appsearch"
-    }
-  ]
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
deleted file mode 100644
index fb1cccf..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 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 android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.SystemService;
-import android.annotation.UserHandleAware;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.content.Context;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-/**
- * Provides access to the centralized AppSearch index maintained by the system.
- *
- * <p>AppSearch is an offline, on-device search library for managing structured data featuring:
- *
- * <ul>
- *   <li>APIs to index and retrieve data via full-text search.
- *   <li>An API for applications to explicitly grant read-access permission of their data to other
- *   applications.
- *   <b>See: {@link SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage}</b>
- *   <li>An API for applications to opt into or out of having their data displayed on System UI
- *   surfaces by the System-designated global querier.
- *   <b>See: {@link SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem}</b>
- * </ul>
- *
- * <p>Applications create a database by opening an {@link AppSearchSession}.
- *
- * <p>Example:
- *
- * <pre>
- * AppSearchManager appSearchManager = context.getSystemService(AppSearchManager.class);
- *
- * AppSearchManager.SearchContext searchContext = new AppSearchManager.SearchContext.Builder().
- *    setDatabaseName(dbName).build());
- * appSearchManager.createSearchSession(searchContext, mExecutor, appSearchSessionResult -&gt; {
- *      mAppSearchSession = appSearchSessionResult.getResultValue();
- * });</pre>
- *
- * <p>After opening the session, a schema must be set in order to define the organizational
- * structure of data. The schema is set by calling {@link AppSearchSession#setSchema}. The schema is
- * composed of a collection of {@link AppSearchSchema} objects, each of which defines a unique type
- * of data.
- *
- * <p>Example:
- *
- * <pre>
- * AppSearchSchema emailSchemaType = new AppSearchSchema.Builder("Email")
- *     .addProperty(new StringPropertyConfig.Builder("subject")
- *        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
- *        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
- *        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
- *    .build()
- * ).build();
- *
- * SetSchemaRequest request = new SetSchemaRequest.Builder().addSchema(emailSchemaType).build();
- * mAppSearchSession.set(request, mExecutor, appSearchResult -&gt; {
- *      if (appSearchResult.isSuccess()) {
- *           //Schema has been successfully set.
- *      }
- * });</pre>
- *
- * <p>The basic unit of data in AppSearch is represented as a {@link GenericDocument} object,
- * containing an ID, namespace, time-to-live, score, and properties. A namespace organizes a logical
- * group of documents. For example, a namespace can be created to group documents on a per-account
- * basis. An ID identifies a single document within a namespace. The combination of namespace and ID
- * uniquely identifies a {@link GenericDocument} in the database.
- *
- * <p>Once the schema has been set, {@link GenericDocument} objects can be put into the database and
- * indexed by calling {@link AppSearchSession#put}.
- *
- * <p>Example:
- *
- * <pre>
- * // Although for this example we use GenericDocument directly, we recommend extending
- * // GenericDocument to create specific types (i.e. Email) with specific setters/getters.
- * GenericDocument email = new GenericDocument.Builder<>(NAMESPACE, ID, EMAIL_SCHEMA_TYPE)
- *     .setPropertyString(“subject”, EMAIL_SUBJECT)
- *     .setScore(EMAIL_SCORE)
- *     .build();
- *
- * PutDocumentsRequest request = new PutDocumentsRequest.Builder().addGenericDocuments(email)
- *     .build();
- * mAppSearchSession.put(request, mExecutor, appSearchBatchResult -&gt; {
- *      if (appSearchBatchResult.isSuccess()) {
- *           //All documents have been successfully indexed.
- *      }
- * });</pre>
- *
- * <p>Searching within the database is done by calling {@link AppSearchSession#search} and providing
- * the query string to search for, as well as a {@link SearchSpec}.
- *
- * <p>Alternatively, {@link AppSearchSession#getByDocumentId} can be called to retrieve documents by
- * namespace and ID.
- *
- * <p>Document removal is done either by time-to-live expiration, or explicitly calling a remove
- * operation. Remove operations can be done by namespace and ID via {@link
- * AppSearchSession#remove(RemoveByDocumentIdRequest, Executor, BatchResultCallback)}, or by query
- * via {@link AppSearchSession#remove(String, SearchSpec, Executor, Consumer)}.
- */
-@SystemService(Context.APP_SEARCH_SERVICE)
-public class AppSearchManager {
-
-    private final IAppSearchManager mService;
-    private final Context mContext;
-
-    /** @hide */
-    public AppSearchManager(@NonNull Context context, @NonNull IAppSearchManager service) {
-        mContext = Objects.requireNonNull(context);
-        mService = Objects.requireNonNull(service);
-    }
-
-    /** Contains information about how to create the search session. */
-    public static final class SearchContext {
-        final String mDatabaseName;
-
-        SearchContext(@NonNull String databaseName) {
-            mDatabaseName = Objects.requireNonNull(databaseName);
-        }
-
-        /**
-         * Returns the name of the database to create or open.
-         *
-         * <p>Databases with different names are fully separate with distinct types, namespaces, and
-         * data.
-         */
-        @NonNull
-        public String getDatabaseName() {
-            return mDatabaseName;
-        }
-
-        /** Builder for {@link SearchContext} objects. */
-        public static final class Builder {
-            private final String mDatabaseName;
-            private boolean mBuilt = false;
-
-            /**
-             * Creates a new {@link SearchContext.Builder}.
-             *
-             * <p>{@link AppSearchSession} will create or open a database under the given name.
-             *
-             * <p>Databases with different names are fully separate with distinct types, namespaces,
-             * and data.
-             *
-             * <p>Database name cannot contain {@code '/'}.
-             *
-             * @param databaseName The name of the database.
-             * @throws IllegalArgumentException if the databaseName contains {@code '/'}.
-             */
-            public Builder(@NonNull String databaseName) {
-                Objects.requireNonNull(databaseName);
-                Preconditions.checkArgument(
-                        !databaseName.contains("/"), "Database name cannot contain '/'");
-                mDatabaseName = databaseName;
-            }
-
-            /** Builds a {@link SearchContext} instance. */
-            @NonNull
-            public SearchContext build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                mBuilt = true;
-                return new SearchContext(mDatabaseName);
-            }
-        }
-    }
-
-    /**
-     * Creates a new {@link AppSearchSession}.
-     *
-     * <p>This process requires an AppSearch native indexing file system. If it's not created, the
-     * initialization process will create one under the user's credential encrypted directory.
-     *
-     * @param searchContext The {@link SearchContext} contains all information to create a new
-     *     {@link AppSearchSession}
-     * @param executor Executor on which to invoke the callback.
-     * @param callback The {@link AppSearchResult}&lt;{@link AppSearchSession}&gt; of performing
-     *     this operation. Or a {@link AppSearchResult} with failure reason code and error
-     *     information.
-     */
-    @UserHandleAware
-    public void createSearchSession(
-            @NonNull SearchContext searchContext,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
-        Objects.requireNonNull(searchContext);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        AppSearchSession.createSearchSession(
-                searchContext,
-                mService,
-                mContext.getUser(),
-                getPackageName(),
-                executor,
-                callback);
-    }
-
-    /**
-     * Creates a new {@link GlobalSearchSession}.
-     *
-     * <p>This process requires an AppSearch native indexing file system. If it's not created, the
-     * initialization process will create one under the user's credential encrypted directory.
-     *
-     * @param executor Executor on which to invoke the callback.
-     * @param callback The {@link AppSearchResult}&lt;{@link GlobalSearchSession}&gt; of performing
-     *     this operation. Or a {@link AppSearchResult} with failure reason code and error
-     *     information.
-     */
-    @UserHandleAware
-    public void createGlobalSearchSession(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        GlobalSearchSession.createGlobalSearchSession(
-                mService, mContext.getUser(), getPackageName(), executor, callback);
-    }
-
-    /** Returns the package name that should be used for uid verification. */
-    @NonNull
-    private String getPackageName() {
-        return mContext.getOpPackageName();
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
deleted file mode 100644
index 7dc527a..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2019 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 android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.content.Context;
-
-/**
- * Class holding initialization code for the AppSearch module.
- *
- * @hide
- */
-@SystemApi
-public class AppSearchManagerFrameworkInitializer {
-    private AppSearchManagerFrameworkInitializer() {}
-
-    /**
-     * Called by {@link SystemServiceRegistry}'s static initializer and registers all AppSearch
-     * services to {@link Context}, so that {@link Context#getSystemService} can return them.
-     *
-     * @throws IllegalStateException if this is called from anywhere besides
-     *     {@link SystemServiceRegistry}
-     */
-    public static void initialize() {
-        SystemServiceRegistry.registerContextAwareService(
-                Context.APP_SEARCH_SERVICE, AppSearchManager.class,
-                (context, service) ->
-                        new AppSearchManager(context, IAppSearchManager.Stub.asInterface(service)));
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java
deleted file mode 100644
index c738504..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchMigrationHelper.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import static android.app.appsearch.AppSearchResult.RESULT_INVALID_SCHEMA;
-import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
-import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
-
-import android.annotation.NonNull;
-import android.annotation.WorkerThread;
-import android.app.appsearch.aidl.AppSearchResultParcel;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.app.appsearch.aidl.IAppSearchResultCallback;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.ArraySet;
-
-import java.io.Closeable;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-/**
- * The helper class for {@link AppSearchSchema} migration.
- *
- * <p>It will query and migrate {@link GenericDocument} in given type to a new version.
- * @hide
- */
-public class AppSearchMigrationHelper implements Closeable {
-    private final IAppSearchManager mService;
-    private final String mPackageName;
-    private final String mDatabaseName;
-    private final UserHandle mUserHandle;
-    private final File mMigratedFile;
-    private final Set<String> mDestinationTypes;
-    private boolean mAreDocumentsMigrated = false;
-
-    AppSearchMigrationHelper(@NonNull IAppSearchManager service,
-            @NonNull UserHandle userHandle,
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Set<AppSearchSchema> newSchemas) throws IOException {
-        mService = Objects.requireNonNull(service);
-        mUserHandle = Objects.requireNonNull(userHandle);
-        mPackageName = Objects.requireNonNull(packageName);
-        mDatabaseName = Objects.requireNonNull(databaseName);
-        mMigratedFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null);
-        mDestinationTypes = new ArraySet<>(newSchemas.size());
-        for (AppSearchSchema newSchema : newSchemas) {
-            mDestinationTypes.add(newSchema.getSchemaType());
-        }
-    }
-
-    /**
-     * Queries all documents that need to be migrated to a different version and transform
-     * documents to that version by passing them to the provided {@link Migrator}.
-     *
-     * <p>The method will be executed on the executor provided to
-     * {@link AppSearchSession#setSchema}.
-     *
-     * @param schemaType The schema type that needs to be updated and whose {@link GenericDocument}
-     *                   need to be migrated.
-     * @param migrator The {@link Migrator} that will upgrade or downgrade a {@link
-     *     GenericDocument} to new version.
-     */
-    @WorkerThread
-    public void queryAndTransform(@NonNull String schemaType, @NonNull Migrator migrator,
-            int currentVersion, int finalVersion)
-            throws IOException, AppSearchException, InterruptedException, ExecutionException {
-        File queryFile = File.createTempFile(/*prefix=*/"appsearch", /*suffix=*/null);
-        try (ParcelFileDescriptor fileDescriptor =
-                     ParcelFileDescriptor.open(queryFile, MODE_WRITE_ONLY)) {
-            CompletableFuture<AppSearchResult<Void>> future = new CompletableFuture<>();
-            mService.writeQueryResultsToFile(mPackageName, mDatabaseName,
-                    fileDescriptor,
-                    /*queryExpression=*/ "",
-                    new SearchSpec.Builder()
-                            .addFilterSchemas(schemaType)
-                            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                            .build().getBundle(),
-                    mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            future.complete(resultParcel.getResult());
-                        }
-                    });
-            AppSearchResult<Void> result = future.get();
-            if (!result.isSuccess()) {
-                throw new AppSearchException(result.getResultCode(), result.getErrorMessage());
-            }
-            readAndTransform(queryFile, migrator, currentVersion, finalVersion);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            queryFile.delete();
-        }
-    }
-
-    /**
-     * Puts all {@link GenericDocument} migrated from the previous call to
-     * {@link #queryAndTransform} into AppSearch.
-     *
-     * <p> This method should be only called once.
-     *
-     * @param responseBuilder a SetSchemaResponse builder whose result will be returned by this
-     *                        function with any
-     *                        {@link android.app.appsearch.SetSchemaResponse.MigrationFailure}
-     *                        added in.
-     * @return the {@link SetSchemaResponse} for {@link AppSearchSession#setSchema} call.
-     */
-    @NonNull
-    AppSearchResult<SetSchemaResponse> putMigratedDocuments(
-            @NonNull SetSchemaResponse.Builder responseBuilder) {
-        if (!mAreDocumentsMigrated) {
-            return AppSearchResult.newSuccessfulResult(responseBuilder.build());
-        }
-        try (ParcelFileDescriptor fileDescriptor =
-                     ParcelFileDescriptor.open(mMigratedFile, MODE_READ_ONLY)) {
-            CompletableFuture<AppSearchResult<List<Bundle>>> future = new CompletableFuture<>();
-            mService.putDocumentsFromFile(mPackageName, mDatabaseName, fileDescriptor, mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            future.complete(resultParcel.getResult());
-                        }
-                    });
-            AppSearchResult<List<Bundle>> result = future.get();
-            if (!result.isSuccess()) {
-                return AppSearchResult.newFailedResult(result);
-            }
-            List<Bundle> migratedFailureBundles = result.getResultValue();
-            for (int i = 0; i < migratedFailureBundles.size(); i++) {
-                responseBuilder.addMigrationFailure(
-                        new SetSchemaResponse.MigrationFailure(migratedFailureBundles.get(i)));
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } catch (Throwable t) {
-            return AppSearchResult.throwableToFailedResult(t);
-        } finally {
-            mMigratedFile.delete();
-        }
-        return AppSearchResult.newSuccessfulResult(responseBuilder.build());
-    }
-
-    /**
-     * Reads all saved {@link GenericDocument}s from the given {@link File}.
-     *
-     * <p>Transforms those {@link GenericDocument}s to the final version.
-     *
-     * <p>Save migrated {@link GenericDocument}s to the {@link #mMigratedFile}.
-     */
-    private void readAndTransform(@NonNull File file, @NonNull Migrator migrator,
-            int currentVersion, int finalVersion)
-            throws IOException, AppSearchException {
-        try (DataInputStream inputStream = new DataInputStream(new FileInputStream(file));
-             DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(
-                     mMigratedFile, /*append=*/ true))) {
-            GenericDocument document;
-            while (true) {
-                try {
-                    document = readDocumentFromInputStream(inputStream);
-                } catch (EOFException e) {
-                    break;
-                    // Nothing wrong. We just finished reading.
-                }
-
-                GenericDocument newDocument;
-                if (currentVersion < finalVersion) {
-                    newDocument = migrator.onUpgrade(currentVersion, finalVersion, document);
-                } else {
-                    // currentVersion == finalVersion case won't trigger migration and get here.
-                    newDocument = migrator.onDowngrade(currentVersion, finalVersion, document);
-                }
-
-                if (!mDestinationTypes.contains(newDocument.getSchemaType())) {
-                    // we exit before the new schema has been set to AppSearch. So no
-                    // observable changes will be applied to stored schemas and documents.
-                    // And the temp file will be deleted at close(), which will be triggered at
-                    // the end of try-with-resources block of SearchSessionImpl.
-                    throw new AppSearchException(
-                            RESULT_INVALID_SCHEMA,
-                            "Receive a migrated document with schema type: "
-                                    + newDocument.getSchemaType()
-                                    + ". But the schema types doesn't exist in the request");
-                }
-                writeBundleToOutputStream(outputStream, newDocument.getBundle());
-            }
-            mAreDocumentsMigrated = true;
-        }
-    }
-
-    /**
-     * Reads the {@link Bundle} of a {@link GenericDocument} from given {@link DataInputStream}.
-     *
-     * @param inputStream The inputStream to read from
-     *
-     * @throws IOException        on read failure.
-     * @throws EOFException       if {@link java.io.InputStream} reaches the end.
-     */
-    @NonNull
-    public static GenericDocument readDocumentFromInputStream(
-            @NonNull DataInputStream inputStream) throws IOException {
-        int length = inputStream.readInt();
-        if (length == 0) {
-            throw new EOFException();
-        }
-        byte[] serializedMessage = new byte[length];
-        inputStream.read(serializedMessage);
-
-        Parcel parcel = Parcel.obtain();
-        try {
-            parcel.unmarshall(serializedMessage, 0, serializedMessage.length);
-            parcel.setDataPosition(0);
-            Bundle bundle = parcel.readBundle();
-            return new GenericDocument(bundle);
-        } finally {
-            parcel.recycle();
-        }
-    }
-
-    /**
-     * Serializes a {@link Bundle} and writes into the given {@link DataOutputStream}.
-     */
-    public static void writeBundleToOutputStream(
-            @NonNull DataOutputStream outputStream, @NonNull Bundle bundle)
-            throws IOException {
-        Parcel parcel = Parcel.obtain();
-        try {
-            parcel.writeBundle(bundle);
-            byte[] serializedMessage = parcel.marshall();
-            outputStream.writeInt(serializedMessage.length);
-            outputStream.write(serializedMessage);
-        } finally {
-            parcel.recycle();
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        mMigratedFile.delete();
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
deleted file mode 100644
index 82b6d62..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ /dev/null
@@ -1,885 +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 android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.app.appsearch.aidl.AppSearchBatchResultParcel;
-import android.app.appsearch.aidl.AppSearchResultParcel;
-import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.app.appsearch.aidl.IAppSearchResultCallback;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.app.appsearch.util.SchemaMigrationUtil;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.io.Closeable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-/**
- * Provides a connection to a single AppSearch database.
- *
- * <p>An {@link AppSearchSession} instance provides access to database operations such as
- * setting a schema, adding documents, and searching.
- *
- * <p>This class is thread safe.
- *
- * @see GlobalSearchSession
- */
-public final class AppSearchSession implements Closeable {
-    private static final String TAG = "AppSearchSession";
-
-    private final String mPackageName;
-    private final String mDatabaseName;
-    private final UserHandle mUserHandle;
-    private final IAppSearchManager mService;
-
-    private boolean mIsMutated = false;
-    private boolean mIsClosed = false;
-
-    /**
-     * Creates a search session for the client, defined by the {@code userHandle} and
-     * {@code packageName}.
-     */
-    static void createSearchSession(
-            @NonNull AppSearchManager.SearchContext searchContext,
-            @NonNull IAppSearchManager service,
-            @NonNull UserHandle userHandle,
-            @NonNull String packageName,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
-        AppSearchSession searchSession =
-                new AppSearchSession(service, userHandle, packageName, searchContext.mDatabaseName);
-        searchSession.initialize(executor, callback);
-    }
-
-    // NOTE: No instance of this class should be created or returned except via initialize().
-    // Once the callback.accept has been called here, the class is ready to use.
-    private void initialize(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
-        try {
-            mService.initialize(
-                    mPackageName,
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchResult<Void> result = resultParcel.getResult();
-                                if (result.isSuccess()) {
-                                    callback.accept(
-                                            AppSearchResult.newSuccessfulResult(
-                                                    AppSearchSession.this));
-                                } else {
-                                    callback.accept(AppSearchResult.newFailedResult(result));
-                                }
-                    });
-                }
-            });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    private AppSearchSession(@NonNull IAppSearchManager service, @NonNull UserHandle userHandle,
-            @NonNull String packageName, @NonNull String databaseName) {
-        mService = service;
-        mUserHandle = userHandle;
-        mPackageName = packageName;
-        mDatabaseName = databaseName;
-    }
-
-    /**
-     * Sets the schema that represents the organizational structure of data within the AppSearch
-     * database.
-     *
-     * <p>Upon creating an {@link AppSearchSession}, {@link #setSchema} should be called. If the
-     * schema needs to be updated, or it has not been previously set, then the provided schema will
-     * be saved and persisted to disk. Otherwise, {@link #setSchema} is handled efficiently as a
-     * no-op call.
-     *
-     * @param request the schema to set or update the AppSearch database to.
-     * @param workExecutor Executor on which to schedule heavy client-side background work such as
-     *                     transforming documents.
-     * @param callbackExecutor Executor on which to invoke the callback.
-     * @param callback Callback to receive errors resulting from setting the schema. If the
-     *                 operation succeeds, the callback will be invoked with {@code null}.
-     */
-    public void setSchema(
-            @NonNull SetSchemaRequest request,
-            @NonNull Executor workExecutor,
-            @NonNull @CallbackExecutor Executor callbackExecutor,
-            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
-        Objects.requireNonNull(request);
-        Objects.requireNonNull(workExecutor);
-        Objects.requireNonNull(callbackExecutor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size());
-        for (AppSearchSchema schema : request.getSchemas()) {
-            schemaBundles.add(schema.getBundle());
-        }
-        Map<String, List<Bundle>> schemasVisibleToPackagesBundles =
-                new ArrayMap<>(request.getSchemasVisibleToPackagesInternal().size());
-        for (Map.Entry<String, Set<PackageIdentifier>> entry :
-                request.getSchemasVisibleToPackagesInternal().entrySet()) {
-            List<Bundle> packageIdentifierBundles = new ArrayList<>(entry.getValue().size());
-            for (PackageIdentifier packageIdentifier : entry.getValue()) {
-                packageIdentifierBundles.add(packageIdentifier.getBundle());
-            }
-            schemasVisibleToPackagesBundles.put(entry.getKey(), packageIdentifierBundles);
-        }
-
-        // No need to trigger migration if user never set migrator
-        if (request.getMigrators().isEmpty()) {
-            setSchemaNoMigrations(
-                    request,
-                    schemaBundles,
-                    schemasVisibleToPackagesBundles,
-                    callbackExecutor,
-                    callback);
-        } else {
-            setSchemaWithMigrations(
-                    request,
-                    schemaBundles,
-                    schemasVisibleToPackagesBundles,
-                    workExecutor,
-                    callbackExecutor,
-                    callback);
-        }
-        mIsMutated = true;
-    }
-
-    /**
-     * Retrieves the schema most recently successfully provided to {@link #setSchema}.
-     *
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive the pending results of schema.
-     */
-    public void getSchema(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<GetSchemaResponse>> callback) {
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.getSchema(
-                    mPackageName,
-                    mDatabaseName,
-                    mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchResult<Bundle> result = resultParcel.getResult();
-                                if (result.isSuccess()) {
-                                    GetSchemaResponse response =
-                                            new GetSchemaResponse(result.getResultValue());
-                                    callback.accept(AppSearchResult.newSuccessfulResult(response));
-                                } else {
-                                    callback.accept(AppSearchResult.newFailedResult(result));
-                                }
-                            });
-                        }
-                    });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Retrieves the set of all namespaces in the current database with at least one document.
-     *
-     * @param executor        Executor on which to invoke the callback.
-     * @param callback        Callback to receive the namespaces.
-     */
-    public void getNamespaces(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<Set<String>>> callback) {
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.getNamespaces(
-                    mPackageName,
-                    mDatabaseName,
-                    mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchResult<List<String>> result = resultParcel.getResult();
-                                if (result.isSuccess()) {
-                                    Set<String> namespaces =
-                                            new ArraySet<>(result.getResultValue());
-                                    callback.accept(
-                                            AppSearchResult.newSuccessfulResult(namespaces));
-                                } else {
-                                    callback.accept(AppSearchResult.newFailedResult(result));
-                                }
-                            });
-                        }
-                    });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Indexes documents into the {@link AppSearchSession} database.
-     *
-     * <p>Each {@link GenericDocument} object must have a {@code schemaType} field set to an {@link
-     * AppSearchSchema} type that has been previously registered by calling the {@link #setSchema}
-     * method.
-     *
-     * @param request containing documents to be indexed.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive pending result of performing this operation. The keys
-     *                 of the returned {@link AppSearchBatchResult} are the IDs of the input
-     *                 documents. The values are {@code null} if they were successfully indexed,
-     *                 or a failed {@link AppSearchResult} otherwise. If an unexpected internal
-     *                 error occurs in the AppSearch service,
-     *                 {@link BatchResultCallback#onSystemError} will be invoked with a
-     *                 {@link Throwable}.
-     */
-    public void put(
-            @NonNull PutDocumentsRequest request,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull BatchResultCallback<String, Void> callback) {
-        Objects.requireNonNull(request);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        List<GenericDocument> documents = request.getGenericDocuments();
-        List<Bundle> documentBundles = new ArrayList<>(documents.size());
-        for (int i = 0; i < documents.size(); i++) {
-            documentBundles.add(documents.get(i).getBundle());
-        }
-        try {
-            mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchBatchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchBatchResultParcel resultParcel) {
-                            executor.execute(() -> callback.onResult(resultParcel.getResult()));
-                        }
-
-                        @Override
-                        public void onSystemError(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> sendSystemErrorToCallback(
-                                    resultParcel.getResult(), callback));
-                        }
-                    });
-            mIsMutated = true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Gets {@link GenericDocument} objects by document IDs in a namespace from the {@link
-     * AppSearchSession} database.
-     *
-     * @param request a request containing a namespace and IDs to get documents for.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive the pending result of performing this operation. The keys
-     *                 of the returned {@link AppSearchBatchResult} are the input IDs. The values
-     *                 are the returned {@link GenericDocument}s on success, or a failed
-     *                 {@link AppSearchResult} otherwise. IDs that are not found will return a
-     *                 failed {@link AppSearchResult} with a result code of
-     *                 {@link AppSearchResult#RESULT_NOT_FOUND}. If an unexpected internal error
-     *                 occurs in the AppSearch service, {@link BatchResultCallback#onSystemError}
-     *                 will be invoked with a {@link Throwable}.
-     */
-    public void getByDocumentId(
-            @NonNull GetByDocumentIdRequest request,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull BatchResultCallback<String, GenericDocument> callback) {
-        Objects.requireNonNull(request);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.getDocuments(
-                    mPackageName,
-                    mDatabaseName,
-                    request.getNamespace(),
-                    new ArrayList<>(request.getIds()),
-                    request.getProjectionsInternal(),
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchBatchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchBatchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchBatchResult<String, Bundle> result =
-                                        resultParcel.getResult();
-                                AppSearchBatchResult.Builder<String, GenericDocument>
-                                        documentResultBuilder =
-                                        new AppSearchBatchResult.Builder<>();
-
-                                // Translate successful results
-                                for (Map.Entry<String, Bundle> bundleEntry :
-                                        result.getSuccesses().entrySet()) {
-                                    GenericDocument document;
-                                    try {
-                                        document = new GenericDocument(bundleEntry.getValue());
-                                    } catch (Throwable t) {
-                                        // These documents went through validation, so how could
-                                        // this fail? We must have done something wrong.
-                                        documentResultBuilder.setFailure(
-                                                bundleEntry.getKey(),
-                                                AppSearchResult.RESULT_INTERNAL_ERROR,
-                                                t.getMessage());
-                                        continue;
-                                    }
-                                    documentResultBuilder.setSuccess(
-                                            bundleEntry.getKey(), document);
-                                }
-
-                                // Translate failed results
-                                for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry :
-                                        ((Map<String, AppSearchResult<Bundle>>)
-                                                result.getFailures()).entrySet()) {
-                                    documentResultBuilder.setFailure(
-                                            bundleEntry.getKey(),
-                                            bundleEntry.getValue().getResultCode(),
-                                            bundleEntry.getValue().getErrorMessage());
-                                }
-                                callback.onResult(documentResultBuilder.build());
-                            });
-                        }
-
-                        @Override
-                        public void onSystemError(AppSearchResultParcel result) {
-                            executor.execute(
-                                    () -> sendSystemErrorToCallback(result.getResult(), callback));
-                        }
-                    });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Retrieves documents from the open {@link AppSearchSession} that match a given query
-     * string and type of search provided.
-     *
-     * <p>Query strings can be empty, contain one term with no operators, or contain multiple terms
-     * and operators.
-     *
-     * <p>For query strings that are empty, all documents that match the {@link SearchSpec} will be
-     * returned.
-     *
-     * <p>For query strings with a single term and no operators, documents that match the provided
-     * query string and {@link SearchSpec} will be returned.
-     *
-     * <p>The following operators are supported:
-     *
-     * <ul>
-     *   <li>AND (implicit)
-     *       <p>AND is an operator that matches documents that contain <i>all</i> provided terms.
-     *       <p><b>NOTE:</b> A space between terms is treated as an "AND" operator. Explicitly
-     *       including "AND" in a query string will treat "AND" as a term, returning documents that
-     *       also contain "AND".
-     *       <p>Example: "apple AND banana" matches documents that contain the terms "apple", "and",
-     *       "banana".
-     *       <p>Example: "apple banana" matches documents that contain both "apple" and "banana".
-     *       <p>Example: "apple banana cherry" matches documents that contain "apple", "banana", and
-     *       "cherry".
-     *   <li>OR
-     *       <p>OR is an operator that matches documents that contain <i>any</i> provided term.
-     *       <p>Example: "apple OR banana" matches documents that contain either "apple" or
-     *       "banana".
-     *       <p>Example: "apple OR banana OR cherry" matches documents that contain any of "apple",
-     *       "banana", or "cherry".
-     *   <li>Exclusion (-)
-     *       <p>Exclusion (-) is an operator that matches documents that <i>do not</i> contain the
-     *       provided term.
-     *       <p>Example: "-apple" matches documents that do not contain "apple".
-     *   <li>Grouped Terms
-     *       <p>For queries that require multiple operators and terms, terms can be grouped into
-     *       subqueries. Subqueries are contained within an open "(" and close ")" parenthesis.
-     *       <p>Example: "(donut OR bagel) (coffee OR tea)" matches documents that contain either
-     *       "donut" or "bagel" and either "coffee" or "tea".
-     *   <li>Property Restricts
-     *       <p>For queries that require a term to match a specific {@link AppSearchSchema} property
-     *       of a document, a ":" must be included between the property name and the term.
-     *       <p>Example: "subject:important" matches documents that contain the term "important" in
-     *       the "subject" property.
-     * </ul>
-     *
-     * <p>Additional search specifications, such as filtering by {@link AppSearchSchema} type or
-     * adding projection, can be set by calling the corresponding {@link SearchSpec.Builder} setter.
-     *
-     * <p>This method is lightweight. The heavy work will be done in {@link
-     * SearchResults#getNextPage}.
-     *
-     * @param queryExpression query string to search.
-     * @param searchSpec spec for setting document filters, adding projection, setting term match
-     *     type, etc.
-     * @return a {@link SearchResults} object for retrieved matched documents.
-     */
-    @NonNull
-    public SearchResults search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
-        Objects.requireNonNull(queryExpression);
-        Objects.requireNonNull(searchSpec);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        return new SearchResults(mService, mPackageName, mDatabaseName, queryExpression,
-                searchSpec, mUserHandle);
-    }
-
-    /**
-     * Reports usage of a particular document by namespace and ID.
-     *
-     * <p>A usage report represents an event in which a user interacted with or viewed a document.
-     *
-     * <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
-     * metrics for that particular document. These metrics are used for ordering {@link #search}
-     * results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and {@link
-     * SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
-     *
-     * <p>Reporting usage of a document is optional.
-     *
-     * @param request The usage reporting request.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive errors. If the operation succeeds, the callback will be
-     *                 invoked with {@code null}.
-     */
-    public void reportUsage(
-            @NonNull ReportUsageRequest request,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<Void>> callback) {
-        Objects.requireNonNull(request);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.reportUsage(
-                    mPackageName,
-                    mDatabaseName,
-                    request.getNamespace(),
-                    request.getDocumentId(),
-                    request.getUsageTimestampMillis(),
-                    /*systemUsage=*/ false,
-                    mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> callback.accept(resultParcel.getResult()));
-                        }
-                    });
-            mIsMutated = true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Removes {@link GenericDocument} objects by document IDs in a namespace from the {@link
-     * AppSearchSession} database.
-     *
-     * <p>Removed documents will no longer be surfaced by {@link #search} or {@link
-     * #getByDocumentId} calls.
-     *
-     * <p>Once the database crosses the document count or byte usage threshold, removed documents
-     * will be deleted from disk.
-     *
-     * @param request {@link RemoveByDocumentIdRequest} with IDs in a namespace to remove from the
-     *     index.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive the pending result of performing this operation. The keys
-     *                 of the returned {@link AppSearchBatchResult} are the input document IDs. The
-     *                 values are {@code null} on success, or a failed {@link AppSearchResult}
-     *                 otherwise. IDs that are not found will return a failed
-     *                 {@link AppSearchResult} with a result code of
-     *                 {@link AppSearchResult#RESULT_NOT_FOUND}. If an unexpected internal error
-     *                 occurs in the AppSearch service, {@link BatchResultCallback#onSystemError}
-     *                 will be invoked with a {@link Throwable}.
-     */
-    public void remove(
-            @NonNull RemoveByDocumentIdRequest request,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull BatchResultCallback<String, Void> callback) {
-        Objects.requireNonNull(request);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.removeByDocumentId(
-                    mPackageName,
-                    mDatabaseName,
-                    request.getNamespace(),
-                    new ArrayList<>(request.getIds()),
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchBatchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchBatchResultParcel resultParcel) {
-                            executor.execute(() -> callback.onResult(resultParcel.getResult()));
-                        }
-
-                        @Override
-                        public void onSystemError(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> sendSystemErrorToCallback(
-                                    resultParcel.getResult(), callback));
-                        }
-                    });
-            mIsMutated = true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
-     * match the {@code queryExpression} in given namespaces and schemaTypes which is set via {@link
-     * SearchSpec.Builder#addFilterNamespaces} and {@link SearchSpec.Builder#addFilterSchemas}.
-     *
-     * <p>An empty {@code queryExpression} matches all documents.
-     *
-     * <p>An empty set of namespaces or schemaTypes matches all namespaces or schemaTypes in the
-     * current database.
-     *
-     * @param queryExpression Query String to search.
-     * @param searchSpec Spec containing schemaTypes, namespaces and query expression indicates how
-     *     document will be removed. All specific about how to scoring, ordering, snippeting and
-     *     resulting will be ignored.
-     * @param executor        Executor on which to invoke the callback.
-     * @param callback        Callback to receive errors resulting from removing the documents. If
-     *                        the operation succeeds, the callback will be invoked with
-     *                        {@code null}.
-     */
-    public void remove(
-            @NonNull String queryExpression,
-            @NonNull SearchSpec searchSpec,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<Void>> callback) {
-        Objects.requireNonNull(queryExpression);
-        Objects.requireNonNull(searchSpec);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.removeByQuery(
-                    mPackageName,
-                    mDatabaseName,
-                    queryExpression,
-                    searchSpec.getBundle(),
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> callback.accept(resultParcel.getResult()));
-                        }
-                    });
-            mIsMutated = true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Gets the storage info for this {@link AppSearchSession} database.
-     *
-     * <p>This may take time proportional to the number of documents and may be inefficient to call
-     * repeatedly.
-     *
-     * @param executor        Executor on which to invoke the callback.
-     * @param callback        Callback to receive the storage info.
-     */
-    public void getStorageInfo(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<StorageInfo>> callback) {
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        try {
-            mService.getStorageInfo(
-                    mPackageName,
-                    mDatabaseName,
-                    mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchResult<Bundle> result = resultParcel.getResult();
-                                if (result.isSuccess()) {
-                                    StorageInfo response = new StorageInfo(result.getResultValue());
-                                    callback.accept(AppSearchResult.newSuccessfulResult(response));
-                                } else {
-                                    callback.accept(AppSearchResult.newFailedResult(result));
-                                }
-                            });
-                        }
-                    });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Closes the {@link AppSearchSession} to persist all schema and document updates,
-     * additions, and deletes to disk.
-     */
-    @Override
-    public void close() {
-        if (mIsMutated && !mIsClosed) {
-            try {
-                mService.persistToDisk(
-                        mPackageName,
-                        mUserHandle,
-                        /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
-                mIsClosed = true;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to close the AppSearchSession", e);
-            }
-        }
-    }
-
-    /**
-     * Set schema to Icing for no-migration scenario.
-     *
-     * <p>We only need one time {@link #setSchema} call for no-migration scenario by using the
-     * forceoverride in the request.
-     */
-    private void setSchemaNoMigrations(
-            @NonNull SetSchemaRequest request,
-            @NonNull List<Bundle> schemaBundles,
-            @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
-        try {
-            mService.setSchema(
-                    mPackageName,
-                    mDatabaseName,
-                    schemaBundles,
-                    new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
-                    schemasVisibleToPackagesBundles,
-                    request.isForceOverride(),
-                    request.getVersion(),
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchResult<Bundle> result = resultParcel.getResult();
-                                if (result.isSuccess()) {
-                                    try {
-                                        SetSchemaResponse setSchemaResponse =
-                                                new SetSchemaResponse(result.getResultValue());
-                                        if (!request.isForceOverride()) {
-                                            // Throw exception if there is any deleted types or
-                                            // incompatible types. That's the only case we swallowed
-                                            // in the AppSearchImpl#setSchema().
-                                            SchemaMigrationUtil.checkDeletedAndIncompatible(
-                                                    setSchemaResponse.getDeletedTypes(),
-                                                    setSchemaResponse.getIncompatibleTypes());
-                                        }
-                                        callback.accept(AppSearchResult
-                                                .newSuccessfulResult(setSchemaResponse));
-                                    } catch (Throwable t) {
-                                        callback.accept(AppSearchResult.throwableToFailedResult(t));
-                                    }
-                                } else {
-                                    callback.accept(AppSearchResult.newFailedResult(result));
-                                }
-                            });
-                        }
-                    });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set schema to Icing for migration scenario.
-     *
-     * <p>First time {@link #setSchema} call with forceOverride is false gives us all incompatible
-     * changes. After trigger migrations, the second time call {@link #setSchema} will actually
-     * apply the changes.
-     */
-    private void setSchemaWithMigrations(
-            @NonNull SetSchemaRequest request,
-            @NonNull List<Bundle> schemaBundles,
-            @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
-            @NonNull Executor workExecutor,
-            @NonNull @CallbackExecutor Executor callbackExecutor,
-            @NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
-        workExecutor.execute(() -> {
-            try {
-                // Migration process
-                // 1. Validate and retrieve all active migrators.
-                CompletableFuture<AppSearchResult<GetSchemaResponse>> getSchemaFuture =
-                        new CompletableFuture<>();
-                getSchema(callbackExecutor, getSchemaFuture::complete);
-                AppSearchResult<GetSchemaResponse> getSchemaResult = getSchemaFuture.get();
-                if (!getSchemaResult.isSuccess()) {
-                    callbackExecutor.execute(() ->
-                            callback.accept(AppSearchResult.newFailedResult(getSchemaResult)));
-                    return;
-                }
-                GetSchemaResponse getSchemaResponse = getSchemaResult.getResultValue();
-                int currentVersion = getSchemaResponse.getVersion();
-                int finalVersion = request.getVersion();
-                Map<String, Migrator> activeMigrators = SchemaMigrationUtil.getActiveMigrators(
-                        getSchemaResponse.getSchemas(), request.getMigrators(), currentVersion,
-                        finalVersion);
-
-                // No need to trigger migration if no migrator is active.
-                if (activeMigrators.isEmpty()) {
-                    setSchemaNoMigrations(request, schemaBundles, schemasVisibleToPackagesBundles,
-                            callbackExecutor, callback);
-                    return;
-                }
-
-                // 2. SetSchema with forceOverride=false, to retrieve the list of
-                // incompatible/deleted types.
-                CompletableFuture<AppSearchResult<Bundle>> setSchemaFuture =
-                        new CompletableFuture<>();
-                mService.setSchema(
-                        mPackageName,
-                        mDatabaseName,
-                        schemaBundles,
-                        new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
-                        schemasVisibleToPackagesBundles,
-                        /*forceOverride=*/ false,
-                        request.getVersion(),
-                        mUserHandle,
-                        /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                        new IAppSearchResultCallback.Stub() {
-                            @Override
-                            public void onResult(AppSearchResultParcel resultParcel) {
-                                setSchemaFuture.complete(resultParcel.getResult());
-                            }
-                        });
-                AppSearchResult<Bundle> setSchemaResult = setSchemaFuture.get();
-                if (!setSchemaResult.isSuccess()) {
-                    callbackExecutor.execute(() ->
-                            callback.accept(AppSearchResult.newFailedResult(setSchemaResult)));
-                    return;
-                }
-                SetSchemaResponse setSchemaResponse =
-                        new SetSchemaResponse(setSchemaResult.getResultValue());
-
-                // 3. If forceOverride is false, check that all incompatible types will be migrated.
-                // If some aren't we must throw an error, rather than proceeding and deleting those
-                // types.
-                if (!request.isForceOverride()) {
-                    SchemaMigrationUtil.checkDeletedAndIncompatibleAfterMigration(setSchemaResponse,
-                            activeMigrators.keySet());
-                }
-
-                try (AppSearchMigrationHelper migrationHelper = new AppSearchMigrationHelper(
-                        mService, mUserHandle, mPackageName, mDatabaseName, request.getSchemas())) {
-
-                    // 4. Trigger migration for all migrators.
-                    // TODO(b/177266929) trigger migration for all types together rather than
-                    //  separately.
-                    for (Map.Entry<String, Migrator> entry : activeMigrators.entrySet()) {
-                        migrationHelper.queryAndTransform(/*schemaType=*/ entry.getKey(),
-                                /*migrator=*/ entry.getValue(), currentVersion,
-                                finalVersion);
-                    }
-
-                    // 5. SetSchema a second time with forceOverride=true if the first attempted
-                    // failed.
-                    if (!setSchemaResponse.getIncompatibleTypes().isEmpty()
-                            || !setSchemaResponse.getDeletedTypes().isEmpty()) {
-                        CompletableFuture<AppSearchResult<Bundle>> setSchema2Future =
-                                new CompletableFuture<>();
-                        // only trigger second setSchema() call if the first one is fail.
-                        mService.setSchema(
-                                mPackageName,
-                                mDatabaseName,
-                                schemaBundles,
-                                new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
-                                schemasVisibleToPackagesBundles,
-                                /*forceOverride=*/ true,
-                                request.getVersion(),
-                                mUserHandle,
-                                /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                                new IAppSearchResultCallback.Stub() {
-                                    @Override
-                                    public void onResult(AppSearchResultParcel resultParcel) {
-                                        setSchema2Future.complete(resultParcel.getResult());
-                                    }
-                                });
-                        AppSearchResult<Bundle> setSchema2Result = setSchema2Future.get();
-                        if (!setSchema2Result.isSuccess()) {
-                            // we failed to set the schema in second time with forceOverride = true,
-                            // which is an impossible case. Since we only swallow the incompatible
-                            // error in the first setSchema call, all other errors will be thrown at
-                            // the first time.
-                            callbackExecutor.execute(() -> callback.accept(
-                                    AppSearchResult.newFailedResult(setSchema2Result)));
-                            return;
-                        }
-                    }
-
-                    SetSchemaResponse.Builder responseBuilder = setSchemaResponse.toBuilder()
-                            .addMigratedTypes(activeMigrators.keySet());
-
-                    // 6. Put all the migrated documents into the index, now that the new schema is
-                    // set.
-                    AppSearchResult<SetSchemaResponse> putResult =
-                            migrationHelper.putMigratedDocuments(responseBuilder);
-                    callbackExecutor.execute(() -> callback.accept(putResult));
-                }
-            } catch (Throwable t) {
-                callbackExecutor.execute(() -> callback.accept(
-                        AppSearchResult.throwableToFailedResult(t)));
-            }
-        });
-    }
-
-    /**
-     * Calls {@link BatchResultCallback#onSystemError} with a throwable derived from the given
-     * failed {@link AppSearchResult}.
-     *
-     * <p>The {@link AppSearchResult} generally comes from
-     * {@link IAppSearchBatchResultCallback#onSystemError}.
-     *
-     * <p>This method should be called from the callback executor thread.
-     */
-    private void sendSystemErrorToCallback(
-            @NonNull AppSearchResult<?> failedResult, @NonNull BatchResultCallback<?, ?> callback) {
-        Preconditions.checkArgument(!failedResult.isSuccess());
-        Throwable throwable = new AppSearchException(
-                failedResult.getResultCode(), failedResult.getErrorMessage());
-        callback.onSystemError(throwable);
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java b/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java
deleted file mode 100644
index 28f8a7a..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 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 android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * The callback interface to return {@link AppSearchBatchResult}.
- *
- * @param <KeyType> The type of the keys for {@link AppSearchBatchResult#getSuccesses} and
- * {@link AppSearchBatchResult#getFailures}.
- * @param <ValueType> The type of result objects associated with the keys.
- */
-public interface BatchResultCallback<KeyType, ValueType> {
-
-    /**
-     * Called when {@link AppSearchBatchResult} results are ready.
-     *
-     * @param result The result of the executed request.
-     */
-    void onResult(@NonNull AppSearchBatchResult<KeyType, ValueType> result);
-
-    /**
-     * Called when a system error occurs.
-     *
-     * <p>This method is only called the infrastructure is fundamentally broken or unavailable, such
-     * that none of the requests could be started. For example, it will be called if the AppSearch
-     * service unexpectedly fails to initialize and can't be recovered by any means, or if
-     * communicating to the server over Binder fails (e.g. system service crashed or device is
-     * rebooting).
-     *
-     * <p>The error is not expected to be recoverable and there is no specific recommended action
-     * other than displaying a permanent message to the user.
-     *
-     * <p>Normal errors that are caused by invalid inputs or recoverable/retriable situations
-     * are reported associated with the input that caused them via the {@link #onResult} method.
-     *
-     * @param throwable an exception describing the system error
-     */
-    default void onSystemError(@Nullable Throwable throwable) {
-        throw new RuntimeException("Unrecoverable system error", throwable);
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
deleted file mode 100644
index 130e442..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
+++ /dev/null
@@ -1,200 +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 android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.app.appsearch.aidl.AppSearchResultParcel;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.app.appsearch.aidl.IAppSearchResultCallback;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.io.Closeable;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-/**
- * Provides a connection to all AppSearch databases the querying application has been granted access
- * to.
- *
- * <p>This class is thread safe.
- *
- * @see AppSearchSession
- */
-public class GlobalSearchSession implements Closeable {
-    private static final String TAG = "AppSearchGlobalSearchSe";
-
-    private final String mPackageName;
-    private final UserHandle mUserHandle;
-    private final IAppSearchManager mService;
-
-    private boolean mIsMutated = false;
-    private boolean mIsClosed = false;
-
-    /**
-     * Creates a search session for the client, defined by the {@code userHandle} and
-     * {@code packageName}.
-     */
-    static void createGlobalSearchSession(
-            @NonNull IAppSearchManager service,
-            @NonNull UserHandle userHandle,
-            @NonNull String packageName,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
-        GlobalSearchSession globalSearchSession = new GlobalSearchSession(service, userHandle,
-                packageName);
-        globalSearchSession.initialize(executor, callback);
-    }
-
-    // NOTE: No instance of this class should be created or returned except via initialize().
-    // Once the callback.accept has been called here, the class is ready to use.
-    private void initialize(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
-        try {
-            mService.initialize(
-                    mPackageName,
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> {
-                                AppSearchResult<Void> result = resultParcel.getResult();
-                                if (result.isSuccess()) {
-                                    callback.accept(
-                                            AppSearchResult.newSuccessfulResult(
-                                                    GlobalSearchSession.this));
-                                } else {
-                                    callback.accept(AppSearchResult.newFailedResult(result));
-                                }
-                    });
-                }
-            });
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    private GlobalSearchSession(@NonNull IAppSearchManager service, @NonNull UserHandle userHandle,
-            @NonNull String packageName) {
-        mService = service;
-        mUserHandle = userHandle;
-        mPackageName = packageName;
-    }
-
-    /**
-     * Retrieves documents from all AppSearch databases that the querying application has access to.
-     *
-     * <p>Applications can be granted access to documents by specifying {@link
-     * SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage} when building a schema.
-     *
-     * <p>Document access can also be granted to system UIs by specifying {@link
-     * SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem} when building a schema.
-     *
-     * <p>See {@link AppSearchSession#search} for a detailed explanation on forming a query string.
-     *
-     * <p>This method is lightweight. The heavy work will be done in {@link
-     * SearchResults#getNextPage}.
-     *
-     * @param queryExpression query string to search.
-     * @param searchSpec spec for setting document filters, adding projection, setting term match
-     *     type, etc.
-     * @return a {@link SearchResults} object for retrieved matched documents.
-     */
-    @NonNull
-    public SearchResults search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
-        Objects.requireNonNull(queryExpression);
-        Objects.requireNonNull(searchSpec);
-        Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
-        return new SearchResults(mService, mPackageName, /*databaseName=*/null, queryExpression,
-                searchSpec, mUserHandle);
-    }
-
-    /**
-     * Reports that a particular document has been used from a system surface.
-     *
-     * <p>See {@link AppSearchSession#reportUsage} for a general description of document usage, as
-     * well as an API that can be used by the app itself.
-     *
-     * <p>Usage reported via this method is accounted separately from usage reported via
-     * {@link AppSearchSession#reportUsage} and may be accessed using the constants
-     * {@link SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_COUNT} and
-     * {@link SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP}.
-     *
-     * @param request The usage reporting request.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive errors. If the operation succeeds, the callback will be
-     *                 invoked with an {@link AppSearchResult} whose value is {@code null}. The
-     *                 callback will be invoked with an {@link AppSearchResult} of
-     *                 {@link AppSearchResult#RESULT_SECURITY_ERROR} if this API is invoked by an
-     *                 app which is not part of the system.
-     */
-    public void reportSystemUsage(
-            @NonNull ReportSystemUsageRequest request,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<Void>> callback) {
-        Objects.requireNonNull(request);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
-        try {
-            mService.reportUsage(
-                    request.getPackageName(),
-                    request.getDatabaseName(),
-                    request.getNamespace(),
-                    request.getDocumentId(),
-                    request.getUsageTimestampMillis(),
-                    /*systemUsage=*/ true,
-                    mUserHandle,
-                    new IAppSearchResultCallback.Stub() {
-                        @Override
-                        public void onResult(AppSearchResultParcel resultParcel) {
-                            executor.execute(() -> callback.accept(resultParcel.getResult()));
-                        }
-                    });
-            mIsMutated = true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Closes the {@link GlobalSearchSession}. Persists all mutations, including usage reports, to
-     * disk.
-     */
-    @Override
-    public void close() {
-        if (mIsMutated && !mIsClosed) {
-            try {
-                mService.persistToDisk(
-                        mPackageName,
-                        mUserHandle,
-                        /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime());
-                mIsClosed = true;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to close the GlobalSearchSession", e);
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
deleted file mode 100644
index 6dfa01f..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
+++ /dev/null
@@ -1,175 +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 android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.aidl.AppSearchResultParcel;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.app.appsearch.aidl.IAppSearchResultCallback;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.io.Closeable;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-/**
- * Encapsulates results of a search operation.
- *
- * <p>Each {@link AppSearchSession#search} operation returns a list of {@link SearchResult} objects,
- * referred to as a "page", limited by the size configured by {@link
- * SearchSpec.Builder#setResultCountPerPage}.
- *
- * <p>To fetch a page of results, call {@link #getNextPage}.
- *
- * <p>All instances of {@link SearchResults} must call {@link SearchResults#close()} after the
- * results are fetched.
- *
- * <p>This class is not thread safe.
- */
-public class SearchResults implements Closeable {
-    private static final String TAG = "SearchResults";
-
-    private final IAppSearchManager mService;
-
-    // The package name of the caller.
-    private final String mPackageName;
-
-    // The database name to search over. If null, this will search over all database names.
-    @Nullable
-    private final String mDatabaseName;
-
-    private final String mQueryExpression;
-
-    private final SearchSpec mSearchSpec;
-
-    private final UserHandle mUserHandle;
-
-    private long mNextPageToken;
-
-    private boolean mIsFirstLoad = true;
-
-    private boolean mIsClosed = false;
-
-    SearchResults(
-            @NonNull IAppSearchManager service,
-            @NonNull String packageName,
-            @Nullable String databaseName,
-            @NonNull String queryExpression,
-            @NonNull SearchSpec searchSpec,
-            @NonNull UserHandle userHandle) {
-        mService = Objects.requireNonNull(service);
-        mPackageName = packageName;
-        mDatabaseName = databaseName;
-        mQueryExpression = Objects.requireNonNull(queryExpression);
-        mSearchSpec = Objects.requireNonNull(searchSpec);
-        mUserHandle = Objects.requireNonNull(userHandle);
-    }
-
-    /**
-     * Retrieves the next page of {@link SearchResult} objects.
-     *
-     * <p>The page size is configured by {@link SearchSpec.Builder#setResultCountPerPage}.
-     *
-     * <p>Continue calling this method to access results until it returns an empty list, signifying
-     * there are no more results.
-     *
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive the pending result of performing this operation.
-     */
-    public void getNextPage(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(callback);
-        Preconditions.checkState(!mIsClosed, "SearchResults has already been closed");
-        try {
-            if (mIsFirstLoad) {
-                mIsFirstLoad = false;
-                long binderCallStartTimeMillis = SystemClock.elapsedRealtime();
-                if (mDatabaseName == null) {
-                    // Global query, there's no one package-database combination to check.
-                    mService.globalQuery(mPackageName, mQueryExpression,
-                            mSearchSpec.getBundle(), mUserHandle,
-                            binderCallStartTimeMillis,
-                            wrapCallback(executor, callback));
-                } else {
-                    // Normal local query, pass in specified database.
-                    mService.query(mPackageName, mDatabaseName, mQueryExpression,
-                            mSearchSpec.getBundle(), mUserHandle,
-                            binderCallStartTimeMillis,
-                            wrapCallback(executor, callback));
-                }
-            } else {
-                mService.getNextPage(mPackageName, mNextPageToken, mUserHandle,
-                        wrapCallback(executor, callback));
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    @Override
-    public void close() {
-        if (!mIsClosed) {
-            try {
-                mService.invalidateNextPageToken(mPackageName, mNextPageToken, mUserHandle);
-                mIsClosed = true;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to close the SearchResults", e);
-            }
-        }
-    }
-
-    private IAppSearchResultCallback wrapCallback(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
-        return new IAppSearchResultCallback.Stub() {
-            @Override
-            public void onResult(AppSearchResultParcel resultParcel) {
-                executor.execute(() -> invokeCallback(resultParcel.getResult(), callback));
-            }
-        };
-    }
-
-    private void invokeCallback(
-            @NonNull AppSearchResult<Bundle> searchResultPageResult,
-            @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
-        if (searchResultPageResult.isSuccess()) {
-            try {
-                SearchResultPage searchResultPage =
-                        new SearchResultPage(searchResultPageResult.getResultValue());
-                mNextPageToken = searchResultPage.getNextPageToken();
-                callback.accept(AppSearchResult.newSuccessfulResult(
-                        searchResultPage.getResults()));
-            } catch (Throwable t) {
-                callback.accept(AppSearchResult.throwableToFailedResult(t));
-            }
-        } else {
-            callback.accept(AppSearchResult.newFailedResult(searchResultPageResult));
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchBatchResultParcel.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchBatchResultParcel.aidl
deleted file mode 100644
index 89908cd..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchBatchResultParcel.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.app.appsearch.aidl;
-
-/** {@hide} */
-parcelable AppSearchBatchResultParcel<ValueType>;
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchBatchResultParcel.java b/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchBatchResultParcel.java
deleted file mode 100644
index b0cc10c..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchBatchResultParcel.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.aidl;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchResult;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Parcelable wrapper around {@link AppSearchBatchResult}.
- *
- * <p>{@link AppSearchBatchResult} can contain any type of key and value, including non-parcelable
- * values. For the specific case of sending {@link AppSearchBatchResult} across Binder, this class
- * wraps an {@link AppSearchBatchResult} that has String keys and Parcelable values. It provides
- * parcelability of the whole structure.
- *
- * @param <ValueType> The type of result object for successful calls. Must be a parcelable type.
- * @hide
- */
-public final class AppSearchBatchResultParcel<ValueType> implements Parcelable {
-    private final AppSearchBatchResult<String, ValueType> mResult;
-
-    /** Creates a new {@link AppSearchBatchResultParcel} from the given result. */
-    public AppSearchBatchResultParcel(@NonNull AppSearchBatchResult<String, ValueType> result) {
-        mResult = Objects.requireNonNull(result);
-    }
-
-    private AppSearchBatchResultParcel(@NonNull Parcel in) {
-        Bundle bundle = in.readBundle();
-        AppSearchBatchResult.Builder<String, ValueType> builder =
-                new AppSearchBatchResult.Builder<>();
-        for (String key : bundle.keySet()) {
-            AppSearchResultParcel<ValueType> resultParcel = bundle.getParcelable(key);
-            builder.setResult(key, resultParcel.getResult());
-        }
-        mResult = builder.build();
-    }
-
-    @NonNull
-    public AppSearchBatchResult<String, ValueType> getResult() {
-        return mResult;
-    }
-
-    /** @hide */
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        Bundle bundle = new Bundle();
-        for (Map.Entry<String, AppSearchResult<ValueType>> entry
-                : mResult.getAll().entrySet()) {
-            bundle.putParcelable(entry.getKey(), new AppSearchResultParcel<>(entry.getValue()));
-        }
-        dest.writeBundle(bundle);
-    }
-
-    /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    @NonNull
-    public static final Creator<AppSearchBatchResultParcel<?>> CREATOR =
-            new Creator<AppSearchBatchResultParcel<?>>() {
-                @NonNull
-                @Override
-                public AppSearchBatchResultParcel<?> createFromParcel(@NonNull Parcel in) {
-                    return new AppSearchBatchResultParcel<>(in);
-                }
-
-                @NonNull
-                @Override
-                public AppSearchBatchResultParcel<?>[] newArray(int size) {
-                    return new AppSearchBatchResultParcel<?>[size];
-                }
-            };
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchResultParcel.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchResultParcel.aidl
deleted file mode 100644
index 4e35bd5..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchResultParcel.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.app.appsearch.aidl;
-
-/** {@hide} */
-parcelable AppSearchResultParcel<ValueType>;
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchResultParcel.java b/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchResultParcel.java
deleted file mode 100644
index 8b137d3..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/AppSearchResultParcel.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.aidl;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Parcelable wrapper around {@link AppSearchResult}.
- *
- * <p>{@link AppSearchResult} can contain any value, including non-parcelable values. For the
- * specific case of sending {@link AppSearchResult} across Binder, this class wraps an
- * {@link AppSearchResult} that contains a parcelable type and provides parcelability of the whole
- * structure.
- *
- * @param <ValueType> The type of result object for successful calls. Must be a parcelable type.
- * @hide
- */
-public final class AppSearchResultParcel<ValueType> implements Parcelable {
-    private final AppSearchResult<ValueType> mResult;
-
-    /** Creates a new {@link AppSearchResultParcel} from the given result. */
-    public AppSearchResultParcel(@NonNull AppSearchResult<ValueType> result) {
-        mResult = Objects.requireNonNull(result);
-    }
-
-    private AppSearchResultParcel(@NonNull Parcel in) {
-        int resultCode = in.readInt();
-        ValueType resultValue = (ValueType) in.readValue(/*loader=*/ null);
-        String errorMessage = in.readString();
-        if (resultCode == AppSearchResult.RESULT_OK) {
-            mResult = AppSearchResult.newSuccessfulResult(resultValue);
-        } else {
-            mResult = AppSearchResult.newFailedResult(resultCode, errorMessage);
-        }
-    }
-
-    @NonNull
-    public AppSearchResult<ValueType> getResult() {
-        return mResult;
-    }
-
-    /** @hide */
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mResult.getResultCode());
-        if (mResult.isSuccess()) {
-            dest.writeValue(mResult.getResultValue());
-        } else {
-            dest.writeValue(null);
-        }
-        dest.writeString(mResult.getErrorMessage());
-    }
-
-    /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    @NonNull
-    public static final Creator<AppSearchResultParcel<?>> CREATOR =
-            new Creator<AppSearchResultParcel<?>>() {
-                @NonNull
-                @Override
-                public AppSearchResultParcel<?> createFromParcel(@NonNull Parcel in) {
-                    return new AppSearchResultParcel<>(in);
-                }
-
-                @NonNull
-                @Override
-                public AppSearchResultParcel<?>[] newArray(int size) {
-                    return new AppSearchResultParcel<?>[size];
-                }
-            };
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchBatchResultCallback.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchBatchResultCallback.aidl
deleted file mode 100644
index 1fe19cc..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchBatchResultCallback.aidl
+++ /dev/null
@@ -1,25 +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.aidl;
-
-import android.app.appsearch.aidl.AppSearchBatchResultParcel;
-import android.app.appsearch.aidl.AppSearchResultParcel;
-
-/** {@hide} */
-oneway interface IAppSearchBatchResultCallback {
-    void onResult(in AppSearchBatchResultParcel resultParcel);
-    void onSystemError(in AppSearchResultParcel resultParcel);
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
deleted file mode 100644
index a2f545f..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
+++ /dev/null
@@ -1,371 +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.aidl;
-
-import android.os.Bundle;
-import android.os.UserHandle;
-
-import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
-import android.app.appsearch.aidl.IAppSearchResultCallback;
-import android.os.ParcelFileDescriptor;
-
-/** {@hide} */
-interface IAppSearchManager {
-    /**
-     * Updates the AppSearch schema for this database.
-     *
-     * @param packageName The name of the package that owns this schema.
-     * @param databaseName  The name of the database where this schema lives.
-     * @param schemaBundles List of {@link AppSearchSchema} bundles.
-     * @param schemasNotDisplayedBySystem Schema types that should not be surfaced on platform
-     *     surfaces.
-     * @param schemasVisibleToPackagesBundles Schema types that are visible to the specified
-     *     packages. The value List contains PackageIdentifier Bundles.
-     * @param forceOverride Whether to apply the new schema even if it is incompatible. All
-     *     incompatible documents will be deleted.
-     * @param schemaVersion  The overall schema version number of the request.
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value are
-     *     {@link SetSchemaResponse} bundle.
-     */
-    void setSchema(
-        in String packageName,
-        in String databaseName,
-        in List<Bundle> schemaBundles,
-        in List<String> schemasNotDisplayedBySystem,
-        in Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
-        boolean forceOverride,
-        in int schemaVersion,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Retrieves the AppSearch schema for this database.
-     *
-     * @param packageName The name of the package that owns the schema.
-     * @param databaseName  The name of the database to retrieve.
-     * @param userHandle Handle of the calling user
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Bundle}&gt; where the bundle is a GetSchemaResponse.
-     */
-    void getSchema(
-        in String packageName,
-        in String databaseName,
-        in UserHandle userHandle,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Retrieves the set of all namespaces in the current database with at least one document.
-     *
-     * @param packageName The name of the package that owns the schema.
-     * @param databaseName  The name of the database to retrieve.
-     * @param userHandle Handle of the calling user
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link List}&lt;{@link String}&gt;&gt;.
-     */
-    void getNamespaces(
-        in String packageName,
-        in String databaseName,
-        in UserHandle userHandle,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Inserts documents into the index.
-     *
-     * @param packageName The name of the package that owns this document.
-     * @param databaseName  The name of the database where this document lives.
-     * @param documentBundes List of GenericDocument bundles.
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback
-     *     If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
-     *     will be called with the cause throwable. Otherwise,
-     *     {@link IAppSearchBatchResultCallback#onResult} will be called with an
-     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
-     *     where the keys are document IDs, and the values are {@code null}.
-     */
-    void putDocuments(
-        in String packageName,
-        in String databaseName,
-        in List<Bundle> documentBundles,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchBatchResultCallback callback);
-
-    /**
-     * Retrieves documents from the index.
-     *
-     * @param packageName The name of the package that owns this document.
-     * @param databaseName  The databaseName this document resides in.
-     * @param namespace    The namespace this document resides in.
-     * @param ids The IDs of the documents to retrieve
-     * @param typePropertyPaths A map of schema type to a list of property paths to return in the
-     *     result.
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback
-     *     If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
-     *     will be called with the cause throwable. Otherwise,
-     *     {@link IAppSearchBatchResultCallback#onResult} will be called with an
-     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Bundle}&gt;
-     *     where the keys are document IDs, and the values are Document bundles.
-     */
-    void getDocuments(
-        in String packageName,
-        in String databaseName,
-        in String namespace,
-        in List<String> ids,
-        in Map<String, List<String>> typePropertyPaths,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchBatchResultCallback callback);
-
-    /**
-     * Searches a document based on a given specifications.
-     *
-     * @param packageName The name of the package to query over.
-     * @param databaseName The databaseName this query for.
-     * @param queryExpression String to search for
-     * @param searchSpecBundle SearchSpec bundle
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
-     *         operation.
-     */
-    void query(
-        in String packageName,
-        in String databaseName,
-        in String queryExpression,
-        in Bundle searchSpecBundle,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Executes a global query, i.e. over all permitted databases, against the AppSearch index and
-     * returns results.
-     *
-     * @param packageName The name of the package making the query.
-     * @param queryExpression String to search for
-     * @param searchSpecBundle SearchSpec bundle
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
-     *         operation.
-     */
-    void globalQuery(
-        in String packageName,
-        in String queryExpression,
-        in Bundle searchSpecBundle,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Fetches the next page of results of a previously executed query. Results can be empty if
-     * next-page token is invalid or all pages have been returned.
-     *
-     * @param packageName The name of the package to persist to disk for.
-     * @param nextPageToken The token of pre-loaded results of previously executed query.
-     * @param userHandle Handle of the calling user
-     * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
-     *                  operation.
-     */
-    void getNextPage(
-        in String packageName,
-        in long nextPageToken,
-        in UserHandle userHandle,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Invalidates the next-page token so that no more results of the related query can be returned.
-     *
-     * @param packageName The name of the package to persist to disk for.
-     * @param nextPageToken The token of pre-loaded results of previously executed query to be
-     *                      Invalidated.
-     * @param userHandle Handle of the calling user
-     */
-    void invalidateNextPageToken(
-        in String packageName,
-        in long nextPageToken,
-        in UserHandle userHandle);
-
-    /**
-    * Searches a document based on a given specifications.
-    *
-    * <p>Documents will be save to the given ParcelFileDescriptor
-    *
-    * @param packageName The name of the package to query over.
-    * @param databaseName The databaseName this query for.
-    * @param fileDescriptor The ParcelFileDescriptor where documents should be written to.
-    * @param queryExpression String to search for.
-    * @param searchSpecBundle SearchSpec bundle.
-    * @param userHandle Handle of the calling user.
-    * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-    *        {@link AppSearchResult}&lt;{@code Void}&gt;.
-    */
-    void writeQueryResultsToFile(
-        in String packageName,
-        in String databaseName,
-        in ParcelFileDescriptor fileDescriptor,
-        in String queryExpression,
-        in Bundle searchSpecBundle,
-        in UserHandle userHandle,
-        in IAppSearchResultCallback callback);
-
-    /**
-    * Inserts documents from the given file into the index.
-    *
-    * @param packageName The name of the package that owns this document.
-    * @param databaseName  The name of the database where this document lives.
-    * @param fileDescriptor The ParcelFileDescriptor where documents should be read from.
-    * @param userHandle Handle of the calling user.
-    * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-    *     {@link AppSearchResult}&lt;{@link List}&lt;{@link Bundle}&gt;&gt;, where the value are
-    *     MigrationFailure bundles.
-    */
-    void putDocumentsFromFile(
-        in String packageName,
-        in String databaseName,
-        in ParcelFileDescriptor fileDescriptor,
-        in UserHandle userHandle,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Reports usage of a particular document by namespace and id.
-     *
-     * <p>A usage report represents an event in which a user interacted with or viewed a document.
-     *
-     * <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
-     * metrics for that particular document. These metrics are used for ordering {@link #query}
-     * results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and
-     * {@link SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
-     *
-     * <p>Reporting usage of a document is optional.
-     *
-     * @param packageName The name of the package that owns this document.
-     * @param databaseName  The name of the database to report usage against.
-     * @param namespace Namespace the document being used belongs to.
-     * @param id ID of the document being used.
-     * @param usageTimestampMillis The timestamp at which the document was used.
-     * @param systemUsage Whether the usage was reported by a system app against another app's doc.
-     * @param userHandle Handle of the calling user
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Void}&gt;.
-     */
-     void reportUsage(
-         in String packageName,
-         in String databaseName,
-         in String namespace,
-         in String id,
-         in long usageTimestampMillis,
-         in boolean systemUsage,
-         in UserHandle userHandle,
-         in IAppSearchResultCallback callback);
-
-    /**
-     * Removes documents by ID.
-     *
-     * @param packageName The name of the package the document is in.
-     * @param databaseName The databaseName the document is in.
-     * @param namespace    Namespace of the document to remove.
-     * @param ids The IDs of the documents to delete
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback
-     *     If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
-     *     will be called with the cause throwable. Otherwise,
-     *     {@link IAppSearchBatchResultCallback#onResult} will be called with an
-     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
-     *     where the keys are document IDs. If a document doesn't exist, it will be reported as a
-     *     failure where the {@code throwable} is {@code null}.
-     */
-    void removeByDocumentId(
-        in String packageName,
-        in String databaseName,
-        in String namespace,
-        in List<String> ids,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchBatchResultCallback callback);
-
-    /**
-     * Removes documents by given query.
-     *
-     * @param packageName The name of the package to query over.
-     * @param databaseName The databaseName this query for.
-     * @param queryExpression String to search for
-     * @param searchSpecBundle SearchSpec bundle
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Void}&gt;.
-     */
-    void removeByQuery(
-        in String packageName,
-        in String databaseName,
-        in String queryExpression,
-        in Bundle searchSpecBundle,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Gets the storage info.
-     *
-     * @param packageName The name of the package to get the storage info for.
-     * @param databaseName The databaseName to get the storage info for.
-     * @param userHandle Handle of the calling user
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Bundle}&gt;, where the value is a
-     *     {@link StorageInfo}.
-     */
-    void getStorageInfo(
-        in String packageName,
-        in String databaseName,
-        in UserHandle userHandle,
-        in IAppSearchResultCallback callback);
-
-    /**
-     * Persists all update/delete requests to the disk.
-     *
-     * @param packageName The name of the package to persist to disk for.
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     */
-    void persistToDisk(
-        in String packageName,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis);
-
-    /**
-     * Creates and initializes AppSearchImpl for the calling app.
-     *
-     * @param packageName The name of the package to initialize for.
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
-     * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
-     *     {@link AppSearchResult}&lt;{@link Void}&gt;.
-     */
-    void initialize(
-        in String packageName,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
-        in IAppSearchResultCallback callback);
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchResultCallback.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchResultCallback.aidl
deleted file mode 100644
index 097f0d1..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchResultCallback.aidl
+++ /dev/null
@@ -1,23 +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.aidl;
-
-import android.app.appsearch.aidl.AppSearchResultParcel;
-
-/** {@hide} */
-oneway interface IAppSearchResultCallback {
-    void onResult(in AppSearchResultParcel resultParcel);
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java
deleted file mode 100644
index d493a1c..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java
+++ /dev/null
@@ -1,209 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.util.ArrayMap;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Provides results for AppSearch batch operations which encompass multiple documents.
- *
- * <p>Individual results of a batch operation are separated into two maps: one for successes and one
- * for failures. For successes, {@link #getSuccesses()} will return a map of keys to instances of
- * the value type. For failures, {@link #getFailures()} will return a map of keys to {@link
- * AppSearchResult} objects.
- *
- * <p>Alternatively, {@link #getAll()} returns a map of keys to {@link AppSearchResult} objects for
- * both successes and failures.
- *
- * @param <KeyType> The type of the keys for which the results will be reported.
- * @param <ValueType> The type of the result objects for successful results.
- * @see AppSearchSession#put
- * @see AppSearchSession#getByDocumentId
- * @see AppSearchSession#remove
- */
-public final class AppSearchBatchResult<KeyType, ValueType> {
-    @NonNull private final Map<KeyType, ValueType> mSuccesses;
-    @NonNull private final Map<KeyType, AppSearchResult<ValueType>> mFailures;
-    @NonNull private final Map<KeyType, AppSearchResult<ValueType>> mAll;
-
-    AppSearchBatchResult(
-            @NonNull Map<KeyType, ValueType> successes,
-            @NonNull Map<KeyType, AppSearchResult<ValueType>> failures,
-            @NonNull Map<KeyType, AppSearchResult<ValueType>> all) {
-        mSuccesses = Objects.requireNonNull(successes);
-        mFailures = Objects.requireNonNull(failures);
-        mAll = Objects.requireNonNull(all);
-    }
-
-    /** Returns {@code true} if this {@link AppSearchBatchResult} has no failures. */
-    public boolean isSuccess() {
-        return mFailures.isEmpty();
-    }
-
-    /**
-     * Returns a {@link Map} of keys mapped to instances of the value type for all successful
-     * individual results.
-     *
-     * <p>Example: {@link AppSearchSession#getByDocumentId} returns an {@link AppSearchBatchResult}.
-     * Each key (the document ID, of {@code String} type) will map to a {@link GenericDocument}
-     * object.
-     *
-     * <p>The values of the {@link Map} will not be {@code null}.
-     */
-    @NonNull
-    public Map<KeyType, ValueType> getSuccesses() {
-        return Collections.unmodifiableMap(mSuccesses);
-    }
-
-    /**
-     * Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all failed
-     * individual results.
-     *
-     * <p>The values of the {@link Map} will not be {@code null}.
-     */
-    @NonNull
-    public Map<KeyType, AppSearchResult<ValueType>> getFailures() {
-        return Collections.unmodifiableMap(mFailures);
-    }
-
-    /**
-     * Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all
-     * individual results.
-     *
-     * <p>The values of the {@link Map} will not be {@code null}.
-     */
-    @NonNull
-    public Map<KeyType, AppSearchResult<ValueType>> getAll() {
-        return Collections.unmodifiableMap(mAll);
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        return "{\n  successes: " + mSuccesses + "\n  failures: " + mFailures + "\n}";
-    }
-
-    /**
-     * Builder for {@link AppSearchBatchResult} objects.
-     *
-     * @param <KeyType> The type of the keys for which the results will be reported.
-     * @param <ValueType> The type of the result objects for successful results.
-     */
-    public static final class Builder<KeyType, ValueType> {
-        private ArrayMap<KeyType, ValueType> mSuccesses = new ArrayMap<>();
-        private ArrayMap<KeyType, AppSearchResult<ValueType>> mFailures = new ArrayMap<>();
-        private ArrayMap<KeyType, AppSearchResult<ValueType>> mAll = new ArrayMap<>();
-        private boolean mBuilt = false;
-
-        /**
-         * Associates the {@code key} with the provided successful return value.
-         *
-         * <p>Any previous mapping for a key, whether success or failure, is deleted.
-         *
-         * <p>This is a convenience function which is equivalent to {@code setResult(key,
-         * AppSearchResult.newSuccessfulResult(value))}.
-         *
-         * @param key The key to associate the result with; usually corresponds to some identifier
-         *     from the input like an ID or name.
-         * @param value An optional value to associate with the successful result of the operation
-         *     being performed.
-         */
-        @SuppressWarnings("MissingGetterMatchingBuilder") // See getSuccesses
-        @NonNull
-        public Builder<KeyType, ValueType> setSuccess(
-                @NonNull KeyType key, @Nullable ValueType value) {
-            Objects.requireNonNull(key);
-            resetIfBuilt();
-            return setResult(key, AppSearchResult.newSuccessfulResult(value));
-        }
-
-        /**
-         * Associates the {@code key} with the provided failure code and error message.
-         *
-         * <p>Any previous mapping for a key, whether success or failure, is deleted.
-         *
-         * <p>This is a convenience function which is equivalent to {@code setResult(key,
-         * AppSearchResult.newFailedResult(resultCode, errorMessage))}.
-         *
-         * @param key The key to associate the result with; usually corresponds to some identifier
-         *     from the input like an ID or name.
-         * @param resultCode One of the constants documented in {@link
-         *     AppSearchResult#getResultCode}.
-         * @param errorMessage An optional string describing the reason or nature of the failure.
-         */
-        @SuppressWarnings("MissingGetterMatchingBuilder") // See getFailures
-        @NonNull
-        public Builder<KeyType, ValueType> setFailure(
-                @NonNull KeyType key,
-                @AppSearchResult.ResultCode int resultCode,
-                @Nullable String errorMessage) {
-            Objects.requireNonNull(key);
-            resetIfBuilt();
-            return setResult(key, AppSearchResult.newFailedResult(resultCode, errorMessage));
-        }
-
-        /**
-         * Associates the {@code key} with the provided {@code result}.
-         *
-         * <p>Any previous mapping for a key, whether success or failure, is deleted.
-         *
-         * @param key The key to associate the result with; usually corresponds to some identifier
-         *     from the input like an ID or name.
-         * @param result The result to associate with the key.
-         */
-        @SuppressWarnings("MissingGetterMatchingBuilder") // See getAll
-        @NonNull
-        public Builder<KeyType, ValueType> setResult(
-                @NonNull KeyType key, @NonNull AppSearchResult<ValueType> result) {
-            Objects.requireNonNull(key);
-            Objects.requireNonNull(result);
-            resetIfBuilt();
-            if (result.isSuccess()) {
-                mSuccesses.put(key, result.getResultValue());
-                mFailures.remove(key);
-            } else {
-                mFailures.put(key, result);
-                mSuccesses.remove(key);
-            }
-            mAll.put(key, result);
-            return this;
-        }
-
-        /**
-         * Builds an {@link AppSearchBatchResult} object from the contents of this {@link Builder}.
-         */
-        @NonNull
-        public AppSearchBatchResult<KeyType, ValueType> build() {
-            mBuilt = true;
-            return new AppSearchBatchResult<>(mSuccesses, mFailures, mAll);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mSuccesses = new ArrayMap<>(mSuccesses);
-                mFailures = new ArrayMap<>(mFailures);
-                mAll = new ArrayMap<>(mAll);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java
deleted file mode 100644
index b1cb132..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java
+++ /dev/null
@@ -1,249 +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 android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Information about the success or failure of an AppSearch call.
- *
- * @param <ValueType> The type of result object for successful calls.
- */
-public final class AppSearchResult<ValueType> {
-    private static final String TAG = "AppSearchResult";
-
-    /**
-     * Result codes from {@link AppSearchSession} methods.
-     *
-     * @hide
-     */
-    @IntDef(
-            value = {
-                RESULT_OK,
-                RESULT_UNKNOWN_ERROR,
-                RESULT_INTERNAL_ERROR,
-                RESULT_INVALID_ARGUMENT,
-                RESULT_IO_ERROR,
-                RESULT_OUT_OF_SPACE,
-                RESULT_NOT_FOUND,
-                RESULT_INVALID_SCHEMA,
-                RESULT_SECURITY_ERROR,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ResultCode {}
-
-    /** The call was successful. */
-    public static final int RESULT_OK = 0;
-
-    /** An unknown error occurred while processing the call. */
-    public static final int RESULT_UNKNOWN_ERROR = 1;
-
-    /**
-     * An internal error occurred within AppSearch, which the caller cannot address.
-     *
-     * <p>This error may be considered similar to {@link IllegalStateException}
-     */
-    public static final int RESULT_INTERNAL_ERROR = 2;
-
-    /**
-     * The caller supplied invalid arguments to the call.
-     *
-     * <p>This error may be considered similar to {@link IllegalArgumentException}.
-     */
-    public static final int RESULT_INVALID_ARGUMENT = 3;
-
-    /**
-     * An issue occurred reading or writing to storage. The call might succeed if repeated.
-     *
-     * <p>This error may be considered similar to {@link java.io.IOException}.
-     */
-    public static final int RESULT_IO_ERROR = 4;
-
-    /** Storage is out of space, and no more space could be reclaimed. */
-    public static final int RESULT_OUT_OF_SPACE = 5;
-
-    /** An entity the caller requested to interact with does not exist in the system. */
-    public static final int RESULT_NOT_FOUND = 6;
-
-    /** The caller supplied a schema which is invalid or incompatible with the previous schema. */
-    public static final int RESULT_INVALID_SCHEMA = 7;
-
-    /** The caller requested an operation it does not have privileges for. */
-    public static final int RESULT_SECURITY_ERROR = 8;
-
-    private final @ResultCode int mResultCode;
-    @Nullable private final ValueType mResultValue;
-    @Nullable private final String mErrorMessage;
-
-    private AppSearchResult(
-            @ResultCode int resultCode,
-            @Nullable ValueType resultValue,
-            @Nullable String errorMessage) {
-        mResultCode = resultCode;
-        mResultValue = resultValue;
-        mErrorMessage = errorMessage;
-    }
-
-    /** Returns {@code true} if {@link #getResultCode} equals {@link AppSearchResult#RESULT_OK}. */
-    public boolean isSuccess() {
-        return getResultCode() == RESULT_OK;
-    }
-
-    /** Returns one of the {@code RESULT} constants defined in {@link AppSearchResult}. */
-    public @ResultCode int getResultCode() {
-        return mResultCode;
-    }
-
-    /**
-     * Returns the result value associated with this result, if it was successful.
-     *
-     * <p>See the documentation of the particular {@link AppSearchSession} call producing this
-     * {@link AppSearchResult} for what is placed in the result value by that call.
-     *
-     * @throws IllegalStateException if this {@link AppSearchResult} is not successful.
-     */
-    @Nullable
-    public ValueType getResultValue() {
-        if (!isSuccess()) {
-            throw new IllegalStateException("AppSearchResult is a failure: " + this);
-        }
-        return mResultValue;
-    }
-
-    /**
-     * Returns the error message associated with this result.
-     *
-     * <p>If {@link #isSuccess} is {@code true}, the error message is always {@code null}. The error
-     * message may be {@code null} even if {@link #isSuccess} is {@code false}. See the
-     * documentation of the particular {@link AppSearchSession} call producing this {@link
-     * AppSearchResult} for what is returned by {@link #getErrorMessage}.
-     */
-    @Nullable
-    public String getErrorMessage() {
-        return mErrorMessage;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object other) {
-        if (this == other) {
-            return true;
-        }
-        if (!(other instanceof AppSearchResult)) {
-            return false;
-        }
-        AppSearchResult<?> otherResult = (AppSearchResult<?>) other;
-        return mResultCode == otherResult.mResultCode
-                && Objects.equals(mResultValue, otherResult.mResultValue)
-                && Objects.equals(mErrorMessage, otherResult.mErrorMessage);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mResultCode, mResultValue, mErrorMessage);
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        if (isSuccess()) {
-            return "[SUCCESS]: " + mResultValue;
-        }
-        return "[FAILURE(" + mResultCode + ")]: " + mErrorMessage;
-    }
-
-    /**
-     * Creates a new successful {@link AppSearchResult}.
-     *
-     * @param value An optional value to associate with the successful result of the operation being
-     *     performed.
-     */
-    @NonNull
-    public static <ValueType> AppSearchResult<ValueType> newSuccessfulResult(
-            @Nullable ValueType value) {
-        return new AppSearchResult<>(RESULT_OK, value, /*errorMessage=*/ null);
-    }
-
-    /**
-     * Creates a new failed {@link AppSearchResult}.
-     *
-     * @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
-     * @param errorMessage An optional string describing the reason or nature of the failure.
-     */
-    @NonNull
-    public static <ValueType> AppSearchResult<ValueType> newFailedResult(
-            @ResultCode int resultCode, @Nullable String errorMessage) {
-        return new AppSearchResult<>(resultCode, /*resultValue=*/ null, errorMessage);
-    }
-
-    /**
-     * Creates a new failed {@link AppSearchResult} by a AppSearchResult in another type.
-     *
-     * @hide
-     */
-    @NonNull
-    public static <ValueType> AppSearchResult<ValueType> newFailedResult(
-            @NonNull AppSearchResult<?> otherFailedResult) {
-        Preconditions.checkState(
-                !otherFailedResult.isSuccess(),
-                "Cannot convert a success result to a failed result");
-        return AppSearchResult.newFailedResult(
-                otherFailedResult.getResultCode(), otherFailedResult.getErrorMessage());
-    }
-
-    /** @hide */
-    @NonNull
-    public static <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
-            @NonNull Throwable t) {
-        // Log for traceability. NOT_FOUND is logged at VERBOSE because this error can occur during
-        // the regular operation of the system (b/183550974). Everything else is logged at DEBUG.
-        if (t instanceof AppSearchException
-                && ((AppSearchException) t).getResultCode() == RESULT_NOT_FOUND) {
-            Log.v(TAG, "Converting throwable to failed result: " + t);
-        } else {
-            Log.d(TAG, "Converting throwable to failed result.", t);
-        }
-
-        if (t instanceof AppSearchException) {
-            return ((AppSearchException) t).toAppSearchResult();
-        }
-
-        String exceptionClass = t.getClass().getSimpleName();
-        @AppSearchResult.ResultCode int resultCode;
-        if (t instanceof IllegalStateException || t instanceof NullPointerException) {
-            resultCode = AppSearchResult.RESULT_INTERNAL_ERROR;
-        } else if (t instanceof IllegalArgumentException) {
-            resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
-        } else if (t instanceof IOException) {
-            resultCode = AppSearchResult.RESULT_IO_ERROR;
-        } else if (t instanceof SecurityException) {
-            resultCode = AppSearchResult.RESULT_SECURITY_ERROR;
-        } else {
-            resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
-        }
-        return AppSearchResult.newFailedResult(resultCode, exceptionClass + ": " + t.getMessage());
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
deleted file mode 100644
index 2e04d71..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ /dev/null
@@ -1,922 +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 android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.exceptions.IllegalSchemaException;
-import android.app.appsearch.util.BundleUtil;
-import android.app.appsearch.util.IndentingStringBuilder;
-import android.os.Bundle;
-import android.util.ArraySet;
-
-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.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * The AppSearch Schema for a particular type of document.
- *
- * <p>For example, an e-mail message or a music recording could be a schema type.
- *
- * <p>The schema consists of type information, properties, and config (like tokenization type).
- *
- * @see AppSearchSession#setSchema
- */
-public final class AppSearchSchema {
-    private static final String SCHEMA_TYPE_FIELD = "schemaType";
-    private static final String PROPERTIES_FIELD = "properties";
-
-    private final Bundle mBundle;
-
-    /** @hide */
-    public AppSearchSchema(@NonNull Bundle bundle) {
-        Objects.requireNonNull(bundle);
-        mBundle = bundle;
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-        appendAppSearchSchemaString(stringBuilder);
-        return stringBuilder.toString();
-    }
-
-    /**
-     * Appends a debugging string for the {@link AppSearchSchema} instance to the given string
-     * builder.
-     *
-     * @param builder the builder to append to.
-     */
-    private void appendAppSearchSchemaString(@NonNull IndentingStringBuilder builder) {
-        Objects.requireNonNull(builder);
-
-        builder.append("{\n");
-        builder.increaseIndentLevel();
-        builder.append("schemaType: \"").append(getSchemaType()).append("\",\n");
-        builder.append("properties: [\n");
-
-        AppSearchSchema.PropertyConfig[] sortedProperties =
-                getProperties().toArray(new AppSearchSchema.PropertyConfig[0]);
-        Arrays.sort(sortedProperties, (o1, o2) -> o1.getName().compareTo(o2.getName()));
-
-        for (int i = 0; i < sortedProperties.length; i++) {
-            AppSearchSchema.PropertyConfig propertyConfig = sortedProperties[i];
-            builder.increaseIndentLevel();
-            propertyConfig.appendPropertyConfigString(builder);
-            if (i != sortedProperties.length - 1) {
-                builder.append(",\n");
-            }
-            builder.decreaseIndentLevel();
-        }
-
-        builder.append("\n");
-        builder.append("]\n");
-        builder.decreaseIndentLevel();
-        builder.append("}");
-    }
-
-    /** Returns the name of this schema type, e.g. Email. */
-    @NonNull
-    public String getSchemaType() {
-        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
-    @SuppressWarnings("MixedMutabilityReturnType")
-    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(PropertyConfig.fromBundle(propertyBundles.get(i)));
-        }
-        return ret;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object other) {
-        if (this == other) {
-            return true;
-        }
-        if (!(other instanceof AppSearchSchema)) {
-            return false;
-        }
-        AppSearchSchema otherSchema = (AppSearchSchema) other;
-        if (!getSchemaType().equals(otherSchema.getSchemaType())) {
-            return false;
-        }
-        return getProperties().equals(otherSchema.getProperties());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(getSchemaType(), getProperties());
-    }
-
-    /** Builder for {@link AppSearchSchema objects}. */
-    public static final class Builder {
-        private final String mSchemaType;
-        private ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
-        private final Set<String> mPropertyNames = new ArraySet<>();
-        private boolean mBuilt = false;
-
-        /** Creates a new {@link AppSearchSchema.Builder}. */
-        public Builder(@NonNull String schemaType) {
-            Objects.requireNonNull(schemaType);
-            mSchemaType = schemaType;
-        }
-
-        /** Adds a property to the given type. */
-        @NonNull
-        public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
-            Objects.requireNonNull(propertyConfig);
-            resetIfBuilt();
-            String name = propertyConfig.getName();
-            if (!mPropertyNames.add(name)) {
-                throw new IllegalSchemaException("Property defined more than once: " + name);
-            }
-            mPropertyBundles.add(propertyConfig.mBundle);
-            return this;
-        }
-
-        /** Constructs a new {@link AppSearchSchema} from the contents of this builder. */
-        @NonNull
-        public AppSearchSchema build() {
-            Bundle bundle = new Bundle();
-            bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mSchemaType);
-            bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
-            mBuilt = true;
-            return new AppSearchSchema(bundle);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mPropertyBundles = new ArrayList<>(mPropertyBundles);
-                mBuilt = false;
-            }
-        }
-    }
-
-    /**
-     * Common configuration for a single property (field) in a Document.
-     *
-     * <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be a
-     * property.
-     */
-    public abstract static class PropertyConfig {
-        static final String NAME_FIELD = "name";
-        static final String DATA_TYPE_FIELD = "dataType";
-        static final String CARDINALITY_FIELD = "cardinality";
-
-        /**
-         * Physical data-types of the contents of the property.
-         *
-         * @hide
-         */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.PropertyConfigProto.DataType.Code.
-        @IntDef(
-                value = {
-                    DATA_TYPE_STRING,
-                    DATA_TYPE_LONG,
-                    DATA_TYPE_DOUBLE,
-                    DATA_TYPE_BOOLEAN,
-                    DATA_TYPE_BYTES,
-                    DATA_TYPE_DOCUMENT,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface DataType {}
-
-        /** @hide */
-        public static final int DATA_TYPE_STRING = 1;
-
-        /** @hide */
-        public static final int DATA_TYPE_LONG = 2;
-
-        /** @hide */
-        public static final int DATA_TYPE_DOUBLE = 3;
-
-        /** @hide */
-        public static final int DATA_TYPE_BOOLEAN = 4;
-
-        /**
-         * Unstructured BLOB.
-         *
-         * @hide
-         */
-        public static final int DATA_TYPE_BYTES = 5;
-
-        /**
-         * Indicates that the property is itself a {@link GenericDocument}, making it part of a
-         * hierarchical schema. Any property using this DataType MUST have a valid {@link
-         * PropertyConfig#getSchemaType}.
-         *
-         * @hide
-         */
-        public static final int DATA_TYPE_DOCUMENT = 6;
-
-        /**
-         * The cardinality of the property (whether it is required, optional or repeated).
-         *
-         * @hide
-         */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.PropertyConfigProto.Cardinality.Code.
-        @IntDef(
-                value = {
-                    CARDINALITY_REPEATED,
-                    CARDINALITY_OPTIONAL,
-                    CARDINALITY_REQUIRED,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface Cardinality {}
-
-        /** Any number of items (including zero) [0...*]. */
-        public static final int CARDINALITY_REPEATED = 1;
-
-        /** Zero or one value [0,1]. */
-        public static final int CARDINALITY_OPTIONAL = 2;
-
-        /** Exactly one value [1]. */
-        public static final int CARDINALITY_REQUIRED = 3;
-
-        final Bundle mBundle;
-
-        @Nullable private Integer mHashCode;
-
-        PropertyConfig(@NonNull Bundle bundle) {
-            mBundle = Objects.requireNonNull(bundle);
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-            appendPropertyConfigString(stringBuilder);
-            return stringBuilder.toString();
-        }
-
-        /**
-         * Appends a debug string for the {@link AppSearchSchema.PropertyConfig} instance to the
-         * given string builder.
-         *
-         * @param builder the builder to append to.
-         */
-        void appendPropertyConfigString(@NonNull IndentingStringBuilder builder) {
-            Objects.requireNonNull(builder);
-
-            builder.append("{\n");
-            builder.increaseIndentLevel();
-            builder.append("name: \"").append(getName()).append("\",\n");
-
-            if (this instanceof AppSearchSchema.StringPropertyConfig) {
-                ((StringPropertyConfig) this).appendStringPropertyConfigFields(builder);
-            } else if (this instanceof AppSearchSchema.DocumentPropertyConfig) {
-                ((DocumentPropertyConfig) this).appendDocumentPropertyConfigFields(builder);
-            }
-
-            switch (getCardinality()) {
-                case AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED:
-                    builder.append("cardinality: CARDINALITY_REPEATED,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL:
-                    builder.append("cardinality: CARDINALITY_OPTIONAL,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED:
-                    builder.append("cardinality: CARDINALITY_REQUIRED,\n");
-                    break;
-                default:
-                    builder.append("cardinality: CARDINALITY_UNKNOWN,\n");
-            }
-
-            switch (getDataType()) {
-                case AppSearchSchema.PropertyConfig.DATA_TYPE_STRING:
-                    builder.append("dataType: DATA_TYPE_STRING,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.DATA_TYPE_LONG:
-                    builder.append("dataType: DATA_TYPE_LONG,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.DATA_TYPE_DOUBLE:
-                    builder.append("dataType: DATA_TYPE_DOUBLE,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.DATA_TYPE_BOOLEAN:
-                    builder.append("dataType: DATA_TYPE_BOOLEAN,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES:
-                    builder.append("dataType: DATA_TYPE_BYTES,\n");
-                    break;
-                case AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT:
-                    builder.append("dataType: DATA_TYPE_DOCUMENT,\n");
-                    break;
-                default:
-                    builder.append("dataType: DATA_TYPE_UNKNOWN,\n");
-            }
-            builder.decreaseIndentLevel();
-            builder.append("}");
-        }
-
-        /** 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).
-         *
-         * @hide
-         */
-        public @DataType int getDataType() {
-            return mBundle.getInt(DATA_TYPE_FIELD, -1);
-        }
-
-        /**
-         * Returns the cardinality of the property (whether it is optional, required or repeated).
-         */
-        public @Cardinality int getCardinality() {
-            return mBundle.getInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
-        }
-
-        @Override
-        public boolean equals(@Nullable Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof PropertyConfig)) {
-                return false;
-            }
-            PropertyConfig otherProperty = (PropertyConfig) other;
-            return BundleUtil.deepEquals(this.mBundle, otherProperty.mBundle);
-        }
-
-        @Override
-        public int hashCode() {
-            if (mHashCode == null) {
-                mHashCode = BundleUtil.deepHashCode(mBundle);
-            }
-            return mHashCode;
-        }
-
-        /**
-         * Converts a {@link Bundle} into a {@link PropertyConfig} depending on its internal data
-         * type.
-         *
-         * <p>The bundle is not cloned.
-         *
-         * @throws IllegalArgumentException if the bundle does no contain a recognized value in its
-         *     {@code DATA_TYPE_FIELD}.
-         * @hide
-         */
-        @NonNull
-        public static PropertyConfig fromBundle(@NonNull Bundle propertyBundle) {
-            switch (propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)) {
-                case PropertyConfig.DATA_TYPE_STRING:
-                    return new StringPropertyConfig(propertyBundle);
-                case PropertyConfig.DATA_TYPE_LONG:
-                    return new LongPropertyConfig(propertyBundle);
-                case PropertyConfig.DATA_TYPE_DOUBLE:
-                    return new DoublePropertyConfig(propertyBundle);
-                case PropertyConfig.DATA_TYPE_BOOLEAN:
-                    return new BooleanPropertyConfig(propertyBundle);
-                case PropertyConfig.DATA_TYPE_BYTES:
-                    return new BytesPropertyConfig(propertyBundle);
-                case PropertyConfig.DATA_TYPE_DOCUMENT:
-                    return new DocumentPropertyConfig(propertyBundle);
-                default:
-                    throw new IllegalArgumentException(
-                            "Unsupported property bundle of type "
-                                    + propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)
-                                    + "; contents: "
-                                    + propertyBundle);
-            }
-        }
-    }
-
-    /** Configuration for a property of type String in a Document. */
-    public static final class StringPropertyConfig extends PropertyConfig {
-        private static final String INDEXING_TYPE_FIELD = "indexingType";
-        private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
-
-        /**
-         * Encapsulates the configurations on how AppSearch should query/index these terms.
-         *
-         * @hide
-         */
-        @IntDef(
-                value = {
-                    INDEXING_TYPE_NONE,
-                    INDEXING_TYPE_EXACT_TERMS,
-                    INDEXING_TYPE_PREFIXES,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface IndexingType {}
-
-        /** Content in this property will not be tokenized or indexed. */
-        public static final int INDEXING_TYPE_NONE = 0;
-
-        /**
-         * Content in this property should only be returned for queries matching the exact tokens
-         * appearing in this property.
-         *
-         * <p>Ex. A property with "fool" should NOT match a query for "foo".
-         */
-        public static final int INDEXING_TYPE_EXACT_TERMS = 1;
-
-        /**
-         * Content in this property should be returned for queries that are either exact matches or
-         * query matches of the tokens appearing in this property.
-         *
-         * <p>Ex. A property with "fool" <b>should</b> match a query for "foo".
-         */
-        public static final int INDEXING_TYPE_PREFIXES = 2;
-
-        /**
-         * Configures how tokens should be extracted from this property.
-         *
-         * @hide
-         */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.IndexingConfig.TokenizerType.Code.
-        @IntDef(
-                value = {
-                    TOKENIZER_TYPE_NONE,
-                    TOKENIZER_TYPE_PLAIN,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface TokenizerType {}
-
-        /**
-         * This value indicates that no tokens should be extracted from this property.
-         *
-         * <p>It is only valid for tokenizer_type to be 'NONE' if {@link #getIndexingType} is {@link
-         * #INDEXING_TYPE_NONE}.
-         */
-        public static final int TOKENIZER_TYPE_NONE = 0;
-
-        /**
-         * Tokenization for plain text. This value indicates that tokens should be extracted from
-         * this property based on word breaks. Segments of whitespace and punctuation are not
-         * considered tokens.
-         *
-         * <p>Ex. A property with "foo bar. baz." will produce tokens for "foo", "bar" and "baz".
-         * The segments " " and "." will not be considered tokens.
-         *
-         * <p>It is only valid for tokenizer_type to be 'PLAIN' if {@link #getIndexingType} is
-         * {@link #INDEXING_TYPE_EXACT_TERMS} or {@link #INDEXING_TYPE_PREFIXES}.
-         */
-        public static final int TOKENIZER_TYPE_PLAIN = 1;
-
-        StringPropertyConfig(@NonNull Bundle bundle) {
-            super(bundle);
-        }
-
-        /** 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 StringPropertyConfig}. */
-        public static final class Builder {
-            private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-            private @IndexingType int mIndexingType = INDEXING_TYPE_NONE;
-            private @TokenizerType int mTokenizerType = TOKENIZER_TYPE_NONE;
-
-            /** Creates a new {@link StringPropertyConfig.Builder}. */
-            public Builder(@NonNull String propertyName) {
-                mPropertyName = Objects.requireNonNull(propertyName);
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>If this method is not called, the default cardinality is {@link
-             * PropertyConfig#CARDINALITY_OPTIONAL}.
-             */
-            @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
-            @NonNull
-            public StringPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mCardinality = cardinality;
-                return this;
-            }
-
-            /**
-             * Configures how a property should be indexed so that it can be retrieved by queries.
-             *
-             * <p>If this method is not called, the default indexing type is {@link
-             * StringPropertyConfig#INDEXING_TYPE_NONE}, so that it cannot be matched by queries.
-             */
-            @NonNull
-            public StringPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
-                Preconditions.checkArgumentInRange(
-                        indexingType, INDEXING_TYPE_NONE, INDEXING_TYPE_PREFIXES, "indexingType");
-                mIndexingType = indexingType;
-                return this;
-            }
-
-            /**
-             * Configures how this property should be tokenized (split into words).
-             *
-             * <p>If this method is not called, the default indexing type is {@link
-             * StringPropertyConfig#TOKENIZER_TYPE_NONE}, so that it is not tokenized.
-             *
-             * <p>This method must be called with a value other than {@link
-             * StringPropertyConfig#TOKENIZER_TYPE_NONE} if the property is indexed (i.e. if {@link
-             * #setIndexingType} has been called with a value other than {@link
-             * StringPropertyConfig#INDEXING_TYPE_NONE}).
-             */
-            @NonNull
-            public StringPropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
-                Preconditions.checkArgumentInRange(
-                        tokenizerType, TOKENIZER_TYPE_NONE, TOKENIZER_TYPE_PLAIN, "tokenizerType");
-                mTokenizerType = tokenizerType;
-                return this;
-            }
-
-            /** Constructs a new {@link StringPropertyConfig} from the contents of this builder. */
-            @NonNull
-            public StringPropertyConfig build() {
-                if (mTokenizerType == TOKENIZER_TYPE_NONE) {
-                    Preconditions.checkState(
-                            mIndexingType == INDEXING_TYPE_NONE,
-                            "Cannot set "
-                                    + "TOKENIZER_TYPE_NONE with an indexing type other than "
-                                    + "INDEXING_TYPE_NONE.");
-                } else {
-                    Preconditions.checkState(
-                            mIndexingType != INDEXING_TYPE_NONE,
-                            "Cannot set " + "TOKENIZER_TYPE_PLAIN  with INDEXING_TYPE_NONE.");
-                }
-                Bundle bundle = new Bundle();
-                bundle.putString(NAME_FIELD, mPropertyName);
-                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
-                bundle.putInt(CARDINALITY_FIELD, mCardinality);
-                bundle.putInt(INDEXING_TYPE_FIELD, mIndexingType);
-                bundle.putInt(TOKENIZER_TYPE_FIELD, mTokenizerType);
-                return new StringPropertyConfig(bundle);
-            }
-        }
-
-        /**
-         * Appends a debug string for the {@link StringPropertyConfig} instance to the given string
-         * builder.
-         *
-         * <p>This appends fields specific to a {@link StringPropertyConfig} instance.
-         *
-         * @param builder the builder to append to.
-         */
-        void appendStringPropertyConfigFields(@NonNull IndentingStringBuilder builder) {
-            switch (getIndexingType()) {
-                case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE:
-                    builder.append("indexingType: INDEXING_TYPE_NONE,\n");
-                    break;
-                case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS:
-                    builder.append("indexingType: INDEXING_TYPE_EXACT_TERMS,\n");
-                    break;
-                case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES:
-                    builder.append("indexingType: INDEXING_TYPE_PREFIXES,\n");
-                    break;
-                default:
-                    builder.append("indexingType: INDEXING_TYPE_UNKNOWN,\n");
-            }
-
-            switch (getTokenizerType()) {
-                case AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE:
-                    builder.append("tokenizerType: TOKENIZER_TYPE_NONE,\n");
-                    break;
-                case AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN:
-                    builder.append("tokenizerType: TOKENIZER_TYPE_PLAIN,\n");
-                    break;
-                default:
-                    builder.append("tokenizerType: TOKENIZER_TYPE_UNKNOWN,\n");
-            }
-        }
-    }
-
-    /** Configuration for a property containing a 64-bit integer. */
-    public static final class LongPropertyConfig extends PropertyConfig {
-        LongPropertyConfig(@NonNull Bundle bundle) {
-            super(bundle);
-        }
-
-        /** Builder for {@link LongPropertyConfig}. */
-        public static final class Builder {
-            private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-
-            /** Creates a new {@link LongPropertyConfig.Builder}. */
-            public Builder(@NonNull String propertyName) {
-                mPropertyName = Objects.requireNonNull(propertyName);
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>If this method is not called, the default cardinality is {@link
-             * PropertyConfig#CARDINALITY_OPTIONAL}.
-             */
-            @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
-            @NonNull
-            public LongPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mCardinality = cardinality;
-                return this;
-            }
-
-            /** Constructs a new {@link LongPropertyConfig} from the contents of this builder. */
-            @NonNull
-            public LongPropertyConfig build() {
-                Bundle bundle = new Bundle();
-                bundle.putString(NAME_FIELD, mPropertyName);
-                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_LONG);
-                bundle.putInt(CARDINALITY_FIELD, mCardinality);
-                return new LongPropertyConfig(bundle);
-            }
-        }
-    }
-
-    /** Configuration for a property containing a double-precision decimal number. */
-    public static final class DoublePropertyConfig extends PropertyConfig {
-        DoublePropertyConfig(@NonNull Bundle bundle) {
-            super(bundle);
-        }
-
-        /** Builder for {@link DoublePropertyConfig}. */
-        public static final class Builder {
-            private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-
-            /** Creates a new {@link DoublePropertyConfig.Builder}. */
-            public Builder(@NonNull String propertyName) {
-                mPropertyName = Objects.requireNonNull(propertyName);
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>If this method is not called, the default cardinality is {@link
-             * PropertyConfig#CARDINALITY_OPTIONAL}.
-             */
-            @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
-            @NonNull
-            public DoublePropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mCardinality = cardinality;
-                return this;
-            }
-
-            /** Constructs a new {@link DoublePropertyConfig} from the contents of this builder. */
-            @NonNull
-            public DoublePropertyConfig build() {
-                Bundle bundle = new Bundle();
-                bundle.putString(NAME_FIELD, mPropertyName);
-                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOUBLE);
-                bundle.putInt(CARDINALITY_FIELD, mCardinality);
-                return new DoublePropertyConfig(bundle);
-            }
-        }
-    }
-
-    /** Configuration for a property containing a boolean. */
-    public static final class BooleanPropertyConfig extends PropertyConfig {
-        BooleanPropertyConfig(@NonNull Bundle bundle) {
-            super(bundle);
-        }
-
-        /** Builder for {@link BooleanPropertyConfig}. */
-        public static final class Builder {
-            private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-
-            /** Creates a new {@link BooleanPropertyConfig.Builder}. */
-            public Builder(@NonNull String propertyName) {
-                mPropertyName = Objects.requireNonNull(propertyName);
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>If this method is not called, the default cardinality is {@link
-             * PropertyConfig#CARDINALITY_OPTIONAL}.
-             */
-            @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
-            @NonNull
-            public BooleanPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mCardinality = cardinality;
-                return this;
-            }
-
-            /** Constructs a new {@link BooleanPropertyConfig} from the contents of this builder. */
-            @NonNull
-            public BooleanPropertyConfig build() {
-                Bundle bundle = new Bundle();
-                bundle.putString(NAME_FIELD, mPropertyName);
-                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BOOLEAN);
-                bundle.putInt(CARDINALITY_FIELD, mCardinality);
-                return new BooleanPropertyConfig(bundle);
-            }
-        }
-    }
-
-    /** Configuration for a property containing a byte array. */
-    public static final class BytesPropertyConfig extends PropertyConfig {
-        BytesPropertyConfig(@NonNull Bundle bundle) {
-            super(bundle);
-        }
-
-        /** Builder for {@link BytesPropertyConfig}. */
-        public static final class Builder {
-            private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-
-            /** Creates a new {@link BytesPropertyConfig.Builder}. */
-            public Builder(@NonNull String propertyName) {
-                mPropertyName = Objects.requireNonNull(propertyName);
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>If this method is not called, the default cardinality is {@link
-             * PropertyConfig#CARDINALITY_OPTIONAL}.
-             */
-            @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
-            @NonNull
-            public BytesPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mCardinality = cardinality;
-                return this;
-            }
-
-            /** Constructs a new {@link BytesPropertyConfig} from the contents of this builder. */
-            @NonNull
-            public BytesPropertyConfig build() {
-                Bundle bundle = new Bundle();
-                bundle.putString(NAME_FIELD, mPropertyName);
-                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BYTES);
-                bundle.putInt(CARDINALITY_FIELD, mCardinality);
-                return new BytesPropertyConfig(bundle);
-            }
-        }
-    }
-
-    /** Configuration for a property containing another Document. */
-    public static final class DocumentPropertyConfig extends PropertyConfig {
-        private static final String SCHEMA_TYPE_FIELD = "schemaType";
-        private static final String INDEX_NESTED_PROPERTIES_FIELD = "indexNestedProperties";
-
-        DocumentPropertyConfig(@NonNull Bundle bundle) {
-            super(bundle);
-        }
-
-        /** Returns the logical schema-type of the contents of this document property. */
-        @NonNull
-        public String getSchemaType() {
-            return Objects.requireNonNull(mBundle.getString(SCHEMA_TYPE_FIELD));
-        }
-
-        /**
-         * Returns whether fields in the nested document should be indexed according to that
-         * document's schema.
-         *
-         * <p>If false, the nested document's properties are not indexed regardless of its own
-         * schema.
-         */
-        public boolean shouldIndexNestedProperties() {
-            return mBundle.getBoolean(INDEX_NESTED_PROPERTIES_FIELD);
-        }
-
-        /** Builder for {@link DocumentPropertyConfig}. */
-        public static final class Builder {
-            private final String mPropertyName;
-            private final String mSchemaType;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-            private boolean mShouldIndexNestedProperties = false;
-
-            /**
-             * Creates a new {@link DocumentPropertyConfig.Builder}.
-             *
-             * @param propertyName The logical name of the property in the schema, which will be
-             *     used as the key for this property in {@link
-             *     GenericDocument.Builder#setPropertyDocument}.
-             * @param schemaType The type of documents which will be stored in this property.
-             *     Documents of different types cannot be mixed into a single property.
-             */
-            public Builder(@NonNull String propertyName, @NonNull String schemaType) {
-                mPropertyName = Objects.requireNonNull(propertyName);
-                mSchemaType = Objects.requireNonNull(schemaType);
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>If this method is not called, the default cardinality is {@link
-             * PropertyConfig#CARDINALITY_OPTIONAL}.
-             */
-            @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
-            @NonNull
-            public DocumentPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mCardinality = cardinality;
-                return this;
-            }
-
-            /**
-             * Configures whether fields in the nested document should be indexed according to that
-             * document's schema.
-             *
-             * <p>If false, the nested document's properties are not indexed regardless of its own
-             * schema.
-             */
-            @NonNull
-            public DocumentPropertyConfig.Builder setShouldIndexNestedProperties(
-                    boolean indexNestedProperties) {
-                mShouldIndexNestedProperties = indexNestedProperties;
-                return this;
-            }
-
-            /** Constructs a new {@link PropertyConfig} from the contents of this builder. */
-            @NonNull
-            public DocumentPropertyConfig build() {
-                Bundle bundle = new Bundle();
-                bundle.putString(NAME_FIELD, mPropertyName);
-                bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
-                bundle.putInt(CARDINALITY_FIELD, mCardinality);
-                bundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, mShouldIndexNestedProperties);
-                bundle.putString(SCHEMA_TYPE_FIELD, mSchemaType);
-                return new DocumentPropertyConfig(bundle);
-            }
-        }
-
-        /**
-         * Appends a debug string for the {@link DocumentPropertyConfig} instance to the given
-         * string builder.
-         *
-         * <p>This appends fields specific to a {@link DocumentPropertyConfig} instance.
-         *
-         * @param builder the builder to append to.
-         */
-        void appendDocumentPropertyConfigFields(@NonNull IndentingStringBuilder builder) {
-            builder.append("shouldIndexNestedProperties: ")
-                    .append(shouldIndexNestedProperties())
-                    .append(",\n");
-
-            builder.append("schemaType: \"").append(getSchemaType()).append("\",\n");
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
deleted file mode 100644
index 4d27519..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
+++ /dev/null
@@ -1,1342 +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 android.annotation.CurrentTimeMillisLong;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.app.appsearch.util.BundleUtil;
-import android.app.appsearch.util.IndentingStringBuilder;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Represents a document unit.
- *
- * <p>Documents contain structured data conforming to their {@link AppSearchSchema} type. Each
- * document is uniquely identified by a namespace and a String ID within that namespace.
- *
- * <p>Documents are constructed by using the {@link GenericDocument.Builder}.
- *
- * @see AppSearchSession#put
- * @see AppSearchSession#getByDocumentId
- * @see AppSearchSession#search
- */
-public class GenericDocument {
-    private static final String TAG = "AppSearchGenericDocumen";
-
-    /** The maximum number of indexed properties a document can have. */
-    private static final int MAX_INDEXED_PROPERTIES = 16;
-
-    /** The default score of document. */
-    private static final int DEFAULT_SCORE = 0;
-
-    /** The default time-to-live in millisecond of a document, which is infinity. */
-    private static final long DEFAULT_TTL_MILLIS = 0L;
-
-    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 ID_FIELD = "id";
-    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.
-     *
-     * <p>Indexed properties are properties which are strings where the {@link
-     * AppSearchSchema.StringPropertyConfig#getIndexingType} value is anything other than {@link
-     * AppSearchSchema.StringPropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
-     */
-    public static int getMaxIndexedProperties() {
-        return MAX_INDEXED_PROPERTIES;
-    }
-
-    /**
-     * Contains all {@link GenericDocument} information in a packaged format.
-     *
-     * <p>Keys are the {@code *_FIELD} constants in this class.
-     */
-    @NonNull final Bundle mBundle;
-
-    /** Contains all properties in {@link GenericDocument} to support getting properties via name */
-    @NonNull private final Bundle mProperties;
-
-    @NonNull private final String mId;
-    @NonNull private final String mSchemaType;
-    private final long mCreationTimestampMillis;
-    @Nullable private Integer mHashCode;
-
-    /**
-     * Rebuilds a {@link GenericDocument} from a bundle.
-     *
-     * @param bundle Packaged {@link GenericDocument} data, such as the result of {@link
-     *     #getBundle}.
-     * @hide
-     */
-    public GenericDocument(@NonNull Bundle bundle) {
-        Objects.requireNonNull(bundle);
-        mBundle = bundle;
-        mProperties = Objects.requireNonNull(bundle.getParcelable(PROPERTIES_FIELD));
-        mId = Objects.requireNonNull(mBundle.getString(ID_FIELD));
-        mSchemaType = Objects.requireNonNull(mBundle.getString(SCHEMA_TYPE_FIELD));
-        mCreationTimestampMillis =
-                mBundle.getLong(CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
-    }
-
-    /**
-     * Creates a new {@link GenericDocument} from an existing instance.
-     *
-     * <p>This method should be only used by constructor of a subclass.
-     */
-    protected GenericDocument(@NonNull GenericDocument document) {
-        this(document.mBundle);
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /** Returns the unique identifier of the {@link GenericDocument}. */
-    @NonNull
-    public String getId() {
-        return mId;
-    }
-
-    /** Returns the namespace of the {@link GenericDocument}. */
-    @NonNull
-    public String getNamespace() {
-        return mBundle.getString(NAMESPACE_FIELD, /*defaultValue=*/ "");
-    }
-
-    /** Returns the {@link AppSearchSchema} type of the {@link GenericDocument}. */
-    @NonNull
-    public String getSchemaType() {
-        return mSchemaType;
-    }
-
-    /**
-     * Returns the creation timestamp of the {@link GenericDocument}, in milliseconds.
-     *
-     * <p>The value is in the {@link System#currentTimeMillis} time base.
-     */
-    @CurrentTimeMillisLong
-    public long getCreationTimestampMillis() {
-        return mCreationTimestampMillis;
-    }
-
-    /**
-     * Returns the TTL (time-to-live) of the {@link GenericDocument}, in milliseconds.
-     *
-     * <p>The TTL is measured against {@link #getCreationTimestampMillis}. At the timestamp of
-     * {@code creationTimestampMillis + ttlMillis}, measured in the {@link System#currentTimeMillis}
-     * time base, the document will be auto-deleted.
-     *
-     * <p>The default value is 0, which means the document is permanent and won't be auto-deleted
-     * until the app is uninstalled or {@link AppSearchSession#remove} is called.
-     */
-    public long getTtlMillis() {
-        return mBundle.getLong(TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
-    }
-
-    /**
-     * Returns the score of the {@link GenericDocument}.
-     *
-     * <p>The score is a query-independent measure of the document's quality, relative to other
-     * {@link GenericDocument} objects of the same {@link AppSearchSchema} type.
-     *
-     * <p>Results may be sorted by score using {@link SearchSpec.Builder#setRankingStrategy}.
-     * Documents with higher scores are considered better than documents with lower scores.
-     *
-     * <p>Any non-negative integer can be used a score.
-     */
-    public int getScore() {
-        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 the property value with the given path as {@link Object}.
-     *
-     * <p>A path can be a simple property name, such as those returned by {@link #getPropertyNames}.
-     * It may also be a dot-delimited path through the nested document hierarchy, with nested {@link
-     * GenericDocument} properties accessed via {@code '.'} and repeated properties optionally
-     * indexed into via {@code [n]}.
-     *
-     * <p>For example, given the following {@link GenericDocument}:
-     *
-     * <pre>
-     *     (Message) {
-     *         from: "sender@example.com"
-     *         to: [{
-     *             name: "Albert Einstein"
-     *             email: "einstein@example.com"
-     *           }, {
-     *             name: "Marie Curie"
-     *             email: "curie@example.com"
-     *           }]
-     *         tags: ["important", "inbox"]
-     *         subject: "Hello"
-     *     }
-     * </pre>
-     *
-     * <p>Here are some example paths and their results:
-     *
-     * <ul>
-     *   <li>{@code "from"} returns {@code "sender@example.com"} as a {@link String} array with one
-     *       element
-     *   <li>{@code "to"} returns the two nested documents containing contact information as a
-     *       {@link GenericDocument} array with two elements
-     *   <li>{@code "to[1]"} returns the second nested document containing Marie Curie's contact
-     *       information as a {@link GenericDocument} array with one element
-     *   <li>{@code "to[1].email"} returns {@code "curie@example.com"}
-     *   <li>{@code "to[100].email"} returns {@code null} as this particular document does not have
-     *       that many elements in its {@code "to"} array.
-     *   <li>{@code "to.email"} aggregates emails across all nested documents that have them,
-     *       returning {@code ["einstein@example.com", "curie@example.com"]} as a {@link String}
-     *       array with two elements.
-     * </ul>
-     *
-     * <p>If you know the expected type of the property you are retrieving, it is recommended to use
-     * one of the typed versions of this method instead, such as {@link #getPropertyString} or
-     * {@link #getPropertyStringArray}.
-     *
-     * @param path The path to look for.
-     * @return The entry with the given path as an object or {@code null} if there is no such path.
-     *     The returned object will be one of the following types: {@code String[]}, {@code long[]},
-     *     {@code double[]}, {@code boolean[]}, {@code byte[][]}, {@code GenericDocument[]}.
-     */
-    @Nullable
-    public Object getProperty(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object rawValue = getRawPropertyFromRawDocument(path, mBundle);
-
-        // Unpack the raw value into the types the user expects, if required.
-        if (rawValue instanceof Bundle) {
-            // getRawPropertyFromRawDocument may return a document as a bare Bundle as a performance
-            // optimization for lookups.
-            GenericDocument document = new GenericDocument((Bundle) rawValue);
-            return new GenericDocument[] {document};
-        }
-
-        if (rawValue instanceof List) {
-            // byte[][] fields are packed into List<Bundle> where each Bundle contains just a single
-            // entry: BYTE_ARRAY_FIELD -> byte[].
-            @SuppressWarnings("unchecked")
-            List<Bundle> bundles = (List<Bundle>) rawValue;
-            if (bundles.size() == 0) {
-                return null;
-            }
-            byte[][] bytes = new byte[bundles.size()][];
-            for (int i = 0; i < bundles.size(); i++) {
-                Bundle bundle = bundles.get(i);
-                if (bundle == null) {
-                    Log.e(TAG, "The inner bundle is null at " + i + ", for path: " + path);
-                    continue;
-                }
-                byte[] innerBytes = bundle.getByteArray(BYTE_ARRAY_FIELD);
-                if (innerBytes == null) {
-                    Log.e(TAG, "The bundle at " + i + " contains a null byte[].");
-                    continue;
-                }
-                bytes[i] = innerBytes;
-            }
-            return bytes;
-        }
-
-        if (rawValue instanceof Parcelable[]) {
-            // The underlying Bundle of nested GenericDocuments is packed into a Parcelable array.
-            // We must unpack it into GenericDocument instances.
-            Parcelable[] bundles = (Parcelable[]) rawValue;
-            if (bundles.length == 0) {
-                return null;
-            }
-            GenericDocument[] documents = new GenericDocument[bundles.length];
-            for (int i = 0; i < bundles.length; i++) {
-                if (bundles[i] == null) {
-                    Log.e(TAG, "The inner bundle is null at " + i + ", for path: " + path);
-                    continue;
-                }
-                if (!(bundles[i] instanceof Bundle)) {
-                    Log.e(
-                            TAG,
-                            "The inner element at "
-                                    + i
-                                    + " is a "
-                                    + bundles[i].getClass()
-                                    + ", not a Bundle for path: "
-                                    + path);
-                    continue;
-                }
-                documents[i] = new GenericDocument((Bundle) bundles[i]);
-            }
-            return documents;
-        }
-
-        // Otherwise the raw property is the same as the final property and needs no transformation.
-        return rawValue;
-    }
-
-    /**
-     * Looks up a property path within the given document bundle.
-     *
-     * <p>The return value may be any of GenericDocument's internal repeated storage types
-     * (String[], long[], double[], boolean[], ArrayList&lt;Bundle&gt;, Parcelable[]).
-     */
-    @Nullable
-    private static Object getRawPropertyFromRawDocument(
-            @NonNull String path, @NonNull Bundle documentBundle) {
-        Objects.requireNonNull(path);
-        Objects.requireNonNull(documentBundle);
-        Bundle properties = Objects.requireNonNull(documentBundle.getBundle(PROPERTIES_FIELD));
-
-        // Determine whether the path is just a raw property name with no control characters
-        int controlIdx = -1;
-        boolean controlIsIndex = false;
-        for (int i = 0; i < path.length(); i++) {
-            char c = path.charAt(i);
-            if (c == '[' || c == '.') {
-                controlIdx = i;
-                controlIsIndex = c == '[';
-                break;
-            }
-        }
-
-        // Look up the value of the first path element
-        Object firstElementValue;
-        if (controlIdx == -1) {
-            firstElementValue = properties.get(path);
-        } else {
-            String name = path.substring(0, controlIdx);
-            firstElementValue = properties.get(name);
-        }
-
-        // If the path has no further elements, we're done.
-        if (firstElementValue == null || controlIdx == -1) {
-            return firstElementValue;
-        }
-
-        // At this point, for a path like "recipients[0]", firstElementValue contains the value of
-        // "recipients". If the first element of the path is an indexed value, we now update
-        // firstElementValue to contain "recipients[0]" instead.
-        String remainingPath;
-        if (!controlIsIndex) {
-            // Remaining path is everything after the .
-            remainingPath = path.substring(controlIdx + 1);
-        } else {
-            int endBracketIdx = path.indexOf(']', controlIdx);
-            if (endBracketIdx == -1) {
-                throw new IllegalArgumentException("Malformed path (no ending ']'): " + path);
-            }
-            if (endBracketIdx + 1 < path.length() && path.charAt(endBracketIdx + 1) != '.') {
-                throw new IllegalArgumentException(
-                        "Malformed path (']' not followed by '.'): " + path);
-            }
-            String indexStr = path.substring(controlIdx + 1, endBracketIdx);
-            int index = Integer.parseInt(indexStr);
-            if (index < 0) {
-                throw new IllegalArgumentException("Path index less than 0: " + path);
-            }
-
-            // Remaining path is everything after the [n]
-            if (endBracketIdx + 1 < path.length()) {
-                // More path remains, and we've already checked that charAt(endBracketIdx+1) == .
-                remainingPath = path.substring(endBracketIdx + 2);
-            } else {
-                // No more path remains.
-                remainingPath = null;
-            }
-
-            // Extract the right array element
-            Object extractedValue = null;
-            if (firstElementValue instanceof String[]) {
-                String[] stringValues = (String[]) firstElementValue;
-                if (index < stringValues.length) {
-                    extractedValue = Arrays.copyOfRange(stringValues, index, index + 1);
-                }
-            } else if (firstElementValue instanceof long[]) {
-                long[] longValues = (long[]) firstElementValue;
-                if (index < longValues.length) {
-                    extractedValue = Arrays.copyOfRange(longValues, index, index + 1);
-                }
-            } else if (firstElementValue instanceof double[]) {
-                double[] doubleValues = (double[]) firstElementValue;
-                if (index < doubleValues.length) {
-                    extractedValue = Arrays.copyOfRange(doubleValues, index, index + 1);
-                }
-            } else if (firstElementValue instanceof boolean[]) {
-                boolean[] booleanValues = (boolean[]) firstElementValue;
-                if (index < booleanValues.length) {
-                    extractedValue = Arrays.copyOfRange(booleanValues, index, index + 1);
-                }
-            } else if (firstElementValue instanceof List) {
-                @SuppressWarnings("unchecked")
-                List<Bundle> bundles = (List<Bundle>) firstElementValue;
-                if (index < bundles.size()) {
-                    extractedValue = bundles.subList(index, index + 1);
-                }
-            } else if (firstElementValue instanceof Parcelable[]) {
-                // Special optimization: to avoid creating new singleton arrays for traversing paths
-                // we return the bare document Bundle in this particular case.
-                Parcelable[] bundles = (Parcelable[]) firstElementValue;
-                if (index < bundles.length) {
-                    extractedValue = (Bundle) bundles[index];
-                }
-            } else {
-                throw new IllegalStateException("Unsupported value type: " + firstElementValue);
-            }
-            firstElementValue = extractedValue;
-        }
-
-        // If we are at the end of the path or there are no deeper elements in this document, we
-        // have nothing to recurse into.
-        if (firstElementValue == null || remainingPath == null) {
-            return firstElementValue;
-        }
-
-        // More of the path remains; recursively evaluate it
-        if (firstElementValue instanceof Bundle) {
-            return getRawPropertyFromRawDocument(remainingPath, (Bundle) firstElementValue);
-        } else if (firstElementValue instanceof Parcelable[]) {
-            Parcelable[] parcelables = (Parcelable[]) firstElementValue;
-            if (parcelables.length == 1) {
-                return getRawPropertyFromRawDocument(remainingPath, (Bundle) parcelables[0]);
-            }
-
-            // Slowest path: we're collecting values across repeated nested docs. (Example: given a
-            // path like recipient.name, where recipient is a repeated field, we return a string
-            // array where each recipient's name is an array element).
-            //
-            // Performance note: Suppose that we have a property path "a.b.c" where the "a"
-            // property has N document values and each containing a "b" property with M document
-            // values and each of those containing a "c" property with an int array.
-            //
-            // We'll allocate a new ArrayList for each of the "b" properties, add the M int arrays
-            // from the "c" properties to it and then we'll allocate an int array in
-            // flattenAccumulator before returning that (1 + M allocation per "b" property).
-            //
-            // When we're on the "a" properties, we'll allocate an ArrayList and add the N
-            // flattened int arrays returned from the "b" properties to the list. Then we'll
-            // allocate an int array in flattenAccumulator (1 + N ("b" allocs) allocations per "a").
-            // So this implementation could incur 1 + N + NM allocs.
-            //
-            // However, we expect the vast majority of getProperty calls to be either for direct
-            // property names (not paths) or else property paths returned from snippetting, which
-            // always refer to exactly one property value and don't aggregate across repeated
-            // values. The implementation is optimized for these two cases, requiring no additional
-            // allocations. So we've decided that the above performance characteristics are OK for
-            // the less used path.
-            List<Object> accumulator = new ArrayList<>(parcelables.length);
-            for (int i = 0; i < parcelables.length; i++) {
-                Object value =
-                        getRawPropertyFromRawDocument(remainingPath, (Bundle) parcelables[i]);
-                if (value != null) {
-                    accumulator.add(value);
-                }
-            }
-            return flattenAccumulator(accumulator);
-        } else {
-            Log.e(TAG, "Failed to apply path to document; no nested value found: " + path);
-            return null;
-        }
-    }
-
-    /**
-     * Combines accumulated repeated properties from multiple documents into a single array.
-     *
-     * @param accumulator List containing objects of the following types: {@code String[]}, {@code
-     *     long[]}, {@code double[]}, {@code boolean[]}, {@code List<Bundle>}, or {@code
-     *     Parcelable[]}.
-     * @return The result of concatenating each individual list element into a larger array/list of
-     *     the same type.
-     */
-    @Nullable
-    private static Object flattenAccumulator(@NonNull List<Object> accumulator) {
-        if (accumulator.isEmpty()) {
-            return null;
-        }
-        Object first = accumulator.get(0);
-        if (first instanceof String[]) {
-            int length = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                length += ((String[]) accumulator.get(i)).length;
-            }
-            String[] result = new String[length];
-            int total = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                String[] castValue = (String[]) accumulator.get(i);
-                System.arraycopy(castValue, 0, result, total, castValue.length);
-                total += castValue.length;
-            }
-            return result;
-        }
-        if (first instanceof long[]) {
-            int length = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                length += ((long[]) accumulator.get(i)).length;
-            }
-            long[] result = new long[length];
-            int total = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                long[] castValue = (long[]) accumulator.get(i);
-                System.arraycopy(castValue, 0, result, total, castValue.length);
-                total += castValue.length;
-            }
-            return result;
-        }
-        if (first instanceof double[]) {
-            int length = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                length += ((double[]) accumulator.get(i)).length;
-            }
-            double[] result = new double[length];
-            int total = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                double[] castValue = (double[]) accumulator.get(i);
-                System.arraycopy(castValue, 0, result, total, castValue.length);
-                total += castValue.length;
-            }
-            return result;
-        }
-        if (first instanceof boolean[]) {
-            int length = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                length += ((boolean[]) accumulator.get(i)).length;
-            }
-            boolean[] result = new boolean[length];
-            int total = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                boolean[] castValue = (boolean[]) accumulator.get(i);
-                System.arraycopy(castValue, 0, result, total, castValue.length);
-                total += castValue.length;
-            }
-            return result;
-        }
-        if (first instanceof List) {
-            int length = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                length += ((List<?>) accumulator.get(i)).size();
-            }
-            List<Bundle> result = new ArrayList<>(length);
-            for (int i = 0; i < accumulator.size(); i++) {
-                @SuppressWarnings("unchecked")
-                List<Bundle> castValue = (List<Bundle>) accumulator.get(i);
-                result.addAll(castValue);
-            }
-            return result;
-        }
-        if (first instanceof Parcelable[]) {
-            int length = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                length += ((Parcelable[]) accumulator.get(i)).length;
-            }
-            Parcelable[] result = new Parcelable[length];
-            int total = 0;
-            for (int i = 0; i < accumulator.size(); i++) {
-                Parcelable[] castValue = (Parcelable[]) accumulator.get(i);
-                System.arraycopy(castValue, 0, result, total, castValue.length);
-                total += castValue.length;
-            }
-            return result;
-        }
-        throw new IllegalStateException("Unexpected property type: " + first);
-    }
-
-    /**
-     * Retrieves a {@link String} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The first {@link String} associated with the given path or {@code null} if there is
-     *     no such value or the value is of a different type.
-     */
-    @Nullable
-    public String getPropertyString(@NonNull String path) {
-        Objects.requireNonNull(path);
-        String[] propertyArray = getPropertyStringArray(path);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return null;
-        }
-        warnIfSinglePropertyTooLong("String", path, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code long} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The first {@code long} associated with the given path or default value {@code 0} if
-     *     there is no such value or the value is of a different type.
-     */
-    public long getPropertyLong(@NonNull String path) {
-        Objects.requireNonNull(path);
-        long[] propertyArray = getPropertyLongArray(path);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return 0;
-        }
-        warnIfSinglePropertyTooLong("Long", path, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code double} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The first {@code double} associated with the given path or default value {@code 0.0}
-     *     if there is no such value or the value is of a different type.
-     */
-    public double getPropertyDouble(@NonNull String path) {
-        Objects.requireNonNull(path);
-        double[] propertyArray = getPropertyDoubleArray(path);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return 0.0;
-        }
-        warnIfSinglePropertyTooLong("Double", path, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code boolean} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The first {@code boolean} associated with the given path or default value {@code
-     *     false} if there is no such value or the value is of a different type.
-     */
-    public boolean getPropertyBoolean(@NonNull String path) {
-        Objects.requireNonNull(path);
-        boolean[] propertyArray = getPropertyBooleanArray(path);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return false;
-        }
-        warnIfSinglePropertyTooLong("Boolean", path, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code byte[]} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The first {@code byte[]} associated with the given path or {@code null} if there is
-     *     no such value or the value is of a different type.
-     */
-    @Nullable
-    public byte[] getPropertyBytes(@NonNull String path) {
-        Objects.requireNonNull(path);
-        byte[][] propertyArray = getPropertyBytesArray(path);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return null;
-        }
-        warnIfSinglePropertyTooLong("ByteArray", path, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@link GenericDocument} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The first {@link GenericDocument} associated with the given path or {@code null} if
-     *     there is no such value or the value is of a different type.
-     */
-    @Nullable
-    public GenericDocument getPropertyDocument(@NonNull String path) {
-        Objects.requireNonNull(path);
-        GenericDocument[] propertyArray = getPropertyDocumentArray(path);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return null;
-        }
-        warnIfSinglePropertyTooLong("Document", path, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /** Prints a warning to logcat if the given propertyLength is greater than 1. */
-    private static void warnIfSinglePropertyTooLong(
-            @NonNull String propertyType, @NonNull String path, int propertyLength) {
-        if (propertyLength > 1) {
-            Log.w(
-                    TAG,
-                    "The value for \""
-                            + path
-                            + "\" contains "
-                            + propertyLength
-                            + " elements. Only the first one will be returned from "
-                            + "getProperty"
-                            + propertyType
-                            + "(). Try getProperty"
-                            + propertyType
-                            + "Array().");
-        }
-    }
-
-    /**
-     * Retrieves a repeated {@code String} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The {@code String[]} associated with the given path, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @Nullable
-    public String[] getPropertyStringArray(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object value = getProperty(path);
-        return safeCastProperty(path, value, String[].class);
-    }
-
-    /**
-     * Retrieves a repeated {@code long[]} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The {@code long[]} associated with the given path, or {@code null} if no value is set
-     *     or the value is of a different type.
-     */
-    @Nullable
-    public long[] getPropertyLongArray(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object value = getProperty(path);
-        return safeCastProperty(path, value, long[].class);
-    }
-
-    /**
-     * Retrieves a repeated {@code double} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The {@code double[]} associated with the given path, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @Nullable
-    public double[] getPropertyDoubleArray(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object value = getProperty(path);
-        return safeCastProperty(path, value, double[].class);
-    }
-
-    /**
-     * Retrieves a repeated {@code boolean} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The {@code boolean[]} associated with the given path, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @Nullable
-    public boolean[] getPropertyBooleanArray(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object value = getProperty(path);
-        return safeCastProperty(path, value, boolean[].class);
-    }
-
-    /**
-     * Retrieves a {@code byte[][]} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The {@code byte[][]} associated with the given path, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @SuppressLint("ArrayReturn")
-    @Nullable
-    public byte[][] getPropertyBytesArray(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object value = getProperty(path);
-        return safeCastProperty(path, value, byte[][].class);
-    }
-
-    /**
-     * Retrieves a repeated {@link GenericDocument} property by path.
-     *
-     * <p>See {@link #getProperty} for a detailed description of the path syntax.
-     *
-     * @param path The path to look for.
-     * @return The {@link GenericDocument}[] associated with the given path, or {@code null} if no
-     *     value is set or the value is of a different type.
-     */
-    @SuppressLint("ArrayReturn")
-    @Nullable
-    public GenericDocument[] getPropertyDocumentArray(@NonNull String path) {
-        Objects.requireNonNull(path);
-        Object value = getProperty(path);
-        return safeCastProperty(path, value, GenericDocument[].class);
-    }
-
-    /**
-     * Casts a repeated property to the provided type, logging an error and returning {@code null}
-     * if the cast fails.
-     *
-     * @param path Path to the property within the document. Used for logging.
-     * @param value Value of the property
-     * @param tClass Class to cast the value into
-     */
-    @Nullable
-    private static <T> T safeCastProperty(
-            @NonNull String path, @Nullable Object value, @NonNull Class<T> tClass) {
-        if (value == null) {
-            return null;
-        }
-        try {
-            return tClass.cast(value);
-        } catch (ClassCastException e) {
-            Log.w(TAG, "Error casting to requested type for path \"" + path + "\"", e);
-            return null;
-        }
-    }
-
-    /**
-     * Copies the contents of this {@link GenericDocument} into a new {@link
-     * GenericDocument.Builder}.
-     *
-     * <p>The returned builder is a deep copy whose data is separate from this document.
-     *
-     * @hide
-     */
-    // TODO(b/171882200): Expose this API in Android T
-    @NonNull
-    public GenericDocument.Builder<GenericDocument.Builder<?>> toBuilder() {
-        Bundle clonedBundle = BundleUtil.deepCopy(mBundle);
-        return new GenericDocument.Builder<>(clonedBundle);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object other) {
-        if (this == other) {
-            return true;
-        }
-        if (!(other instanceof GenericDocument)) {
-            return false;
-        }
-        GenericDocument otherDocument = (GenericDocument) other;
-        return BundleUtil.deepEquals(this.mBundle, otherDocument.mBundle);
-    }
-
-    @Override
-    public int hashCode() {
-        if (mHashCode == null) {
-            mHashCode = BundleUtil.deepHashCode(mBundle);
-        }
-        return mHashCode;
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-        appendGenericDocumentString(stringBuilder);
-        return stringBuilder.toString();
-    }
-
-    /**
-     * Appends a debug string for the {@link GenericDocument} instance to the given string builder.
-     *
-     * @param builder the builder to append to.
-     */
-    void appendGenericDocumentString(@NonNull IndentingStringBuilder builder) {
-        Objects.requireNonNull(builder);
-
-        builder.append("{\n");
-        builder.increaseIndentLevel();
-
-        builder.append("namespace: \"").append(getNamespace()).append("\",\n");
-        builder.append("id: \"").append(getId()).append("\",\n");
-        builder.append("score: ").append(getScore()).append(",\n");
-        builder.append("schemaType: \"").append(getSchemaType()).append("\",\n");
-        builder.append("creationTimestampMillis: ")
-                .append(getCreationTimestampMillis())
-                .append(",\n");
-        builder.append("timeToLiveMillis: ").append(getTtlMillis()).append(",\n");
-
-        builder.append("properties: {\n");
-
-        String[] sortedProperties = getPropertyNames().toArray(new String[0]);
-        Arrays.sort(sortedProperties);
-
-        for (int i = 0; i < sortedProperties.length; i++) {
-            Object property = getProperty(sortedProperties[i]);
-            builder.increaseIndentLevel();
-            appendPropertyString(sortedProperties[i], property, builder);
-            if (i != sortedProperties.length - 1) {
-                builder.append(",\n");
-            }
-            builder.decreaseIndentLevel();
-        }
-
-        builder.append("\n");
-        builder.append("}");
-
-        builder.decreaseIndentLevel();
-        builder.append("\n");
-        builder.append("}");
-    }
-
-    /**
-     * Appends a debug string for the given document property to the given string builder.
-     *
-     * @param propertyName name of property to create string for.
-     * @param property property object to create string for.
-     * @param builder the builder to append to.
-     */
-    private void appendPropertyString(
-            @NonNull String propertyName,
-            @NonNull Object property,
-            @NonNull IndentingStringBuilder builder) {
-        Objects.requireNonNull(propertyName);
-        Objects.requireNonNull(property);
-        Objects.requireNonNull(builder);
-
-        builder.append("\"").append(propertyName).append("\": [");
-        if (property instanceof GenericDocument[]) {
-            GenericDocument[] documentValues = (GenericDocument[]) property;
-            for (int i = 0; i < documentValues.length; ++i) {
-                builder.append("\n");
-                builder.increaseIndentLevel();
-                documentValues[i].appendGenericDocumentString(builder);
-                if (i != documentValues.length - 1) {
-                    builder.append(",");
-                }
-                builder.append("\n");
-                builder.decreaseIndentLevel();
-            }
-            builder.append("]");
-        } else {
-            int propertyArrLength = Array.getLength(property);
-            for (int i = 0; i < propertyArrLength; i++) {
-                Object propertyElement = Array.get(property, i);
-                if (propertyElement instanceof String) {
-                    builder.append("\"").append((String) propertyElement).append("\"");
-                } else if (propertyElement instanceof byte[]) {
-                    builder.append(Arrays.toString((byte[]) propertyElement));
-                } else {
-                    builder.append(propertyElement.toString());
-                }
-                if (i != propertyArrLength - 1) {
-                    builder.append(", ");
-                } else {
-                    builder.append("]");
-                }
-            }
-        }
-    }
-
-    /**
-     * The builder class for {@link GenericDocument}.
-     *
-     * @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 Bundle mBundle;
-        private Bundle mProperties;
-        private final BuilderType mBuilderTypeInstance;
-        private boolean mBuilt = false;
-
-        /**
-         * Creates a new {@link GenericDocument.Builder}.
-         *
-         * <p>Document IDs are unique within a namespace.
-         *
-         * <p>The number of namespaces per app should be kept small for efficiency reasons.
-         *
-         * @param namespace the namespace to set for the {@link GenericDocument}.
-         * @param id the unique identifier for the {@link GenericDocument} in its namespace.
-         * @param schemaType the {@link AppSearchSchema} type of the {@link GenericDocument}. The
-         *     provided {@code schemaType} must be defined using {@link AppSearchSession#setSchema}
-         *     prior to inserting a document of this {@code schemaType} into the AppSearch index
-         *     using {@link AppSearchSession#put}. Otherwise, the document will be rejected by
-         *     {@link AppSearchSession#put} with result code {@link
-         *     AppSearchResult#RESULT_NOT_FOUND}.
-         */
-        @SuppressWarnings("unchecked")
-        public Builder(@NonNull String namespace, @NonNull String id, @NonNull String schemaType) {
-            Objects.requireNonNull(namespace);
-            Objects.requireNonNull(id);
-            Objects.requireNonNull(schemaType);
-
-            mBundle = new Bundle();
-            mBuilderTypeInstance = (BuilderType) this;
-            mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
-            mBundle.putString(GenericDocument.ID_FIELD, id);
-            mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
-            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
-            mBundle.putInt(GenericDocument.SCORE_FIELD, DEFAULT_SCORE);
-
-            mProperties = new Bundle();
-            mBundle.putBundle(PROPERTIES_FIELD, mProperties);
-        }
-
-        /**
-         * Creates a new {@link GenericDocument.Builder} from the given Bundle.
-         *
-         * <p>The bundle is NOT copied.
-         */
-        @SuppressWarnings("unchecked")
-        Builder(@NonNull Bundle bundle) {
-            mBundle = Objects.requireNonNull(bundle);
-            mProperties = mBundle.getBundle(PROPERTIES_FIELD);
-            mBuilderTypeInstance = (BuilderType) this;
-        }
-
-        /**
-         * Sets the app-defined namespace this document resides in, changing the value provided in
-         * the constructor. No special values are reserved or understood by the infrastructure.
-         *
-         * <p>Document IDs are unique within a namespace.
-         *
-         * <p>The number of namespaces per app should be kept small for efficiency reasons.
-         *
-         * @hide
-         */
-        @NonNull
-        public BuilderType setNamespace(@NonNull String namespace) {
-            Objects.requireNonNull(namespace);
-            resetIfBuilt();
-            mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the ID of this document, changing the value provided in the constructor. No special
-         * values are reserved or understood by the infrastructure.
-         *
-         * <p>Document IDs are unique within a namespace.
-         *
-         * @hide
-         */
-        @NonNull
-        public BuilderType setId(@NonNull String id) {
-            Objects.requireNonNull(id);
-            resetIfBuilt();
-            mBundle.putString(GenericDocument.ID_FIELD, id);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the schema type of this document, changing the value provided in the constructor.
-         *
-         * <p>To successfully index a document, the schema type must match the name of an {@link
-         * AppSearchSchema} object previously provided to {@link AppSearchSession#setSchema}.
-         *
-         * @hide
-         */
-        @NonNull
-        public BuilderType setSchemaType(@NonNull String schemaType) {
-            Objects.requireNonNull(schemaType);
-            resetIfBuilt();
-            mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the score of the {@link GenericDocument}.
-         *
-         * <p>The score is a query-independent measure of the document's quality, relative to other
-         * {@link GenericDocument} objects of the same {@link AppSearchSchema} type.
-         *
-         * <p>Results may be sorted by score using {@link SearchSpec.Builder#setRankingStrategy}.
-         * Documents with higher scores are considered better than documents with lower scores.
-         *
-         * <p>Any non-negative integer can be used a score. By default, scores are set to 0.
-         *
-         * @param score any non-negative {@code int} representing the document's score.
-         */
-        @NonNull
-        public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) {
-            if (score < 0) {
-                throw new IllegalArgumentException("Document score cannot be negative.");
-            }
-            resetIfBuilt();
-            mBundle.putInt(GenericDocument.SCORE_FIELD, score);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the creation timestamp of the {@link GenericDocument}, in milliseconds.
-         *
-         * <p>This should be set using a value obtained from the {@link System#currentTimeMillis}
-         * time base.
-         *
-         * <p>If this method is not called, this will be set to the time the object is built.
-         *
-         * @param creationTimestampMillis a creation timestamp in milliseconds.
-         */
-        @NonNull
-        public BuilderType setCreationTimestampMillis(
-                @CurrentTimeMillisLong long creationTimestampMillis) {
-            resetIfBuilt();
-            mBundle.putLong(
-                    GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, creationTimestampMillis);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the TTL (time-to-live) of the {@link GenericDocument}, in milliseconds.
-         *
-         * <p>The TTL is measured against {@link #getCreationTimestampMillis}. At the timestamp of
-         * {@code creationTimestampMillis + ttlMillis}, measured in the {@link
-         * System#currentTimeMillis} time base, the document will be auto-deleted.
-         *
-         * <p>The default value is 0, which means the document is permanent and won't be
-         * auto-deleted until the app is uninstalled or {@link AppSearchSession#remove} is called.
-         *
-         * @param ttlMillis a non-negative duration in milliseconds.
-         */
-        @NonNull
-        public BuilderType setTtlMillis(long ttlMillis) {
-            if (ttlMillis < 0) {
-                throw new IllegalArgumentException("Document ttlMillis cannot be negative.");
-            }
-            resetIfBuilt();
-            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, ttlMillis);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code String} values for a property, replacing its previous values.
-         *
-         * @param name the name associated with the {@code values}. Must match the name for this
-         *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
-         * @param values the {@code String} values of the property.
-         * @throws IllegalArgumentException if no values are provided, or if a passed in {@code
-         *     String} is {@code null}.
-         */
-        @NonNull
-        public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
-            Objects.requireNonNull(name);
-            Objects.requireNonNull(values);
-            resetIfBuilt();
-            putInPropertyBundle(name, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code boolean} values for a property, replacing its previous
-         * values.
-         *
-         * @param name the name associated with the {@code values}. Must match the name for this
-         *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
-         * @param values the {@code boolean} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
-            Objects.requireNonNull(name);
-            Objects.requireNonNull(values);
-            resetIfBuilt();
-            putInPropertyBundle(name, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code long} values for a property, replacing its previous values.
-         *
-         * @param name the name associated with the {@code values}. Must match the name for this
-         *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
-         * @param values the {@code long} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
-            Objects.requireNonNull(name);
-            Objects.requireNonNull(values);
-            resetIfBuilt();
-            putInPropertyBundle(name, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code double} values for a property, replacing its previous values.
-         *
-         * @param name the name associated with the {@code values}. Must match the name for this
-         *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
-         * @param values the {@code double} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
-            Objects.requireNonNull(name);
-            Objects.requireNonNull(values);
-            resetIfBuilt();
-            putInPropertyBundle(name, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code byte[]} for a property, replacing its previous values.
-         *
-         * @param name the name associated with the {@code values}. Must match the name for this
-         *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
-         * @param values the {@code byte[]} of the property.
-         * @throws IllegalArgumentException if no values are provided, or if a passed in {@code
-         *     byte[]} is {@code null}.
-         */
-        @NonNull
-        public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
-            Objects.requireNonNull(name);
-            Objects.requireNonNull(values);
-            resetIfBuilt();
-            putInPropertyBundle(name, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@link GenericDocument} values for a property, replacing its
-         * previous values.
-         *
-         * @param name the name associated with the {@code values}. Must match the name for this
-         *     property as given in {@link AppSearchSchema.PropertyConfig#getName}.
-         * @param values the {@link GenericDocument} values of the property.
-         * @throws IllegalArgumentException if no values are provided, or if a passed in {@link
-         *     GenericDocument} is {@code null}.
-         */
-        @NonNull
-        public BuilderType setPropertyDocument(
-                @NonNull String name, @NonNull GenericDocument... values) {
-            Objects.requireNonNull(name);
-            Objects.requireNonNull(values);
-            resetIfBuilt();
-            putInPropertyBundle(name, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Clears the value for the property with the given name.
-         *
-         * <p>Note that this method does not support property paths.
-         *
-         * @param name The name of the property to clear.
-         * @hide
-         */
-        @NonNull
-        public BuilderType clearProperty(@NonNull String name) {
-            Objects.requireNonNull(name);
-            resetIfBuilt();
-            mProperties.remove(name);
-            return mBuilderTypeInstance;
-        }
-
-        private void putInPropertyBundle(@NonNull String name, @NonNull String[] values)
-                throws IllegalArgumentException {
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] == null) {
-                    throw new IllegalArgumentException("The String at " + i + " is null.");
-                }
-            }
-            mProperties.putStringArray(name, values);
-        }
-
-        private void putInPropertyBundle(@NonNull String name, @NonNull boolean[] values) {
-            mProperties.putBooleanArray(name, values);
-        }
-
-        private void putInPropertyBundle(@NonNull String name, @NonNull double[] values) {
-            mProperties.putDoubleArray(name, values);
-        }
-
-        private void putInPropertyBundle(@NonNull String name, @NonNull long[] values) {
-            mProperties.putLongArray(name, values);
-        }
-
-        /**
-         * Converts and saves a byte[][] into {@link #mProperties}.
-         *
-         * <p>Bundle doesn't support for two dimension array byte[][], we are converting byte[][]
-         * into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
-         */
-        private void putInPropertyBundle(@NonNull String name, @NonNull byte[][] values) {
-            ArrayList<Bundle> bundles = new ArrayList<>(values.length);
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] == null) {
-                    throw new IllegalArgumentException("The byte[] at " + i + " is null.");
-                }
-                Bundle bundle = new Bundle();
-                bundle.putByteArray(BYTE_ARRAY_FIELD, values[i]);
-                bundles.add(bundle);
-            }
-            mProperties.putParcelableArrayList(name, bundles);
-        }
-
-        private void putInPropertyBundle(@NonNull String name, @NonNull GenericDocument[] values) {
-            Parcelable[] documentBundles = new Parcelable[values.length];
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] == null) {
-                    throw new IllegalArgumentException("The document at " + i + " is null.");
-                }
-                documentBundles[i] = values[i].mBundle;
-            }
-            mProperties.putParcelableArray(name, documentBundles);
-        }
-
-        /** Builds the {@link GenericDocument} object. */
-        @NonNull
-        public GenericDocument build() {
-            mBuilt = true;
-            // Set current timestamp for creation timestamp by default.
-            if (mBundle.getLong(GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, -1) == -1) {
-                mBundle.putLong(
-                        GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD,
-                        System.currentTimeMillis());
-            }
-            return new GenericDocument(mBundle);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mBundle = BundleUtil.deepCopy(mBundle);
-                mProperties = mBundle.getBundle(PROPERTIES_FIELD);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
deleted file mode 100644
index 558899e..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetByDocumentIdRequest.java
+++ /dev/null
@@ -1,181 +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 android.annotation.NonNull;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Encapsulates a request to retrieve documents by namespace and IDs from the {@link
- * AppSearchSession} database.
- *
- * @see AppSearchSession#getByDocumentId
- */
-public final class GetByDocumentIdRequest {
-    /**
-     * Schema type to be used in {@link GetByDocumentIdRequest.Builder#addProjection} to apply
-     * property paths to all results, excepting any types that have had their own, specific property
-     * paths set.
-     */
-    public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
-
-    private final String mNamespace;
-    private final Set<String> mIds;
-    private final Map<String, List<String>> mTypePropertyPathsMap;
-
-    GetByDocumentIdRequest(
-            @NonNull String namespace,
-            @NonNull Set<String> ids,
-            @NonNull Map<String, List<String>> typePropertyPathsMap) {
-        mNamespace = Objects.requireNonNull(namespace);
-        mIds = Objects.requireNonNull(ids);
-        mTypePropertyPathsMap = Objects.requireNonNull(typePropertyPathsMap);
-    }
-
-    /** Returns the namespace attached to the request. */
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    /** Returns the set of document IDs attached to the request. */
-    @NonNull
-    public Set<String> getIds() {
-        return Collections.unmodifiableSet(mIds);
-    }
-
-    /**
-     * Returns a map from schema type to property paths to be used for projection.
-     *
-     * <p>If the map is empty, then all properties will be retrieved for all results.
-     *
-     * <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned by this
-     * function, rather than calling it multiple times.
-     */
-    @NonNull
-    public Map<String, List<String>> getProjections() {
-        Map<String, List<String>> copy = new ArrayMap<>();
-        for (Map.Entry<String, List<String>> entry : mTypePropertyPathsMap.entrySet()) {
-            copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
-        }
-        return copy;
-    }
-
-    /**
-     * Returns a map from schema type to property paths to be used for projection.
-     *
-     * <p>If the map is empty, then all properties will be retrieved for all results.
-     *
-     * <p>A more efficient version of {@link #getProjections}, but it returns a modifiable map. This
-     * is not meant to be unhidden and should only be used by internal classes.
-     *
-     * @hide
-     */
-    @NonNull
-    public Map<String, List<String>> getProjectionsInternal() {
-        return mTypePropertyPathsMap;
-    }
-
-    /** Builder for {@link GetByDocumentIdRequest} objects. */
-    public static final class Builder {
-        private final String mNamespace;
-        private ArraySet<String> mIds = new ArraySet<>();
-        private ArrayMap<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
-        private boolean mBuilt = false;
-
-        /** Creates a {@link GetByDocumentIdRequest.Builder} instance. */
-        public Builder(@NonNull String namespace) {
-            mNamespace = Objects.requireNonNull(namespace);
-        }
-
-        /** Adds one or more document IDs to the request. */
-        @NonNull
-        public Builder addIds(@NonNull String... ids) {
-            Objects.requireNonNull(ids);
-            resetIfBuilt();
-            return addIds(Arrays.asList(ids));
-        }
-
-        /** Adds a collection of IDs to the request. */
-        @NonNull
-        public Builder addIds(@NonNull Collection<String> ids) {
-            Objects.requireNonNull(ids);
-            resetIfBuilt();
-            mIds.addAll(ids);
-            return this;
-        }
-
-        /**
-         * Adds property paths for the specified type to be used for projection. If property paths
-         * are added for a type, then only the properties referred to will be retrieved for results
-         * of that type. If a property path that is specified isn't present in a result, it will be
-         * ignored for that result. Property paths cannot be null.
-         *
-         * <p>If no property paths are added for a particular type, then all properties of results
-         * of that type will be retrieved.
-         *
-         * <p>If property path is added for the {@link
-         * GetByDocumentIdRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will
-         * apply to all results, excepting any types that have their own, specific property paths
-         * set.
-         *
-         * @see SearchSpec.Builder#addProjection
-         */
-        @NonNull
-        public Builder addProjection(
-                @NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
-            Objects.requireNonNull(schemaType);
-            Objects.requireNonNull(propertyPaths);
-            resetIfBuilt();
-            List<String> propertyPathsList = new ArrayList<>(propertyPaths.size());
-            for (String propertyPath : propertyPaths) {
-                Objects.requireNonNull(propertyPath);
-                propertyPathsList.add(propertyPath);
-            }
-            mProjectionTypePropertyPaths.put(schemaType, propertyPathsList);
-            return this;
-        }
-
-        /** Builds a new {@link GetByDocumentIdRequest}. */
-        @NonNull
-        public GetByDocumentIdRequest build() {
-            mBuilt = true;
-            return new GetByDocumentIdRequest(mNamespace, mIds, mProjectionTypePropertyPaths);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mIds = new ArraySet<>(mIds);
-                // No need to clone each propertyPathsList inside mProjectionTypePropertyPaths since
-                // the builder only replaces it, never adds to it. So even if the builder is used
-                // again, the previous one will remain with the object.
-                mProjectionTypePropertyPaths = new ArrayMap<>(mProjectionTypePropertyPaths);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
deleted file mode 100644
index 018f16d..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/GetSchemaResponse.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.os.Bundle;
-import android.util.ArraySet;
-
-import java.util.ArrayList;
-import java.util.Objects;
-import java.util.Set;
-
-/** The response class of {@link AppSearchSession#getSchema} */
-public final class GetSchemaResponse {
-    private static final String VERSION_FIELD = "version";
-    private static final String SCHEMAS_FIELD = "schemas";
-
-    private final Bundle mBundle;
-
-    GetSchemaResponse(@NonNull Bundle bundle) {
-        mBundle = Objects.requireNonNull(bundle);
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Returns the overall database schema version.
-     *
-     * <p>If the database is empty, 0 will be returned.
-     */
-    @IntRange(from = 0)
-    public int getVersion() {
-        return mBundle.getInt(VERSION_FIELD);
-    }
-
-    /**
-     * Return the schemas most recently successfully provided to {@link AppSearchSession#setSchema}.
-     *
-     * <p>It is inefficient to call this method repeatedly.
-     */
-    @NonNull
-    public Set<AppSearchSchema> getSchemas() {
-        ArrayList<Bundle> schemaBundles = mBundle.getParcelableArrayList(SCHEMAS_FIELD);
-        Set<AppSearchSchema> schemas = new ArraySet<>(schemaBundles.size());
-        for (int i = 0; i < schemaBundles.size(); i++) {
-            schemas.add(new AppSearchSchema(schemaBundles.get(i)));
-        }
-        return schemas;
-    }
-
-    /** Builder for {@link GetSchemaResponse} objects. */
-    public static final class Builder {
-        private int mVersion = 0;
-        private ArrayList<Bundle> mSchemaBundles = new ArrayList<>();
-        private boolean mBuilt = false;
-
-        /**
-         * Sets the database overall schema version.
-         *
-         * <p>Default version is 0
-         */
-        @NonNull
-        public Builder setVersion(@IntRange(from = 0) int version) {
-            resetIfBuilt();
-            mVersion = version;
-            return this;
-        }
-
-        /** Adds one {@link AppSearchSchema} to the schema list. */
-        @NonNull
-        public Builder addSchema(@NonNull AppSearchSchema schema) {
-            Objects.requireNonNull(schema);
-            resetIfBuilt();
-            mSchemaBundles.add(schema.getBundle());
-            return this;
-        }
-
-        /** Builds a {@link GetSchemaResponse} object. */
-        @NonNull
-        public GetSchemaResponse build() {
-            Bundle bundle = new Bundle();
-            bundle.putInt(VERSION_FIELD, mVersion);
-            bundle.putParcelableArrayList(SCHEMAS_FIELD, mSchemaBundles);
-            mBuilt = true;
-            return new GetSchemaResponse(bundle);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mSchemaBundles = new ArrayList<>(mSchemaBundles);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java b/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
deleted file mode 100644
index c5a0f63..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/Migrator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import android.annotation.NonNull;
-import android.annotation.WorkerThread;
-
-/**
- * A migrator class to translate {@link GenericDocument} from different version of {@link
- * AppSearchSchema}
- *
- * <p>Make non-backwards-compatible changes will delete all stored documents in old schema. You can
- * save your documents by setting {@link Migrator} via the {@link
- * SetSchemaRequest.Builder#setMigrator} for each type and target version you want to save.
- *
- * <p>{@link #onDowngrade} or {@link #onUpgrade} will be triggered if the version number of the
- * schema stored in AppSearch is different with the version in the request.
- *
- * <p>If any error or Exception occurred in the {@link #onDowngrade} or {@link #onUpgrade}, all the
- * setSchema request will be rejected unless the schema changes are backwards-compatible, and stored
- * documents won't have any observable changes.
- */
-public abstract class Migrator {
-    /**
-     * Returns {@code true} if this migrator's source type needs to be migrated to update from
-     * currentVersion to finalVersion.
-     *
-     * <p>Migration won't be triggered if currentVersion is equal to finalVersion even if {@link
-     * #shouldMigrate} return true;
-     */
-    public abstract boolean shouldMigrate(int currentVersion, int finalVersion);
-
-    /**
-     * Migrates {@link GenericDocument} to a newer version of {@link AppSearchSchema}.
-     *
-     * <p>This method will be invoked only if the {@link SetSchemaRequest} is setting a higher
-     * version number than the current {@link AppSearchSchema} saved in AppSearch.
-     *
-     * <p>If this {@link Migrator} is provided to cover a compatible schema change via {@link
-     * AppSearchSession#setSchema}, documents under the old version won't be removed unless you use
-     * the same document ID.
-     *
-     * <p>This method will be invoked on the background worker thread provided via {@link
-     * AppSearchSession#setSchema}.
-     *
-     * @param currentVersion The current version of the document's schema.
-     * @param finalVersion The final version that documents need to be migrated to.
-     * @param document The {@link GenericDocument} need to be translated to new version.
-     * @return A {@link GenericDocument} in new version.
-     */
-    @WorkerThread
-    @NonNull
-    public abstract GenericDocument onUpgrade(
-            int currentVersion, int finalVersion, @NonNull GenericDocument document);
-
-    /**
-     * Migrates {@link GenericDocument} to an older version of {@link AppSearchSchema}.
-     *
-     * <p>This method will be invoked only if the {@link SetSchemaRequest} is setting a lower
-     * version number than the current {@link AppSearchSchema} saved in AppSearch.
-     *
-     * <p>If this {@link Migrator} is provided to cover a compatible schema change via {@link
-     * AppSearchSession#setSchema}, documents under the old version won't be removed unless you use
-     * the same document ID.
-     *
-     * <p>This method will be invoked on the background worker thread.
-     *
-     * @param currentVersion The current version of the document's schema.
-     * @param finalVersion The final version that documents need to be migrated to.
-     * @param document The {@link GenericDocument} need to be translated to new version.
-     * @return A {@link GenericDocument} in new version.
-     */
-    @WorkerThread
-    @NonNull
-    public abstract GenericDocument onDowngrade(
-            int currentVersion, int finalVersion, @NonNull GenericDocument document);
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/PackageIdentifier.java b/apex/appsearch/framework/java/external/android/app/appsearch/PackageIdentifier.java
deleted file mode 100644
index 4f63bae..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/PackageIdentifier.java
+++ /dev/null
@@ -1,81 +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 android.annotation.NonNull;
-import android.app.appsearch.util.BundleUtil;
-import android.os.Bundle;
-
-import java.util.Objects;
-
-/** This class represents a uniquely identifiable package. */
-public class PackageIdentifier {
-    private static final String PACKAGE_NAME_FIELD = "packageName";
-    private static final String SHA256_CERTIFICATE_FIELD = "sha256Certificate";
-
-    private final Bundle mBundle;
-
-    /**
-     * Creates a unique identifier for a package.
-     *
-     * @param packageName Name of the package.
-     * @param sha256Certificate SHA256 certificate digest of the package.
-     */
-    public PackageIdentifier(@NonNull String packageName, @NonNull byte[] sha256Certificate) {
-        mBundle = new Bundle();
-        mBundle.putString(PACKAGE_NAME_FIELD, packageName);
-        mBundle.putByteArray(SHA256_CERTIFICATE_FIELD, sha256Certificate);
-    }
-
-    /** @hide */
-    public PackageIdentifier(@NonNull Bundle bundle) {
-        mBundle = Objects.requireNonNull(bundle);
-    }
-
-    /** @hide */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    @NonNull
-    public String getPackageName() {
-        return Objects.requireNonNull(mBundle.getString(PACKAGE_NAME_FIELD));
-    }
-
-    @NonNull
-    public byte[] getSha256Certificate() {
-        return Objects.requireNonNull(mBundle.getByteArray(SHA256_CERTIFICATE_FIELD));
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || !(obj instanceof PackageIdentifier)) {
-            return false;
-        }
-        final PackageIdentifier other = (PackageIdentifier) obj;
-        return BundleUtil.deepEquals(mBundle, other.mBundle);
-    }
-
-    @Override
-    public int hashCode() {
-        return BundleUtil.deepHashCode(mBundle);
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
deleted file mode 100644
index 3424128..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
+++ /dev/null
@@ -1,84 +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 android.annotation.NonNull;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Encapsulates a request to index documents into an {@link AppSearchSession} database.
- *
- * @see AppSearchSession#put
- */
-public final class PutDocumentsRequest {
-    private final List<GenericDocument> mDocuments;
-
-    PutDocumentsRequest(List<GenericDocument> documents) {
-        mDocuments = documents;
-    }
-
-    /** Returns a list of {@link GenericDocument} objects that are part of this request. */
-    @NonNull
-    public List<GenericDocument> getGenericDocuments() {
-        return Collections.unmodifiableList(mDocuments);
-    }
-
-    /** Builder for {@link PutDocumentsRequest} objects. */
-    public static final class Builder {
-        private ArrayList<GenericDocument> mDocuments = new ArrayList<>();
-        private boolean mBuilt = false;
-
-        /** Adds one or more {@link GenericDocument} objects to the request. */
-        @NonNull
-        public Builder addGenericDocuments(@NonNull GenericDocument... documents) {
-            Objects.requireNonNull(documents);
-            resetIfBuilt();
-            return addGenericDocuments(Arrays.asList(documents));
-        }
-
-        /** Adds a collection of {@link GenericDocument} objects to the request. */
-        @NonNull
-        public Builder addGenericDocuments(
-                @NonNull Collection<? extends GenericDocument> documents) {
-            Objects.requireNonNull(documents);
-            resetIfBuilt();
-            mDocuments.addAll(documents);
-            return this;
-        }
-
-        /** Creates a new {@link PutDocumentsRequest} object. */
-        @NonNull
-        public PutDocumentsRequest build() {
-            mBuilt = true;
-            return new PutDocumentsRequest(mDocuments);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mDocuments = new ArrayList<>(mDocuments);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
deleted file mode 100644
index b86fd27..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByDocumentIdRequest.java
+++ /dev/null
@@ -1,97 +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 android.annotation.NonNull;
-import android.util.ArraySet;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Encapsulates a request to remove documents by namespace and IDs from the {@link AppSearchSession}
- * database.
- *
- * @see AppSearchSession#remove
- */
-public final class RemoveByDocumentIdRequest {
-    private final String mNamespace;
-    private final Set<String> mIds;
-
-    RemoveByDocumentIdRequest(String namespace, Set<String> ids) {
-        mNamespace = namespace;
-        mIds = ids;
-    }
-
-    /** Returns the namespace to remove documents from. */
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    /** Returns the set of document IDs attached to the request. */
-    @NonNull
-    public Set<String> getIds() {
-        return Collections.unmodifiableSet(mIds);
-    }
-
-    /** Builder for {@link RemoveByDocumentIdRequest} objects. */
-    public static final class Builder {
-        private final String mNamespace;
-        private ArraySet<String> mIds = new ArraySet<>();
-        private boolean mBuilt = false;
-
-        /** Creates a {@link RemoveByDocumentIdRequest.Builder} instance. */
-        public Builder(@NonNull String namespace) {
-            mNamespace = Objects.requireNonNull(namespace);
-        }
-
-        /** Adds one or more document IDs to the request. */
-        @NonNull
-        public Builder addIds(@NonNull String... ids) {
-            Objects.requireNonNull(ids);
-            resetIfBuilt();
-            return addIds(Arrays.asList(ids));
-        }
-
-        /** Adds a collection of IDs to the request. */
-        @NonNull
-        public Builder addIds(@NonNull Collection<String> ids) {
-            Objects.requireNonNull(ids);
-            resetIfBuilt();
-            mIds.addAll(ids);
-            return this;
-        }
-
-        /** Builds a new {@link RemoveByDocumentIdRequest}. */
-        @NonNull
-        public RemoveByDocumentIdRequest build() {
-            mBuilt = true;
-            return new RemoveByDocumentIdRequest(mNamespace, mIds);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mIds = new ArraySet<>(mIds);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
deleted file mode 100644
index 26bdf03..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportSystemUsageRequest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-
-import java.util.Objects;
-
-/**
- * A request to report usage of a document owned by another app from a system UI surface.
- *
- * <p>Usage reported in this way is measured separately from usage reported via {@link
- * AppSearchSession#reportUsage}.
- *
- * <p>See {@link GlobalSearchSession#reportSystemUsage} for a detailed description of usage
- * reporting.
- */
-public final class ReportSystemUsageRequest {
-    private final String mPackageName;
-    private final String mDatabase;
-    private final String mNamespace;
-    private final String mDocumentId;
-    private final long mUsageTimestampMillis;
-
-    ReportSystemUsageRequest(
-            @NonNull String packageName,
-            @NonNull String database,
-            @NonNull String namespace,
-            @NonNull String documentId,
-            long usageTimestampMillis) {
-        mPackageName = Objects.requireNonNull(packageName);
-        mDatabase = Objects.requireNonNull(database);
-        mNamespace = Objects.requireNonNull(namespace);
-        mDocumentId = Objects.requireNonNull(documentId);
-        mUsageTimestampMillis = usageTimestampMillis;
-    }
-
-    /** Returns the package name of the app which owns the document that was used. */
-    @NonNull
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /** Returns the database in which the document that was used resides. */
-    @NonNull
-    public String getDatabaseName() {
-        return mDatabase;
-    }
-
-    /** Returns the namespace of the document that was used. */
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    /** Returns the ID of document that was used. */
-    @NonNull
-    public String getDocumentId() {
-        return mDocumentId;
-    }
-
-    /**
-     * Returns the timestamp in milliseconds of the usage report (the time at which the document was
-     * used).
-     *
-     * <p>The value is in the {@link System#currentTimeMillis} time base.
-     */
-    @CurrentTimeMillisLong
-    public long getUsageTimestampMillis() {
-        return mUsageTimestampMillis;
-    }
-
-    /** Builder for {@link ReportSystemUsageRequest} objects. */
-    public static final class Builder {
-        private final String mPackageName;
-        private final String mDatabase;
-        private final String mNamespace;
-        private final String mDocumentId;
-        private Long mUsageTimestampMillis;
-
-        /**
-         * Creates a {@link ReportSystemUsageRequest.Builder} instance.
-         *
-         * @param packageName The package name of the app which owns the document that was used
-         *     (e.g. from {@link SearchResult#getPackageName}).
-         * @param databaseName The database in which the document that was used resides (e.g. from
-         *     {@link SearchResult#getDatabaseName}).
-         * @param namespace The namespace of the document that was used (e.g. from {@link
-         *     GenericDocument#getNamespace}.
-         * @param documentId The ID of document that was used (e.g. from {@link
-         *     GenericDocument#getId}.
-         */
-        public Builder(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull String namespace,
-                @NonNull String documentId) {
-            mPackageName = Objects.requireNonNull(packageName);
-            mDatabase = Objects.requireNonNull(databaseName);
-            mNamespace = Objects.requireNonNull(namespace);
-            mDocumentId = Objects.requireNonNull(documentId);
-        }
-
-        /**
-         * Sets the timestamp in milliseconds of the usage report (the time at which the document
-         * was used).
-         *
-         * <p>The value is in the {@link System#currentTimeMillis} time base.
-         *
-         * <p>If unset, this defaults to the current timestamp at the time that the {@link
-         * ReportSystemUsageRequest} is constructed.
-         */
-        @NonNull
-        public ReportSystemUsageRequest.Builder setUsageTimestampMillis(
-                @CurrentTimeMillisLong long usageTimestampMillis) {
-            mUsageTimestampMillis = usageTimestampMillis;
-            return this;
-        }
-
-        /** Builds a new {@link ReportSystemUsageRequest}. */
-        @NonNull
-        public ReportSystemUsageRequest build() {
-            if (mUsageTimestampMillis == null) {
-                mUsageTimestampMillis = System.currentTimeMillis();
-            }
-            return new ReportSystemUsageRequest(
-                    mPackageName, mDatabase, mNamespace, mDocumentId, mUsageTimestampMillis);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
deleted file mode 100644
index e807803..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/ReportUsageRequest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-
-import java.util.Objects;
-
-/**
- * A request to report usage of a document.
- *
- * <p>See {@link AppSearchSession#reportUsage} for a detailed description of usage reporting.
- *
- * @see AppSearchSession#reportUsage
- */
-public final class ReportUsageRequest {
-    private final String mNamespace;
-    private final String mDocumentId;
-    private final long mUsageTimestampMillis;
-
-    ReportUsageRequest(
-            @NonNull String namespace, @NonNull String documentId, long usageTimestampMillis) {
-        mNamespace = Objects.requireNonNull(namespace);
-        mDocumentId = Objects.requireNonNull(documentId);
-        mUsageTimestampMillis = usageTimestampMillis;
-    }
-
-    /** Returns the namespace of the document that was used. */
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    /** Returns the ID of document that was used. */
-    @NonNull
-    public String getDocumentId() {
-        return mDocumentId;
-    }
-
-    /**
-     * Returns the timestamp in milliseconds of the usage report (the time at which the document was
-     * used).
-     *
-     * <p>The value is in the {@link System#currentTimeMillis} time base.
-     */
-    @CurrentTimeMillisLong
-    public long getUsageTimestampMillis() {
-        return mUsageTimestampMillis;
-    }
-
-    /** Builder for {@link ReportUsageRequest} objects. */
-    public static final class Builder {
-        private final String mNamespace;
-        private final String mDocumentId;
-        private Long mUsageTimestampMillis;
-
-        /**
-         * Creates a new {@link ReportUsageRequest.Builder} instance.
-         *
-         * @param namespace The namespace of the document that was used (e.g. from {@link
-         *     GenericDocument#getNamespace}.
-         * @param documentId The ID of document that was used (e.g. from {@link
-         *     GenericDocument#getId}.
-         */
-        public Builder(@NonNull String namespace, @NonNull String documentId) {
-            mNamespace = Objects.requireNonNull(namespace);
-            mDocumentId = Objects.requireNonNull(documentId);
-        }
-
-        /**
-         * Sets the timestamp in milliseconds of the usage report (the time at which the document
-         * was used).
-         *
-         * <p>The value is in the {@link System#currentTimeMillis} time base.
-         *
-         * <p>If unset, this defaults to the current timestamp at the time that the {@link
-         * ReportUsageRequest} is constructed.
-         */
-        @NonNull
-        public ReportUsageRequest.Builder setUsageTimestampMillis(
-                @CurrentTimeMillisLong long usageTimestampMillis) {
-            mUsageTimestampMillis = usageTimestampMillis;
-            return this;
-        }
-
-        /** Builds a new {@link ReportUsageRequest}. */
-        @NonNull
-        public ReportUsageRequest build() {
-            if (mUsageTimestampMillis == null) {
-                mUsageTimestampMillis = System.currentTimeMillis();
-            }
-            return new ReportUsageRequest(mNamespace, mDocumentId, mUsageTimestampMillis);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
deleted file mode 100644
index f6a597c..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
+++ /dev/null
@@ -1,549 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * This class represents one of the results obtained from an AppSearch query.
- *
- * <p>This allows clients to obtain:
- *
- * <ul>
- *   <li>The document which matched, using {@link #getGenericDocument}
- *   <li>Information about which properties in the document matched, and "snippet" information
- *       containing textual summaries of the document's matches, using {@link #getMatchInfos}
- * </ul>
- *
- * <p>"Snippet" refers to a substring of text from the content of document that is returned as a
- * part of search result.
- *
- * @see SearchResults
- */
-public final class SearchResult {
-    static final String DOCUMENT_FIELD = "document";
-    static final String MATCH_INFOS_FIELD = "matchInfos";
-    static final String PACKAGE_NAME_FIELD = "packageName";
-    static final String DATABASE_NAME_FIELD = "databaseName";
-    static final String RANKING_SIGNAL_FIELD = "rankingSignal";
-
-    @NonNull private final Bundle mBundle;
-
-    /** Cache of the inflated document. Comes from inflating mDocumentBundle at first use. */
-    @Nullable private GenericDocument mDocument;
-
-    /** Cache of the inflated matches. Comes from inflating mMatchBundles at first use. */
-    @Nullable private List<MatchInfo> mMatchInfos;
-
-    /** @hide */
-    public SearchResult(@NonNull Bundle bundle) {
-        mBundle = Objects.requireNonNull(bundle);
-    }
-
-    /** @hide */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Contains the matching {@link GenericDocument}.
-     *
-     * @return Document object which matched the query.
-     */
-    @NonNull
-    public GenericDocument getGenericDocument() {
-        if (mDocument == null) {
-            mDocument =
-                    new GenericDocument(Objects.requireNonNull(mBundle.getBundle(DOCUMENT_FIELD)));
-        }
-        return mDocument;
-    }
-
-    /**
-     * Returns a list of {@link MatchInfo}s providing information about how the document in {@link
-     * #getGenericDocument} matched the query.
-     *
-     * @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.
-     */
-    @NonNull
-    public List<MatchInfo> getMatchInfos() {
-        if (mMatchInfos == null) {
-            List<Bundle> matchBundles =
-                    Objects.requireNonNull(mBundle.getParcelableArrayList(MATCH_INFOS_FIELD));
-            mMatchInfos = new ArrayList<>(matchBundles.size());
-            for (int i = 0; i < matchBundles.size(); i++) {
-                MatchInfo matchInfo = new MatchInfo(matchBundles.get(i), getGenericDocument());
-                mMatchInfos.add(matchInfo);
-            }
-        }
-        return mMatchInfos;
-    }
-
-    /**
-     * Contains the package name of the app that stored the {@link GenericDocument}.
-     *
-     * @return Package name that stored the document
-     */
-    @NonNull
-    public String getPackageName() {
-        return Objects.requireNonNull(mBundle.getString(PACKAGE_NAME_FIELD));
-    }
-
-    /**
-     * Contains the database name that stored the {@link GenericDocument}.
-     *
-     * @return Name of the database within which the document is stored
-     */
-    @NonNull
-    public String getDatabaseName() {
-        return Objects.requireNonNull(mBundle.getString(DATABASE_NAME_FIELD));
-    }
-
-    /**
-     * Returns the ranking signal of the {@link GenericDocument}, according to the ranking strategy
-     * set in {@link SearchSpec.Builder#setRankingStrategy(int)}.
-     *
-     * <p>The meaning of the ranking signal and its value is determined by the selected ranking
-     * strategy:
-     *
-     * <ul>
-     *   <li>{@link SearchSpec#RANKING_STRATEGY_NONE} - this value will be 0
-     *   <li>{@link SearchSpec#RANKING_STRATEGY_DOCUMENT_SCORE} - the value returned by calling
-     *       {@link GenericDocument#getScore()} on the document returned by {@link
-     *       #getGenericDocument()}
-     *   <li>{@link SearchSpec#RANKING_STRATEGY_CREATION_TIMESTAMP} - the value returned by calling
-     *       {@link GenericDocument#getCreationTimestampMillis()} on the document returned by {@link
-     *       #getGenericDocument()}
-     *   <li>{@link SearchSpec#RANKING_STRATEGY_RELEVANCE_SCORE} - an arbitrary double value where a
-     *       higher value means more relevant
-     *   <li>{@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} - the number of times usage has been
-     *       reported for the document returned by {@link #getGenericDocument()}
-     *   <li>{@link SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} - the timestamp of the
-     *       most recent usage that has been reported for the document returned by {@link
-     *       #getGenericDocument()}
-     * </ul>
-     *
-     * @return Ranking signal of the document
-     */
-    public double getRankingSignal() {
-        return mBundle.getDouble(RANKING_SIGNAL_FIELD);
-    }
-
-    /** Builder for {@link SearchResult} objects. */
-    public static final class Builder {
-        private final String mPackageName;
-        private final String mDatabaseName;
-        private ArrayList<Bundle> mMatchInfoBundles = new ArrayList<>();
-        private GenericDocument mGenericDocument;
-        private double mRankingSignal;
-        private boolean mBuilt = false;
-
-        /**
-         * Constructs a new builder for {@link SearchResult} objects.
-         *
-         * @param packageName the package name the matched document belongs to
-         * @param databaseName the database name the matched document belongs to.
-         */
-        public Builder(@NonNull String packageName, @NonNull String databaseName) {
-            mPackageName = Objects.requireNonNull(packageName);
-            mDatabaseName = Objects.requireNonNull(databaseName);
-        }
-
-        /** Sets the document which matched. */
-        @NonNull
-        public Builder setGenericDocument(@NonNull GenericDocument document) {
-            Objects.requireNonNull(document);
-            resetIfBuilt();
-            mGenericDocument = document;
-            return this;
-        }
-
-        /** Adds another match to this SearchResult. */
-        @NonNull
-        public Builder addMatchInfo(@NonNull MatchInfo matchInfo) {
-            Preconditions.checkState(
-                    matchInfo.mDocument == null,
-                    "This MatchInfo is already associated with a SearchResult and can't be "
-                            + "reassigned");
-            resetIfBuilt();
-            mMatchInfoBundles.add(matchInfo.mBundle);
-            return this;
-        }
-
-        /** Sets the ranking signal of the matched document in this SearchResult. */
-        @NonNull
-        public Builder setRankingSignal(double rankingSignal) {
-            resetIfBuilt();
-            mRankingSignal = rankingSignal;
-            return this;
-        }
-
-        /** Constructs a new {@link SearchResult}. */
-        @NonNull
-        public SearchResult build() {
-            Bundle bundle = new Bundle();
-            bundle.putString(PACKAGE_NAME_FIELD, mPackageName);
-            bundle.putString(DATABASE_NAME_FIELD, mDatabaseName);
-            bundle.putBundle(DOCUMENT_FIELD, mGenericDocument.getBundle());
-            bundle.putDouble(RANKING_SIGNAL_FIELD, mRankingSignal);
-            bundle.putParcelableArrayList(MATCH_INFOS_FIELD, mMatchInfoBundles);
-            mBuilt = true;
-            return new SearchResult(bundle);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mMatchInfoBundles = new ArrayList<>(mMatchInfoBundles);
-                mBuilt = false;
-            }
-        }
-    }
-
-    /**
-     * 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.
-     *
-     * <p>Class Example 1: A document contains following text in property subject:
-     *
-     * <p>A commonly used fake word is foo. Another nonsense word that’s used a lot is bar.
-     *
-     * <p>If the queryExpression is "foo".
-     *
-     * <p>{@link MatchInfo#getPropertyPath()} returns "subject"
-     *
-     * <p>{@link MatchInfo#getFullText()} returns "A commonly used fake word is foo. Another
-     * nonsense word that’s used a lot is bar."
-     *
-     * <p>{@link MatchInfo#getExactMatchRange()} returns [29, 32]
-     *
-     * <p>{@link MatchInfo#getExactMatch()} returns "foo"
-     *
-     * <p>{@link MatchInfo#getSnippetRange()} returns [26, 33]
-     *
-     * <p>{@link MatchInfo#getSnippet()} returns "is foo."
-     *
-     * <p>
-     *
-     * <p>Class Example 2: A document contains a property name sender which contains 2 property
-     * names name and email, so we will have 2 property paths: {@code sender.name} and {@code
-     * sender.email}.
-     *
-     * <p>Let {@code sender.name = "Test Name Jr."} and {@code sender.email =
-     * "TestNameJr@gmail.com"}
-     *
-     * <p>If the queryExpression is "Test". We will have 2 matches.
-     *
-     * <p>Match-1
-     *
-     * <p>{@link MatchInfo#getPropertyPath()} returns "sender.name"
-     *
-     * <p>{@link MatchInfo#getFullText()} returns "Test Name Jr."
-     *
-     * <p>{@link MatchInfo#getExactMatchRange()} returns [0, 4]
-     *
-     * <p>{@link MatchInfo#getExactMatch()} returns "Test"
-     *
-     * <p>{@link MatchInfo#getSnippetRange()} returns [0, 9]
-     *
-     * <p>{@link MatchInfo#getSnippet()} returns "Test Name"
-     *
-     * <p>Match-2
-     *
-     * <p>{@link MatchInfo#getPropertyPath()} returns "sender.email"
-     *
-     * <p>{@link MatchInfo#getFullText()} returns "TestNameJr@gmail.com"
-     *
-     * <p>{@link MatchInfo#getExactMatchRange()} returns [0, 20]
-     *
-     * <p>{@link MatchInfo#getExactMatch()} returns "TestNameJr@gmail.com"
-     *
-     * <p>{@link MatchInfo#getSnippetRange()} returns [0, 20]
-     *
-     * <p>{@link MatchInfo#getSnippet()} returns "TestNameJr@gmail.com"
-     */
-    public static final class MatchInfo {
-        /** The path of the matching snippet property. */
-        private static final String PROPERTY_PATH_FIELD = "propertyPath";
-
-        private static final String EXACT_MATCH_RANGE_LOWER_FIELD = "exactMatchRangeLower";
-        private static final String EXACT_MATCH_RANGE_UPPER_FIELD = "exactMatchRangeUpper";
-        private static final String SNIPPET_RANGE_LOWER_FIELD = "snippetRangeLower";
-        private static final String SNIPPET_RANGE_UPPER_FIELD = "snippetRangeUpper";
-
-        private final String mPropertyPath;
-        final Bundle mBundle;
-
-        /**
-         * Document which the match comes from.
-         *
-         * <p>If this is {@code null}, methods which require access to the document, like {@link
-         * #getExactMatch}, will throw {@link NullPointerException}.
-         */
-        @Nullable final GenericDocument mDocument;
-
-        /** Full text of the matched property. Populated on first use. */
-        @Nullable private String mFullText;
-
-        /** Range of property that exactly matched the query. Populated on first use. */
-        @Nullable private MatchRange mExactMatchRange;
-
-        /** Range of some reasonable amount of context around the query. Populated on first use. */
-        @Nullable private MatchRange mWindowRange;
-
-        MatchInfo(@NonNull Bundle bundle, @Nullable GenericDocument document) {
-            mBundle = Objects.requireNonNull(bundle);
-            mDocument = document;
-            mPropertyPath = Objects.requireNonNull(bundle.getString(PROPERTY_PATH_FIELD));
-        }
-
-        /**
-         * Gets the property path corresponding to the given entry.
-         *
-         * <p>A property path is a '.' - delimited sequence of property names indicating which
-         * property in the document these snippets correspond to.
-         *
-         * <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc. For class
-         * example 1 this returns "subject"
-         */
-        @NonNull
-        public String getPropertyPath() {
-            return mPropertyPath;
-        }
-
-        /**
-         * Gets the full text corresponding to the given entry.
-         *
-         * <p>For class example this returns "A commonly used fake word is foo. Another nonsense
-         * word that's used a lot is bar."
-         */
-        @NonNull
-        public String getFullText() {
-            if (mFullText == null) {
-                Preconditions.checkState(
-                        mDocument != null,
-                        "Document has not been populated; this MatchInfo cannot be used yet");
-                mFullText = getPropertyValues(mDocument, mPropertyPath);
-            }
-            return mFullText;
-        }
-
-        /**
-         * Gets the exact {@link MatchRange} corresponding to the given entry.
-         *
-         * <p>For class example 1 this returns [29, 32]
-         */
-        @NonNull
-        public MatchRange getExactMatchRange() {
-            if (mExactMatchRange == null) {
-                mExactMatchRange =
-                        new MatchRange(
-                                mBundle.getInt(EXACT_MATCH_RANGE_LOWER_FIELD),
-                                mBundle.getInt(EXACT_MATCH_RANGE_UPPER_FIELD));
-            }
-            return mExactMatchRange;
-        }
-
-        /**
-         * Gets the {@link MatchRange} corresponding to the given entry.
-         *
-         * <p>For class example 1 this returns "foo"
-         */
-        @NonNull
-        public CharSequence getExactMatch() {
-            return getSubstring(getExactMatchRange());
-        }
-
-        /**
-         * Gets the snippet {@link MatchRange} corresponding to the given entry.
-         *
-         * <p>Only populated when set maxSnippetSize > 0 in {@link
-         * SearchSpec.Builder#setMaxSnippetSize}.
-         *
-         * <p>For class example 1 this returns [29, 41].
-         */
-        @NonNull
-        public MatchRange getSnippetRange() {
-            if (mWindowRange == null) {
-                mWindowRange =
-                        new MatchRange(
-                                mBundle.getInt(SNIPPET_RANGE_LOWER_FIELD),
-                                mBundle.getInt(SNIPPET_RANGE_UPPER_FIELD));
-            }
-            return mWindowRange;
-        }
-
-        /**
-         * Gets the snippet corresponding to the given entry.
-         *
-         * <p>Snippet - Provides a subset of the content to display. Only populated when requested
-         * maxSnippetSize > 0. The size of this content can be changed by {@link
-         * SearchSpec.Builder#setMaxSnippetSize}. Windowing is centered around the middle of the
-         * matched token with content on either side clipped to token boundaries.
-         *
-         * <p>For class example 1 this returns "foo. Another"
-         */
-        @NonNull
-        public CharSequence getSnippet() {
-            return getSubstring(getSnippetRange());
-        }
-
-        private CharSequence getSubstring(MatchRange range) {
-            return getFullText().substring(range.getStart(), range.getEnd());
-        }
-
-        /** Extracts the matching string from the document. */
-        private static String getPropertyValues(GenericDocument document, String propertyName) {
-            // In IcingLib snippeting is available for only 3 data types i.e String, double and
-            // long, so we need to check which of these three are requested.
-            // TODO (tytytyww): support double[] and long[].
-            String result = document.getPropertyString(propertyName);
-            if (result == null) {
-                throw new IllegalStateException(
-                        "No content found for requested property path: " + propertyName);
-            }
-            return result;
-        }
-
-        /** Builder for {@link MatchInfo} objects. */
-        public static final class Builder {
-            private final String mPropertyPath;
-            private MatchRange mExactMatchRange = new MatchRange(0, 0);
-            private MatchRange mSnippetRange = new MatchRange(0, 0);
-
-            /**
-             * Creates a new {@link MatchInfo.Builder} reporting a match with the given property
-             * path.
-             *
-             * <p>A property path is a dot-delimited sequence of property names indicating which
-             * property in the document these snippets correspond to.
-             *
-             * <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc.
-             * For class example 1 this returns "subject".
-             *
-             * @param propertyPath A {@code dot-delimited sequence of property names indicating
-             *                     which property in the document these snippets correspond to.
-             */
-            public Builder(@NonNull String propertyPath) {
-                mPropertyPath = Objects.requireNonNull(propertyPath);
-            }
-
-            /** Sets the exact {@link MatchRange} corresponding to the given entry. */
-            @NonNull
-            public Builder setExactMatchRange(@NonNull MatchRange matchRange) {
-                mExactMatchRange = Objects.requireNonNull(matchRange);
-                return this;
-            }
-
-            /** Sets the snippet {@link MatchRange} corresponding to the given entry. */
-            @NonNull
-            public Builder setSnippetRange(@NonNull MatchRange matchRange) {
-                mSnippetRange = Objects.requireNonNull(matchRange);
-                return this;
-            }
-
-            /** Constructs a new {@link MatchInfo}. */
-            @NonNull
-            public MatchInfo build() {
-                Bundle bundle = new Bundle();
-                bundle.putString(SearchResult.MatchInfo.PROPERTY_PATH_FIELD, mPropertyPath);
-                bundle.putInt(MatchInfo.EXACT_MATCH_RANGE_LOWER_FIELD, mExactMatchRange.getStart());
-                bundle.putInt(MatchInfo.EXACT_MATCH_RANGE_UPPER_FIELD, mExactMatchRange.getEnd());
-                bundle.putInt(MatchInfo.SNIPPET_RANGE_LOWER_FIELD, mSnippetRange.getStart());
-                bundle.putInt(MatchInfo.SNIPPET_RANGE_UPPER_FIELD, mSnippetRange.getEnd());
-                return new MatchInfo(bundle, /*document=*/ null);
-            }
-        }
-    }
-
-    /**
-     * Class providing the position range of matching information.
-     *
-     * <p>All ranges are finite, and the left side of the range is always {@code <=} the right side
-     * of the range.
-     *
-     * <p>Example: MatchRange(0, 100) represent a hundred ints from 0 to 99."
-     */
-    public static final class MatchRange {
-        private final int mEnd;
-        private final int mStart;
-
-        /**
-         * Creates a new immutable range.
-         *
-         * <p>The endpoints are {@code [start, end)}; that is the range is bounded. {@code start}
-         * must be lesser or equal to {@code end}.
-         *
-         * @param start The start point (inclusive)
-         * @param end The end point (exclusive)
-         */
-        public MatchRange(int start, int end) {
-            if (start > end) {
-                throw new IllegalArgumentException(
-                        "Start point must be less than or equal to " + "end point");
-            }
-            mStart = start;
-            mEnd = end;
-        }
-
-        /** Gets the start point (inclusive). */
-        public int getStart() {
-            return mStart;
-        }
-
-        /** Gets the end point (exclusive). */
-        public int getEnd() {
-            return mEnd;
-        }
-
-        @Override
-        public boolean equals(@Nullable Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof MatchRange)) {
-                return false;
-            }
-            MatchRange otherMatchRange = (MatchRange) other;
-            return this.getStart() == otherMatchRange.getStart()
-                    && this.getEnd() == otherMatchRange.getEnd();
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return "MatchRange { start: " + mStart + " , end: " + mEnd + "}";
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mStart, mEnd);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResultPage.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResultPage.java
deleted file mode 100644
index 4853b5b..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchResultPage.java
+++ /dev/null
@@ -1,74 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * This class represents a page of {@link SearchResult}s
- *
- * @hide
- */
-public class SearchResultPage {
-    public static final String RESULTS_FIELD = "results";
-    public static final String NEXT_PAGE_TOKEN_FIELD = "nextPageToken";
-    private final long mNextPageToken;
-
-    @Nullable private List<SearchResult> mResults;
-
-    @NonNull private final Bundle mBundle;
-
-    public SearchResultPage(@NonNull Bundle bundle) {
-        mBundle = Objects.requireNonNull(bundle);
-        mNextPageToken = mBundle.getLong(NEXT_PAGE_TOKEN_FIELD);
-    }
-
-    /** Returns the {@link Bundle} of this class. */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /** Returns the Token to get next {@link SearchResultPage}. */
-    public long getNextPageToken() {
-        return mNextPageToken;
-    }
-
-    /** Returns all {@link android.app.appsearch.SearchResult}s of this page */
-    @NonNull
-    public List<SearchResult> getResults() {
-        if (mResults == null) {
-            ArrayList<Bundle> resultBundles = mBundle.getParcelableArrayList(RESULTS_FIELD);
-            if (resultBundles == null) {
-                mResults = Collections.emptyList();
-            } else {
-                mResults = new ArrayList<>(resultBundles.size());
-                for (int i = 0; i < resultBundles.size(); i++) {
-                    mResults.add(new SearchResult(resultBundles.get(i)));
-                }
-            }
-        }
-        return mResults;
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
deleted file mode 100644
index 5abd4f6..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
+++ /dev/null
@@ -1,676 +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 android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.app.appsearch.util.BundleUtil;
-import android.os.Bundle;
-import android.util.ArrayMap;
-
-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;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * This class represents the specification logic for AppSearch. It can be used to set the type of
- * search, like prefix or exact only or apply filters to search for a specific schema type only etc.
- */
-// TODO(sidchhabra) : AddResultSpec fields for Snippets etc.
-public final class SearchSpec {
-    /**
-     * Schema type to be used in {@link SearchSpec.Builder#addProjection} to apply property paths to
-     * all results, excepting any types that have had their own, specific property paths set.
-     */
-    public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
-
-    static final String TERM_MATCH_TYPE_FIELD = "termMatchType";
-    static final String SCHEMA_FIELD = "schema";
-    static final String NAMESPACE_FIELD = "namespace";
-    static final String PACKAGE_NAME_FIELD = "packageName";
-    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";
-    static final String PROJECTION_TYPE_PROPERTY_PATHS_FIELD = "projectionTypeFieldMasks";
-    static final String RESULT_GROUPING_TYPE_FLAGS = "resultGroupingTypeFlags";
-    static final String RESULT_GROUPING_LIMIT = "resultGroupingLimit";
-
-    /** @hide */
-    public static final int DEFAULT_NUM_PER_PAGE = 10;
-
-    // TODO(b/170371356): In framework, we may want these limits to be flag controlled.
-    //  If that happens, the @IntRange() directives in this class may have to change.
-    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;
-
-    /**
-     * Term Match Type for the query.
-     *
-     * @hide
-     */
-    // NOTE: The integer values of these constants must match the proto enum constants in
-    // {@link com.google.android.icing.proto.SearchSpecProto.termMatchType}
-    @IntDef(value = {TERM_MATCH_EXACT_ONLY, TERM_MATCH_PREFIX})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TermMatch {}
-
-    /**
-     * Query terms will only match exact tokens in the index.
-     *
-     * <p>Ex. A query term "foo" will only match indexed token "foo", and not "foot" or "football".
-     */
-    public static final int TERM_MATCH_EXACT_ONLY = 1;
-    /**
-     * Query terms will match indexed tokens when the query term is a prefix of the token.
-     *
-     * <p>Ex. A query term "foo" will match indexed tokens like "foo", "foot", and "football".
-     */
-    public static final int TERM_MATCH_PREFIX = 2;
-
-    /**
-     * Ranking Strategy for query result.
-     *
-     * @hide
-     */
-    // NOTE: The integer values of these constants must match the proto enum constants in
-    // {@link ScoringSpecProto.RankingStrategy.Code}
-    @IntDef(
-            value = {
-                RANKING_STRATEGY_NONE,
-                RANKING_STRATEGY_DOCUMENT_SCORE,
-                RANKING_STRATEGY_CREATION_TIMESTAMP,
-                RANKING_STRATEGY_RELEVANCE_SCORE,
-                RANKING_STRATEGY_USAGE_COUNT,
-                RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP,
-                RANKING_STRATEGY_SYSTEM_USAGE_COUNT,
-                RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RankingStrategy {}
-
-    /** No Ranking, results are returned in arbitrary order. */
-    public static final int RANKING_STRATEGY_NONE = 0;
-    /** Ranked by app-provided document scores. */
-    public static final int RANKING_STRATEGY_DOCUMENT_SCORE = 1;
-    /** Ranked by document creation timestamps. */
-    public static final int RANKING_STRATEGY_CREATION_TIMESTAMP = 2;
-    /** Ranked by document relevance score. */
-    public static final int RANKING_STRATEGY_RELEVANCE_SCORE = 3;
-    /** Ranked by number of usages, as reported by the app. */
-    public static final int RANKING_STRATEGY_USAGE_COUNT = 4;
-    /** Ranked by timestamp of last usage, as reported by the app. */
-    public static final int RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP = 5;
-    /** Ranked by number of usages from a system UI surface. */
-    public static final int RANKING_STRATEGY_SYSTEM_USAGE_COUNT = 6;
-    /** Ranked by timestamp of last usage from a system UI surface. */
-    public static final int RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP = 7;
-
-    /**
-     * Order for query result.
-     *
-     * @hide
-     */
-    // NOTE: The integer values of these constants must match the proto enum constants in
-    // {@link ScoringSpecProto.Order.Code}
-    @IntDef(value = {ORDER_DESCENDING, ORDER_ASCENDING})
-    @Retention(RetentionPolicy.SOURCE)
-    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;
-
-    /**
-     * Grouping type for result limits.
-     *
-     * @hide
-     */
-    @IntDef(
-            flag = true,
-            value = {GROUPING_TYPE_PER_PACKAGE, GROUPING_TYPE_PER_NAMESPACE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface GroupingType {}
-
-    /**
-     * Results should be grouped together by package for the purpose of enforcing a limit on the
-     * number of results returned per package.
-     */
-    public static final int GROUPING_TYPE_PER_PACKAGE = 0b01;
-    /**
-     * Results should be grouped together by namespace for the purpose of enforcing a limit on the
-     * number of results returned per namespace.
-     */
-    public static final int GROUPING_TYPE_PER_NAMESPACE = 0b10;
-
-    private final Bundle mBundle;
-
-    /** @hide */
-    public SearchSpec(@NonNull Bundle bundle) {
-        Objects.requireNonNull(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> getFilterSchemas() {
-        List<String> schemas = mBundle.getStringArrayList(SCHEMA_FIELD);
-        if (schemas == null) {
-            return Collections.emptyList();
-        }
-        return Collections.unmodifiableList(schemas);
-    }
-
-    /**
-     * Returns the list of namespaces to search over.
-     *
-     * <p>If empty, the query will search over all namespaces.
-     */
-    @NonNull
-    public List<String> getFilterNamespaces() {
-        List<String> namespaces = mBundle.getStringArrayList(NAMESPACE_FIELD);
-        if (namespaces == null) {
-            return Collections.emptyList();
-        }
-        return Collections.unmodifiableList(namespaces);
-    }
-
-    /**
-     * Returns the list of package name filters to search over.
-     *
-     * <p>If empty, the query will search over all packages that the caller has access to. If
-     * package names are specified which caller doesn't have access to, then those package names
-     * will be ignored.
-     */
-    @NonNull
-    public List<String> getFilterPackageNames() {
-        List<String> packageNames = mBundle.getStringArrayList(PACKAGE_NAME_FIELD);
-        if (packageNames == null) {
-            return Collections.emptyList();
-        }
-        return Collections.unmodifiableList(packageNames);
-    }
-
-    /** Returns the number of results per page in the result set. */
-    public int getResultCountPerPage() {
-        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);
-    }
-
-    /**
-     * Returns a map from schema type to property paths to be used for projection.
-     *
-     * <p>If the map is empty, then all properties will be retrieved for all results.
-     *
-     * <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned by this
-     * function, rather than calling it multiple times.
-     */
-    @NonNull
-    public Map<String, List<String>> getProjections() {
-        Bundle typePropertyPathsBundle = mBundle.getBundle(PROJECTION_TYPE_PROPERTY_PATHS_FIELD);
-        Set<String> schemas = typePropertyPathsBundle.keySet();
-        Map<String, List<String>> typePropertyPathsMap = new ArrayMap<>(schemas.size());
-        for (String schema : schemas) {
-            typePropertyPathsMap.put(schema, typePropertyPathsBundle.getStringArrayList(schema));
-        }
-        return typePropertyPathsMap;
-    }
-
-    /**
-     * Get the type of grouping limit to apply, or 0 if {@link Builder#setResultGrouping} was not
-     * called.
-     */
-    public @GroupingType int getResultGroupingTypeFlags() {
-        return mBundle.getInt(RESULT_GROUPING_TYPE_FLAGS);
-    }
-
-    /**
-     * Get the maximum number of results to return for each group.
-     *
-     * @return the maximum number of results to return for each group or Integer.MAX_VALUE if {@link
-     *     Builder#setResultGrouping(int, int)} was not called.
-     */
-    public int getResultGroupingLimit() {
-        return mBundle.getInt(RESULT_GROUPING_LIMIT, Integer.MAX_VALUE);
-    }
-
-    /** Builder for {@link SearchSpec objects}. */
-    public static final class Builder {
-        private ArrayList<String> mSchemas = new ArrayList<>();
-        private ArrayList<String> mNamespaces = new ArrayList<>();
-        private ArrayList<String> mPackageNames = new ArrayList<>();
-        private Bundle mProjectionTypePropertyMasks = new Bundle();
-
-        private int mResultCountPerPage = DEFAULT_NUM_PER_PAGE;
-        private @TermMatch int mTermMatchType = TERM_MATCH_PREFIX;
-        private int mSnippetCount = 0;
-        private int mSnippetCountPerProperty = MAX_SNIPPET_PER_PROPERTY_COUNT;
-        private int mMaxSnippetSize = 0;
-        private @RankingStrategy int mRankingStrategy = RANKING_STRATEGY_NONE;
-        private @Order int mOrder = ORDER_DESCENDING;
-        private @GroupingType int mGroupingTypeFlags = 0;
-        private int mGroupingLimit = 0;
-        private boolean mBuilt = false;
-
-        /**
-         * Indicates how the query terms should match {@code TermMatchCode} in the index.
-         *
-         * <p>If this method is not called, the default term match type is {@link
-         * SearchSpec#TERM_MATCH_PREFIX}.
-         */
-        @NonNull
-        public Builder setTermMatch(@TermMatch int termMatchType) {
-            Preconditions.checkArgumentInRange(
-                    termMatchType, TERM_MATCH_EXACT_ONLY, TERM_MATCH_PREFIX, "Term match type");
-            resetIfBuilt();
-            mTermMatchType = termMatchType;
-            return this;
-        }
-
-        /**
-         * 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 addFilterSchemas(@NonNull String... schemas) {
-            Objects.requireNonNull(schemas);
-            resetIfBuilt();
-            return addFilterSchemas(Arrays.asList(schemas));
-        }
-
-        /**
-         * 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 addFilterSchemas(@NonNull Collection<String> schemas) {
-            Objects.requireNonNull(schemas);
-            resetIfBuilt();
-            mSchemas.addAll(schemas);
-            return this;
-        }
-
-        /**
-         * 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 addFilterNamespaces(@NonNull String... namespaces) {
-            Objects.requireNonNull(namespaces);
-            resetIfBuilt();
-            return addFilterNamespaces(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 addFilterNamespaces(@NonNull Collection<String> namespaces) {
-            Objects.requireNonNull(namespaces);
-            resetIfBuilt();
-            mNamespaces.addAll(namespaces);
-            return this;
-        }
-
-        /**
-         * Adds a package name filter to {@link SearchSpec} Entry. Only search for documents that
-         * were indexed from the specified packages.
-         *
-         * <p>If unset, the query will search over all packages that the caller has access to. If
-         * package names are specified which caller doesn't have access to, then those package names
-         * will be ignored.
-         */
-        @NonNull
-        public Builder addFilterPackageNames(@NonNull String... packageNames) {
-            Objects.requireNonNull(packageNames);
-            resetIfBuilt();
-            return addFilterPackageNames(Arrays.asList(packageNames));
-        }
-
-        /**
-         * Adds a package name filter to {@link SearchSpec} Entry. Only search for documents that
-         * were indexed from the specified packages.
-         *
-         * <p>If unset, the query will search over all packages that the caller has access to. If
-         * package names are specified which caller doesn't have access to, then those package names
-         * will be ignored.
-         */
-        @NonNull
-        public Builder addFilterPackageNames(@NonNull Collection<String> packageNames) {
-            Objects.requireNonNull(packageNames);
-            resetIfBuilt();
-            mPackageNames.addAll(packageNames);
-            return this;
-        }
-
-        /**
-         * Sets the number of results per page in the returned object.
-         *
-         * <p>The default number of results per page is 10.
-         */
-        @NonNull
-        public SearchSpec.Builder setResultCountPerPage(
-                @IntRange(from = 0, to = MAX_NUM_PER_PAGE) int resultCountPerPage) {
-            Preconditions.checkArgumentInRange(
-                    resultCountPerPage, 0, MAX_NUM_PER_PAGE, "resultCountPerPage");
-            resetIfBuilt();
-            mResultCountPerPage = resultCountPerPage;
-            return this;
-        }
-
-        /** Sets ranking strategy for AppSearch results. */
-        @NonNull
-        public Builder setRankingStrategy(@RankingStrategy int rankingStrategy) {
-            Preconditions.checkArgumentInRange(
-                    rankingStrategy,
-                    RANKING_STRATEGY_NONE,
-                    RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP,
-                    "Result ranking strategy");
-            resetIfBuilt();
-            mRankingStrategy = rankingStrategy;
-            return this;
-        }
-
-        /**
-         * Indicates the order of returned search results, the default is {@link #ORDER_DESCENDING},
-         * meaning that results with higher scores come first.
-         *
-         * <p>This order field will be ignored if RankingStrategy = {@code RANKING_STRATEGY_NONE}.
-         */
-        @NonNull
-        public Builder setOrder(@Order int order) {
-            Preconditions.checkArgumentInRange(
-                    order, ORDER_DESCENDING, ORDER_ASCENDING, "Result ranking order");
-            resetIfBuilt();
-            mOrder = order;
-            return this;
-        }
-
-        /**
-         * Only the first {@code snippetCount} documents based on the ranking strategy will have
-         * snippet information provided.
-         *
-         * <p>The list returned from {@link SearchResult#getMatchInfos} will contain at most this
-         * many entries.
-         *
-         * <p>If set to 0 (default), snippeting is disabled and the list returned from {@link
-         * SearchResult#getMatchInfos} will be empty.
-         */
-        @NonNull
-        public SearchSpec.Builder setSnippetCount(
-                @IntRange(from = 0, to = MAX_SNIPPET_COUNT) int snippetCount) {
-            Preconditions.checkArgumentInRange(snippetCount, 0, MAX_SNIPPET_COUNT, "snippetCount");
-            resetIfBuilt();
-            mSnippetCount = snippetCount;
-            return this;
-        }
-
-        /**
-         * Sets {@code snippetCountPerProperty}. Only the first {@code snippetCountPerProperty}
-         * snippets for each property of each {@link GenericDocument} will contain snippet
-         * information.
-         *
-         * <p>If set to 0, snippeting is disabled and the list returned from {@link
-         * SearchResult#getMatchInfos} will be empty.
-         *
-         * <p>The default behavior is to snippet all matches a property contains, up to the maximum
-         * value of 10,000.
-         */
-        @NonNull
-        public SearchSpec.Builder setSnippetCountPerProperty(
-                @IntRange(from = 0, to = MAX_SNIPPET_PER_PROPERTY_COUNT)
-                        int snippetCountPerProperty) {
-            Preconditions.checkArgumentInRange(
-                    snippetCountPerProperty,
-                    0,
-                    MAX_SNIPPET_PER_PROPERTY_COUNT,
-                    "snippetCountPerProperty");
-            resetIfBuilt();
-            mSnippetCountPerProperty = snippetCountPerProperty;
-            return this;
-        }
-
-        /**
-         * Sets {@code maxSnippetSize}, the maximum snippet size. Snippet windows start at {@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.
-         */
-        @NonNull
-        public SearchSpec.Builder setMaxSnippetSize(
-                @IntRange(from = 0, to = MAX_SNIPPET_SIZE_LIMIT) int maxSnippetSize) {
-            Preconditions.checkArgumentInRange(
-                    maxSnippetSize, 0, MAX_SNIPPET_SIZE_LIMIT, "maxSnippetSize");
-            resetIfBuilt();
-            mMaxSnippetSize = maxSnippetSize;
-            return this;
-        }
-
-        /**
-         * Adds property paths for the specified type to be used for projection. If property paths
-         * are added for a type, then only the properties referred to will be retrieved for results
-         * of that type. If a property path that is specified isn't present in a result, it will be
-         * ignored for that result. Property paths cannot be null.
-         *
-         * <p>If no property paths are added for a particular type, then all properties of results
-         * of that type will be retrieved.
-         *
-         * <p>If property path is added for the {@link SearchSpec#PROJECTION_SCHEMA_TYPE_WILDCARD},
-         * then those property paths will apply to all results, excepting any types that have their
-         * own, specific property paths set.
-         *
-         * <p>Suppose the following document is in the index.
-         *
-         * <pre>{@code
-         * Email: Document {
-         *   sender: Document {
-         *     name: "Mr. Person"
-         *     email: "mrperson123@google.com"
-         *   }
-         *   recipients: [
-         *     Document {
-         *       name: "John Doe"
-         *       email: "johndoe123@google.com"
-         *     }
-         *     Document {
-         *       name: "Jane Doe"
-         *       email: "janedoe123@google.com"
-         *     }
-         *   ]
-         *   subject: "IMPORTANT"
-         *   body: "Limited time offer!"
-         * }
-         * }</pre>
-         *
-         * <p>Then, suppose that a query for "important" is issued with the following projection
-         * type property paths:
-         *
-         * <pre>{@code
-         * {schema: "Email", ["subject", "sender.name", "recipients.name"]}
-         * }</pre>
-         *
-         * <p>The above document will be returned as:
-         *
-         * <pre>{@code
-         * Email: Document {
-         *   sender: Document {
-         *     name: "Mr. Body"
-         *   }
-         *   recipients: [
-         *     Document {
-         *       name: "John Doe"
-         *     }
-         *     Document {
-         *       name: "Jane Doe"
-         *     }
-         *   ]
-         *   subject: "IMPORTANT"
-         * }
-         * }</pre>
-         */
-        @NonNull
-        public SearchSpec.Builder addProjection(
-                @NonNull String schema, @NonNull Collection<String> propertyPaths) {
-            Objects.requireNonNull(schema);
-            Objects.requireNonNull(propertyPaths);
-            resetIfBuilt();
-            ArrayList<String> propertyPathsArrayList = new ArrayList<>(propertyPaths.size());
-            for (String propertyPath : propertyPaths) {
-                Objects.requireNonNull(propertyPath);
-                propertyPathsArrayList.add(propertyPath);
-            }
-            mProjectionTypePropertyMasks.putStringArrayList(schema, propertyPathsArrayList);
-            return this;
-        }
-
-        /**
-         * Set the maximum number of results to return for each group, where groups are defined by
-         * grouping type.
-         *
-         * <p>Calling this method will override any previous calls. So calling
-         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 7) and then calling
-         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 2) will result in only the latter, a limit
-         * of two results per package, being applied. Or calling setResultGrouping
-         * (GROUPING_TYPE_PER_PACKAGE, 1) and then calling setResultGrouping
-         * (GROUPING_TYPE_PER_PACKAGE | GROUPING_PER_NAMESPACE, 5) will result in five results per
-         * package per namespace.
-         *
-         * @param groupingTypeFlags One or more combination of grouping types.
-         * @param limit Number of results to return per {@code groupingTypeFlags}.
-         * @throws IllegalArgumentException if groupingTypeFlags is zero.
-         */
-        // Individual parameters available from getResultGroupingTypeFlags and
-        // getResultGroupingLimit
-        @SuppressLint("MissingGetterMatchingBuilder")
-        @NonNull
-        public Builder setResultGrouping(@GroupingType int groupingTypeFlags, int limit) {
-            Preconditions.checkState(
-                    groupingTypeFlags != 0, "Result grouping type cannot be zero.");
-            resetIfBuilt();
-            mGroupingTypeFlags = groupingTypeFlags;
-            mGroupingLimit = limit;
-            return this;
-        }
-
-        /** Constructs a new {@link SearchSpec} from the contents of this builder. */
-        @NonNull
-        public SearchSpec build() {
-            Bundle bundle = new Bundle();
-            bundle.putStringArrayList(SCHEMA_FIELD, mSchemas);
-            bundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
-            bundle.putStringArrayList(PACKAGE_NAME_FIELD, mPackageNames);
-            bundle.putBundle(PROJECTION_TYPE_PROPERTY_PATHS_FIELD, mProjectionTypePropertyMasks);
-            bundle.putInt(NUM_PER_PAGE_FIELD, mResultCountPerPage);
-            bundle.putInt(TERM_MATCH_TYPE_FIELD, mTermMatchType);
-            bundle.putInt(SNIPPET_COUNT_FIELD, mSnippetCount);
-            bundle.putInt(SNIPPET_COUNT_PER_PROPERTY_FIELD, mSnippetCountPerProperty);
-            bundle.putInt(MAX_SNIPPET_FIELD, mMaxSnippetSize);
-            bundle.putInt(RANKING_STRATEGY_FIELD, mRankingStrategy);
-            bundle.putInt(ORDER_FIELD, mOrder);
-            bundle.putInt(RESULT_GROUPING_TYPE_FLAGS, mGroupingTypeFlags);
-            bundle.putInt(RESULT_GROUPING_LIMIT, mGroupingLimit);
-            mBuilt = true;
-            return new SearchSpec(bundle);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mSchemas = new ArrayList<>(mSchemas);
-                mNamespaces = new ArrayList<>(mNamespaces);
-                mPackageNames = new ArrayList<>(mPackageNames);
-                mProjectionTypePropertyMasks = BundleUtil.deepCopy(mProjectionTypePropertyMasks);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
deleted file mode 100644
index b72ca9a..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
+++ /dev/null
@@ -1,461 +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 android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.util.ArrayMap;
-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.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Encapsulates a request to update the schema of an {@link AppSearchSession} database.
- *
- * <p>The schema is composed of a collection of {@link AppSearchSchema} objects, each of which
- * defines a unique type of data.
- *
- * <p>The first call to SetSchemaRequest will set the provided schema and store it within the {@link
- * AppSearchSession} database.
- *
- * <p>Subsequent calls will compare the provided schema to the previously saved schema, to determine
- * how to treat existing documents.
- *
- * <p>The following types of schema modifications are always safe and are made without deleting any
- * existing documents:
- *
- * <ul>
- *   <li>Addition of new {@link AppSearchSchema} types
- *   <li>Addition of new properties to an existing {@link AppSearchSchema} type
- *   <li>Changing the cardinality of a property to be less restrictive
- * </ul>
- *
- * <p>The following types of schema changes are not backwards compatible:
- *
- * <ul>
- *   <li>Removal of an existing {@link AppSearchSchema} type
- *   <li>Removal of a property from an existing {@link AppSearchSchema} type
- *   <li>Changing the data type of an existing property
- *   <li>Changing the cardinality of a property to be more restrictive
- * </ul>
- *
- * <p>Providing a schema with incompatible changes, will throw an {@link
- * android.app.appsearch.exceptions.AppSearchException}, with a message describing the
- * incompatibility. As a result, the previously set schema will remain unchanged.
- *
- * <p>Backward incompatible changes can be made by :
- *
- * <ul>
- *   <li>setting {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. This
- *       deletes all documents that are incompatible with the new schema. The new schema is then
- *       saved and persisted to disk.
- *   <li>Add a {@link Migrator} for each incompatible type and make no deletion. The migrator will
- *       migrate documents from it's old schema version to the new version. Migrated types will be
- *       set into both {@link SetSchemaResponse#getIncompatibleTypes()} and {@link
- *       SetSchemaResponse#getMigratedTypes()}. See the migration section below.
- * </ul>
- *
- * @see AppSearchSession#setSchema
- * @see Migrator
- */
-public final class SetSchemaRequest {
-    private final Set<AppSearchSchema> mSchemas;
-    private final Set<String> mSchemasNotDisplayedBySystem;
-    private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
-    private final Map<String, Migrator> mMigrators;
-    private final boolean mForceOverride;
-    private final int mVersion;
-
-    SetSchemaRequest(
-            @NonNull Set<AppSearchSchema> schemas,
-            @NonNull Set<String> schemasNotDisplayedBySystem,
-            @NonNull Map<String, Set<PackageIdentifier>> schemasVisibleToPackages,
-            @NonNull Map<String, Migrator> migrators,
-            boolean forceOverride,
-            int version) {
-        mSchemas = Objects.requireNonNull(schemas);
-        mSchemasNotDisplayedBySystem = Objects.requireNonNull(schemasNotDisplayedBySystem);
-        mSchemasVisibleToPackages = Objects.requireNonNull(schemasVisibleToPackages);
-        mMigrators = Objects.requireNonNull(migrators);
-        mForceOverride = forceOverride;
-        mVersion = version;
-    }
-
-    /** Returns the {@link AppSearchSchema} types that are part of this request. */
-    @NonNull
-    public Set<AppSearchSchema> getSchemas() {
-        return Collections.unmodifiableSet(mSchemas);
-    }
-
-    /**
-     * Returns all the schema types that are opted out of being displayed and visible on any system
-     * UI surface.
-     */
-    @NonNull
-    public Set<String> getSchemasNotDisplayedBySystem() {
-        return Collections.unmodifiableSet(mSchemasNotDisplayedBySystem);
-    }
-
-    /**
-     * Returns a mapping of schema types to the set of packages that have access to that schema
-     * type.
-     *
-     * <p>It’s inefficient to call this method repeatedly.
-     */
-    @NonNull
-    public Map<String, Set<PackageIdentifier>> getSchemasVisibleToPackages() {
-        Map<String, Set<PackageIdentifier>> copy = new ArrayMap<>();
-        for (String key : mSchemasVisibleToPackages.keySet()) {
-            copy.put(key, new ArraySet<>(mSchemasVisibleToPackages.get(key)));
-        }
-        return copy;
-    }
-
-    /**
-     * Returns the map of {@link Migrator}, the key will be the schema type of the {@link Migrator}
-     * associated with.
-     */
-    @NonNull
-    public Map<String, Migrator> getMigrators() {
-        return Collections.unmodifiableMap(mMigrators);
-    }
-
-    /**
-     * Returns a mapping of {@link AppSearchSchema} types to the set of packages that have access to
-     * that schema type.
-     *
-     * <p>A more efficient version of {@link #getSchemasVisibleToPackages}, but it returns a
-     * modifiable map. This is not meant to be unhidden and should only be used by internal classes.
-     *
-     * @hide
-     */
-    @NonNull
-    public Map<String, Set<PackageIdentifier>> getSchemasVisibleToPackagesInternal() {
-        return mSchemasVisibleToPackages;
-    }
-
-    /** Returns whether this request will force the schema to be overridden. */
-    public boolean isForceOverride() {
-        return mForceOverride;
-    }
-
-    /** Returns the database overall schema version. */
-    @IntRange(from = 1)
-    public int getVersion() {
-        return mVersion;
-    }
-
-    /** Builder for {@link SetSchemaRequest} objects. */
-    public static final class Builder {
-        private static final int DEFAULT_VERSION = 1;
-        private ArraySet<AppSearchSchema> mSchemas = new ArraySet<>();
-        private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
-        private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
-                new ArrayMap<>();
-        private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>();
-        private boolean mForceOverride = false;
-        private int mVersion = DEFAULT_VERSION;
-        private boolean mBuilt = false;
-
-        /**
-         * Adds one or more {@link AppSearchSchema} types to the schema.
-         *
-         * <p>An {@link AppSearchSchema} object represents one type of structured data.
-         *
-         * <p>Any documents of these types will be displayed on system UI surfaces by default.
-         */
-        @NonNull
-        public Builder addSchemas(@NonNull AppSearchSchema... schemas) {
-            Objects.requireNonNull(schemas);
-            resetIfBuilt();
-            return addSchemas(Arrays.asList(schemas));
-        }
-
-        /**
-         * Adds a collection of {@link AppSearchSchema} objects to the schema.
-         *
-         * <p>An {@link AppSearchSchema} object represents one type of structured data.
-         */
-        @NonNull
-        public Builder addSchemas(@NonNull Collection<AppSearchSchema> schemas) {
-            Objects.requireNonNull(schemas);
-            resetIfBuilt();
-            mSchemas.addAll(schemas);
-            return this;
-        }
-
-        /**
-         * Sets whether or not documents from the provided {@code schemaType} will be displayed and
-         * visible on any system UI surface.
-         *
-         * <p>This setting applies to the provided {@code schemaType} only, and does not persist
-         * across {@link AppSearchSession#setSchema} calls.
-         *
-         * <p>The default behavior, if this method is not called, is to allow types to be displayed
-         * on system UI surfaces.
-         *
-         * @param schemaType The name of an {@link AppSearchSchema} within the same {@link
-         *     SetSchemaRequest}, which will be configured.
-         * @param displayed Whether documents of this type will be displayed on system UI surfaces.
-         */
-        // Merged list available from getSchemasNotDisplayedBySystem
-        @SuppressLint("MissingGetterMatchingBuilder")
-        @NonNull
-        public Builder setSchemaTypeDisplayedBySystem(
-                @NonNull String schemaType, boolean displayed) {
-            Objects.requireNonNull(schemaType);
-            resetIfBuilt();
-            if (displayed) {
-                mSchemasNotDisplayedBySystem.remove(schemaType);
-            } else {
-                mSchemasNotDisplayedBySystem.add(schemaType);
-            }
-            return this;
-        }
-
-        /**
-         * Sets whether or not documents from the provided {@code schemaType} can be read by the
-         * specified package.
-         *
-         * <p>Each package is represented by a {@link PackageIdentifier}, containing a package name
-         * and a byte array of type {@link android.content.pm.PackageManager#CERT_INPUT_SHA256}.
-         *
-         * <p>To opt into one-way data sharing with another application, the developer will need to
-         * explicitly grant the other application’s package name and certificate Read access to its
-         * data.
-         *
-         * <p>For two-way data sharing, both applications need to explicitly grant Read access to
-         * one another.
-         *
-         * <p>By default, data sharing between applications is disabled.
-         *
-         * @param schemaType The schema type to set visibility on.
-         * @param visible Whether the {@code schemaType} will be visible or not.
-         * @param packageIdentifier Represents the package that will be granted visibility.
-         */
-        // Merged list available from getSchemasVisibleToPackages
-        @SuppressLint("MissingGetterMatchingBuilder")
-        @NonNull
-        public Builder setSchemaTypeVisibilityForPackage(
-                @NonNull String schemaType,
-                boolean visible,
-                @NonNull PackageIdentifier packageIdentifier) {
-            Objects.requireNonNull(schemaType);
-            Objects.requireNonNull(packageIdentifier);
-            resetIfBuilt();
-
-            Set<PackageIdentifier> packageIdentifiers = mSchemasVisibleToPackages.get(schemaType);
-            if (visible) {
-                if (packageIdentifiers == null) {
-                    packageIdentifiers = new ArraySet<>();
-                }
-                packageIdentifiers.add(packageIdentifier);
-                mSchemasVisibleToPackages.put(schemaType, packageIdentifiers);
-            } else {
-                if (packageIdentifiers == null) {
-                    // Return early since there was nothing set to begin with.
-                    return this;
-                }
-                packageIdentifiers.remove(packageIdentifier);
-                if (packageIdentifiers.isEmpty()) {
-                    // Remove the entire key so that we don't have empty sets as values.
-                    mSchemasVisibleToPackages.remove(schemaType);
-                }
-            }
-
-            return this;
-        }
-
-        /**
-         * Sets the {@link Migrator} associated with the given SchemaType.
-         *
-         * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type
-         * from the current version number stored in AppSearch to the final version set via {@link
-         * #setVersion}.
-         *
-         * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch
-         * is different from the final version set via {@link #setVersion} and {@link
-         * Migrator#shouldMigrate} returns {@code true}.
-         *
-         * <p>The target schema type of the output {@link GenericDocument} of {@link
-         * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link
-         * SetSchemaRequest}.
-         *
-         * @param schemaType The schema type to set migrator on.
-         * @param migrator The migrator translates a document from its current version to the final
-         *     version set via {@link #setVersion}.
-         * @see SetSchemaRequest.Builder#setVersion
-         * @see SetSchemaRequest.Builder#addSchemas
-         * @see AppSearchSession#setSchema
-         */
-        @NonNull
-        @SuppressLint("MissingGetterMatchingBuilder") // Getter return plural objects.
-        public Builder setMigrator(@NonNull String schemaType, @NonNull Migrator migrator) {
-            Objects.requireNonNull(schemaType);
-            Objects.requireNonNull(migrator);
-            resetIfBuilt();
-            mMigrators.put(schemaType, migrator);
-            return this;
-        }
-
-        /**
-         * Sets a Map of {@link Migrator}s.
-         *
-         * <p>The key of the map is the schema type that the {@link Migrator} value applies to.
-         *
-         * <p>The {@link Migrator} migrates all {@link GenericDocument}s under given schema type
-         * from the current version number stored in AppSearch to the final version set via {@link
-         * #setVersion}.
-         *
-         * <p>A {@link Migrator} will be invoked if the current version number stored in AppSearch
-         * is different from the final version set via {@link #setVersion} and {@link
-         * Migrator#shouldMigrate} returns {@code true}.
-         *
-         * <p>The target schema type of the output {@link GenericDocument} of {@link
-         * Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this {@link
-         * SetSchemaRequest}.
-         *
-         * @param migrators A {@link Map} of migrators that translate a document from it's current
-         *     version to the final version set via {@link #setVersion}. The key of the map is the
-         *     schema type that the {@link Migrator} value applies to.
-         * @see SetSchemaRequest.Builder#setVersion
-         * @see SetSchemaRequest.Builder#addSchemas
-         * @see AppSearchSession#setSchema
-         */
-        @NonNull
-        public Builder setMigrators(@NonNull Map<String, Migrator> migrators) {
-            Objects.requireNonNull(migrators);
-            resetIfBuilt();
-            mMigrators.putAll(migrators);
-            return this;
-        }
-
-        /**
-         * Sets whether or not to override the current schema in the {@link AppSearchSession}
-         * database.
-         *
-         * <p>Call this method whenever backward incompatible changes need to be made by setting
-         * {@code forceOverride} to {@code true}. As a result, during execution of the setSchema
-         * operation, all documents that are incompatible with the new schema will be deleted and
-         * the new schema will be saved and persisted.
-         *
-         * <p>By default, this is {@code false}.
-         */
-        @NonNull
-        public Builder setForceOverride(boolean forceOverride) {
-            resetIfBuilt();
-            mForceOverride = forceOverride;
-            return this;
-        }
-
-        /**
-         * Sets the version number of the overall {@link AppSearchSchema} in the database.
-         *
-         * <p>The {@link AppSearchSession} database can only ever hold documents for one version at
-         * a time.
-         *
-         * <p>Setting a version number that is different from the version number currently stored in
-         * AppSearch will result in AppSearch calling the {@link Migrator}s provided to {@link
-         * AppSearchSession#setSchema} to migrate the documents already in AppSearch from the
-         * previous version to the one set in this request. The version number can be updated
-         * without any other changes to the set of schemas.
-         *
-         * <p>The version number can stay the same, increase, or decrease relative to the current
-         * version number that is already stored in the {@link AppSearchSession} database.
-         *
-         * <p>The version of an empty database will always be 0. You cannot set version to the
-         * {@link SetSchemaRequest}, if it doesn't contains any {@link AppSearchSchema}.
-         *
-         * @param version A positive integer representing the version of the entire set of schemas
-         *     represents the version of the whole schema in the {@link AppSearchSession} database,
-         *     default version is 1.
-         * @throws IllegalArgumentException if the version is negative.
-         * @see AppSearchSession#setSchema
-         * @see Migrator
-         * @see SetSchemaRequest.Builder#setMigrator
-         */
-        @NonNull
-        public Builder setVersion(@IntRange(from = 1) int version) {
-            Preconditions.checkArgument(version >= 1, "Version must be a positive number.");
-            resetIfBuilt();
-            mVersion = version;
-            return this;
-        }
-
-        /**
-         * Builds a new {@link SetSchemaRequest} object.
-         *
-         * @throws IllegalArgumentException if schema types were referenced, but the corresponding
-         *     {@link AppSearchSchema} type was never added.
-         */
-        @NonNull
-        public SetSchemaRequest build() {
-            // Verify that any schema types with display or visibility settings refer to a real
-            // schema.
-            // Create a copy because we're going to remove from the set for verification purposes.
-            Set<String> referencedSchemas = new ArraySet<>(mSchemasNotDisplayedBySystem);
-            referencedSchemas.addAll(mSchemasVisibleToPackages.keySet());
-
-            for (AppSearchSchema schema : mSchemas) {
-                referencedSchemas.remove(schema.getSchemaType());
-            }
-            if (!referencedSchemas.isEmpty()) {
-                // We still have schema types that weren't seen in our mSchemas set. This means
-                // there wasn't a corresponding AppSearchSchema.
-                throw new IllegalArgumentException(
-                        "Schema types " + referencedSchemas + " referenced, but were not added.");
-            }
-            if (mSchemas.isEmpty() && mVersion != DEFAULT_VERSION) {
-                throw new IllegalArgumentException(
-                        "Cannot set version to the request if schema is empty.");
-            }
-            mBuilt = true;
-            return new SetSchemaRequest(
-                    mSchemas,
-                    mSchemasNotDisplayedBySystem,
-                    mSchemasVisibleToPackages,
-                    mMigrators,
-                    mForceOverride,
-                    mVersion);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                ArrayMap<String, Set<PackageIdentifier>> schemasVisibleToPackages =
-                        new ArrayMap<>(mSchemasVisibleToPackages.size());
-                for (Map.Entry<String, Set<PackageIdentifier>> entry :
-                        mSchemasVisibleToPackages.entrySet()) {
-                    schemasVisibleToPackages.put(entry.getKey(), new ArraySet<>(entry.getValue()));
-                }
-                mSchemasVisibleToPackages = schemasVisibleToPackages;
-
-                mSchemas = new ArraySet<>(mSchemas);
-                mSchemasNotDisplayedBySystem = new ArraySet<>(mSchemasNotDisplayedBySystem);
-                mMigrators = new ArrayMap<>(mMigrators);
-                mBuilt = false;
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
deleted file mode 100644
index a3a4a23..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaResponse.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.util.ArraySet;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/** The response class of {@link AppSearchSession#setSchema} */
-public class SetSchemaResponse {
-
-    private static final String DELETED_TYPES_FIELD = "deletedTypes";
-    private static final String INCOMPATIBLE_TYPES_FIELD = "incompatibleTypes";
-    private static final String MIGRATED_TYPES_FIELD = "migratedTypes";
-
-    private final Bundle mBundle;
-    /**
-     * The migrationFailures won't be saved in the bundle. Since:
-     *
-     * <ul>
-     *   <li>{@link MigrationFailure} is generated in {@link AppSearchSession} which will be the SDK
-     *       side in platform. We don't need to pass it from service side via binder.
-     *   <li>Translate multiple {@link MigrationFailure}s to bundles in {@link Builder} and then
-     *       back in constructor will be a huge waste.
-     * </ul>
-     */
-    private final List<MigrationFailure> mMigrationFailures;
-
-    /** Cache of the inflated deleted schema types. Comes from inflating mBundles at first use. */
-    @Nullable private Set<String> mDeletedTypes;
-
-    /** Cache of the inflated migrated schema types. Comes from inflating mBundles at first use. */
-    @Nullable private Set<String> mMigratedTypes;
-
-    /**
-     * Cache of the inflated incompatible schema types. Comes from inflating mBundles at first use.
-     */
-    @Nullable private Set<String> mIncompatibleTypes;
-
-    SetSchemaResponse(@NonNull Bundle bundle, @NonNull List<MigrationFailure> migrationFailures) {
-        mBundle = Objects.requireNonNull(bundle);
-        mMigrationFailures = Objects.requireNonNull(migrationFailures);
-    }
-
-    SetSchemaResponse(@NonNull Bundle bundle) {
-        this(bundle, /*migrationFailures=*/ Collections.emptyList());
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /**
-     * Returns a {@link List} of all failed {@link MigrationFailure}.
-     *
-     * <p>A {@link MigrationFailure} will be generated if the system trying to save a post-migrated
-     * {@link GenericDocument} but fail.
-     *
-     * <p>{@link MigrationFailure} contains the namespace, id and schemaType of the post-migrated
-     * {@link GenericDocument} and the error reason. Mostly it will be mismatch the schema it
-     * migrated to.
-     */
-    @NonNull
-    public List<MigrationFailure> getMigrationFailures() {
-        return Collections.unmodifiableList(mMigrationFailures);
-    }
-
-    /**
-     * Returns a {@link Set} of deleted schema types.
-     *
-     * <p>A "deleted" type is a schema type that was previously a part of the database schema but
-     * was not present in the {@link SetSchemaRequest} object provided in the
-     * {@link AppSearchSession#setSchema) call.
-     *
-     * <p>Documents for a deleted type are removed from the database.
-     */
-    @NonNull
-    public Set<String> getDeletedTypes() {
-        if (mDeletedTypes == null) {
-            mDeletedTypes =
-                    new ArraySet<>(
-                            Objects.requireNonNull(
-                                    mBundle.getStringArrayList(DELETED_TYPES_FIELD)));
-        }
-        return Collections.unmodifiableSet(mDeletedTypes);
-    }
-
-    /**
-     * Returns a {@link Set} of schema type that were migrated by the {@link
-     * AppSearchSession#setSchema} call.
-     *
-     * <p>A "migrated" type is a schema type that has triggered a {@link Migrator} instance to
-     * migrate documents of the schema type to another schema type, or to another version of the
-     * schema type.
-     *
-     * <p>If a document fails to be migrated, a {@link MigrationFailure} will be generated for that
-     * document.
-     *
-     * @see Migrator
-     */
-    @NonNull
-    public Set<String> getMigratedTypes() {
-        if (mMigratedTypes == null) {
-            mMigratedTypes =
-                    new ArraySet<>(
-                            Objects.requireNonNull(
-                                    mBundle.getStringArrayList(MIGRATED_TYPES_FIELD)));
-        }
-        return Collections.unmodifiableSet(mMigratedTypes);
-    }
-
-    /**
-     * Returns a {@link Set} of schema type whose new definitions set in the {@link
-     * AppSearchSession#setSchema} call were incompatible with the pre-existing schema.
-     *
-     * <p>If a {@link Migrator} is provided for this type and the migration is success triggered.
-     * The type will also appear in {@link #getMigratedTypes()}.
-     *
-     * @see SetSchemaRequest
-     * @see AppSearchSession#setSchema
-     * @see SetSchemaRequest.Builder#setForceOverride
-     */
-    @NonNull
-    public Set<String> getIncompatibleTypes() {
-        if (mIncompatibleTypes == null) {
-            mIncompatibleTypes =
-                    new ArraySet<>(
-                            Objects.requireNonNull(
-                                    mBundle.getStringArrayList(INCOMPATIBLE_TYPES_FIELD)));
-        }
-        return Collections.unmodifiableSet(mIncompatibleTypes);
-    }
-
-    /**
-     * Translates the {@link SetSchemaResponse}'s bundle to {@link Builder}.
-     *
-     * @hide
-     */
-    @NonNull
-    // TODO(b/179302942) change to Builder(mBundle) powered by mBundle.deepCopy
-    public Builder toBuilder() {
-        return new Builder()
-                .addDeletedTypes(getDeletedTypes())
-                .addIncompatibleTypes(getIncompatibleTypes())
-                .addMigratedTypes(getMigratedTypes())
-                .addMigrationFailures(mMigrationFailures);
-    }
-
-    /** Builder for {@link SetSchemaResponse} objects. */
-    public static final class Builder {
-        private List<MigrationFailure> mMigrationFailures = new ArrayList<>();
-        private ArrayList<String> mDeletedTypes = new ArrayList<>();
-        private ArrayList<String> mMigratedTypes = new ArrayList<>();
-        private ArrayList<String> mIncompatibleTypes = new ArrayList<>();
-        private boolean mBuilt = false;
-
-        /** Adds {@link MigrationFailure}s to the list of migration failures. */
-        @NonNull
-        public Builder addMigrationFailures(
-                @NonNull Collection<MigrationFailure> migrationFailures) {
-            Objects.requireNonNull(migrationFailures);
-            resetIfBuilt();
-            mMigrationFailures.addAll(migrationFailures);
-            return this;
-        }
-
-        /** Adds a {@link MigrationFailure} to the list of migration failures. */
-        @NonNull
-        public Builder addMigrationFailure(@NonNull MigrationFailure migrationFailure) {
-            Objects.requireNonNull(migrationFailure);
-            resetIfBuilt();
-            mMigrationFailures.add(migrationFailure);
-            return this;
-        }
-
-        /** Adds deletedTypes to the list of deleted schema types. */
-        @NonNull
-        public Builder addDeletedTypes(@NonNull Collection<String> deletedTypes) {
-            Objects.requireNonNull(deletedTypes);
-            resetIfBuilt();
-            mDeletedTypes.addAll(deletedTypes);
-            return this;
-        }
-
-        /** Adds one deletedType to the list of deleted schema types. */
-        @NonNull
-        public Builder addDeletedType(@NonNull String deletedType) {
-            Objects.requireNonNull(deletedType);
-            resetIfBuilt();
-            mDeletedTypes.add(deletedType);
-            return this;
-        }
-
-        /** Adds incompatibleTypes to the list of incompatible schema types. */
-        @NonNull
-        public Builder addIncompatibleTypes(@NonNull Collection<String> incompatibleTypes) {
-            Objects.requireNonNull(incompatibleTypes);
-            resetIfBuilt();
-            mIncompatibleTypes.addAll(incompatibleTypes);
-            return this;
-        }
-
-        /** Adds one incompatibleType to the list of incompatible schema types. */
-        @NonNull
-        public Builder addIncompatibleType(@NonNull String incompatibleType) {
-            Objects.requireNonNull(incompatibleType);
-            resetIfBuilt();
-            mIncompatibleTypes.add(incompatibleType);
-            return this;
-        }
-
-        /** Adds migratedTypes to the list of migrated schema types. */
-        @NonNull
-        public Builder addMigratedTypes(@NonNull Collection<String> migratedTypes) {
-            Objects.requireNonNull(migratedTypes);
-            resetIfBuilt();
-            mMigratedTypes.addAll(migratedTypes);
-            return this;
-        }
-
-        /** Adds one migratedType to the list of migrated schema types. */
-        @NonNull
-        public Builder addMigratedType(@NonNull String migratedType) {
-            Objects.requireNonNull(migratedType);
-            resetIfBuilt();
-            mMigratedTypes.add(migratedType);
-            return this;
-        }
-
-        /** Builds a {@link SetSchemaResponse} object. */
-        @NonNull
-        public SetSchemaResponse build() {
-            Bundle bundle = new Bundle();
-            bundle.putStringArrayList(INCOMPATIBLE_TYPES_FIELD, mIncompatibleTypes);
-            bundle.putStringArrayList(DELETED_TYPES_FIELD, mDeletedTypes);
-            bundle.putStringArrayList(MIGRATED_TYPES_FIELD, mMigratedTypes);
-            mBuilt = true;
-            // Avoid converting the potential thousands of MigrationFailures to Pracelable and
-            // back just for put in bundle. In platform, we should set MigrationFailures in
-            // AppSearchSession after we pass SetSchemaResponse via binder.
-            return new SetSchemaResponse(bundle, mMigrationFailures);
-        }
-
-        private void resetIfBuilt() {
-            if (mBuilt) {
-                mMigrationFailures = new ArrayList<>(mMigrationFailures);
-                mDeletedTypes = new ArrayList<>(mDeletedTypes);
-                mMigratedTypes = new ArrayList<>(mMigratedTypes);
-                mIncompatibleTypes = new ArrayList<>(mIncompatibleTypes);
-                mBuilt = false;
-            }
-        }
-    }
-
-    /**
-     * The class represents a post-migrated {@link GenericDocument} that failed to be saved by
-     * {@link AppSearchSession#setSchema}.
-     */
-    public static class MigrationFailure {
-        private static final String SCHEMA_TYPE_FIELD = "schemaType";
-        private static final String NAMESPACE_FIELD = "namespace";
-        private static final String DOCUMENT_ID_FIELD = "id";
-        private static final String ERROR_MESSAGE_FIELD = "errorMessage";
-        private static final String RESULT_CODE_FIELD = "resultCode";
-
-        private final Bundle mBundle;
-
-        /**
-         * Constructs a new {@link MigrationFailure}.
-         *
-         * @param namespace The namespace of the document which failed to be migrated.
-         * @param documentId The id of the document which failed to be migrated.
-         * @param schemaType The type of the document which failed to be migrated.
-         * @param failedResult The reason why the document failed to be indexed.
-         * @throws IllegalArgumentException if the provided {@code failedResult} was not a failure.
-         */
-        public MigrationFailure(
-                @NonNull String namespace,
-                @NonNull String documentId,
-                @NonNull String schemaType,
-                @NonNull AppSearchResult<?> failedResult) {
-            mBundle = new Bundle();
-            mBundle.putString(NAMESPACE_FIELD, Objects.requireNonNull(namespace));
-            mBundle.putString(DOCUMENT_ID_FIELD, Objects.requireNonNull(documentId));
-            mBundle.putString(SCHEMA_TYPE_FIELD, Objects.requireNonNull(schemaType));
-
-            Objects.requireNonNull(failedResult);
-            Preconditions.checkArgument(
-                    !failedResult.isSuccess(), "failedResult was actually successful");
-            mBundle.putString(ERROR_MESSAGE_FIELD, failedResult.getErrorMessage());
-            mBundle.putInt(RESULT_CODE_FIELD, failedResult.getResultCode());
-        }
-
-        MigrationFailure(@NonNull Bundle bundle) {
-            mBundle = Objects.requireNonNull(bundle);
-        }
-
-        /**
-         * Returns the Bundle of the {@link MigrationFailure}.
-         *
-         * @hide
-         */
-        @NonNull
-        public Bundle getBundle() {
-            return mBundle;
-        }
-
-        /** Returns the namespace of the {@link GenericDocument} that failed to be migrated. */
-        @NonNull
-        public String getNamespace() {
-            return mBundle.getString(NAMESPACE_FIELD, /*defaultValue=*/ "");
-        }
-
-        /** Returns the id of the {@link GenericDocument} that failed to be migrated. */
-        @NonNull
-        public String getDocumentId() {
-            return mBundle.getString(DOCUMENT_ID_FIELD, /*defaultValue=*/ "");
-        }
-
-        /** Returns the schema type of the {@link GenericDocument} that failed to be migrated. */
-        @NonNull
-        public String getSchemaType() {
-            return mBundle.getString(SCHEMA_TYPE_FIELD, /*defaultValue=*/ "");
-        }
-
-        /**
-         * Returns the {@link AppSearchResult} that indicates why the post-migration {@link
-         * GenericDocument} failed to be indexed.
-         */
-        @NonNull
-        public AppSearchResult<Void> getAppSearchResult() {
-            return AppSearchResult.newFailedResult(
-                    mBundle.getInt(RESULT_CODE_FIELD),
-                    mBundle.getString(ERROR_MESSAGE_FIELD, /*defaultValue=*/ ""));
-        }
-
-        @NonNull
-        @Override
-        public String toString() {
-            return "MigrationFailure { schemaType: "
-                    + getSchemaType()
-                    + ", namespace: "
-                    + getNamespace()
-                    + ", documentId: "
-                    + getDocumentId()
-                    + ", appSearchResult: "
-                    + getAppSearchResult().toString()
-                    + "}";
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java b/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
deleted file mode 100644
index 64d4828..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/StorageInfo.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import android.annotation.NonNull;
-import android.os.Bundle;
-
-import java.util.Objects;
-
-/** The response class of {@code AppSearchSession#getStorageInfo}. */
-public class StorageInfo {
-
-    private static final String SIZE_BYTES_FIELD = "sizeBytes";
-    private static final String ALIVE_DOCUMENTS_COUNT = "aliveDocumentsCount";
-    private static final String ALIVE_NAMESPACES_COUNT = "aliveNamespacesCount";
-
-    private final Bundle mBundle;
-
-    StorageInfo(@NonNull Bundle bundle) {
-        mBundle = Objects.requireNonNull(bundle);
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /** Returns the estimated size of the session's database in bytes. */
-    public long getSizeBytes() {
-        return mBundle.getLong(SIZE_BYTES_FIELD);
-    }
-
-    /**
-     * Returns the number of alive documents in the current session.
-     *
-     * <p>Alive documents are documents that haven't been deleted and haven't exceeded the ttl as
-     * set in {@link GenericDocument.Builder#setTtlMillis}.
-     */
-    public int getAliveDocumentsCount() {
-        return mBundle.getInt(ALIVE_DOCUMENTS_COUNT);
-    }
-
-    /**
-     * Returns the number of namespaces that have at least one alive document in the current
-     * session's database.
-     *
-     * <p>Alive documents are documents that haven't been deleted and haven't exceeded the ttl as
-     * set in {@link GenericDocument.Builder#setTtlMillis}.
-     */
-    public int getAliveNamespacesCount() {
-        return mBundle.getInt(ALIVE_NAMESPACES_COUNT);
-    }
-
-    /** Builder for {@link StorageInfo} objects. */
-    public static final class Builder {
-        private long mSizeBytes;
-        private int mAliveDocumentsCount;
-        private int mAliveNamespacesCount;
-
-        /** Sets the size in bytes. */
-        @NonNull
-        public StorageInfo.Builder setSizeBytes(long sizeBytes) {
-            mSizeBytes = sizeBytes;
-            return this;
-        }
-
-        /** Sets the number of alive documents. */
-        @NonNull
-        public StorageInfo.Builder setAliveDocumentsCount(int aliveDocumentsCount) {
-            mAliveDocumentsCount = aliveDocumentsCount;
-            return this;
-        }
-
-        /** Sets the number of alive namespaces. */
-        @NonNull
-        public StorageInfo.Builder setAliveNamespacesCount(int aliveNamespacesCount) {
-            mAliveNamespacesCount = aliveNamespacesCount;
-            return this;
-        }
-
-        /** Builds a {@link StorageInfo} object. */
-        @NonNull
-        public StorageInfo build() {
-            Bundle bundle = new Bundle();
-            bundle.putLong(SIZE_BYTES_FIELD, mSizeBytes);
-            bundle.putInt(ALIVE_DOCUMENTS_COUNT, mAliveDocumentsCount);
-            bundle.putInt(ALIVE_NAMESPACES_COUNT, mAliveNamespacesCount);
-            return new StorageInfo(bundle);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/AppSearchException.java b/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/AppSearchException.java
deleted file mode 100644
index 62593ae8..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/AppSearchException.java
+++ /dev/null
@@ -1,85 +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.exceptions;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchResult;
-
-/**
- * An exception thrown by {@link android.app.appsearch.AppSearchSession} or a subcomponent.
- *
- * <p>These exceptions can be converted into a failed {@link AppSearchResult} for propagating to the
- * client.
- */
-public class AppSearchException extends Exception {
-    private final @AppSearchResult.ResultCode int mResultCode;
-
-    /**
-     * Initializes an {@link AppSearchException} with no message.
-     *
-     * @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
-     */
-    public AppSearchException(@AppSearchResult.ResultCode int resultCode) {
-        this(resultCode, /*message=*/ null);
-    }
-
-    /**
-     * Initializes an {@link AppSearchException} with a result code and message.
-     *
-     * @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
-     * @param message The detail message (which is saved for later retrieval by the {@link
-     *     #getMessage()} method).
-     */
-    public AppSearchException(
-            @AppSearchResult.ResultCode int resultCode, @Nullable String message) {
-        this(resultCode, message, /*cause=*/ null);
-    }
-
-    /**
-     * Initializes an {@link AppSearchException} with a result code, message and cause.
-     *
-     * @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
-     * @param message The detail message (which is saved for later retrieval by the {@link
-     *     #getMessage()} method).
-     * @param cause The cause (which is saved for later retrieval by the {@link #getCause()}
-     *     method). (A null value is permitted, and indicates that the cause is nonexistent or
-     *     unknown.)
-     */
-    public AppSearchException(
-            @AppSearchResult.ResultCode int resultCode,
-            @Nullable String message,
-            @Nullable Throwable cause) {
-        super(message, cause);
-        mResultCode = resultCode;
-    }
-
-    /**
-     * Returns the result code this exception was constructed with.
-     *
-     * @return One of the constants documented in {@link AppSearchResult#getResultCode}.
-     */
-    public @AppSearchResult.ResultCode int getResultCode() {
-        return mResultCode;
-    }
-
-    /** Converts this {@link java.lang.Exception} into a failed {@link AppSearchResult}. */
-    @NonNull
-    public <T> AppSearchResult<T> toAppSearchResult() {
-        return AppSearchResult.newFailedResult(mResultCode, getMessage());
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSchemaException.java b/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSchemaException.java
deleted file mode 100644
index 5f8da7f..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSchemaException.java
+++ /dev/null
@@ -1,36 +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.exceptions;
-
-import android.annotation.NonNull;
-
-/**
- * Indicates that a {@link android.app.appsearch.AppSearchSchema} has logical inconsistencies such
- * as unpopulated mandatory fields or illegal combinations of parameters.
- *
- * @hide
- */
-public class IllegalSchemaException extends IllegalArgumentException {
-    /**
-     * Constructs a new {@link IllegalSchemaException}.
-     *
-     * @param message A developer-readable description of the issue with the bundle.
-     */
-    public IllegalSchemaException(@NonNull String message) {
-        super(message);
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/BundleUtil.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/BundleUtil.java
deleted file mode 100644
index e77043f..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/util/BundleUtil.java
+++ /dev/null
@@ -1,251 +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.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Utilities for working with {@link android.os.Bundle}.
- *
- * @hide
- */
-public final class BundleUtil {
-    private BundleUtil() {}
-
-    /**
-     * Deeply checks two bundles are equal or not.
-     *
-     * <p>Two bundles will be considered equal if they contain the same keys, and each value is also
-     * equal. Bundle values are compared using deepEquals.
-     */
-    public static boolean deepEquals(@Nullable Bundle one, @Nullable Bundle two) {
-        if (one == null && two == null) {
-            return true;
-        }
-        if (one == null || two == null) {
-            return false;
-        }
-        if (one.size() != two.size()) {
-            return false;
-        }
-        if (!one.keySet().equals(two.keySet())) {
-            return false;
-        }
-        // Bundle inherit its equals() from Object.java, which only compare their memory address.
-        // We should iterate all keys and check their presents and values in both bundle.
-        for (String key : one.keySet()) {
-            if (!bundleValueEquals(one.get(key), two.get(key))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Deeply checks whether two values in a Bundle are equal or not.
-     *
-     * <p>Values of type Bundle are compared using {@link #deepEquals}.
-     */
-    private static boolean bundleValueEquals(@Nullable Object one, @Nullable Object two) {
-        if (one == null && two == null) {
-            return true;
-        }
-        if (one == null || two == null) {
-            return false;
-        }
-        if (one.equals(two)) {
-            return true;
-        }
-        if (one instanceof Bundle && two instanceof Bundle) {
-            return deepEquals((Bundle) one, (Bundle) two);
-        } else if (one instanceof int[] && two instanceof int[]) {
-            return Arrays.equals((int[]) one, (int[]) two);
-        } else if (one instanceof byte[] && two instanceof byte[]) {
-            return Arrays.equals((byte[]) one, (byte[]) two);
-        } else if (one instanceof char[] && two instanceof char[]) {
-            return Arrays.equals((char[]) one, (char[]) two);
-        } else if (one instanceof long[] && two instanceof long[]) {
-            return Arrays.equals((long[]) one, (long[]) two);
-        } else if (one instanceof float[] && two instanceof float[]) {
-            return Arrays.equals((float[]) one, (float[]) two);
-        } else if (one instanceof short[] && two instanceof short[]) {
-            return Arrays.equals((short[]) one, (short[]) two);
-        } else if (one instanceof double[] && two instanceof double[]) {
-            return Arrays.equals((double[]) one, (double[]) two);
-        } else if (one instanceof boolean[] && two instanceof boolean[]) {
-            return Arrays.equals((boolean[]) one, (boolean[]) two);
-        } else if (one instanceof Object[] && two instanceof Object[]) {
-            Object[] arrayOne = (Object[]) one;
-            Object[] arrayTwo = (Object[]) two;
-            if (arrayOne.length != arrayTwo.length) {
-                return false;
-            }
-            if (Arrays.equals(arrayOne, arrayTwo)) {
-                return true;
-            }
-            for (int i = 0; i < arrayOne.length; i++) {
-                if (!bundleValueEquals(arrayOne[i], arrayTwo[i])) {
-                    return false;
-                }
-            }
-            return true;
-        } else if (one instanceof ArrayList && two instanceof ArrayList) {
-            ArrayList<?> listOne = (ArrayList<?>) one;
-            ArrayList<?> listTwo = (ArrayList<?>) two;
-            if (listOne.size() != listTwo.size()) {
-                return false;
-            }
-            for (int i = 0; i < listOne.size(); i++) {
-                if (!bundleValueEquals(listOne.get(i), listTwo.get(i))) {
-                    return false;
-                }
-            }
-            return true;
-        } else if (one instanceof SparseArray && two instanceof SparseArray) {
-            SparseArray<?> arrayOne = (SparseArray<?>) one;
-            SparseArray<?> arrayTwo = (SparseArray<?>) two;
-            if (arrayOne.size() != arrayTwo.size()) {
-                return false;
-            }
-            for (int i = 0; i < arrayOne.size(); i++) {
-                if (arrayOne.keyAt(i) != arrayTwo.keyAt(i)
-                        || !bundleValueEquals(arrayOne.valueAt(i), arrayTwo.valueAt(i))) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Calculates the hash code for a bundle.
-     *
-     * <p>The hash code is only effected by the contents in the bundle. Bundles will get consistent
-     * hash code if they have same contents.
-     */
-    public static int deepHashCode(@Nullable Bundle bundle) {
-        if (bundle == null) {
-            return 0;
-        }
-        int[] hashCodes = new int[bundle.size() + 1];
-        int hashCodeIdx = 0;
-        // Bundle inherit its hashCode() from Object.java, which only relative to their memory
-        // address. Bundle doesn't have an order, so we should iterate all keys and combine
-        // their value's hashcode into an array. And use the hashcode of the array to be
-        // the hashcode of the bundle.
-        // Because bundle.keySet() doesn't guarantee any particular order, we need to sort the keys
-        // in case the iteration order varies from run to run.
-        String[] keys = bundle.keySet().toArray(new String[0]);
-        Arrays.sort(keys);
-        // Hash the keys so we can detect key-only differences
-        hashCodes[hashCodeIdx++] = Arrays.hashCode(keys);
-        for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
-            Object value = bundle.get(keys[keyIdx]);
-            if (value instanceof Bundle) {
-                hashCodes[hashCodeIdx++] = deepHashCode((Bundle) value);
-            } else if (value instanceof int[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((int[]) value);
-            } else if (value instanceof byte[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((byte[]) value);
-            } else if (value instanceof char[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((char[]) value);
-            } else if (value instanceof long[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((long[]) value);
-            } else if (value instanceof float[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((float[]) value);
-            } else if (value instanceof short[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((short[]) value);
-            } else if (value instanceof double[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((double[]) value);
-            } else if (value instanceof boolean[]) {
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((boolean[]) value);
-            } else if (value instanceof String[]) {
-                // Optimization to avoid Object[] handler creating an inner array for common cases
-                hashCodes[hashCodeIdx++] = Arrays.hashCode((String[]) value);
-            } else if (value instanceof Object[]) {
-                Object[] array = (Object[]) value;
-                int[] innerHashCodes = new int[array.length];
-                for (int j = 0; j < array.length; j++) {
-                    if (array[j] instanceof Bundle) {
-                        innerHashCodes[j] = deepHashCode((Bundle) array[j]);
-                    } else if (array[j] != null) {
-                        innerHashCodes[j] = array[j].hashCode();
-                    }
-                }
-                hashCodes[hashCodeIdx++] = Arrays.hashCode(innerHashCodes);
-            } else if (value instanceof ArrayList) {
-                ArrayList<?> list = (ArrayList<?>) value;
-                int[] innerHashCodes = new int[list.size()];
-                for (int j = 0; j < innerHashCodes.length; j++) {
-                    Object item = list.get(j);
-                    if (item instanceof Bundle) {
-                        innerHashCodes[j] = deepHashCode((Bundle) item);
-                    } else if (item != null) {
-                        innerHashCodes[j] = item.hashCode();
-                    }
-                }
-                hashCodes[hashCodeIdx++] = Arrays.hashCode(innerHashCodes);
-            } else if (value instanceof SparseArray) {
-                SparseArray<?> array = (SparseArray<?>) value;
-                int[] innerHashCodes = new int[array.size() * 2];
-                for (int j = 0; j < array.size(); j++) {
-                    innerHashCodes[j * 2] = array.keyAt(j);
-                    Object item = array.valueAt(j);
-                    if (item instanceof Bundle) {
-                        innerHashCodes[j * 2 + 1] = deepHashCode((Bundle) item);
-                    } else if (item != null) {
-                        innerHashCodes[j * 2 + 1] = item.hashCode();
-                    }
-                }
-                hashCodes[hashCodeIdx++] = Arrays.hashCode(innerHashCodes);
-            } else {
-                hashCodes[hashCodeIdx++] = value.hashCode();
-            }
-        }
-        return Arrays.hashCode(hashCodes);
-    }
-
-    /**
-     * Deeply clones a Bundle.
-     *
-     * <p>Values which are Bundles, Lists or Arrays are deeply copied themselves.
-     */
-    @NonNull
-    public static Bundle deepCopy(@NonNull Bundle bundle) {
-        // Write bundle to bytes
-        Parcel parcel = Parcel.obtain();
-        try {
-            parcel.writeBundle(bundle);
-            byte[] serializedMessage = parcel.marshall();
-
-            // Read bundle from bytes
-            parcel.unmarshall(serializedMessage, 0, serializedMessage.length);
-            parcel.setDataPosition(0);
-            return parcel.readBundle();
-        } finally {
-            parcel.recycle();
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java
deleted file mode 100644
index b494c3c..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.util;
-
-import android.annotation.NonNull;
-
-/**
- * Utility for building indented strings.
- *
- * <p>This is a wrapper for {@link StringBuilder} for appending strings with indentation. The
- * indentation level can be increased by calling {@link #increaseIndentLevel()} and decreased by
- * calling {@link #decreaseIndentLevel()}.
- *
- * <p>Indentation is applied after each newline character for the given indent level.
- *
- * @hide
- */
-public class IndentingStringBuilder {
-    private final StringBuilder mStringBuilder = new StringBuilder();
-
-    // Indicates whether next non-newline character should have an indent applied before it.
-    private boolean mIndentNext = false;
-    private int mIndentLevel = 0;
-
-    /** Increases the indent level by one for appended strings. */
-    @NonNull
-    public IndentingStringBuilder increaseIndentLevel() {
-        mIndentLevel++;
-        return this;
-    }
-
-    /** Decreases the indent level by one for appended strings. */
-    @NonNull
-    public IndentingStringBuilder decreaseIndentLevel() throws IllegalStateException {
-        if (mIndentLevel == 0) {
-            throw new IllegalStateException("Cannot set indent level below 0.");
-        }
-        mIndentLevel--;
-        return this;
-    }
-
-    /**
-     * Appends provided {@code String} at the current indentation level.
-     *
-     * <p>Indentation is applied after each newline character.
-     */
-    @NonNull
-    public IndentingStringBuilder append(@NonNull String str) {
-        applyIndentToString(str);
-        return this;
-    }
-
-    /**
-     * Appends provided {@code Object}, represented as a {@code String}, at the current indentation
-     * level.
-     *
-     * <p>Indentation is applied after each newline character.
-     */
-    @NonNull
-    public IndentingStringBuilder append(@NonNull Object obj) {
-        applyIndentToString(obj.toString());
-        return this;
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        return mStringBuilder.toString();
-    }
-
-    /** Adds indent string to the {@link StringBuilder} instance for current indent level. */
-    private void applyIndent() {
-        for (int i = 0; i < mIndentLevel; i++) {
-            mStringBuilder.append("  ");
-        }
-    }
-
-    /**
-     * Applies indent, for current indent level, after each newline character.
-     *
-     * <p>Consecutive newline characters are not indented.
-     */
-    private void applyIndentToString(@NonNull String str) {
-        int index = str.indexOf("\n");
-        if (index == 0) {
-            // String begins with new line character: append newline and slide past newline.
-            mStringBuilder.append("\n");
-            mIndentNext = true;
-            if (str.length() > 1) {
-                applyIndentToString(str.substring(index + 1));
-            }
-        } else if (index >= 1) {
-            // String contains new line character: divide string between newline, append new line,
-            // and recurse on each string.
-            String beforeIndentString = str.substring(0, index);
-            applyIndentToString(beforeIndentString);
-            mStringBuilder.append("\n");
-            mIndentNext = true;
-            if (str.length() > index + 1) {
-                String afterIndentString = str.substring(index + 1);
-                applyIndentToString(afterIndentString);
-            }
-        } else {
-            // String does not contain newline character: append string.
-            if (mIndentNext) {
-                applyIndent();
-                mIndentNext = false;
-            }
-            mStringBuilder.append(str);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/LogUtil.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/LogUtil.java
deleted file mode 100644
index f2cc3b9..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/util/LogUtil.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.util.Log;
-
-import java.util.Objects;
-
-/**
- * Utilities for logging to logcat.
- *
- * @hide
- */
-public final class LogUtil {
-    /**
-     * The {@link #piiTrace} logs are intended for sensitive data that can't be enabled in
-     * production, so they are build-gated by this constant.
-     *
-     * <p>
-     *
-     * <ul>
-     *   <li>0: no tracing.
-     *   <li>1: fast tracing (statuses/counts only)
-     *   <li>2: full tracing (complete messages)
-     * </ul>
-     */
-    private static final int PII_TRACE_LEVEL = 0;
-
-    private final String mTag;
-
-    public LogUtil(@NonNull String tag) {
-        mTag = Objects.requireNonNull(tag);
-    }
-
-    /** Returns whether piiTrace() is enabled (PII_TRACE_LEVEL > 0). */
-    public boolean isPiiTraceEnabled() {
-        return PII_TRACE_LEVEL > 0;
-    }
-
-    /**
-     * If icing lib interaction tracing is enabled via {@link #PII_TRACE_LEVEL}, logs the provided
-     * message to logcat.
-     *
-     * <p>If {@link #PII_TRACE_LEVEL} is 0, nothing is logged and this method returns immediately.
-     */
-    public void piiTrace(@NonNull String message) {
-        piiTrace(message, /*fastTraceObj=*/ null, /*fullTraceObj=*/ null);
-    }
-
-    /**
-     * If icing lib interaction tracing is enabled via {@link #PII_TRACE_LEVEL}, logs the provided
-     * message and object to logcat.
-     *
-     * <p>If {@link #PII_TRACE_LEVEL} is 0, nothing is logged and this method returns immediately.
-     *
-     * <p>Otherwise, {@code traceObj} is logged if it is non-null.
-     */
-    public void piiTrace(@NonNull String message, @Nullable Object traceObj) {
-        piiTrace(message, /*fastTraceObj=*/ traceObj, /*fullTraceObj=*/ null);
-    }
-
-    /**
-     * If icing lib interaction tracing is enabled via {@link #PII_TRACE_LEVEL}, logs the provided
-     * message and objects to logcat.
-     *
-     * <p>If {@link #PII_TRACE_LEVEL} is 0, nothing is logged and this method returns immediately.
-     *
-     * <p>If {@link #PII_TRACE_LEVEL} is 1, {@code fastTraceObj} is logged if it is non-null.
-     *
-     * <p>If {@link #PII_TRACE_LEVEL} is 2, {@code fullTraceObj} is logged if it is non-null, else
-     * {@code fastTraceObj} is logged if it is non-null..
-     */
-    public void piiTrace(
-            @NonNull String message, @Nullable Object fastTraceObj, @Nullable Object fullTraceObj) {
-        if (PII_TRACE_LEVEL == 0) {
-            return;
-        }
-        StringBuilder builder = new StringBuilder("(trace) ").append(message);
-        if (PII_TRACE_LEVEL == 1 && fastTraceObj != null) {
-            builder.append(": ").append(fastTraceObj);
-        } else if (PII_TRACE_LEVEL == 2 && fullTraceObj != null) {
-            builder.append(": ").append(fullTraceObj);
-        } else if (PII_TRACE_LEVEL == 2 && fastTraceObj != null) {
-            builder.append(": ").append(fastTraceObj);
-        }
-        Log.i(mTag, builder.toString());
-    }
-}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java
deleted file mode 100644
index 10e014b..0000000
--- a/apex/appsearch/framework/java/external/android/app/appsearch/util/SchemaMigrationUtil.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.util;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.Migrator;
-import android.app.appsearch.SetSchemaResponse;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Utilities for schema migration.
- *
- * @hide
- */
-public final class SchemaMigrationUtil {
-    private SchemaMigrationUtil() {}
-
-    /**
-     * Returns all active {@link Migrator}s that need to be triggered in this migration.
-     *
-     * <p>{@link Migrator#shouldMigrate} returns {@code true} will make the {@link Migrator} active.
-     */
-    @NonNull
-    public static Map<String, Migrator> getActiveMigrators(
-            @NonNull Set<AppSearchSchema> existingSchemas,
-            @NonNull Map<String, Migrator> migrators,
-            int currentVersion,
-            int finalVersion) {
-        if (currentVersion == finalVersion) {
-            return Collections.emptyMap();
-        }
-        Set<String> existingTypes = new ArraySet<>(existingSchemas.size());
-        for (AppSearchSchema schema : existingSchemas) {
-            existingTypes.add(schema.getSchemaType());
-        }
-
-        Map<String, Migrator> activeMigrators = new ArrayMap<>();
-        for (Map.Entry<String, Migrator> entry : migrators.entrySet()) {
-            // The device contains the source type, and we should trigger migration for the type.
-            String schemaType = entry.getKey();
-            Migrator migrator = entry.getValue();
-            if (existingTypes.contains(schemaType)
-                    && migrator.shouldMigrate(currentVersion, finalVersion)) {
-                activeMigrators.put(schemaType, migrator);
-            }
-        }
-        return activeMigrators;
-    }
-
-    /**
-     * Checks the setSchema() call won't delete any types or has incompatible types after all {@link
-     * Migrator} has been triggered..
-     */
-    public static void checkDeletedAndIncompatibleAfterMigration(
-            @NonNull SetSchemaResponse setSchemaResponse, @NonNull Set<String> activeMigrators)
-            throws AppSearchException {
-        Set<String> unmigratedIncompatibleTypes =
-                new ArraySet<>(setSchemaResponse.getIncompatibleTypes());
-        unmigratedIncompatibleTypes.removeAll(activeMigrators);
-
-        Set<String> unmigratedDeletedTypes = new ArraySet<>(setSchemaResponse.getDeletedTypes());
-        unmigratedDeletedTypes.removeAll(activeMigrators);
-
-        // check if there are any unmigrated incompatible types or deleted types. If there
-        // are, we will getActiveMigratorsthrow an exception. That's the only case we
-        // swallowed in the AppSearchImpl#setSchema().
-        // Since the force override is false, the schema will not have been set if there are
-        // any incompatible or deleted types.
-        checkDeletedAndIncompatible(unmigratedDeletedTypes, unmigratedIncompatibleTypes);
-    }
-
-    /** Checks the setSchema() call won't delete any types or has incompatible types. */
-    public static void checkDeletedAndIncompatible(
-            @NonNull Set<String> deletedTypes, @NonNull Set<String> incompatibleTypes)
-            throws AppSearchException {
-        if (deletedTypes.size() > 0 || incompatibleTypes.size() > 0) {
-            String newMessage =
-                    "Schema is incompatible."
-                            + "\n  Deleted types: "
-                            + deletedTypes
-                            + "\n  Incompatible types: "
-                            + incompatibleTypes;
-            throw new AppSearchException(AppSearchResult.RESULT_INVALID_SCHEMA, newMessage);
-        }
-    }
-}
diff --git a/apex/appsearch/service/Android.bp b/apex/appsearch/service/Android.bp
deleted file mode 100644
index b6521ff..0000000
--- a/apex/appsearch/service/Android.bp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 2019 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-genrule {
-    name: "statslog-appsearch-java-gen",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out) --module appsearch --javaPackage com.android.server.appsearch.stats --javaClass AppSearchStatsLog",
-    out: ["com/android/server/appsearch/stats/AppSearchStatsLog.java"],
-}
-
-java_library {
-    name: "statslog-appsearch-lib",
-    srcs: [":statslog-appsearch-java-gen"],
-    libs: [
-        "framework-statsd.stubs.module_lib",
-    ],
-    sdk_version: "system_server_current",
-    apex_available: ["com.android.appsearch"],
-}
-
-java_library {
-    name: "service-appsearch",
-    srcs: ["java/**/*.java"],
-    sdk_version: "system_server_current",
-    static_libs: [
-        "icing-java-proto-lite",
-        "libicing-java",
-        "statslog-appsearch-lib",
-        // Entries below this line are outside of the appsearch package tree and must be kept in
-        // sync with jarjar.txt
-        "modules-utils-preconditions",
-    ],
-    libs: [
-        "framework-appsearch.impl",
-        "framework-statsd.stubs.module_lib",
-    ],
-    defaults: ["framework-system-server-module-defaults"],
-    permitted_packages: [
-        "com.android.server.appsearch",
-        "com.google.android.icing",
-    ],
-    jarjar_rules: "jarjar-rules.txt",
-    visibility: [
-        // These are required until appsearch is properly unbundled.
-        "//frameworks/base/services/tests/mockingservicestests",
-        "//frameworks/base/services/tests/servicestests",
-    ],
-    apex_available: ["com.android.appsearch"],
-    installable: true,
-}
diff --git a/apex/appsearch/service/jarjar-rules.txt b/apex/appsearch/service/jarjar-rules.txt
deleted file mode 100644
index c79ea22..0000000
--- a/apex/appsearch/service/jarjar-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# Rename all icing classes to match our module name. OEMs could start using icing lib for some other
-# purpose in system service, which would cause class collisions when loading our apex into the
-# system service.
-rule com.google.protobuf.** com.android.server.appsearch.protobuf.@1
-rule com.google.android.icing.proto.** com.android.server.appsearch.icing.proto.@1
-
-# Rename all com.android.internal.util classes to prevent class name collisions
-# between this module and the other versions of the utility classes linked into
-# the framework.
-
-# These must be kept in sync with the sources of framework-utils-appsearch
-rule com.android.internal.util.Preconditions* com.android.server.appsearch.internal.util.Preconditions@1
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java
deleted file mode 100644
index 29048b2..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch;
-
-import android.annotation.NonNull;
-import android.os.Bundle;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.OnPropertiesChangedListener;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * It contains all the keys for the flags, as well as caches some of latest flag values from
- * DeviceConfig.
- *
- * <p>Though the latest flag values can always be retrieved by calling {@code
- * DeviceConfig.getProperty}, we want to cache some of those values. For example, the sampling
- * intervals for logging, they are needed for each api call and it would be a little expensive to
- * call
- * {@code DeviceConfig.getProperty} every time.
- *
- * <p>Listener is registered to DeviceConfig keep the cached value up to date.
- *
- * <p>This class is thread-safe.
- *
- * @hide
- */
-public final class AppSearchConfig implements AutoCloseable {
-    private static volatile AppSearchConfig sConfig;
-
-    /**
-     * It would be used as default min time interval between samples in millis if there is no value
-     * set for {@link AppSearchConfig#KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS} in DeviceConfig.
-     */
-    @VisibleForTesting
-    static final long DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 50;
-
-    /**
-     * It would be used as default sampling interval if there is no value
-     * set for {@link AppSearchConfig#KEY_SAMPLING_INTERVAL_DEFAULT} in DeviceConfig.
-     */
-    @VisibleForTesting
-    static final int DEFAULT_SAMPLING_INTERVAL = 10;
-
-    @VisibleForTesting
-    static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES = 512 * 1024; // 512KiB
-    @VisibleForTesting
-    static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = 20_000;
-    @VisibleForTesting
-    static final int DEFAULT_BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024; // 1 MiB
-    @VisibleForTesting
-    static final int DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS = Integer.MAX_VALUE;
-    @VisibleForTesting
-    static final int DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD = 10_000;
-
-    /*
-     * Keys for ALL the flags stored in DeviceConfig.
-     */
-    public static final String KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS =
-            "min_time_interval_between_samples_millis";
-    public static final String KEY_SAMPLING_INTERVAL_DEFAULT = "sampling_interval_default";
-    public static final String KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS =
-            "sampling_interval_for_batch_call_stats";
-    public static final String KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS =
-            "sampling_interval_for_put_document_stats";
-    public static final String KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS =
-            "sampling_interval_for_initialize_stats";
-    public static final String KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS =
-            "sampling_interval_for_search_stats";
-    public static final String KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS =
-            "sampling_interval_for_global_search_stats";
-    public static final String KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS =
-            "sampling_interval_for_optimize_stats";
-    public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES =
-            "limit_config_max_document_size_bytes";
-    public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT =
-            "limit_config_max_document_docunt";
-    public static final String KEY_BYTES_OPTIMIZE_THRESHOLD = "bytes_optimize_threshold";
-    public static final String KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS = "time_optimize_threshold";
-    public static final String KEY_DOC_COUNT_OPTIMIZE_THRESHOLD = "doc_count_optimize_threshold";
-
-    // Array contains all the corresponding keys for the cached values.
-    private static final String[] KEYS_TO_ALL_CACHED_VALUES = {
-            KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-            KEY_SAMPLING_INTERVAL_DEFAULT,
-            KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-            KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-            KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS,
-            KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS,
-            KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS,
-            KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS,
-            KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES,
-            KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT,
-            KEY_BYTES_OPTIMIZE_THRESHOLD,
-            KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
-            KEY_DOC_COUNT_OPTIMIZE_THRESHOLD
-    };
-
-    // Lock needed for all the operations in this class.
-    private final Object mLock = new Object();
-
-    /**
-     * Bundle to hold all the cached flag values corresponding to
-     * {@link AppSearchConfig#KEYS_TO_ALL_CACHED_VALUES}.
-     */
-    @GuardedBy("mLock")
-    private final Bundle mBundleLocked = new Bundle();
-
-
-    @GuardedBy("mLock")
-    private boolean mIsClosedLocked = false;
-
-    /** Listener to update cached flag values from DeviceConfig. */
-    private final OnPropertiesChangedListener mOnDeviceConfigChangedListener =
-            properties -> {
-                if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_APPSEARCH)) {
-                    return;
-                }
-
-                updateCachedValues(properties);
-            };
-
-    private AppSearchConfig() {
-    }
-
-    /**
-     * Creates an instance of {@link AppSearchConfig}.
-     *
-     * @param executor used to fetch and cache the flag values from DeviceConfig during creation or
-     *                 config change.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    @NonNull
-    public static AppSearchConfig create(@NonNull Executor executor) {
-        Objects.requireNonNull(executor);
-        AppSearchConfig configManager = new AppSearchConfig();
-        configManager.initialize(executor);
-        return configManager;
-    }
-
-    /**
-     * Gets an instance of {@link AppSearchConfig} to be used.
-     *
-     * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
-     * existing instance will be returned.
-     */
-    @NonNull
-    public static AppSearchConfig getInstance(@NonNull Executor executor) {
-        Objects.requireNonNull(executor);
-        if (sConfig == null) {
-            synchronized (AppSearchConfig.class) {
-                if (sConfig == null) {
-                    sConfig = create(executor);
-                }
-            }
-        }
-        return sConfig;
-    }
-
-    /**
-     * Initializes the {@link AppSearchConfig}
-     *
-     * <p>It fetches the custom properties from DeviceConfig if available.
-     *
-     * @param executor listener would be run on to handle P/H flag change.
-     */
-    private void initialize(@NonNull Executor executor) {
-        executor.execute(() -> {
-            // Attach the callback to get updates on those properties.
-            DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APPSEARCH,
-                    executor,
-                    mOnDeviceConfigChangedListener);
-
-            DeviceConfig.Properties properties = DeviceConfig.getProperties(
-                    DeviceConfig.NAMESPACE_APPSEARCH, KEYS_TO_ALL_CACHED_VALUES);
-            updateCachedValues(properties);
-        });
-    }
-
-    // TODO(b/173532925) check this will be called. If we have a singleton instance for this
-    //  class, probably we don't need it.
-    @Override
-    public void close() {
-        synchronized (mLock) {
-            if (mIsClosedLocked) {
-                return;
-            }
-
-            DeviceConfig.removeOnPropertiesChangedListener(mOnDeviceConfigChangedListener);
-            mIsClosedLocked = true;
-        }
-    }
-
-    /** Returns cached value for minTimeIntervalBetweenSamplesMillis. */
-    public long getCachedMinTimeIntervalBetweenSamplesMillis() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getLong(KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                    DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS);
-        }
-    }
-
-    /**
-     * Returns cached value for default sampling interval for all the stats NOT listed in
-     * the configuration.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalDefault() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_DEFAULT, DEFAULT_SAMPLING_INTERVAL);
-        }
-    }
-
-    /**
-     * Returns cached value for sampling interval for batch calls.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalForBatchCallStats() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-                    getCachedSamplingIntervalDefault());
-        }
-    }
-
-    /**
-     * Returns cached value for sampling interval for putDocument.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalForPutDocumentStats() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                    getCachedSamplingIntervalDefault());
-        }
-    }
-
-    /**
-     * Returns cached value for sampling interval for initialize.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalForInitializeStats() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS,
-                    getCachedSamplingIntervalDefault());
-        }
-    }
-
-    /**
-     * Returns cached value for sampling interval for search.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalForSearchStats() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS,
-                    getCachedSamplingIntervalDefault());
-        }
-    }
-
-    /**
-     * Returns cached value for sampling interval for globalSearch.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalForGlobalSearchStats() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS,
-                    getCachedSamplingIntervalDefault());
-        }
-    }
-
-    /**
-     * Returns cached value for sampling interval for optimize.
-     *
-     * <p>For example, sampling_interval=10 means that one out of every 10 stats was logged.
-     */
-    public int getCachedSamplingIntervalForOptimizeStats() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS,
-                    getCachedSamplingIntervalDefault());
-        }
-    }
-
-    /** Returns the maximum serialized size an indexed document can be, in bytes. */
-    public int getCachedLimitConfigMaxDocumentSizeBytes() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES,
-                    DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES);
-        }
-    }
-
-    /** Returns the maximum number of active docs allowed per package. */
-    public int getCachedLimitConfigMaxDocumentCount() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT,
-                    DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT);
-        }
-    }
-
-    /**
-     * Returns the cached optimize byte size threshold.
-     *
-     * An AppSearch Optimize job will be triggered if the bytes size of garbage resource exceeds
-     * this threshold.
-     */
-    int getCachedBytesOptimizeThreshold() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_BYTES_OPTIMIZE_THRESHOLD,
-                    DEFAULT_BYTES_OPTIMIZE_THRESHOLD);
-        }
-    }
-
-    /**
-     * Returns the cached optimize time interval threshold.
-     *
-     * An AppSearch Optimize job will be triggered if the time since last optimize job exceeds
-     * this threshold.
-     */
-    int getCachedTimeOptimizeThresholdMs() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
-                    DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS);
-        }
-    }
-
-    /**
-     * Returns the cached optimize document count threshold threshold.
-     *
-     * An AppSearch Optimize job will be triggered if the number of document of garbage resource
-     * exceeds this threshold.
-     */
-    int getCachedDocCountOptimizeThreshold() {
-        synchronized (mLock) {
-            throwIfClosedLocked();
-            return mBundleLocked.getInt(KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
-                    DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD);
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void throwIfClosedLocked() {
-        if (mIsClosedLocked) {
-            throw new IllegalStateException("Trying to use a closed AppSearchConfig instance.");
-        }
-    }
-
-    private void updateCachedValues(@NonNull DeviceConfig.Properties properties) {
-        for (String key : properties.getKeyset()) {
-            updateCachedValue(key, properties);
-        }
-    }
-
-    private void updateCachedValue(@NonNull String key,
-            @NonNull DeviceConfig.Properties properties) {
-        if (properties.getString(key, /*defaultValue=*/ null) == null) {
-            // Key is missing or value is just null. That is not expected if the key is
-            // defined in the configuration.
-            //
-            // We choose NOT to put the default value in the bundle.
-            // Instead, we let the getters handle what default value should be returned.
-            //
-            // Also we keep the old value in the bundle. So getters can still
-            // return last valid value.
-            return;
-        }
-
-        switch (key) {
-            case KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS:
-                synchronized (mLock) {
-                    mBundleLocked.putLong(key,
-                            properties.getLong(key,
-                                    DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS));
-                }
-                break;
-            case KEY_SAMPLING_INTERVAL_DEFAULT:
-            case KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS:
-            case KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS:
-            case KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS:
-            case KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS:
-            case KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS:
-            case KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS:
-                synchronized (mLock) {
-                    mBundleLocked.putInt(key, properties.getInt(key, DEFAULT_SAMPLING_INTERVAL));
-                }
-                break;
-            case KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES:
-                synchronized (mLock) {
-                    mBundleLocked.putInt(
-                            key,
-                            properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES));
-                }
-                break;
-            case KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT:
-                synchronized (mLock) {
-                    mBundleLocked.putInt(
-                            key,
-                            properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT));
-                }
-                break;
-            case KEY_BYTES_OPTIMIZE_THRESHOLD:
-                synchronized (mLock) {
-                    mBundleLocked.putInt(key, properties.getInt(key,
-                            DEFAULT_BYTES_OPTIMIZE_THRESHOLD));
-                }
-                break;
-            case KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS:
-                synchronized (mLock) {
-                    mBundleLocked.putInt(key, properties.getInt(key,
-                            DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS));
-                }
-                break;
-            case KEY_DOC_COUNT_OPTIMIZE_THRESHOLD:
-                synchronized (mLock) {
-                    mBundleLocked.putInt(key, properties.getInt(key,
-                            DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD));
-                }
-                break;
-            default:
-                break;
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
deleted file mode 100644
index db23a6d..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ /dev/null
@@ -1,1522 +0,0 @@
-/*
- * Copyright (C) 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 com.android.server.appsearch;
-
-import static android.app.appsearch.AppSearchResult.throwableToFailedResult;
-import static android.os.Process.INVALID_UID;
-
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchMigrationHelper;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetSchemaResponse;
-import android.app.appsearch.PackageIdentifier;
-import android.app.appsearch.SearchResultPage;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.SetSchemaResponse;
-import android.app.appsearch.StorageInfo;
-import android.app.appsearch.aidl.AppSearchBatchResultParcel;
-import android.app.appsearch.aidl.AppSearchResultParcel;
-import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
-import android.app.appsearch.aidl.IAppSearchManager;
-import android.app.appsearch.aidl.IAppSearchResultCallback;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageStats;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.LocalManagerRegistry;
-import com.android.server.SystemService;
-import com.android.server.appsearch.external.localstorage.stats.CallStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
-import com.android.server.appsearch.stats.StatsCollector;
-import com.android.server.appsearch.util.PackageUtil;
-import com.android.server.usage.StorageStatsManagerLocal;
-import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
-
-import com.google.android.icing.proto.PersistType;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * The main service implementation which contains AppSearch's platform functionality.
- * @hide
- */
-public class AppSearchManagerService extends SystemService {
-    private static final String TAG = "AppSearchManagerService";
-    private final Context mContext;
-    private PackageManager mPackageManager;
-    private UserManager mUserManager;
-    private AppSearchUserInstanceManager mAppSearchUserInstanceManager;
-
-    // Never call shutdownNow(). It will cancel the futures it's returned. And since
-    // Executor#execute won't return anything, we will hang forever waiting for the execution.
-    // AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all
-    // mutate requests will need to gain write lock and query requests need to gain read lock.
-    private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
-            Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
-            new LinkedBlockingQueue<>());
-
-    // Cache of unlocked users so we don't have to query UserManager service each time. The "locked"
-    // suffix refers to the fact that access to the field should be locked; unrelated to the
-    // unlocked status of users.
-    @GuardedBy("mUnlockedUsersLocked")
-    private final Set<UserHandle> mUnlockedUsersLocked = new ArraySet<>();
-
-    public AppSearchManagerService(Context context) {
-        super(context);
-        mContext = context;
-    }
-
-    @Override
-    public void onStart() {
-        publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
-        mPackageManager = getContext().getPackageManager();
-        mAppSearchUserInstanceManager = AppSearchUserInstanceManager.getInstance();
-        mUserManager = mContext.getSystemService(UserManager.class);
-        registerReceivers();
-        LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
-                .registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
-    }
-
-    @Override
-    public void onBootPhase(/* @BootPhase */ int phase) {
-        if (phase == PHASE_BOOT_COMPLETED) {
-            StatsCollector.getInstance(mContext, EXECUTOR);
-        }
-    }
-
-    private void registerReceivers() {
-        mContext.registerReceiverForAllUsers(
-                new UserActionReceiver(),
-                new IntentFilter(Intent.ACTION_USER_REMOVED),
-                /*broadcastPermission=*/ null,
-                /*scheduler=*/ null);
-
-        //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
-        // broadcasts
-        IntentFilter packageChangedFilter = new IntentFilter();
-        packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
-        packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
-        packageChangedFilter.addDataScheme("package");
-        packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-        mContext.registerReceiverForAllUsers(
-                new PackageChangedReceiver(),
-                packageChangedFilter,
-                /*broadcastPermission=*/ null,
-                /*scheduler=*/ null);
-    }
-
-    private class UserActionReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(@NonNull Context context, @NonNull Intent intent) {
-            Objects.requireNonNull(context);
-            Objects.requireNonNull(intent);
-
-            switch (intent.getAction()) {
-                case Intent.ACTION_USER_REMOVED:
-                    UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
-                    if (userHandle == null) {
-                        Log.e(TAG, "Extra "
-                                + Intent.EXTRA_USER + " is missing in the intent: " + intent);
-                        return;
-                    }
-                    handleUserRemoved(userHandle);
-                    break;
-                default:
-                    Log.e(TAG, "Received unknown intent: " + intent);
-            }
-        }
-    }
-
-    /**
-     * Handles user removed action.
-     *
-     * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
-     * "credential encrypted" system directory of each user. That directory will be auto-deleted
-     * when a user is removed.
-     *
-     * @param userHandle The multi-user handle of the user that need to be removed.
-     *
-     * @see android.os.Environment#getDataSystemCeDirectory
-     */
-    private void handleUserRemoved(@NonNull UserHandle userHandle) {
-        try {
-            mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
-            Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
-        } catch (Throwable t) {
-            Log.e(TAG, "Unable to remove data for: " + userHandle, t);
-        }
-    }
-
-    private class PackageChangedReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(@NonNull Context context, @NonNull Intent intent) {
-            Objects.requireNonNull(context);
-            Objects.requireNonNull(intent);
-
-            switch (intent.getAction()) {
-                case Intent.ACTION_PACKAGE_FULLY_REMOVED:
-                case Intent.ACTION_PACKAGE_DATA_CLEARED:
-                    String packageName = intent.getData().getSchemeSpecificPart();
-                    if (packageName == null) {
-                        Log.e(TAG, "Package name is missing in the intent: " + intent);
-                        return;
-                    }
-                    int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID);
-                    if (uid == INVALID_UID) {
-                        Log.e(TAG, "uid is missing in the intent: " + intent);
-                        return;
-                    }
-                    handlePackageRemoved(packageName, uid);
-                    break;
-                default:
-                    Log.e(TAG, "Received unknown intent: " + intent);
-            }
-        }
-    }
-
-    private void handlePackageRemoved(@NonNull String packageName, int uid) {
-        UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
-        try {
-            if (isUserLocked(userHandle)) {
-                // We cannot access a locked user's directry and remove package data from it.
-                // We should remove those uninstalled package data when the user is unlocking.
-                return;
-            }
-            // Only clear the package's data if AppSearch exists for this user.
-            if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
-                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
-                AppSearchUserInstance instance =
-                        mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
-                //TODO(b/145759910) clear visibility setting for package.
-                instance.getAppSearchImpl().clearPackageData(packageName);
-                instance.getLogger().removeCachedUidForPackage(packageName);
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "Unable to remove data for package: " + packageName, t);
-        }
-    }
-
-    @Override
-    public void onUserUnlocking(@NonNull TargetUser user) {
-        Objects.requireNonNull(user);
-        UserHandle userHandle = user.getUserHandle();
-        synchronized (mUnlockedUsersLocked) {
-            mUnlockedUsersLocked.add(userHandle);
-        }
-        EXECUTOR.execute(() -> {
-            try {
-                // Only clear the package's data if AppSearch exists for this user.
-                if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
-                    Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                    userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
-                    List<PackageInfo> installedPackageInfos = userContext
-                            .getPackageManager()
-                            .getInstalledPackages(/*flags=*/0);
-                    Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size());
-                    for (int i = 0; i < installedPackageInfos.size(); i++) {
-                        packagesToKeep.add(installedPackageInfos.get(i).packageName);
-                    }
-                    packagesToKeep.add(VisibilityStore.PACKAGE_NAME);
-                    //TODO(b/145759910) clear visibility setting for package.
-                    instance.getAppSearchImpl().prunePackageData(packagesToKeep);
-                }
-            } catch (Throwable t) {
-                Log.e(TAG, "Unable to prune packages for " + user, t);
-            }
-        });
-    }
-
-    @Override
-    public void onUserStopping(@NonNull TargetUser user) {
-        Objects.requireNonNull(user);
-
-        synchronized (mUnlockedUsersLocked) {
-            UserHandle userHandle = user.getUserHandle();
-            mUnlockedUsersLocked.remove(userHandle);
-            try {
-                mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
-            } catch (Throwable t) {
-                Log.e(TAG, "Error handling user stopping.", t);
-            }
-        }
-    }
-
-    private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
-        if (isUserLocked(callingUser)) {
-            throw new IllegalStateException(callingUser + " is locked or not running.");
-        }
-    }
-
-    private boolean isUserLocked(@NonNull UserHandle callingUser) {
-        synchronized (mUnlockedUsersLocked) {
-            // First, check the local copy.
-            if (mUnlockedUsersLocked.contains(callingUser)) {
-                return false;
-            }
-            // If the local copy says the user is locked, check with UM for the actual state,
-            // since the user might just have been unlocked.
-            return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
-        }
-    }
-
-    private class Stub extends IAppSearchManager.Stub {
-        @Override
-        public void setSchema(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull List<Bundle> schemaBundles,
-                @NonNull List<String> schemasNotDisplayedBySystem,
-                @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
-                boolean forceOverride,
-                int schemaVersion,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(schemaBundles);
-            Objects.requireNonNull(schemasNotDisplayedBySystem);
-            Objects.requireNonNull(schemasVisibleToPackagesBundles);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
-                    for (int i = 0; i < schemaBundles.size(); i++) {
-                        schemas.add(new AppSearchSchema(schemaBundles.get(i)));
-                    }
-                    Map<String, List<PackageIdentifier>> schemasVisibleToPackages =
-                            new ArrayMap<>(schemasVisibleToPackagesBundles.size());
-                    for (Map.Entry<String, List<Bundle>> entry :
-                            schemasVisibleToPackagesBundles.entrySet()) {
-                        List<PackageIdentifier> packageIdentifiers =
-                                new ArrayList<>(entry.getValue().size());
-                        for (int i = 0; i < entry.getValue().size(); i++) {
-                            packageIdentifiers.add(
-                                    new PackageIdentifier(entry.getValue().get(i)));
-                        }
-                        schemasVisibleToPackages.put(entry.getKey(), packageIdentifiers);
-                    }
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    SetSchemaResponse setSchemaResponse = instance.getAppSearchImpl().setSchema(
-                            packageName,
-                            databaseName,
-                            schemas,
-                            instance.getVisibilityStore(),
-                            schemasNotDisplayedBySystem,
-                            schemasVisibleToPackages,
-                            forceOverride,
-                            schemaVersion);
-                    ++operationSuccessCount;
-                    invokeCallbackOnResult(callback,
-                            AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
-
-                    // setSchema will sync the schemas in the request to AppSearch, any existing
-                    // schemas which  is not included in the request will be delete if we force
-                    // override incompatible schemas. And all documents of these types will be
-                    // deleted as well. We should checkForOptimize for these deletion.
-                    checkForOptimize(instance);
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setDatabase(databaseName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void getSchema(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    GetSchemaResponse response =
-                            instance.getAppSearchImpl().getSchema(packageName, databaseName);
-                    invokeCallbackOnResult(
-                            callback,
-                            AppSearchResult.newSuccessfulResult(response.getBundle()));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void getNamespaces(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    List<String> namespaces =
-                            instance.getAppSearchImpl().getNamespaces(packageName, databaseName);
-                    invokeCallbackOnResult(
-                            callback, AppSearchResult.newSuccessfulResult(namespaces));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void putDocuments(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull List<Bundle> documentBundles,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchBatchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(documentBundles);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchBatchResult.Builder<String, Void> resultBuilder =
-                            new AppSearchBatchResult.Builder<>();
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    for (int i = 0; i < documentBundles.size(); i++) {
-                        GenericDocument document = new GenericDocument(documentBundles.get(i));
-                        try {
-                            instance.getAppSearchImpl().putDocument(
-                                    packageName, databaseName, document, instance.getLogger());
-                            resultBuilder.setSuccess(document.getId(), /*value=*/ null);
-                            ++operationSuccessCount;
-                        } catch (Throwable t) {
-                            resultBuilder.setResult(document.getId(), throwableToFailedResult(t));
-                            AppSearchResult<Void> result = throwableToFailedResult(t);
-                            resultBuilder.setResult(document.getId(), result);
-                            // Since we can only include one status code in the atom,
-                            // for failures, we would just save the one for the last failure
-                            statusCode = result.getResultCode();
-                            ++operationFailureCount;
-                        }
-                    }
-                    // Now that the batch has been written. Persist the newly written data.
-                    instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
-                    invokeCallbackOnResult(callback, resultBuilder.build());
-
-                    // The existing documents with same ID will be deleted, so there may be some
-                    // resources that could be released after optimize().
-                    checkForOptimize(instance, /*mutateBatchSize=*/ documentBundles.size());
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setDatabase(databaseName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void getDocuments(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull String namespace,
-                @NonNull List<String> ids,
-                @NonNull Map<String, List<String>> typePropertyPaths,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchBatchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(namespace);
-            Objects.requireNonNull(ids);
-            Objects.requireNonNull(typePropertyPaths);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
-                            new AppSearchBatchResult.Builder<>();
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    for (int i = 0; i < ids.size(); i++) {
-                        String id = ids.get(i);
-                        try {
-                            GenericDocument document = instance.getAppSearchImpl().getDocument(
-                                    packageName,
-                                    databaseName,
-                                    namespace,
-                                    id,
-                                    typePropertyPaths);
-                            ++operationSuccessCount;
-                            resultBuilder.setSuccess(id, document.getBundle());
-                        } catch (Throwable t) {
-                            // Since we can only include one status code in the atom,
-                            // for failures, we would just save the one for the last failure
-                            AppSearchResult<Bundle> result = throwableToFailedResult(t);
-                            resultBuilder.setResult(id, result);
-                            statusCode = result.getResultCode();
-                            ++operationFailureCount;
-                        }
-                    }
-                    invokeCallbackOnResult(callback, resultBuilder.build());
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setDatabase(databaseName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void query(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull String queryExpression,
-                @NonNull Bundle searchSpecBundle,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(queryExpression);
-            Objects.requireNonNull(searchSpecBundle);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
-                            packageName,
-                            databaseName,
-                            queryExpression,
-                            new SearchSpec(searchSpecBundle),
-                            instance.getLogger());
-                    ++operationSuccessCount;
-                    invokeCallbackOnResult(
-                            callback,
-                            AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setDatabase(databaseName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_SEARCH)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void globalQuery(
-                @NonNull String packageName,
-                @NonNull String queryExpression,
-                @NonNull Bundle searchSpecBundle,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(queryExpression);
-            Objects.requireNonNull(searchSpecBundle);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-
-                    boolean callerHasSystemAccess =
-                            instance.getVisibilityStore().doesCallerHaveSystemAccess(packageName);
-                    SearchResultPage searchResultPage = instance.getAppSearchImpl().globalQuery(
-                            queryExpression,
-                            new SearchSpec(searchSpecBundle),
-                            packageName,
-                            instance.getVisibilityStore(),
-                            callingUid,
-                            callerHasSystemAccess,
-                            instance.getLogger());
-                    ++operationSuccessCount;
-                    invokeCallbackOnResult(
-                            callback,
-                            AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void getNextPage(
-                @NonNull String packageName,
-                long nextPageToken,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
-            // opened it
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    SearchResultPage searchResultPage =
-                            instance.getAppSearchImpl().getNextPage(packageName, nextPageToken);
-                    invokeCallbackOnResult(
-                            callback,
-                            AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void invalidateNextPageToken(@NonNull String packageName, long nextPageToken,
-                @NonNull UserHandle userHandle) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(userHandle);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    instance.getAppSearchImpl().invalidateNextPageToken(packageName, nextPageToken);
-                } catch (Throwable t) {
-                    Log.e(TAG, "Unable to invalidate the query page token", t);
-                }
-            });
-        }
-
-        @Override
-        public void writeQueryResultsToFile(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull ParcelFileDescriptor fileDescriptor,
-                @NonNull String queryExpression,
-                @NonNull Bundle searchSpecBundle,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(fileDescriptor);
-            Objects.requireNonNull(queryExpression);
-            Objects.requireNonNull(searchSpecBundle);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    // we don't need to append the file. The file is always brand new.
-                    try (DataOutputStream outputStream = new DataOutputStream(
-                            new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
-                        SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
-                                packageName,
-                                databaseName,
-                                queryExpression,
-                                new SearchSpec(searchSpecBundle),
-                                /*logger=*/ null);
-                        while (!searchResultPage.getResults().isEmpty()) {
-                            for (int i = 0; i < searchResultPage.getResults().size(); i++) {
-                                AppSearchMigrationHelper.writeBundleToOutputStream(
-                                        outputStream, searchResultPage.getResults().get(i)
-                                                .getGenericDocument().getBundle());
-                            }
-                            searchResultPage = instance.getAppSearchImpl().getNextPage(
-                                    packageName, searchResultPage.getNextPageToken());
-                        }
-                    }
-                    invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void putDocumentsFromFile(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull ParcelFileDescriptor fileDescriptor,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(fileDescriptor);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-
-                    GenericDocument document;
-                    ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
-                    try (DataInputStream inputStream = new DataInputStream(
-                            new FileInputStream(fileDescriptor.getFileDescriptor()))) {
-                        while (true) {
-                            try {
-                                document = AppSearchMigrationHelper
-                                        .readDocumentFromInputStream(inputStream);
-                            } catch (EOFException e) {
-                                // nothing wrong, we just finish the reading.
-                                break;
-                            }
-                            try {
-                                instance.getAppSearchImpl().putDocument(
-                                        packageName, databaseName, document, /*logger=*/ null);
-                            } catch (Throwable t) {
-                                migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
-                                        document.getNamespace(),
-                                        document.getId(),
-                                        document.getSchemaType(),
-                                        AppSearchResult.throwableToFailedResult(t))
-                                        .getBundle());
-                            }
-                        }
-                    }
-                    instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
-                    invokeCallbackOnResult(callback,
-                            AppSearchResult.newSuccessfulResult(migrationFailureBundles));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void reportUsage(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull String namespace,
-                @NonNull String documentId,
-                long usageTimeMillis,
-                boolean systemUsage,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(namespace);
-            Objects.requireNonNull(documentId);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-
-                    if (systemUsage
-                            && !instance.getVisibilityStore()
-                            .doesCallerHaveSystemAccess(packageName)) {
-                        throw new AppSearchException(
-                                AppSearchResult.RESULT_SECURITY_ERROR,
-                                packageName + " does not have access to report system usage");
-                    }
-
-                    instance.getAppSearchImpl().reportUsage(
-                            packageName, databaseName, namespace, documentId,
-                            usageTimeMillis, systemUsage);
-                    invokeCallbackOnResult(
-                            callback, AppSearchResult.newSuccessfulResult(/*value=*/ null));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void removeByDocumentId(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull String namespace,
-                @NonNull List<String> ids,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchBatchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(namespace);
-            Objects.requireNonNull(ids);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchBatchResult.Builder<String, Void> resultBuilder =
-                            new AppSearchBatchResult.Builder<>();
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    for (int i = 0; i < ids.size(); i++) {
-                        String id = ids.get(i);
-                        try {
-                            instance.getAppSearchImpl().remove(
-                                    packageName,
-                                    databaseName,
-                                    namespace,
-                                    id,
-                                    /*removeStatsBuilder=*/ null);
-                            ++operationSuccessCount;
-                            resultBuilder.setSuccess(id, /*result= */ null);
-                        } catch (Throwable t) {
-                            AppSearchResult<Void> result = throwableToFailedResult(t);
-                            resultBuilder.setResult(id, result);
-                            // Since we can only include one status code in the atom,
-                            // for failures, we would just save the one for the last failure
-                            statusCode = result.getResultCode();
-                            ++operationFailureCount;
-                        }
-                    }
-                    // Now that the batch has been written. Persist the newly written data.
-                    instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
-                    invokeCallbackOnResult(callback, resultBuilder.build());
-
-                    checkForOptimize(instance, ids.size());
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setDatabase(databaseName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void removeByQuery(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull String queryExpression,
-                @NonNull Bundle searchSpecBundle,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchResultCallback callback) {
-            // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(queryExpression);
-            Objects.requireNonNull(searchSpecBundle);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    instance.getAppSearchImpl().removeByQuery(
-                            packageName,
-                            databaseName,
-                            queryExpression,
-                            new SearchSpec(searchSpecBundle),
-                            /*removeStatsBuilder=*/ null);
-                    // Now that the batch has been written. Persist the newly written data.
-                    instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
-                    ++operationSuccessCount;
-                    invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
-
-                    checkForOptimize(instance);
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setPackageName(packageName)
-                                .setDatabase(databaseName)
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void getStorageInfo(
-                @NonNull String packageName,
-                @NonNull String databaseName,
-                @NonNull UserHandle userHandle,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    AppSearchUserInstance instance =
-                            mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    StorageInfo storageInfo = instance.getAppSearchImpl()
-                            .getStorageInfoForDatabase(packageName, databaseName);
-                    Bundle storageInfoBundle = storageInfo.getBundle();
-                    invokeCallbackOnResult(
-                            callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
-                } catch (Throwable t) {
-                    invokeCallbackOnError(callback, t);
-                }
-            });
-        }
-
-        @Override
-        public void persistToDisk(
-                @NonNull String packageName,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(userHandle);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
-                    instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
-                    ++operationSuccessCount;
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    Log.e(TAG, "Unable to persist the data to disk", t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_FLUSH)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void initialize(
-                @NonNull String packageName,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
-                @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(userHandle);
-            Objects.requireNonNull(callback);
-
-            long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-            int callingUid = Binder.getCallingUid();
-            UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
-
-            EXECUTOR.execute(() -> {
-                @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
-                AppSearchUserInstance instance = null;
-                int operationSuccessCount = 0;
-                int operationFailureCount = 0;
-                try {
-                    Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0);
-                    verifyUserUnlocked(callingUser);
-                    verifyCallingPackage(userContext, callingUser, callingUid, packageName);
-                    verifyNotInstantApp(userContext, packageName);
-                    instance = mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                            userContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
-                    ++operationSuccessCount;
-                    invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
-                } catch (Throwable t) {
-                    ++operationFailureCount;
-                    statusCode = throwableToFailedResult(t).getResultCode();
-                    invokeCallbackOnError(callback, t);
-                } finally {
-                    if (instance != null) {
-                        int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
-                        int totalLatencyMillis =
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
-                        instance.getLogger().logStats(new CallStats.Builder()
-                                .setStatusCode(statusCode)
-                                .setTotalLatencyMillis(totalLatencyMillis)
-                                .setCallType(CallStats.CALL_TYPE_INITIALIZE)
-                                // TODO(b/173532925) check the existing binder call latency chart
-                                // is good enough for us:
-                                // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
-                                .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                                .setNumOperationsSucceeded(operationSuccessCount)
-                                .setNumOperationsFailed(operationFailureCount)
-                                .build());
-                    }
-                }
-            });
-        }
-
-        private void verifyCallingPackage(
-                @NonNull Context userContext,
-                @NonNull UserHandle actualCallingUser,
-                int actualCallingUid,
-                @NonNull String claimedCallingPackage) {
-            Objects.requireNonNull(actualCallingUser);
-            Objects.requireNonNull(claimedCallingPackage);
-
-            int claimedCallingUid = PackageUtil.getPackageUid(
-                    userContext, claimedCallingPackage);
-            if (claimedCallingUid == INVALID_UID) {
-                throw new SecurityException(
-                        "Specified calling package [" + claimedCallingPackage + "] not found");
-            }
-            if (claimedCallingUid != actualCallingUid) {
-                throw new SecurityException(
-                        "Specified calling package ["
-                                + claimedCallingPackage
-                                + "] does not match the calling uid "
-                                + actualCallingUid);
-            }
-        }
-
-        /** Invokes the {@link IAppSearchResultCallback} with the result. */
-        private void invokeCallbackOnResult(
-                IAppSearchResultCallback callback, AppSearchResult<?> result) {
-            try {
-                callback.onResult(new AppSearchResultParcel<>(result));
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to send result to the callback", e);
-            }
-        }
-
-        /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
-        private void invokeCallbackOnResult(
-                IAppSearchBatchResultCallback callback, AppSearchBatchResult<String, ?> result) {
-            try {
-                callback.onResult(new AppSearchBatchResultParcel<>(result));
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to send result to the callback", e);
-            }
-        }
-
-        /**
-         * Invokes the {@link IAppSearchResultCallback} with an throwable.
-         *
-         * <p>The throwable is convert to a {@link AppSearchResult};
-         */
-        private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
-            AppSearchResult<?> result = throwableToFailedResult(throwable);
-            try {
-                callback.onResult(new AppSearchResultParcel<>(result));
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to send result to the callback", e);
-            }
-        }
-
-        /**
-         * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
-         *
-         * <p>The throwable is converted to {@link AppSearchResult}.
-         */
-        private void invokeCallbackOnError(
-                @NonNull IAppSearchBatchResultCallback callback, @NonNull Throwable throwable) {
-            AppSearchResult<?> result = throwableToFailedResult(throwable);
-            try {
-                callback.onSystemError(new AppSearchResultParcel<>(result));
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to send error to the callback", e);
-            }
-        }
-    }
-
-    /**
-     * Helper for dealing with incoming user arguments to system service calls.
-     *
-     * @param requestedUser The user which the caller is requesting to execute as.
-     * @param callingUid The actual uid of the caller as determined by Binder.
-     * @return the user handle that the call should run as. Will always be a concrete user.
-     */
-    @NonNull
-    private UserHandle handleIncomingUser(@NonNull UserHandle requestedUser, int callingUid) {
-        UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
-        if (callingUser.equals(requestedUser)) {
-            return requestedUser;
-        }
-
-        // Duplicates UserController#ensureNotSpecialUser
-        if (requestedUser.getIdentifier() < 0) {
-            throw new IllegalArgumentException(
-                    "Call does not support special user " + requestedUser);
-        }
-
-        throw new SecurityException(
-                "Requested user, " + requestedUser + ", is not the same as the calling user, "
-                        + callingUser + ".");
-    }
-
-    /**
-     * Helper for ensuring instant apps can't make calls to AppSearch.
-     *
-     * @param userContext Context of the user making the call.
-     * @param packageName Package name of the caller.
-     * @throws SecurityException if the caller is an instant app.
-     */
-    private void verifyNotInstantApp(@NonNull Context userContext, @NonNull String packageName) {
-        PackageManager callingPackageManager = userContext.getPackageManager();
-        if (callingPackageManager.isInstantApp(packageName)) {
-            throw new SecurityException("Caller not allowed to create AppSearch session"
-                    + "; userHandle=" + userContext.getUser() + ", callingPackage=" + packageName);
-        }
-    }
-
-    // TODO(b/179160886): Cache the previous storage stats.
-    private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
-        @Override
-        public void augmentStatsForPackageForUser(
-                @NonNull PackageStats stats,
-                @NonNull String packageName,
-                @NonNull UserHandle userHandle,
-                boolean canCallerAccessAllStats) {
-            Objects.requireNonNull(stats);
-            Objects.requireNonNull(packageName);
-            Objects.requireNonNull(userHandle);
-
-            try {
-                verifyUserUnlocked(userHandle);
-                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
-                AppSearchUserInstance instance =
-                        mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
-                stats.dataSize += instance.getAppSearchImpl()
-                        .getStorageInfoForPackage(packageName).getSizeBytes();
-            } catch (Throwable t) {
-                Log.e(
-                        TAG,
-                        "Unable to augment storage stats for "
-                                + userHandle
-                                + " packageName "
-                                + packageName,
-                        t);
-            }
-        }
-
-        @Override
-        public void augmentStatsForUid(
-                @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
-            Objects.requireNonNull(stats);
-
-            UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
-            try {
-                verifyUserUnlocked(userHandle);
-                String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
-                if (packagesForUid == null) {
-                    return;
-                }
-                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
-                AppSearchUserInstance instance =
-                        mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
-                for (int i = 0; i < packagesForUid.length; i++) {
-                    stats.dataSize += instance.getAppSearchImpl()
-                            .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
-                }
-            } catch (Throwable t) {
-                Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
-            }
-        }
-
-        @Override
-        public void augmentStatsForUser(
-                @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
-            // TODO(b/179160886): this implementation could incur many jni calls and a lot of
-            //  in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
-            //  size of the icing dir (or use the overall StorageInfo without interpolating it).
-            Objects.requireNonNull(stats);
-            Objects.requireNonNull(userHandle);
-
-            try {
-                verifyUserUnlocked(userHandle);
-                List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
-                        /*flags=*/0, userHandle.getIdentifier());
-                if (packagesForUser == null) {
-                    return;
-                }
-                Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0);
-                AppSearchUserInstance instance =
-                        mAppSearchUserInstanceManager.getOrCreateUserInstance(
-                                userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
-                for (int i = 0; i < packagesForUser.size(); i++) {
-                    String packageName = packagesForUser.get(i).packageName;
-                    stats.dataSize += instance.getAppSearchImpl()
-                            .getStorageInfoForPackage(packageName).getSizeBytes();
-                }
-            } catch (Throwable t) {
-                Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
-            }
-        }
-    }
-
-    private void checkForOptimize(AppSearchUserInstance instance, int mutateBatchSize) {
-        EXECUTOR.execute(() -> {
-            long totalLatencyStartMillis = SystemClock.elapsedRealtime();
-            OptimizeStats.Builder builder = new OptimizeStats.Builder();
-            try {
-                instance.getAppSearchImpl().checkForOptimize(mutateBatchSize, builder);
-            } catch (AppSearchException e) {
-                Log.w(TAG, "Error occurred when check for optimize", e);
-            } finally {
-                OptimizeStats oStats = builder
-                        .setTotalLatencyMillis(
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis))
-                        .build();
-                if (oStats.getOriginalDocumentCount() > 0) {
-                    // see if optimize has been run by checking originalDocumentCount
-                    instance.getLogger().logStats(oStats);
-                }
-            }
-        });
-    }
-
-    private void checkForOptimize(AppSearchUserInstance instance) {
-        EXECUTOR.execute(() -> {
-            long totalLatencyStartMillis = SystemClock.elapsedRealtime();
-            OptimizeStats.Builder builder = new OptimizeStats.Builder();
-            try {
-                instance.getAppSearchImpl().checkForOptimize(builder);
-            } catch (AppSearchException e) {
-                Log.w(TAG, "Error occurred when check for optimize", e);
-            } finally {
-                OptimizeStats oStats = builder
-                        .setTotalLatencyMillis(
-                                (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis))
-                        .build();
-                if (oStats.getOriginalDocumentCount() > 0) {
-                    // see if optimize has been run by checking originalDocumentCount
-                    instance.getLogger().logStats(oStats);
-                }
-            }
-        });
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
deleted file mode 100644
index 56e2af5..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch;
-
-import android.annotation.NonNull;
-
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.stats.PlatformLogger;
-import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
-
-import java.util.Objects;
-
-/**
- * Container for AppSearch classes that should only be initialized once per device-user and make up
- * the core of the AppSearch system.
- */
-public final class AppSearchUserInstance {
-    private final PlatformLogger mLogger;
-    private final AppSearchImpl mAppSearchImpl;
-    private final VisibilityStoreImpl mVisibilityStore;
-
-    AppSearchUserInstance(
-            @NonNull PlatformLogger logger,
-            @NonNull AppSearchImpl appSearchImpl,
-            @NonNull VisibilityStoreImpl visibilityStore) {
-        mLogger = Objects.requireNonNull(logger);
-        mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
-        mVisibilityStore = Objects.requireNonNull(visibilityStore);
-    }
-
-    @NonNull
-    public PlatformLogger getLogger() {
-        return mLogger;
-    }
-
-    @NonNull
-    public AppSearchImpl getAppSearchImpl() {
-        return mAppSearchImpl;
-    }
-
-    @NonNull
-    public VisibilityStoreImpl getVisibilityStore() {
-        return mVisibilityStore;
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
deleted file mode 100644
index 529f2b0..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch;
-
-import android.annotation.NonNull;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.stats.PlatformLogger;
-import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Manages the lifecycle of AppSearch classes that should only be initialized once per device-user
- * and make up the core of the AppSearch system.
- *
- * @hide
- */
-public final class AppSearchUserInstanceManager {
-    private static final String TAG = "AppSearchUserInstanceMa";
-
-    private static volatile AppSearchUserInstanceManager sAppSearchUserInstanceManager;
-
-    @GuardedBy("mInstancesLocked")
-    private final Map<UserHandle, AppSearchUserInstance> mInstancesLocked = new ArrayMap<>();
-
-    private AppSearchUserInstanceManager() {}
-
-    /**
-     * Gets an instance of AppSearchUserInstanceManager to be used.
-     *
-     * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
-     * existing instance will be returned.
-     */
-    @NonNull
-    public static AppSearchUserInstanceManager getInstance() {
-        if (sAppSearchUserInstanceManager == null) {
-            synchronized (AppSearchUserInstanceManager.class) {
-                if (sAppSearchUserInstanceManager == null) {
-                    sAppSearchUserInstanceManager = new AppSearchUserInstanceManager();
-                }
-            }
-        }
-        return sAppSearchUserInstanceManager;
-    }
-
-    /**
-     * Returns AppSearch directory in the credential encrypted system directory for the given user.
-     *
-     * <p>This folder should only be accessed after unlock.
-     */
-    public static File getAppSearchDir(@NonNull UserHandle userHandle) {
-        // Duplicates the implementation of Environment#getDataSystemCeDirectory
-        // TODO(b/191059409): Unhide Environment#getDataSystemCeDirectory and switch to it.
-        File systemCeDir = new File(Environment.getDataDirectory(), "system_ce");
-        File systemCeUserDir = new File(systemCeDir, String.valueOf(userHandle.getIdentifier()));
-        return new File(systemCeUserDir, "appsearch");
-    }
-
-    /**
-     * Gets an instance of AppSearchUserInstance for the given user, or creates one if none exists.
-     *
-     * <p>If no AppSearchUserInstance exists for the unlocked user, Icing will be initialized and
-     * one will be created.
-     *
-     * @param userContext Context of the user calling AppSearch
-     * @param userHandle The multi-user handle of the device user calling AppSearch
-     * @param config Flag manager for AppSearch
-     * @return An initialized {@link AppSearchUserInstance} for this user
-     */
-    @NonNull
-    public AppSearchUserInstance getOrCreateUserInstance(
-            @NonNull Context userContext,
-            @NonNull UserHandle userHandle,
-            @NonNull AppSearchConfig config)
-            throws AppSearchException {
-        Objects.requireNonNull(userContext);
-        Objects.requireNonNull(userHandle);
-        Objects.requireNonNull(config);
-
-        synchronized (mInstancesLocked) {
-            AppSearchUserInstance instance = mInstancesLocked.get(userHandle);
-            if (instance == null) {
-                instance = createUserInstance(userContext, userHandle, config);
-                mInstancesLocked.put(userHandle, instance);
-            }
-            return instance;
-        }
-    }
-
-    /**
-     * Closes and removes an {@link AppSearchUserInstance} for the given user.
-     *
-     * <p>All mutations applied to the underlying {@link AppSearchImpl} will be persisted to disk.
-     *
-     * @param userHandle The multi-user user handle of the user that need to be removed.
-     */
-    public void closeAndRemoveUserInstance(@NonNull UserHandle userHandle) {
-        Objects.requireNonNull(userHandle);
-        synchronized (mInstancesLocked) {
-            AppSearchUserInstance instance = mInstancesLocked.remove(userHandle);
-            if (instance != null) {
-                instance.getAppSearchImpl().close();
-            }
-        }
-    }
-
-    /**
-     * Gets an {@link AppSearchUserInstance} for the given user.
-     *
-     * <p>This method should only be called by an initialized SearchSession, which has already
-     * called {@link #getOrCreateUserInstance} before.
-     *
-     * @param userHandle The multi-user handle of the device user calling AppSearch
-     * @return An initialized {@link AppSearchUserInstance} for this user
-     * @throws IllegalStateException if {@link AppSearchUserInstance} haven't created for the given
-     *                               user.
-     */
-    @NonNull
-    public AppSearchUserInstance getUserInstance(@NonNull UserHandle userHandle) {
-        Objects.requireNonNull(userHandle);
-        synchronized (mInstancesLocked) {
-            AppSearchUserInstance instance = mInstancesLocked.get(userHandle);
-            if (instance == null) {
-                // Impossible scenario, user cannot call an uninitialized SearchSession,
-                // getInstance should always find the instance for the given user and never try to
-                // create an instance for this user again.
-                throw new IllegalStateException(
-                        "AppSearchUserInstance has never been created for: " + userHandle);
-            }
-            return instance;
-        }
-    }
-
-    /**
-     * Returns the list of all {@link UserHandle}s.
-     *
-     * <p>It can return an empty list if there is no {@link AppSearchUserInstance} created yet.
-     */
-    @NonNull
-    public List<UserHandle> getAllUserHandles() {
-        synchronized (mInstancesLocked) {
-            return new ArrayList<>(mInstancesLocked.keySet());
-        }
-    }
-
-    @NonNull
-    private AppSearchUserInstance createUserInstance(
-            @NonNull Context userContext,
-            @NonNull UserHandle userHandle,
-            @NonNull AppSearchConfig config)
-            throws AppSearchException {
-        long totalLatencyStartMillis = SystemClock.elapsedRealtime();
-        InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
-
-        // Initialize the classes that make up AppSearchUserInstance
-        PlatformLogger logger = new PlatformLogger(userContext, config);
-
-        File appSearchDir = getAppSearchDir(userHandle);
-        File icingDir = new File(appSearchDir, "icing");
-        Log.i(TAG, "Creating new AppSearch instance at: " + icingDir);
-        AppSearchImpl appSearchImpl = AppSearchImpl.create(
-                icingDir,
-                new FrameworkLimitConfig(config),
-                initStatsBuilder,
-                new FrameworkOptimizeStrategy(config));
-
-        long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
-        VisibilityStoreImpl visibilityStore =
-                VisibilityStoreImpl.create(appSearchImpl, userContext);
-        long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
-
-        initStatsBuilder
-                .setTotalLatencyMillis(
-                        (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis))
-                .setPrepareVisibilityStoreLatencyMillis(
-                        (int)
-                                (prepareVisibilityStoreLatencyEndMillis
-                                        - prepareVisibilityStoreLatencyStartMillis));
-        logger.logStats(initStatsBuilder.build());
-
-        return new AppSearchUserInstance(logger, appSearchImpl, visibilityStore);
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/FrameworkLimitConfig.java b/apex/appsearch/service/java/com/android/server/appsearch/FrameworkLimitConfig.java
deleted file mode 100644
index d16168a..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/FrameworkLimitConfig.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch;
-
-import android.annotation.NonNull;
-
-import com.android.server.appsearch.external.localstorage.LimitConfig;
-
-import java.util.Objects;
-
-class FrameworkLimitConfig implements LimitConfig {
-    private final AppSearchConfig mAppSearchConfig;
-
-    FrameworkLimitConfig(@NonNull AppSearchConfig appSearchConfig) {
-        mAppSearchConfig = Objects.requireNonNull(appSearchConfig);
-    }
-
-    @Override
-    public int getMaxDocumentSizeBytes() {
-        return mAppSearchConfig.getCachedLimitConfigMaxDocumentSizeBytes();
-    }
-
-    @Override
-    public int getMaxDocumentCount() {
-        return mAppSearchConfig.getCachedLimitConfigMaxDocumentCount();
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java b/apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java
deleted file mode 100644
index d934449..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch;
-
-import android.annotation.NonNull;
-
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.external.localstorage.OptimizeStrategy;
-
-import com.google.android.icing.proto.GetOptimizeInfoResultProto;
-
-import java.util.Objects;
-
-/**
- * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link
- * AppSearchImpl#optimize()} in Jetpack environment.
- *
- * @hide
- */
-public class FrameworkOptimizeStrategy implements OptimizeStrategy {
-    private final AppSearchConfig mAppSearchConfig;
-    FrameworkOptimizeStrategy(@NonNull AppSearchConfig config) {
-        mAppSearchConfig = Objects.requireNonNull(config);
-    }
-
-    @Override
-    public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) {
-        return optimizeInfo.getOptimizableDocs()
-                    >= mAppSearchConfig.getCachedDocCountOptimizeThreshold()
-                || optimizeInfo.getEstimatedOptimizableBytes()
-                    >= mAppSearchConfig.getCachedBytesOptimizeThreshold()
-                || optimizeInfo.getTimeSinceLastOptimizeMs()
-                    >= mAppSearchConfig.getCachedTimeOptimizeThresholdMs();
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING b/apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING
deleted file mode 100644
index 38cd7a8..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "CtsAppSearchTestCases"
-    },
-    {
-      "name": "CtsAppSearchHostTestCases"
-    },
-    {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.appsearch"
-        }
-      ]
-    },
-    {
-      "name": "FrameworksCoreTests",
-      "options": [
-        {
-           "include-filter": "android.app.appsearch"
-        }
-      ]
-    }
-  ]
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
deleted file mode 100644
index 15916cc..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ /dev/null
@@ -1,2299 +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 com.android.server.appsearch.external.localstorage;
-
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.addPrefixToDocument;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.createPrefix;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.getDatabaseName;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.getPackageName;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.getPrefix;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.removePrefix;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.removePrefixesFromDocument;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.WorkerThread;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByDocumentIdRequest;
-import android.app.appsearch.GetSchemaResponse;
-import android.app.appsearch.PackageIdentifier;
-import android.app.appsearch.SearchResultPage;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.SetSchemaResponse;
-import android.app.appsearch.StorageInfo;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.app.appsearch.util.LogUtil;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
-import com.android.server.appsearch.external.localstorage.converter.ResultCodeToProtoConverter;
-import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
-import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
-import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
-import com.android.server.appsearch.external.localstorage.converter.SetSchemaResponseToProtoConverter;
-import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
-import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
-import com.android.server.appsearch.external.localstorage.stats.SearchStats;
-import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
-
-import com.google.android.icing.IcingSearchEngine;
-import com.google.android.icing.proto.DeleteByQueryResultProto;
-import com.google.android.icing.proto.DeleteResultProto;
-import com.google.android.icing.proto.DocumentProto;
-import com.google.android.icing.proto.DocumentStorageInfoProto;
-import com.google.android.icing.proto.GetAllNamespacesResultProto;
-import com.google.android.icing.proto.GetOptimizeInfoResultProto;
-import com.google.android.icing.proto.GetResultProto;
-import com.google.android.icing.proto.GetResultSpecProto;
-import com.google.android.icing.proto.GetSchemaResultProto;
-import com.google.android.icing.proto.IcingSearchEngineOptions;
-import com.google.android.icing.proto.InitializeResultProto;
-import com.google.android.icing.proto.NamespaceStorageInfoProto;
-import com.google.android.icing.proto.OptimizeResultProto;
-import com.google.android.icing.proto.PersistToDiskResultProto;
-import com.google.android.icing.proto.PersistType;
-import com.google.android.icing.proto.PropertyConfigProto;
-import com.google.android.icing.proto.PutResultProto;
-import com.google.android.icing.proto.ReportUsageResultProto;
-import com.google.android.icing.proto.ResetResultProto;
-import com.google.android.icing.proto.ResultSpecProto;
-import com.google.android.icing.proto.SchemaProto;
-import com.google.android.icing.proto.SchemaTypeConfigProto;
-import com.google.android.icing.proto.ScoringSpecProto;
-import com.google.android.icing.proto.SearchResultProto;
-import com.google.android.icing.proto.SearchSpecProto;
-import com.google.android.icing.proto.SetSchemaResultProto;
-import com.google.android.icing.proto.StatusProto;
-import com.google.android.icing.proto.StorageInfoProto;
-import com.google.android.icing.proto.StorageInfoResultProto;
-import com.google.android.icing.proto.TypePropertyMask;
-import com.google.android.icing.proto.UsageReport;
-
-import java.io.Closeable;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * Manages interaction with the native IcingSearchEngine and other components to implement AppSearch
- * functionality.
- *
- * <p>Never create two instances using the same folder.
- *
- * <p>A single instance of {@link AppSearchImpl} can support all packages and databases. This is
- * done by combining the package and database name into a unique prefix and prefixing the schemas
- * and documents stored under that owner. Schemas and documents are physically saved together in
- * {@link IcingSearchEngine}, but logically isolated:
- *
- * <ul>
- *   <li>Rewrite SchemaType in SchemaProto by adding the package-database prefix and save into
- *       SchemaTypes set in {@link #setSchema}.
- *   <li>Rewrite namespace and SchemaType in DocumentProto by adding package-database prefix and
- *       save to namespaces set in {@link #putDocument}.
- *   <li>Remove package-database prefix when retrieving documents in {@link #getDocument} and {@link
- *       #query}.
- *   <li>Rewrite filters in {@link SearchSpecProto} to have all namespaces and schema types of the
- *       queried database when user using empty filters in {@link #query}.
- * </ul>
- *
- * <p>Methods in this class belong to two groups, the query group and the mutate group.
- *
- * <ul>
- *   <li>All methods are going to modify global parameters and data in Icing are executed under
- *       WRITE lock to keep thread safety.
- *   <li>All methods are going to access global parameters or query data from Icing are executed
- *       under READ lock to improve query performance.
- * </ul>
- *
- * <p>This class is thread safe.
- *
- * @hide
- */
-@WorkerThread
-public final class AppSearchImpl implements Closeable {
-    private static final String TAG = "AppSearchImpl";
-
-    /** A value 0 means that there're no more pages in the search results. */
-    private static final long EMPTY_PAGE_TOKEN = 0;
-
-    @VisibleForTesting static final int CHECK_OPTIMIZE_INTERVAL = 100;
-
-    private final ReadWriteLock mReadWriteLock = new ReentrantReadWriteLock();
-    private final LogUtil mLogUtil = new LogUtil(TAG);
-    private final OptimizeStrategy mOptimizeStrategy;
-    private final LimitConfig mLimitConfig;
-
-    @GuardedBy("mReadWriteLock")
-    @VisibleForTesting
-    final IcingSearchEngine mIcingSearchEngineLocked;
-
-    // This map contains schema types and SchemaTypeConfigProtos for all package-database
-    // prefixes. It maps each package-database prefix to an inner-map. The inner-map maps each
-    // prefixed schema type to its respective SchemaTypeConfigProto.
-    @GuardedBy("mReadWriteLock")
-    private final Map<String, Map<String, SchemaTypeConfigProto>> mSchemaMapLocked =
-            new ArrayMap<>();
-
-    // This map contains namespaces for all package-database prefixes. All values in the map are
-    // prefixed with the package-database prefix.
-    // TODO(b/172360376): Check if this can be replaced with an ArrayMap
-    @GuardedBy("mReadWriteLock")
-    private final Map<String, Set<String>> mNamespaceMapLocked = new HashMap<>();
-
-    /** Maps package name to active document count. */
-    @GuardedBy("mReadWriteLock")
-    private final Map<String, Integer> mDocumentCountMapLocked = new ArrayMap<>();
-
-    // Maps packages to the set of valid nextPageTokens that the package can manipulate. A token
-    // is unique and constant per query (i.e. the same token '123' is used to iterate through
-    // pages of search results). The tokens themselves are generated and tracked by
-    // IcingSearchEngine. IcingSearchEngine considers a token valid and won't be reused
-    // until we call invalidateNextPageToken on the token.
-    //
-    // Note that we synchronize on itself because the nextPageToken cache is checked at
-    // query-time, and queries are done in parallel with a read lock. Ideally, this would be
-    // guarded by the normal mReadWriteLock.writeLock, but ReentrantReadWriteLocks can't upgrade
-    // read to write locks. This lock should be acquired at the smallest scope possible.
-    // mReadWriteLock is a higher-level lock, so calls shouldn't be made out
-    // to any functions that grab the lock.
-    @GuardedBy("mNextPageTokensLocked")
-    private final Map<String, Set<Long>> mNextPageTokensLocked = new ArrayMap<>();
-
-    /**
-     * The counter to check when to call {@link #checkForOptimize}. The interval is {@link
-     * #CHECK_OPTIMIZE_INTERVAL}.
-     */
-    @GuardedBy("mReadWriteLock")
-    private int mOptimizeIntervalCountLocked = 0;
-
-    /** Whether this instance has been closed, and therefore unusable. */
-    @GuardedBy("mReadWriteLock")
-    private boolean mClosedLocked = false;
-
-    /**
-     * Creates and initializes an instance of {@link AppSearchImpl} which writes data to the given
-     * folder.
-     *
-     * <p>Clients can pass a {@link AppSearchLogger} here through their AppSearchSession, but it
-     * can't be saved inside {@link AppSearchImpl}, because the impl will be shared by all the
-     * sessions for the same package in JetPack.
-     *
-     * <p>Instead, logger instance needs to be passed to each individual method, like create, query
-     * and putDocument.
-     *
-     * @param initStatsBuilder collects stats for initialization if provided.
-     */
-    @NonNull
-    public static AppSearchImpl create(
-            @NonNull File icingDir,
-            @NonNull LimitConfig limitConfig,
-            @Nullable InitializeStats.Builder initStatsBuilder,
-            @NonNull OptimizeStrategy optimizeStrategy)
-            throws AppSearchException {
-        return new AppSearchImpl(icingDir, limitConfig, initStatsBuilder, optimizeStrategy);
-    }
-
-    /** @param initStatsBuilder collects stats for initialization if provided. */
-    private AppSearchImpl(
-            @NonNull File icingDir,
-            @NonNull LimitConfig limitConfig,
-            @Nullable InitializeStats.Builder initStatsBuilder,
-            @NonNull OptimizeStrategy optimizeStrategy)
-            throws AppSearchException {
-        Objects.requireNonNull(icingDir);
-        mLimitConfig = Objects.requireNonNull(limitConfig);
-        mOptimizeStrategy = Objects.requireNonNull(optimizeStrategy);
-
-        mReadWriteLock.writeLock().lock();
-        try {
-            // We synchronize here because we don't want to call IcingSearchEngine.initialize() more
-            // than once. It's unnecessary and can be a costly operation.
-            IcingSearchEngineOptions options =
-                    IcingSearchEngineOptions.newBuilder()
-                            .setBaseDir(icingDir.getAbsolutePath())
-                            .build();
-            mLogUtil.piiTrace("Constructing IcingSearchEngine, request", options);
-            mIcingSearchEngineLocked = new IcingSearchEngine(options);
-            mLogUtil.piiTrace(
-                    "Constructing IcingSearchEngine, response",
-                    Objects.hashCode(mIcingSearchEngineLocked));
-
-            // The core initialization procedure. If any part of this fails, we bail into
-            // resetLocked(), deleting all data (but hopefully allowing AppSearchImpl to come up).
-            try {
-                mLogUtil.piiTrace("icingSearchEngine.initialize, request");
-                InitializeResultProto initializeResultProto = mIcingSearchEngineLocked.initialize();
-                mLogUtil.piiTrace(
-                        "icingSearchEngine.initialize, response",
-                        initializeResultProto.getStatus(),
-                        initializeResultProto);
-
-                if (initStatsBuilder != null) {
-                    initStatsBuilder
-                            .setStatusCode(
-                                    statusProtoToResultCode(initializeResultProto.getStatus()))
-                            // TODO(b/173532925) how to get DeSyncs value
-                            .setHasDeSync(false);
-                    AppSearchLoggerHelper.copyNativeStats(
-                            initializeResultProto.getInitializeStats(), initStatsBuilder);
-                }
-                checkSuccess(initializeResultProto.getStatus());
-
-                // Read all protos we need to construct AppSearchImpl's cache maps
-                long prepareSchemaAndNamespacesLatencyStartMillis = SystemClock.elapsedRealtime();
-                SchemaProto schemaProto = getSchemaProtoLocked();
-
-                mLogUtil.piiTrace("init:getAllNamespaces, request");
-                GetAllNamespacesResultProto getAllNamespacesResultProto =
-                        mIcingSearchEngineLocked.getAllNamespaces();
-                mLogUtil.piiTrace(
-                        "init:getAllNamespaces, response",
-                        getAllNamespacesResultProto.getNamespacesCount(),
-                        getAllNamespacesResultProto);
-
-                StorageInfoProto storageInfoProto = getRawStorageInfoProto();
-
-                // Log the time it took to read the data that goes into the cache maps
-                if (initStatsBuilder != null) {
-                    // In case there is some error for getAllNamespaces, we can still
-                    // set the latency for preparation.
-                    // If there is no error, the value will be overridden by the actual one later.
-                    initStatsBuilder
-                            .setStatusCode(
-                                    statusProtoToResultCode(
-                                            getAllNamespacesResultProto.getStatus()))
-                            .setPrepareSchemaAndNamespacesLatencyMillis(
-                                    (int)
-                                            (SystemClock.elapsedRealtime()
-                                                    - prepareSchemaAndNamespacesLatencyStartMillis));
-                }
-                checkSuccess(getAllNamespacesResultProto.getStatus());
-
-                // Populate schema map
-                List<SchemaTypeConfigProto> schemaProtoTypesList = schemaProto.getTypesList();
-                for (int i = 0; i < schemaProtoTypesList.size(); i++) {
-                    SchemaTypeConfigProto schema = schemaProtoTypesList.get(i);
-                    String prefixedSchemaType = schema.getSchemaType();
-                    addToMap(mSchemaMapLocked, getPrefix(prefixedSchemaType), schema);
-                }
-
-                // Populate namespace map
-                List<String> prefixedNamespaceList =
-                        getAllNamespacesResultProto.getNamespacesList();
-                for (int i = 0; i < prefixedNamespaceList.size(); i++) {
-                    String prefixedNamespace = prefixedNamespaceList.get(i);
-                    addToMap(mNamespaceMapLocked, getPrefix(prefixedNamespace), prefixedNamespace);
-                }
-
-                // Populate document count map
-                rebuildDocumentCountMapLocked(storageInfoProto);
-
-                // logging prepare_schema_and_namespaces latency
-                if (initStatsBuilder != null) {
-                    initStatsBuilder.setPrepareSchemaAndNamespacesLatencyMillis(
-                            (int)
-                                    (SystemClock.elapsedRealtime()
-                                            - prepareSchemaAndNamespacesLatencyStartMillis));
-                }
-
-                mLogUtil.piiTrace("Init completed successfully");
-
-            } catch (AppSearchException e) {
-                // Some error. Reset and see if it fixes it.
-                Log.e(TAG, "Error initializing, resetting IcingSearchEngine.", e);
-                if (initStatsBuilder != null) {
-                    initStatsBuilder.setStatusCode(e.getResultCode());
-                }
-                resetLocked(initStatsBuilder);
-            }
-
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    @GuardedBy("mReadWriteLock")
-    private void throwIfClosedLocked() {
-        if (mClosedLocked) {
-            throw new IllegalStateException("Trying to use a closed AppSearchImpl instance.");
-        }
-    }
-
-    /**
-     * Persists data to disk and closes the instance.
-     *
-     * <p>This instance is no longer usable after it's been closed. Call {@link #create} to create a
-     * new, usable instance.
-     */
-    @Override
-    public void close() {
-        mReadWriteLock.writeLock().lock();
-        try {
-            if (mClosedLocked) {
-                return;
-            }
-            persistToDisk(PersistType.Code.FULL);
-            mLogUtil.piiTrace("icingSearchEngine.close, request");
-            mIcingSearchEngineLocked.close();
-            mLogUtil.piiTrace("icingSearchEngine.close, response");
-            mClosedLocked = true;
-        } catch (AppSearchException e) {
-            Log.w(TAG, "Error when closing AppSearchImpl.", e);
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Updates the AppSearch schema for this app.
-     *
-     * <p>This method belongs to mutate group.
-     *
-     * @param packageName The package name that owns the schemas.
-     * @param databaseName The name of the database where this schema lives.
-     * @param schemas Schemas to set for this app.
-     * @param visibilityStore If set, {@code schemasNotDisplayedBySystem} and {@code
-     *     schemasVisibleToPackages} will be saved here if the schema is successfully applied.
-     * @param schemasNotDisplayedBySystem Schema types that should not be surfaced on platform
-     *     surfaces.
-     * @param schemasVisibleToPackages Schema types that are visible to the specified packages.
-     * @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
-     *     which do not comply with the new schema will be deleted.
-     * @param version The overall version number of the request.
-     * @return The response contains deleted schema types and incompatible schema types of this
-     *     call.
-     * @throws AppSearchException On IcingSearchEngine error. If the status code is
-     *     FAILED_PRECONDITION for the incompatible change, the exception will be converted to the
-     *     SetSchemaResponse.
-     */
-    @NonNull
-    public SetSchemaResponse setSchema(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull List<AppSearchSchema> schemas,
-            @Nullable VisibilityStore visibilityStore,
-            @NonNull List<String> schemasNotDisplayedBySystem,
-            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages,
-            boolean forceOverride,
-            int version)
-            throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            SchemaProto.Builder existingSchemaBuilder = getSchemaProtoLocked().toBuilder();
-
-            SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();
-            for (int i = 0; i < schemas.size(); i++) {
-                AppSearchSchema schema = schemas.get(i);
-                SchemaTypeConfigProto schemaTypeProto =
-                        SchemaToProtoConverter.toSchemaTypeConfigProto(schema, version);
-                newSchemaBuilder.addTypes(schemaTypeProto);
-            }
-
-            String prefix = createPrefix(packageName, databaseName);
-            // Combine the existing schema (which may have types from other prefixes) with this
-            // prefix's new schema. Modifies the existingSchemaBuilder.
-            RewrittenSchemaResults rewrittenSchemaResults =
-                    rewriteSchema(prefix, existingSchemaBuilder, newSchemaBuilder.build());
-
-            // Apply schema
-            SchemaProto finalSchema = existingSchemaBuilder.build();
-            mLogUtil.piiTrace("setSchema, request", finalSchema.getTypesCount(), finalSchema);
-            SetSchemaResultProto setSchemaResultProto =
-                    mIcingSearchEngineLocked.setSchema(finalSchema, forceOverride);
-            mLogUtil.piiTrace(
-                    "setSchema, response", setSchemaResultProto.getStatus(), setSchemaResultProto);
-
-            // Determine whether it succeeded.
-            try {
-                checkSuccess(setSchemaResultProto.getStatus());
-            } catch (AppSearchException e) {
-                // Swallow the exception for the incompatible change case. We will propagate
-                // those deleted schemas and incompatible types to the SetSchemaResponse.
-                boolean isFailedPrecondition =
-                        setSchemaResultProto.getStatus().getCode()
-                                == StatusProto.Code.FAILED_PRECONDITION;
-                boolean isIncompatible =
-                        setSchemaResultProto.getDeletedSchemaTypesCount() > 0
-                                || setSchemaResultProto.getIncompatibleSchemaTypesCount() > 0;
-                if (isFailedPrecondition && isIncompatible) {
-                    return SetSchemaResponseToProtoConverter.toSetSchemaResponse(
-                            setSchemaResultProto, prefix);
-                } else {
-                    throw e;
-                }
-            }
-
-            // Update derived data structures.
-            for (SchemaTypeConfigProto schemaTypeConfigProto :
-                    rewrittenSchemaResults.mRewrittenPrefixedTypes.values()) {
-                addToMap(mSchemaMapLocked, prefix, schemaTypeConfigProto);
-            }
-
-            for (String schemaType : rewrittenSchemaResults.mDeletedPrefixedTypes) {
-                removeFromMap(mSchemaMapLocked, prefix, schemaType);
-            }
-
-            if (visibilityStore != null) {
-                Set<String> prefixedSchemasNotDisplayedBySystem =
-                        new ArraySet<>(schemasNotDisplayedBySystem.size());
-                for (int i = 0; i < schemasNotDisplayedBySystem.size(); i++) {
-                    prefixedSchemasNotDisplayedBySystem.add(
-                            prefix + schemasNotDisplayedBySystem.get(i));
-                }
-
-                Map<String, List<PackageIdentifier>> prefixedSchemasVisibleToPackages =
-                        new ArrayMap<>(schemasVisibleToPackages.size());
-                for (Map.Entry<String, List<PackageIdentifier>> entry :
-                        schemasVisibleToPackages.entrySet()) {
-                    prefixedSchemasVisibleToPackages.put(prefix + entry.getKey(), entry.getValue());
-                }
-
-                visibilityStore.setVisibility(
-                        packageName,
-                        databaseName,
-                        prefixedSchemasNotDisplayedBySystem,
-                        prefixedSchemasVisibleToPackages);
-            }
-
-            return SetSchemaResponseToProtoConverter.toSetSchemaResponse(
-                    setSchemaResultProto, prefix);
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Retrieves the AppSearch schema for this package name, database.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param packageName Package name that owns this schema
-     * @param databaseName The name of the database where this schema lives.
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    @NonNull
-    public GetSchemaResponse getSchema(@NonNull String packageName, @NonNull String databaseName)
-            throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            SchemaProto fullSchema = getSchemaProtoLocked();
-
-            String prefix = createPrefix(packageName, databaseName);
-            GetSchemaResponse.Builder responseBuilder = new GetSchemaResponse.Builder();
-            for (int i = 0; i < fullSchema.getTypesCount(); i++) {
-                String typePrefix = getPrefix(fullSchema.getTypes(i).getSchemaType());
-                if (!prefix.equals(typePrefix)) {
-                    continue;
-                }
-                // Rewrite SchemaProto.types.schema_type
-                SchemaTypeConfigProto.Builder typeConfigBuilder =
-                        fullSchema.getTypes(i).toBuilder();
-                String newSchemaType = typeConfigBuilder.getSchemaType().substring(prefix.length());
-                typeConfigBuilder.setSchemaType(newSchemaType);
-
-                // Rewrite SchemaProto.types.properties.schema_type
-                for (int propertyIdx = 0;
-                        propertyIdx < typeConfigBuilder.getPropertiesCount();
-                        propertyIdx++) {
-                    PropertyConfigProto.Builder propertyConfigBuilder =
-                            typeConfigBuilder.getProperties(propertyIdx).toBuilder();
-                    if (!propertyConfigBuilder.getSchemaType().isEmpty()) {
-                        String newPropertySchemaType =
-                                propertyConfigBuilder.getSchemaType().substring(prefix.length());
-                        propertyConfigBuilder.setSchemaType(newPropertySchemaType);
-                        typeConfigBuilder.setProperties(propertyIdx, propertyConfigBuilder);
-                    }
-                }
-
-                AppSearchSchema schema =
-                        SchemaToProtoConverter.toAppSearchSchema(typeConfigBuilder);
-
-                // TODO(b/183050495) find a place to store the version for the database, rather
-                // than read from a schema.
-                responseBuilder.setVersion(fullSchema.getTypes(i).getVersion());
-                responseBuilder.addSchema(schema);
-            }
-            return responseBuilder.build();
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Retrieves the list of namespaces with at least one document for this package name, database.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param packageName Package name that owns this schema
-     * @param databaseName The name of the database where this schema lives.
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    @NonNull
-    public List<String> getNamespaces(@NonNull String packageName, @NonNull String databaseName)
-            throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-            mLogUtil.piiTrace("getAllNamespaces, request");
-            // We can't just use mNamespaceMap here because we have no way to prune namespaces from
-            // mNamespaceMap when they have no more documents (e.g. after setting schema to empty or
-            // using deleteByQuery).
-            GetAllNamespacesResultProto getAllNamespacesResultProto =
-                    mIcingSearchEngineLocked.getAllNamespaces();
-            mLogUtil.piiTrace(
-                    "getAllNamespaces, response",
-                    getAllNamespacesResultProto.getNamespacesCount(),
-                    getAllNamespacesResultProto);
-            checkSuccess(getAllNamespacesResultProto.getStatus());
-            String prefix = createPrefix(packageName, databaseName);
-            List<String> results = new ArrayList<>();
-            for (int i = 0; i < getAllNamespacesResultProto.getNamespacesCount(); i++) {
-                String prefixedNamespace = getAllNamespacesResultProto.getNamespaces(i);
-                if (prefixedNamespace.startsWith(prefix)) {
-                    results.add(prefixedNamespace.substring(prefix.length()));
-                }
-            }
-            return results;
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Adds a document to the AppSearch index.
-     *
-     * <p>This method belongs to mutate group.
-     *
-     * @param packageName The package name that owns this document.
-     * @param databaseName The databaseName this document resides in.
-     * @param document The document to index.
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    public void putDocument(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull GenericDocument document,
-            @Nullable AppSearchLogger logger)
-            throws AppSearchException {
-        PutDocumentStats.Builder pStatsBuilder = null;
-        if (logger != null) {
-            pStatsBuilder = new PutDocumentStats.Builder(packageName, databaseName);
-        }
-        long totalStartTimeMillis = SystemClock.elapsedRealtime();
-
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            // Generate Document Proto
-            long generateDocumentProtoStartTimeMillis = SystemClock.elapsedRealtime();
-            DocumentProto.Builder documentBuilder =
-                    GenericDocumentToProtoConverter.toDocumentProto(document).toBuilder();
-            long generateDocumentProtoEndTimeMillis = SystemClock.elapsedRealtime();
-
-            // Rewrite Document Type
-            long rewriteDocumentTypeStartTimeMillis = SystemClock.elapsedRealtime();
-            String prefix = createPrefix(packageName, databaseName);
-            addPrefixToDocument(documentBuilder, prefix);
-            long rewriteDocumentTypeEndTimeMillis = SystemClock.elapsedRealtime();
-            DocumentProto finalDocument = documentBuilder.build();
-
-            // Check limits
-            int newDocumentCount =
-                    enforceLimitConfigLocked(
-                            packageName, finalDocument.getUri(), finalDocument.getSerializedSize());
-
-            // Insert document
-            mLogUtil.piiTrace("putDocument, request", finalDocument.getUri(), finalDocument);
-            PutResultProto putResultProto = mIcingSearchEngineLocked.put(finalDocument);
-            mLogUtil.piiTrace("putDocument, response", putResultProto.getStatus(), putResultProto);
-
-            // Update caches
-            addToMap(mNamespaceMapLocked, prefix, finalDocument.getNamespace());
-            mDocumentCountMapLocked.put(packageName, newDocumentCount);
-
-            // Logging stats
-            if (pStatsBuilder != null) {
-                pStatsBuilder
-                        .setStatusCode(statusProtoToResultCode(putResultProto.getStatus()))
-                        .setGenerateDocumentProtoLatencyMillis(
-                                (int)
-                                        (generateDocumentProtoEndTimeMillis
-                                                - generateDocumentProtoStartTimeMillis))
-                        .setRewriteDocumentTypesLatencyMillis(
-                                (int)
-                                        (rewriteDocumentTypeEndTimeMillis
-                                                - rewriteDocumentTypeStartTimeMillis));
-                AppSearchLoggerHelper.copyNativeStats(
-                        putResultProto.getPutDocumentStats(), pStatsBuilder);
-            }
-
-            checkSuccess(putResultProto.getStatus());
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-
-            if (logger != null) {
-                long totalEndTimeMillis = SystemClock.elapsedRealtime();
-                pStatsBuilder.setTotalLatencyMillis(
-                        (int) (totalEndTimeMillis - totalStartTimeMillis));
-                logger.logStats(pStatsBuilder.build());
-            }
-        }
-    }
-
-    /**
-     * Checks that a new document can be added to the given packageName with the given serialized
-     * size without violating our {@link LimitConfig}.
-     *
-     * @return the new count of documents for the given package, including the new document.
-     * @throws AppSearchException with a code of {@link AppSearchResult#RESULT_OUT_OF_SPACE} if the
-     *     limits are violated by the new document.
-     */
-    @GuardedBy("mReadWriteLock")
-    private int enforceLimitConfigLocked(String packageName, String newDocUri, int newDocSize)
-            throws AppSearchException {
-        // Limits check: size of document
-        if (newDocSize > mLimitConfig.getMaxDocumentSizeBytes()) {
-            throw new AppSearchException(
-                    AppSearchResult.RESULT_OUT_OF_SPACE,
-                    "Document \""
-                            + newDocUri
-                            + "\" for package \""
-                            + packageName
-                            + "\" serialized to "
-                            + newDocSize
-                            + " bytes, which exceeds "
-                            + "limit of "
-                            + mLimitConfig.getMaxDocumentSizeBytes()
-                            + " bytes");
-        }
-
-        // Limits check: number of documents
-        Integer oldDocumentCount = mDocumentCountMapLocked.get(packageName);
-        int newDocumentCount;
-        if (oldDocumentCount == null) {
-            newDocumentCount = 1;
-        } else {
-            newDocumentCount = oldDocumentCount + 1;
-        }
-        if (newDocumentCount > mLimitConfig.getMaxDocumentCount()) {
-            // Our management of mDocumentCountMapLocked doesn't account for document
-            // replacements, so our counter might have overcounted if the app has replaced docs.
-            // Rebuild the counter from StorageInfo in case this is so.
-            // TODO(b/170371356):  If Icing lib exposes something in the result which says
-            //  whether the document was a replacement, we could subtract 1 again after the put
-            //  to keep the count accurate. That would allow us to remove this code.
-            rebuildDocumentCountMapLocked(getRawStorageInfoProto());
-            oldDocumentCount = mDocumentCountMapLocked.get(packageName);
-            if (oldDocumentCount == null) {
-                newDocumentCount = 1;
-            } else {
-                newDocumentCount = oldDocumentCount + 1;
-            }
-        }
-        if (newDocumentCount > mLimitConfig.getMaxDocumentCount()) {
-            // Now we really can't fit it in, even accounting for replacements.
-            throw new AppSearchException(
-                    AppSearchResult.RESULT_OUT_OF_SPACE,
-                    "Package \""
-                            + packageName
-                            + "\" exceeded limit of "
-                            + mLimitConfig.getMaxDocumentCount()
-                            + " documents. Some documents "
-                            + "must be removed to index additional ones.");
-        }
-
-        return newDocumentCount;
-    }
-
-    /**
-     * Retrieves a document from the AppSearch index by namespace and document ID.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param packageName The package that owns this document.
-     * @param databaseName The databaseName this document resides in.
-     * @param namespace The namespace this document resides in.
-     * @param id The ID of the document to get.
-     * @param typePropertyPaths A map of schema type to a list of property paths to return in the
-     *     result.
-     * @return The Document contents
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    @NonNull
-    public GenericDocument getDocument(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String namespace,
-            @NonNull String id,
-            @NonNull Map<String, List<String>> typePropertyPaths)
-            throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-            String prefix = createPrefix(packageName, databaseName);
-            List<TypePropertyMask> nonPrefixedPropertyMasks =
-                    TypePropertyPathToProtoConverter.toTypePropertyMaskList(typePropertyPaths);
-            List<TypePropertyMask> prefixedPropertyMasks =
-                    new ArrayList<>(nonPrefixedPropertyMasks.size());
-            for (int i = 0; i < nonPrefixedPropertyMasks.size(); ++i) {
-                TypePropertyMask typePropertyMask = nonPrefixedPropertyMasks.get(i);
-                String nonPrefixedType = typePropertyMask.getSchemaType();
-                String prefixedType =
-                        nonPrefixedType.equals(
-                                        GetByDocumentIdRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
-                                ? nonPrefixedType
-                                : prefix + nonPrefixedType;
-                prefixedPropertyMasks.add(
-                        typePropertyMask.toBuilder().setSchemaType(prefixedType).build());
-            }
-            GetResultSpecProto getResultSpec =
-                    GetResultSpecProto.newBuilder()
-                            .addAllTypePropertyMasks(prefixedPropertyMasks)
-                            .build();
-
-            String finalNamespace = createPrefix(packageName, databaseName) + namespace;
-            if (mLogUtil.isPiiTraceEnabled()) {
-                mLogUtil.piiTrace(
-                        "getDocument, request", finalNamespace + ", " + id + "," + getResultSpec);
-            }
-            GetResultProto getResultProto =
-                    mIcingSearchEngineLocked.get(finalNamespace, id, getResultSpec);
-            mLogUtil.piiTrace("getDocument, response", getResultProto.getStatus(), getResultProto);
-            checkSuccess(getResultProto.getStatus());
-
-            // The schema type map cannot be null at this point. It could only be null if no
-            // schema had ever been set for that prefix. Given we have retrieved a document from
-            // the index, we know a schema had to have been set.
-            Map<String, SchemaTypeConfigProto> schemaTypeMap = mSchemaMapLocked.get(prefix);
-            DocumentProto.Builder documentBuilder = getResultProto.getDocument().toBuilder();
-            removePrefixesFromDocument(documentBuilder);
-            return GenericDocumentToProtoConverter.toGenericDocument(
-                    documentBuilder.build(), prefix, schemaTypeMap);
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Executes a query against the AppSearch index and returns results.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param packageName The package name that is performing the query.
-     * @param databaseName The databaseName this query for.
-     * @param queryExpression Query String to search.
-     * @param searchSpec Spec for setting filters, raw query etc.
-     * @param logger logger to collect query stats
-     * @return The results of performing this search. It may contain an empty list of results if no
-     *     documents matched the query.
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    @NonNull
-    public SearchResultPage query(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String queryExpression,
-            @NonNull SearchSpec searchSpec,
-            @Nullable AppSearchLogger logger)
-            throws AppSearchException {
-        long totalLatencyStartMillis = SystemClock.elapsedRealtime();
-        SearchStats.Builder sStatsBuilder = null;
-        if (logger != null) {
-            sStatsBuilder =
-                    new SearchStats.Builder(SearchStats.VISIBILITY_SCOPE_LOCAL, packageName)
-                            .setDatabase(databaseName);
-        }
-
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            List<String> filterPackageNames = searchSpec.getFilterPackageNames();
-            if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
-                // Client wanted to query over some packages that weren't its own. This isn't
-                // allowed through local query so we can return early with no results.
-                if (logger != null) {
-                    sStatsBuilder.setStatusCode(AppSearchResult.RESULT_SECURITY_ERROR);
-                }
-                return new SearchResultPage(Bundle.EMPTY);
-            }
-
-            String prefix = createPrefix(packageName, databaseName);
-            Set<String> allowedPrefixedSchemas = getAllowedPrefixSchemasLocked(prefix, searchSpec);
-
-            SearchResultPage searchResultPage =
-                    doQueryLocked(
-                            Collections.singleton(createPrefix(packageName, databaseName)),
-                            allowedPrefixedSchemas,
-                            queryExpression,
-                            searchSpec,
-                            sStatsBuilder);
-            addNextPageToken(packageName, searchResultPage.getNextPageToken());
-            return searchResultPage;
-        } finally {
-            mReadWriteLock.readLock().unlock();
-            if (logger != null) {
-                sStatsBuilder.setTotalLatencyMillis(
-                        (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis));
-                logger.logStats(sStatsBuilder.build());
-            }
-        }
-    }
-
-    /**
-     * Executes a global query, i.e. over all permitted prefixes, against the AppSearch index and
-     * returns results.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param queryExpression Query String to search.
-     * @param searchSpec Spec for setting filters, raw query etc.
-     * @param callerPackageName Package name of the caller, should belong to the {@code
-     *     callerUserHandle}.
-     * @param visibilityStore Optional visibility store to obtain system and package visibility
-     *     settings from
-     * @param callerUid UID of the client making the globalQuery call.
-     * @param callerHasSystemAccess Whether the caller has been positively identified as having
-     *     access to schemas marked system surfaceable.
-     * @param logger logger to collect globalQuery stats
-     * @return The results of performing this search. It may contain an empty list of results if no
-     *     documents matched the query.
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    @NonNull
-    public SearchResultPage globalQuery(
-            @NonNull String queryExpression,
-            @NonNull SearchSpec searchSpec,
-            @NonNull String callerPackageName,
-            @Nullable VisibilityStore visibilityStore,
-            int callerUid,
-            boolean callerHasSystemAccess,
-            @Nullable AppSearchLogger logger)
-            throws AppSearchException {
-        long totalLatencyStartMillis = SystemClock.elapsedRealtime();
-        SearchStats.Builder sStatsBuilder = null;
-        if (logger != null) {
-            sStatsBuilder =
-                    new SearchStats.Builder(SearchStats.VISIBILITY_SCOPE_GLOBAL, callerPackageName);
-        }
-
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            // Convert package filters to prefix filters
-            Set<String> packageFilters = new ArraySet<>(searchSpec.getFilterPackageNames());
-            Set<String> prefixFilters = new ArraySet<>();
-            if (packageFilters.isEmpty()) {
-                // Client didn't restrict their search over packages. Try to query over all
-                // packages/prefixes
-                prefixFilters = mNamespaceMapLocked.keySet();
-            } else {
-                // Client did restrict their search over packages. Only include the prefixes that
-                // belong to the specified packages.
-                for (String prefix : mNamespaceMapLocked.keySet()) {
-                    String packageName = getPackageName(prefix);
-                    if (packageFilters.contains(packageName)) {
-                        prefixFilters.add(prefix);
-                    }
-                }
-            }
-
-            // Convert schema filters to prefixed schema filters
-            ArraySet<String> prefixedSchemaFilters = new ArraySet<>();
-            for (String prefix : prefixFilters) {
-                List<String> schemaFilters = searchSpec.getFilterSchemas();
-                if (schemaFilters.isEmpty()) {
-                    // Client didn't specify certain schemas to search over, check all schemas
-                    prefixedSchemaFilters.addAll(mSchemaMapLocked.get(prefix).keySet());
-                } else {
-                    // Client specified some schemas to search over, check each one
-                    for (int i = 0; i < schemaFilters.size(); i++) {
-                        prefixedSchemaFilters.add(prefix + schemaFilters.get(i));
-                    }
-                }
-            }
-
-            // Remove the schemas the client is not allowed to search over
-            Iterator<String> prefixedSchemaIt = prefixedSchemaFilters.iterator();
-            while (prefixedSchemaIt.hasNext()) {
-                String prefixedSchema = prefixedSchemaIt.next();
-                String packageName = getPackageName(prefixedSchema);
-
-                boolean allow;
-                if (packageName.equals(callerPackageName)) {
-                    // Callers can always retrieve their own data
-                    allow = true;
-                } else if (visibilityStore == null) {
-                    // If there's no visibility store, there's no extra access
-                    allow = false;
-                } else {
-                    String databaseName = getDatabaseName(prefixedSchema);
-                    allow =
-                            visibilityStore.isSchemaSearchableByCaller(
-                                    packageName,
-                                    databaseName,
-                                    prefixedSchema,
-                                    callerUid,
-                                    callerHasSystemAccess);
-                }
-
-                if (!allow) {
-                    prefixedSchemaIt.remove();
-                }
-            }
-
-            SearchResultPage searchResultPage =
-                    doQueryLocked(
-                            prefixFilters,
-                            prefixedSchemaFilters,
-                            queryExpression,
-                            searchSpec,
-                            sStatsBuilder);
-            addNextPageToken(callerPackageName, searchResultPage.getNextPageToken());
-            return searchResultPage;
-        } finally {
-            mReadWriteLock.readLock().unlock();
-
-            if (logger != null) {
-                sStatsBuilder.setTotalLatencyMillis(
-                        (int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis));
-                logger.logStats(sStatsBuilder.build());
-            }
-        }
-    }
-
-    /**
-     * Returns a mapping of package names to all the databases owned by that package.
-     *
-     * <p>This method is inefficient to call repeatedly.
-     */
-    @NonNull
-    public Map<String, Set<String>> getPackageToDatabases() {
-        mReadWriteLock.readLock().lock();
-        try {
-            Map<String, Set<String>> packageToDatabases = new ArrayMap<>();
-            for (String prefix : mSchemaMapLocked.keySet()) {
-                String packageName = getPackageName(prefix);
-
-                Set<String> databases = packageToDatabases.get(packageName);
-                if (databases == null) {
-                    databases = new ArraySet<>();
-                    packageToDatabases.put(packageName, databases);
-                }
-
-                String databaseName = getDatabaseName(prefix);
-                databases.add(databaseName);
-            }
-
-            return packageToDatabases;
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    @GuardedBy("mReadWriteLock")
-    private SearchResultPage doQueryLocked(
-            @NonNull Set<String> prefixes,
-            @NonNull Set<String> allowedPrefixedSchemas,
-            @NonNull String queryExpression,
-            @NonNull SearchSpec searchSpec,
-            @Nullable SearchStats.Builder sStatsBuilder)
-            throws AppSearchException {
-        long rewriteSearchSpecLatencyStartMillis = SystemClock.elapsedRealtime();
-
-        SearchSpecProto.Builder searchSpecBuilder =
-                SearchSpecToProtoConverter.toSearchSpecProto(searchSpec).toBuilder()
-                        .setQuery(queryExpression);
-        // rewriteSearchSpecForPrefixesLocked will return false if there is nothing to search
-        // over given their search filters, so we can return an empty SearchResult and skip
-        // sending request to Icing.
-        if (!rewriteSearchSpecForPrefixesLocked(
-                searchSpecBuilder, prefixes, allowedPrefixedSchemas)) {
-            if (sStatsBuilder != null) {
-                sStatsBuilder.setRewriteSearchSpecLatencyMillis(
-                        (int)
-                                (SystemClock.elapsedRealtime()
-                                        - rewriteSearchSpecLatencyStartMillis));
-            }
-            return new SearchResultPage(Bundle.EMPTY);
-        }
-
-        // rewriteSearchSpec, rewriteResultSpec and convertScoringSpec are all counted in
-        // rewriteSearchSpecLatencyMillis
-        ResultSpecProto.Builder resultSpecBuilder =
-                SearchSpecToProtoConverter.toResultSpecProto(searchSpec).toBuilder();
-
-        int groupingType = searchSpec.getResultGroupingTypeFlags();
-        if ((groupingType & SearchSpec.GROUPING_TYPE_PER_PACKAGE) != 0
-                && (groupingType & SearchSpec.GROUPING_TYPE_PER_NAMESPACE) != 0) {
-            addPerPackagePerNamespaceResultGroupingsLocked(
-                    resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
-        } else if ((groupingType & SearchSpec.GROUPING_TYPE_PER_PACKAGE) != 0) {
-            addPerPackageResultGroupingsLocked(
-                    resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
-        } else if ((groupingType & SearchSpec.GROUPING_TYPE_PER_NAMESPACE) != 0) {
-            addPerNamespaceResultGroupingsLocked(
-                    resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
-        }
-
-        rewriteResultSpecForPrefixesLocked(resultSpecBuilder, prefixes, allowedPrefixedSchemas);
-        ScoringSpecProto scoringSpec = SearchSpecToProtoConverter.toScoringSpecProto(searchSpec);
-        SearchSpecProto finalSearchSpec = searchSpecBuilder.build();
-        ResultSpecProto finalResultSpec = resultSpecBuilder.build();
-
-        long rewriteSearchSpecLatencyEndMillis = SystemClock.elapsedRealtime();
-
-        if (mLogUtil.isPiiTraceEnabled()) {
-            mLogUtil.piiTrace(
-                    "search, request",
-                    finalSearchSpec.getQuery(),
-                    finalSearchSpec + ", " + scoringSpec + ", " + finalResultSpec);
-        }
-        SearchResultProto searchResultProto =
-                mIcingSearchEngineLocked.search(finalSearchSpec, scoringSpec, finalResultSpec);
-        mLogUtil.piiTrace(
-                "search, response", searchResultProto.getResultsCount(), searchResultProto);
-
-        if (sStatsBuilder != null) {
-            sStatsBuilder
-                    .setStatusCode(statusProtoToResultCode(searchResultProto.getStatus()))
-                    .setRewriteSearchSpecLatencyMillis(
-                            (int)
-                                    (rewriteSearchSpecLatencyEndMillis
-                                            - rewriteSearchSpecLatencyStartMillis));
-            AppSearchLoggerHelper.copyNativeStats(searchResultProto.getQueryStats(), sStatsBuilder);
-        }
-
-        checkSuccess(searchResultProto.getStatus());
-
-        long rewriteSearchResultLatencyStartMillis = SystemClock.elapsedRealtime();
-        SearchResultPage resultPage = rewriteSearchResultProto(searchResultProto, mSchemaMapLocked);
-        if (sStatsBuilder != null) {
-            sStatsBuilder.setRewriteSearchResultLatencyMillis(
-                    (int) (SystemClock.elapsedRealtime() - rewriteSearchResultLatencyStartMillis));
-        }
-
-        return resultPage;
-    }
-
-    /**
-     * Fetches the next page of results of a previously executed query. Results can be empty if
-     * next-page token is invalid or all pages have been returned.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param packageName Package name of the caller.
-     * @param nextPageToken The token of pre-loaded results of previously executed query.
-     * @return The next page of results of previously executed query.
-     * @throws AppSearchException on IcingSearchEngine error or if can't advance on nextPageToken.
-     */
-    @NonNull
-    public SearchResultPage getNextPage(@NonNull String packageName, long nextPageToken)
-            throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            mLogUtil.piiTrace("getNextPage, request", nextPageToken);
-            checkNextPageToken(packageName, nextPageToken);
-            SearchResultProto searchResultProto =
-                    mIcingSearchEngineLocked.getNextPage(nextPageToken);
-            mLogUtil.piiTrace(
-                    "getNextPage, response",
-                    searchResultProto.getResultsCount(),
-                    searchResultProto);
-            checkSuccess(searchResultProto.getStatus());
-            if (nextPageToken != EMPTY_PAGE_TOKEN
-                    && searchResultProto.getNextPageToken() == EMPTY_PAGE_TOKEN) {
-                // At this point, we're guaranteed that this nextPageToken exists for this package,
-                // otherwise checkNextPageToken would've thrown an exception.
-                // Since the new token is 0, this is the last page. We should remove the old token
-                // from our cache since it no longer refers to this query.
-                synchronized (mNextPageTokensLocked) {
-                    mNextPageTokensLocked.get(packageName).remove(nextPageToken);
-                }
-            }
-            return rewriteSearchResultProto(searchResultProto, mSchemaMapLocked);
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Invalidates the next-page token so that no more results of the related query can be returned.
-     *
-     * <p>This method belongs to query group.
-     *
-     * @param packageName Package name of the caller.
-     * @param nextPageToken The token of pre-loaded results of previously executed query to be
-     *     Invalidated.
-     * @throws AppSearchException if nextPageToken is unusable.
-     */
-    public void invalidateNextPageToken(@NonNull String packageName, long nextPageToken)
-            throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            mLogUtil.piiTrace("invalidateNextPageToken, request", nextPageToken);
-            checkNextPageToken(packageName, nextPageToken);
-            mIcingSearchEngineLocked.invalidateNextPageToken(nextPageToken);
-
-            synchronized (mNextPageTokensLocked) {
-                // At this point, we're guaranteed that this nextPageToken exists for this package,
-                // otherwise checkNextPageToken would've thrown an exception.
-                mNextPageTokensLocked.get(packageName).remove(nextPageToken);
-            }
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /** Reports a usage of the given document at the given timestamp. */
-    public void reportUsage(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String namespace,
-            @NonNull String documentId,
-            long usageTimestampMillis,
-            boolean systemUsage)
-            throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            String prefixedNamespace = createPrefix(packageName, databaseName) + namespace;
-            UsageReport.UsageType usageType =
-                    systemUsage
-                            ? UsageReport.UsageType.USAGE_TYPE2
-                            : UsageReport.UsageType.USAGE_TYPE1;
-            UsageReport report =
-                    UsageReport.newBuilder()
-                            .setDocumentNamespace(prefixedNamespace)
-                            .setDocumentUri(documentId)
-                            .setUsageTimestampMs(usageTimestampMillis)
-                            .setUsageType(usageType)
-                            .build();
-
-            mLogUtil.piiTrace("reportUsage, request", report.getDocumentUri(), report);
-            ReportUsageResultProto result = mIcingSearchEngineLocked.reportUsage(report);
-            mLogUtil.piiTrace("reportUsage, response", result.getStatus(), result);
-            checkSuccess(result.getStatus());
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Removes the given document by id.
-     *
-     * <p>This method belongs to mutate group.
-     *
-     * @param packageName The package name that owns the document.
-     * @param databaseName The databaseName the document is in.
-     * @param namespace Namespace of the document to remove.
-     * @param id ID of the document to remove.
-     * @param removeStatsBuilder builder for {@link RemoveStats} to hold stats for remove
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    public void remove(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String namespace,
-            @NonNull String id,
-            @Nullable RemoveStats.Builder removeStatsBuilder)
-            throws AppSearchException {
-        long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            String prefixedNamespace = createPrefix(packageName, databaseName) + namespace;
-            if (mLogUtil.isPiiTraceEnabled()) {
-                mLogUtil.piiTrace("removeById, request", prefixedNamespace + ", " + id);
-            }
-            DeleteResultProto deleteResultProto =
-                    mIcingSearchEngineLocked.delete(prefixedNamespace, id);
-            mLogUtil.piiTrace(
-                    "removeById, response", deleteResultProto.getStatus(), deleteResultProto);
-
-            if (removeStatsBuilder != null) {
-                removeStatsBuilder.setStatusCode(
-                        statusProtoToResultCode(deleteResultProto.getStatus()));
-                AppSearchLoggerHelper.copyNativeStats(
-                        deleteResultProto.getDeleteStats(), removeStatsBuilder);
-            }
-            checkSuccess(deleteResultProto.getStatus());
-
-            // Update derived maps
-            updateDocumentCountAfterRemovalLocked(packageName, /*numDocumentsDeleted=*/ 1);
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-            if (removeStatsBuilder != null) {
-                removeStatsBuilder.setTotalLatencyMillis(
-                        (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis));
-            }
-        }
-    }
-
-    /**
-     * Removes documents by given query.
-     *
-     * <p>This method belongs to mutate group.
-     *
-     * @param packageName The package name that owns the documents.
-     * @param databaseName The databaseName the document is in.
-     * @param queryExpression Query String to search.
-     * @param searchSpec Defines what and how to remove
-     * @param removeStatsBuilder builder for {@link RemoveStats} to hold stats for remove
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    public void removeByQuery(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String queryExpression,
-            @NonNull SearchSpec searchSpec,
-            @Nullable RemoveStats.Builder removeStatsBuilder)
-            throws AppSearchException {
-        long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            List<String> filterPackageNames = searchSpec.getFilterPackageNames();
-            if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
-                // We're only removing documents within the parameter `packageName`. If we're not
-                // restricting our remove-query to this package name, then there's nothing for us to
-                // remove.
-                return;
-            }
-
-            SearchSpecProto searchSpecProto =
-                    SearchSpecToProtoConverter.toSearchSpecProto(searchSpec);
-            SearchSpecProto.Builder searchSpecBuilder =
-                    searchSpecProto.toBuilder().setQuery(queryExpression);
-
-            String prefix = createPrefix(packageName, databaseName);
-            Set<String> allowedPrefixedSchemas = getAllowedPrefixSchemasLocked(prefix, searchSpec);
-
-            // rewriteSearchSpecForPrefixesLocked will return false if there is nothing to search
-            // over given their search filters, so we can return early and skip sending request
-            // to Icing.
-            if (!rewriteSearchSpecForPrefixesLocked(
-                    searchSpecBuilder, Collections.singleton(prefix), allowedPrefixedSchemas)) {
-                return;
-            }
-            SearchSpecProto finalSearchSpec = searchSpecBuilder.build();
-            mLogUtil.piiTrace("removeByQuery, request", finalSearchSpec);
-            DeleteByQueryResultProto deleteResultProto =
-                    mIcingSearchEngineLocked.deleteByQuery(finalSearchSpec);
-            mLogUtil.piiTrace(
-                    "removeByQuery, response", deleteResultProto.getStatus(), deleteResultProto);
-
-            if (removeStatsBuilder != null) {
-                removeStatsBuilder.setStatusCode(
-                        statusProtoToResultCode(deleteResultProto.getStatus()));
-                // TODO(b/187206766) also log query stats here once IcingLib returns it
-                AppSearchLoggerHelper.copyNativeStats(
-                        deleteResultProto.getDeleteStats(), removeStatsBuilder);
-            }
-
-            // It seems that the caller wants to get success if the data matching the query is
-            // not in the DB because it was not there or was successfully deleted.
-            checkCodeOneOf(
-                    deleteResultProto.getStatus(), StatusProto.Code.OK, StatusProto.Code.NOT_FOUND);
-
-            // Update derived maps
-            int numDocumentsDeleted = deleteResultProto.getDeleteStats().getNumDocumentsDeleted();
-            updateDocumentCountAfterRemovalLocked(packageName, numDocumentsDeleted);
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-            if (removeStatsBuilder != null) {
-                removeStatsBuilder.setTotalLatencyMillis(
-                        (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis));
-            }
-        }
-    }
-
-    @GuardedBy("mReadWriteLock")
-    private void updateDocumentCountAfterRemovalLocked(
-            @NonNull String packageName, int numDocumentsDeleted) {
-        if (numDocumentsDeleted > 0) {
-            Integer oldDocumentCount = mDocumentCountMapLocked.get(packageName);
-            // This should always be true: how can we delete documents for a package without
-            // having seen that package during init? This is just a safeguard.
-            if (oldDocumentCount != null) {
-                // This should always be >0; how can we remove more documents than we've indexed?
-                // This is just a safeguard.
-                int newDocumentCount = Math.max(oldDocumentCount - numDocumentsDeleted, 0);
-                mDocumentCountMapLocked.put(packageName, newDocumentCount);
-            }
-        }
-    }
-
-    /** Estimates the storage usage info for a specific package. */
-    @NonNull
-    public StorageInfo getStorageInfoForPackage(@NonNull String packageName)
-            throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            Map<String, Set<String>> packageToDatabases = getPackageToDatabases();
-            Set<String> databases = packageToDatabases.get(packageName);
-            if (databases == null) {
-                // Package doesn't exist, no storage info to report
-                return new StorageInfo.Builder().build();
-            }
-
-            // Accumulate all the namespaces we're interested in.
-            Set<String> wantedPrefixedNamespaces = new ArraySet<>();
-            for (String database : databases) {
-                Set<String> prefixedNamespaces =
-                        mNamespaceMapLocked.get(createPrefix(packageName, database));
-                if (prefixedNamespaces != null) {
-                    wantedPrefixedNamespaces.addAll(prefixedNamespaces);
-                }
-            }
-            if (wantedPrefixedNamespaces.isEmpty()) {
-                return new StorageInfo.Builder().build();
-            }
-
-            return getStorageInfoForNamespaces(getRawStorageInfoProto(), wantedPrefixedNamespaces);
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /** Estimates the storage usage info for a specific database in a package. */
-    @NonNull
-    public StorageInfo getStorageInfoForDatabase(
-            @NonNull String packageName, @NonNull String databaseName) throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            Map<String, Set<String>> packageToDatabases = getPackageToDatabases();
-            Set<String> databases = packageToDatabases.get(packageName);
-            if (databases == null) {
-                // Package doesn't exist, no storage info to report
-                return new StorageInfo.Builder().build();
-            }
-            if (!databases.contains(databaseName)) {
-                // Database doesn't exist, no storage info to report
-                return new StorageInfo.Builder().build();
-            }
-
-            Set<String> wantedPrefixedNamespaces =
-                    mNamespaceMapLocked.get(createPrefix(packageName, databaseName));
-            if (wantedPrefixedNamespaces == null || wantedPrefixedNamespaces.isEmpty()) {
-                return new StorageInfo.Builder().build();
-            }
-
-            return getStorageInfoForNamespaces(getRawStorageInfoProto(), wantedPrefixedNamespaces);
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Returns the native storage info capsuled in {@link StorageInfoResultProto} directly from
-     * IcingSearchEngine.
-     */
-    @NonNull
-    public StorageInfoProto getRawStorageInfoProto() throws AppSearchException {
-        mReadWriteLock.readLock().lock();
-        try {
-            throwIfClosedLocked();
-            mLogUtil.piiTrace("getStorageInfo, request");
-            StorageInfoResultProto storageInfoResult = mIcingSearchEngineLocked.getStorageInfo();
-            mLogUtil.piiTrace(
-                    "getStorageInfo, response", storageInfoResult.getStatus(), storageInfoResult);
-            checkSuccess(storageInfoResult.getStatus());
-            return storageInfoResult.getStorageInfo();
-        } finally {
-            mReadWriteLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Extracts and returns {@link StorageInfo} from {@link StorageInfoProto} based on prefixed
-     * namespaces.
-     */
-    @NonNull
-    private static StorageInfo getStorageInfoForNamespaces(
-            @NonNull StorageInfoProto storageInfoProto, @NonNull Set<String> prefixedNamespaces) {
-        if (!storageInfoProto.hasDocumentStorageInfo()) {
-            return new StorageInfo.Builder().build();
-        }
-
-        long totalStorageSize = storageInfoProto.getTotalStorageSize();
-        DocumentStorageInfoProto documentStorageInfo = storageInfoProto.getDocumentStorageInfo();
-        int totalDocuments =
-                documentStorageInfo.getNumAliveDocuments()
-                        + documentStorageInfo.getNumExpiredDocuments();
-
-        if (totalStorageSize == 0 || totalDocuments == 0) {
-            // Maybe we can exit early and also avoid a divide by 0 error.
-            return new StorageInfo.Builder().build();
-        }
-
-        // Accumulate stats across the package's namespaces.
-        int aliveDocuments = 0;
-        int expiredDocuments = 0;
-        int aliveNamespaces = 0;
-        List<NamespaceStorageInfoProto> namespaceStorageInfos =
-                documentStorageInfo.getNamespaceStorageInfoList();
-        for (int i = 0; i < namespaceStorageInfos.size(); i++) {
-            NamespaceStorageInfoProto namespaceStorageInfo = namespaceStorageInfos.get(i);
-            // The namespace from icing lib is already the prefixed format
-            if (prefixedNamespaces.contains(namespaceStorageInfo.getNamespace())) {
-                if (namespaceStorageInfo.getNumAliveDocuments() > 0) {
-                    aliveNamespaces++;
-                    aliveDocuments += namespaceStorageInfo.getNumAliveDocuments();
-                }
-                expiredDocuments += namespaceStorageInfo.getNumExpiredDocuments();
-            }
-        }
-        int namespaceDocuments = aliveDocuments + expiredDocuments;
-
-        // Since we don't have the exact size of all the documents, we do an estimation. Note
-        // that while the total storage takes into account schema, index, etc. in addition to
-        // documents, we'll only calculate the percentage based on number of documents a
-        // client has.
-        return new StorageInfo.Builder()
-                .setSizeBytes((long) (namespaceDocuments * 1.0 / totalDocuments * totalStorageSize))
-                .setAliveDocumentsCount(aliveDocuments)
-                .setAliveNamespacesCount(aliveNamespaces)
-                .build();
-    }
-
-    /**
-     * Persists all update/delete requests to the disk.
-     *
-     * <p>If the app crashes after a call to PersistToDisk with {@link PersistType.Code#FULL}, Icing
-     * would be able to fully recover all data written up to this point without a costly recovery
-     * process.
-     *
-     * <p>If the app crashes after a call to PersistToDisk with {@link PersistType.Code#LITE}, Icing
-     * would trigger a costly recovery process in next initialization. After that, Icing would still
-     * be able to recover all written data - excepting Usage data. Usage data is only guaranteed to
-     * be safe after a call to PersistToDisk with {@link PersistType.Code#FULL}
-     *
-     * <p>If the app crashes after an update/delete request has been made, but before any call to
-     * PersistToDisk, then all data in Icing will be lost.
-     *
-     * @param persistType the amount of data to persist. {@link PersistType.Code#LITE} will only
-     *     persist the minimal amount of data to ensure all data can be recovered. {@link
-     *     PersistType.Code#FULL} will persist all data necessary to prevent data loss without
-     *     needing data recovery.
-     * @throws AppSearchException on any error that AppSearch persist data to disk.
-     */
-    public void persistToDisk(@NonNull PersistType.Code persistType) throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-
-            mLogUtil.piiTrace("persistToDisk, request", persistType);
-            PersistToDiskResultProto persistToDiskResultProto =
-                    mIcingSearchEngineLocked.persistToDisk(persistType);
-            mLogUtil.piiTrace(
-                    "persistToDisk, response",
-                    persistToDiskResultProto.getStatus(),
-                    persistToDiskResultProto);
-            checkSuccess(persistToDiskResultProto.getStatus());
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Remove all {@link AppSearchSchema}s and {@link GenericDocument}s under the given package.
-     *
-     * @param packageName The name of package to be removed.
-     * @throws AppSearchException if we cannot remove the data.
-     */
-    public void clearPackageData(@NonNull String packageName) throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-            Set<String> existingPackages = getPackageToDatabases().keySet();
-            if (existingPackages.contains(packageName)) {
-                existingPackages.remove(packageName);
-                prunePackageData(existingPackages);
-            }
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Remove all {@link AppSearchSchema}s and {@link GenericDocument}s that doesn't belong to any
-     * of the given installed packages
-     *
-     * @param installedPackages The name of all installed package.
-     * @throws AppSearchException if we cannot remove the data.
-     */
-    public void prunePackageData(@NonNull Set<String> installedPackages) throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            throwIfClosedLocked();
-            Map<String, Set<String>> packageToDatabases = getPackageToDatabases();
-            if (installedPackages.containsAll(packageToDatabases.keySet())) {
-                // No package got removed. We are good.
-                return;
-            }
-
-            // Prune schema proto
-            SchemaProto existingSchema = getSchemaProtoLocked();
-            SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();
-            for (int i = 0; i < existingSchema.getTypesCount(); i++) {
-                String packageName = getPackageName(existingSchema.getTypes(i).getSchemaType());
-                if (installedPackages.contains(packageName)) {
-                    newSchemaBuilder.addTypes(existingSchema.getTypes(i));
-                }
-            }
-
-            SchemaProto finalSchema = newSchemaBuilder.build();
-
-            // Apply schema, set force override to true to remove all schemas and documents that
-            // doesn't belong to any of these installed packages.
-            mLogUtil.piiTrace(
-                    "clearPackageData.setSchema, request",
-                    finalSchema.getTypesCount(),
-                    finalSchema);
-            SetSchemaResultProto setSchemaResultProto =
-                    mIcingSearchEngineLocked.setSchema(
-                            finalSchema, /*ignoreErrorsAndDeleteDocuments=*/ true);
-            mLogUtil.piiTrace(
-                    "clearPackageData.setSchema, response",
-                    setSchemaResultProto.getStatus(),
-                    setSchemaResultProto);
-
-            // Determine whether it succeeded.
-            checkSuccess(setSchemaResultProto.getStatus());
-
-            // Prune cached maps
-            for (Map.Entry<String, Set<String>> entry : packageToDatabases.entrySet()) {
-                String packageName = entry.getKey();
-                Set<String> databaseNames = entry.getValue();
-                if (!installedPackages.contains(packageName) && databaseNames != null) {
-                    mDocumentCountMapLocked.remove(packageName);
-                    synchronized (mNextPageTokensLocked) {
-                        mNextPageTokensLocked.remove(packageName);
-                    }
-                    for (String databaseName : databaseNames) {
-                        String removedPrefix = createPrefix(packageName, databaseName);
-                        mSchemaMapLocked.remove(removedPrefix);
-                        mNamespaceMapLocked.remove(removedPrefix);
-                    }
-                }
-            }
-            // TODO(b/145759910) clear visibility setting for package.
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Clears documents and schema across all packages and databaseNames.
-     *
-     * <p>This method belongs to mutate group.
-     *
-     * @throws AppSearchException on IcingSearchEngine error.
-     */
-    @GuardedBy("mReadWriteLock")
-    private void resetLocked(@Nullable InitializeStats.Builder initStatsBuilder)
-            throws AppSearchException {
-        mLogUtil.piiTrace("icingSearchEngine.reset, request");
-        ResetResultProto resetResultProto = mIcingSearchEngineLocked.reset();
-        mLogUtil.piiTrace(
-                "icingSearchEngine.reset, response",
-                resetResultProto.getStatus(),
-                resetResultProto);
-        mOptimizeIntervalCountLocked = 0;
-        mSchemaMapLocked.clear();
-        mNamespaceMapLocked.clear();
-        mDocumentCountMapLocked.clear();
-        synchronized (mNextPageTokensLocked) {
-            mNextPageTokensLocked.clear();
-        }
-        if (initStatsBuilder != null) {
-            initStatsBuilder
-                    .setHasReset(true)
-                    .setResetStatusCode(statusProtoToResultCode(resetResultProto.getStatus()));
-        }
-
-        checkSuccess(resetResultProto.getStatus());
-    }
-
-    @GuardedBy("mReadWriteLock")
-    private void rebuildDocumentCountMapLocked(@NonNull StorageInfoProto storageInfoProto) {
-        mDocumentCountMapLocked.clear();
-        List<NamespaceStorageInfoProto> namespaceStorageInfoProtoList =
-                storageInfoProto.getDocumentStorageInfo().getNamespaceStorageInfoList();
-        for (int i = 0; i < namespaceStorageInfoProtoList.size(); i++) {
-            NamespaceStorageInfoProto namespaceStorageInfoProto =
-                    namespaceStorageInfoProtoList.get(i);
-            String packageName = getPackageName(namespaceStorageInfoProto.getNamespace());
-            Integer oldCount = mDocumentCountMapLocked.get(packageName);
-            int newCount;
-            if (oldCount == null) {
-                newCount = namespaceStorageInfoProto.getNumAliveDocuments();
-            } else {
-                newCount = oldCount + namespaceStorageInfoProto.getNumAliveDocuments();
-            }
-            mDocumentCountMapLocked.put(packageName, newCount);
-        }
-    }
-
-    /** Wrapper around schema changes */
-    @VisibleForTesting
-    static class RewrittenSchemaResults {
-        // Any prefixed types that used to exist in the schema, but are deleted in the new one.
-        final Set<String> mDeletedPrefixedTypes = new ArraySet<>();
-
-        // Map of prefixed schema types to SchemaTypeConfigProtos that were part of the new schema.
-        final Map<String, SchemaTypeConfigProto> mRewrittenPrefixedTypes = new ArrayMap<>();
-    }
-
-    /**
-     * Rewrites all types mentioned in the given {@code newSchema} to prepend {@code prefix}.
-     * Rewritten types will be added to the {@code existingSchema}.
-     *
-     * @param prefix The full prefix to prepend to the schema.
-     * @param existingSchema A schema that may contain existing types from across all prefixes. Will
-     *     be mutated to contain the properly rewritten schema types from {@code newSchema}.
-     * @param newSchema Schema with types to add to the {@code existingSchema}.
-     * @return a RewrittenSchemaResults that contains all prefixed schema type names in the given
-     *     prefix as well as a set of schema types that were deleted.
-     */
-    @VisibleForTesting
-    static RewrittenSchemaResults rewriteSchema(
-            @NonNull String prefix,
-            @NonNull SchemaProto.Builder existingSchema,
-            @NonNull SchemaProto newSchema)
-            throws AppSearchException {
-        HashMap<String, SchemaTypeConfigProto> newTypesToProto = new HashMap<>();
-        // Rewrite the schema type to include the typePrefix.
-        for (int typeIdx = 0; typeIdx < newSchema.getTypesCount(); typeIdx++) {
-            SchemaTypeConfigProto.Builder typeConfigBuilder =
-                    newSchema.getTypes(typeIdx).toBuilder();
-
-            // Rewrite SchemaProto.types.schema_type
-            String newSchemaType = prefix + typeConfigBuilder.getSchemaType();
-            typeConfigBuilder.setSchemaType(newSchemaType);
-
-            // Rewrite SchemaProto.types.properties.schema_type
-            for (int propertyIdx = 0;
-                    propertyIdx < typeConfigBuilder.getPropertiesCount();
-                    propertyIdx++) {
-                PropertyConfigProto.Builder propertyConfigBuilder =
-                        typeConfigBuilder.getProperties(propertyIdx).toBuilder();
-                if (!propertyConfigBuilder.getSchemaType().isEmpty()) {
-                    String newPropertySchemaType = prefix + propertyConfigBuilder.getSchemaType();
-                    propertyConfigBuilder.setSchemaType(newPropertySchemaType);
-                    typeConfigBuilder.setProperties(propertyIdx, propertyConfigBuilder);
-                }
-            }
-
-            newTypesToProto.put(newSchemaType, typeConfigBuilder.build());
-        }
-
-        // newTypesToProto is modified below, so we need a copy first
-        RewrittenSchemaResults rewrittenSchemaResults = new RewrittenSchemaResults();
-        rewrittenSchemaResults.mRewrittenPrefixedTypes.putAll(newTypesToProto);
-
-        // Combine the existing schema (which may have types from other prefixes) with this
-        // prefix's new schema. Modifies the existingSchemaBuilder.
-        // Check if we need to replace any old schema types with the new ones.
-        for (int i = 0; i < existingSchema.getTypesCount(); i++) {
-            String schemaType = existingSchema.getTypes(i).getSchemaType();
-            SchemaTypeConfigProto newProto = newTypesToProto.remove(schemaType);
-            if (newProto != null) {
-                // Replacement
-                existingSchema.setTypes(i, newProto);
-            } else if (prefix.equals(getPrefix(schemaType))) {
-                // All types existing before but not in newSchema should be removed.
-                existingSchema.removeTypes(i);
-                --i;
-                rewrittenSchemaResults.mDeletedPrefixedTypes.add(schemaType);
-            }
-        }
-        // We've been removing existing types from newTypesToProto, so everything that remains is
-        // new.
-        existingSchema.addAllTypes(newTypesToProto.values());
-
-        return rewrittenSchemaResults;
-    }
-
-    /**
-     * Rewrites the search spec filters with {@code prefixes}.
-     *
-     * <p>This method should be only called in query methods and get the READ lock to keep thread
-     * safety.
-     *
-     * @param searchSpecBuilder Client-provided SearchSpec
-     * @param prefixes Prefixes that we should prepend to all our filters
-     * @param allowedPrefixedSchemas Prefixed schemas that the client is allowed to query over. This
-     *     supersedes the schema filters that may exist on the {@code searchSpecBuilder}.
-     * @return false if none there would be nothing to search over.
-     */
-    @VisibleForTesting
-    @GuardedBy("mReadWriteLock")
-    boolean rewriteSearchSpecForPrefixesLocked(
-            @NonNull SearchSpecProto.Builder searchSpecBuilder,
-            @NonNull Set<String> prefixes,
-            @NonNull Set<String> allowedPrefixedSchemas) {
-        // Create a copy since retainAll() modifies the original set.
-        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
-        existingPrefixes.retainAll(prefixes);
-
-        if (existingPrefixes.isEmpty()) {
-            // None of the prefixes exist, empty query.
-            return false;
-        }
-
-        if (allowedPrefixedSchemas.isEmpty()) {
-            // Not allowed to search over any schemas, empty query.
-            return false;
-        }
-
-        // Clear the schema type filters since we'll be rewriting them with the
-        // allowedPrefixedSchemas.
-        searchSpecBuilder.clearSchemaTypeFilters();
-        searchSpecBuilder.addAllSchemaTypeFilters(allowedPrefixedSchemas);
-
-        // Cache the namespaces before clearing everything.
-        List<String> namespaceFilters = searchSpecBuilder.getNamespaceFiltersList();
-        searchSpecBuilder.clearNamespaceFilters();
-
-        // Rewrite non-schema filters to include a prefix.
-        for (String prefix : existingPrefixes) {
-            // TODO(b/169883602): We currently grab every namespace for every prefix. We can
-            //  optimize this by checking if a prefix has any allowedSchemaTypes. If not, that
-            //  means we don't want to query over anything in that prefix anyways, so we don't
-            //  need to grab its namespaces either.
-
-            // Empty namespaces on the search spec means to query over all namespaces.
-            Set<String> existingNamespaces = mNamespaceMapLocked.get(prefix);
-            if (existingNamespaces != null) {
-                if (namespaceFilters.isEmpty()) {
-                    // Include all namespaces
-                    searchSpecBuilder.addAllNamespaceFilters(existingNamespaces);
-                } else {
-                    // Prefix the given namespaces.
-                    for (int i = 0; i < namespaceFilters.size(); i++) {
-                        String prefixedNamespace = prefix + namespaceFilters.get(i);
-                        if (existingNamespaces.contains(prefixedNamespace)) {
-                            searchSpecBuilder.addNamespaceFilters(prefixedNamespace);
-                        }
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the set of allowed prefixed schemas that the {@code prefix} can query while taking
-     * into account the {@code searchSpec} schema filters.
-     *
-     * <p>This only checks intersection of schema filters on the search spec with those that the
-     * prefix owns itself. This does not check global query permissions.
-     */
-    @GuardedBy("mReadWriteLock")
-    private Set<String> getAllowedPrefixSchemasLocked(
-            @NonNull String prefix, @NonNull SearchSpec searchSpec) {
-        Set<String> allowedPrefixedSchemas = new ArraySet<>();
-
-        // Add all the schema filters the client specified.
-        List<String> schemaFilters = searchSpec.getFilterSchemas();
-        for (int i = 0; i < schemaFilters.size(); i++) {
-            allowedPrefixedSchemas.add(prefix + schemaFilters.get(i));
-        }
-
-        if (allowedPrefixedSchemas.isEmpty()) {
-            // If the client didn't specify any schema filters, search over all of their schemas
-            Map<String, SchemaTypeConfigProto> prefixedSchemaMap = mSchemaMapLocked.get(prefix);
-            if (prefixedSchemaMap != null) {
-                allowedPrefixedSchemas.addAll(prefixedSchemaMap.keySet());
-            }
-        }
-        return allowedPrefixedSchemas;
-    }
-
-    /**
-     * Rewrites the typePropertyMasks that exist in {@code prefixes}.
-     *
-     * <p>This method should be only called in query methods and get the READ lock to keep thread
-     * safety.
-     *
-     * @param resultSpecBuilder ResultSpecs as specified by client
-     * @param prefixes Prefixes that we should prepend to all our filters
-     * @param allowedPrefixedSchemas Prefixed schemas that the client is allowed to query over.
-     */
-    @VisibleForTesting
-    @GuardedBy("mReadWriteLock")
-    void rewriteResultSpecForPrefixesLocked(
-            @NonNull ResultSpecProto.Builder resultSpecBuilder,
-            @NonNull Set<String> prefixes,
-            @NonNull Set<String> allowedPrefixedSchemas) {
-        // Create a copy since retainAll() modifies the original set.
-        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
-        existingPrefixes.retainAll(prefixes);
-
-        List<TypePropertyMask> prefixedTypePropertyMasks = new ArrayList<>();
-        // Rewrite filters to include a database prefix.
-        for (String prefix : existingPrefixes) {
-            // Qualify the given schema types
-            for (TypePropertyMask typePropertyMask : resultSpecBuilder.getTypePropertyMasksList()) {
-                String unprefixedType = typePropertyMask.getSchemaType();
-                boolean isWildcard =
-                        unprefixedType.equals(SearchSpec.PROJECTION_SCHEMA_TYPE_WILDCARD);
-                String prefixedType = isWildcard ? unprefixedType : prefix + unprefixedType;
-                if (isWildcard || allowedPrefixedSchemas.contains(prefixedType)) {
-                    prefixedTypePropertyMasks.add(
-                            typePropertyMask.toBuilder().setSchemaType(prefixedType).build());
-                }
-            }
-        }
-        resultSpecBuilder
-                .clearTypePropertyMasks()
-                .addAllTypePropertyMasks(prefixedTypePropertyMasks);
-    }
-
-    /**
-     * Adds result groupings for each namespace in each package being queried for.
-     *
-     * <p>This method should be only called in query methods and get the READ lock to keep thread
-     * safety.
-     *
-     * @param resultSpecBuilder ResultSpecs as specified by client
-     * @param prefixes Prefixes that we should prepend to all our filters
-     * @param maxNumResults The maximum number of results for each grouping to support.
-     */
-    @GuardedBy("mReadWriteLock")
-    private void addPerPackagePerNamespaceResultGroupingsLocked(
-            @NonNull ResultSpecProto.Builder resultSpecBuilder,
-            @NonNull Set<String> prefixes,
-            int maxNumResults) {
-        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
-        existingPrefixes.retainAll(prefixes);
-
-        // Create a map for package+namespace to prefixedNamespaces. This is NOT necessarily the
-        // same as the list of namespaces. If one package has multiple databases, each with the same
-        // namespace, then those should be grouped together.
-        Map<String, List<String>> packageAndNamespaceToNamespaces = new ArrayMap<>();
-        for (String prefix : existingPrefixes) {
-            Set<String> prefixedNamespaces = mNamespaceMapLocked.get(prefix);
-            if (prefixedNamespaces == null) {
-                continue;
-            }
-            String packageName = getPackageName(prefix);
-            // Create a new prefix without the database name. This will allow us to group namespaces
-            // that have the same name and package but a different database name together.
-            String emptyDatabasePrefix = createPrefix(packageName, /*databaseName*/ "");
-            for (String prefixedNamespace : prefixedNamespaces) {
-                String namespace;
-                try {
-                    namespace = removePrefix(prefixedNamespace);
-                } catch (AppSearchException e) {
-                    // This should never happen. Skip this namespace if it does.
-                    Log.e(TAG, "Prefixed namespace " + prefixedNamespace + " is malformed.");
-                    continue;
-                }
-                String emptyDatabasePrefixedNamespace = emptyDatabasePrefix + namespace;
-                List<String> namespaceList =
-                        packageAndNamespaceToNamespaces.get(emptyDatabasePrefixedNamespace);
-                if (namespaceList == null) {
-                    namespaceList = new ArrayList<>();
-                    packageAndNamespaceToNamespaces.put(
-                            emptyDatabasePrefixedNamespace, namespaceList);
-                }
-                namespaceList.add(prefixedNamespace);
-            }
-        }
-
-        for (List<String> namespaces : packageAndNamespaceToNamespaces.values()) {
-            resultSpecBuilder.addResultGroupings(
-                    ResultSpecProto.ResultGrouping.newBuilder()
-                            .addAllNamespaces(namespaces)
-                            .setMaxResults(maxNumResults));
-        }
-    }
-
-    /**
-     * Adds result groupings for each package being queried for.
-     *
-     * <p>This method should be only called in query methods and get the READ lock to keep thread
-     * safety.
-     *
-     * @param resultSpecBuilder ResultSpecs as specified by client
-     * @param prefixes Prefixes that we should prepend to all our filters
-     * @param maxNumResults The maximum number of results for each grouping to support.
-     */
-    @GuardedBy("mReadWriteLock")
-    private void addPerPackageResultGroupingsLocked(
-            @NonNull ResultSpecProto.Builder resultSpecBuilder,
-            @NonNull Set<String> prefixes,
-            int maxNumResults) {
-        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
-        existingPrefixes.retainAll(prefixes);
-
-        // Build up a map of package to namespaces.
-        Map<String, List<String>> packageToNamespacesMap = new ArrayMap<>();
-        for (String prefix : existingPrefixes) {
-            Set<String> prefixedNamespaces = mNamespaceMapLocked.get(prefix);
-            if (prefixedNamespaces == null) {
-                continue;
-            }
-            String packageName = getPackageName(prefix);
-            List<String> packageNamespaceList = packageToNamespacesMap.get(packageName);
-            if (packageNamespaceList == null) {
-                packageNamespaceList = new ArrayList<>();
-                packageToNamespacesMap.put(packageName, packageNamespaceList);
-            }
-            packageNamespaceList.addAll(prefixedNamespaces);
-        }
-
-        for (List<String> prefixedNamespaces : packageToNamespacesMap.values()) {
-            resultSpecBuilder.addResultGroupings(
-                    ResultSpecProto.ResultGrouping.newBuilder()
-                            .addAllNamespaces(prefixedNamespaces)
-                            .setMaxResults(maxNumResults));
-        }
-    }
-
-    /**
-     * Adds result groupings for each namespace being queried for.
-     *
-     * <p>This method should be only called in query methods and get the READ lock to keep thread
-     * safety.
-     *
-     * @param resultSpecBuilder ResultSpecs as specified by client
-     * @param prefixes Prefixes that we should prepend to all our filters
-     * @param maxNumResults The maximum number of results for each grouping to support.
-     */
-    @GuardedBy("mReadWriteLock")
-    private void addPerNamespaceResultGroupingsLocked(
-            @NonNull ResultSpecProto.Builder resultSpecBuilder,
-            @NonNull Set<String> prefixes,
-            int maxNumResults) {
-        Set<String> existingPrefixes = new ArraySet<>(mNamespaceMapLocked.keySet());
-        existingPrefixes.retainAll(prefixes);
-
-        // Create a map of namespace to prefixedNamespaces. This is NOT necessarily the
-        // same as the list of namespaces. If a namespace exists under different packages and/or
-        // different databases, they should still be grouped together.
-        Map<String, List<String>> namespaceToPrefixedNamespaces = new ArrayMap<>();
-        for (String prefix : existingPrefixes) {
-            Set<String> prefixedNamespaces = mNamespaceMapLocked.get(prefix);
-            if (prefixedNamespaces == null) {
-                continue;
-            }
-            for (String prefixedNamespace : prefixedNamespaces) {
-                String namespace;
-                try {
-                    namespace = removePrefix(prefixedNamespace);
-                } catch (AppSearchException e) {
-                    // This should never happen. Skip this namespace if it does.
-                    Log.e(TAG, "Prefixed namespace " + prefixedNamespace + " is malformed.");
-                    continue;
-                }
-                List<String> groupedPrefixedNamespaces =
-                        namespaceToPrefixedNamespaces.get(namespace);
-                if (groupedPrefixedNamespaces == null) {
-                    groupedPrefixedNamespaces = new ArrayList<>();
-                    namespaceToPrefixedNamespaces.put(namespace, groupedPrefixedNamespaces);
-                }
-                groupedPrefixedNamespaces.add(prefixedNamespace);
-            }
-        }
-
-        for (List<String> namespaces : namespaceToPrefixedNamespaces.values()) {
-            resultSpecBuilder.addResultGroupings(
-                    ResultSpecProto.ResultGrouping.newBuilder()
-                            .addAllNamespaces(namespaces)
-                            .setMaxResults(maxNumResults));
-        }
-    }
-
-    @VisibleForTesting
-    @GuardedBy("mReadWriteLock")
-    SchemaProto getSchemaProtoLocked() throws AppSearchException {
-        mLogUtil.piiTrace("getSchema, request");
-        GetSchemaResultProto schemaProto = mIcingSearchEngineLocked.getSchema();
-        mLogUtil.piiTrace("getSchema, response", schemaProto.getStatus(), schemaProto);
-        // TODO(b/161935693) check GetSchemaResultProto is success or not. Call reset() if it's not.
-        // TODO(b/161935693) only allow GetSchemaResultProto NOT_FOUND on first run
-        checkCodeOneOf(schemaProto.getStatus(), StatusProto.Code.OK, StatusProto.Code.NOT_FOUND);
-        return schemaProto.getSchema();
-    }
-
-    private void addNextPageToken(String packageName, long nextPageToken) {
-        if (nextPageToken == EMPTY_PAGE_TOKEN) {
-            // There is no more pages. No need to add it.
-            return;
-        }
-        synchronized (mNextPageTokensLocked) {
-            Set<Long> tokens = mNextPageTokensLocked.get(packageName);
-            if (tokens == null) {
-                tokens = new ArraySet<>();
-                mNextPageTokensLocked.put(packageName, tokens);
-            }
-            tokens.add(nextPageToken);
-        }
-    }
-
-    private void checkNextPageToken(String packageName, long nextPageToken)
-            throws AppSearchException {
-        if (nextPageToken == EMPTY_PAGE_TOKEN) {
-            // Swallow the check for empty page token, token = 0 means there is no more page and it
-            // won't return anything from Icing.
-            return;
-        }
-        synchronized (mNextPageTokensLocked) {
-            Set<Long> nextPageTokens = mNextPageTokensLocked.get(packageName);
-            if (nextPageTokens == null || !nextPageTokens.contains(nextPageToken)) {
-                throw new AppSearchException(
-                        AppSearchResult.RESULT_SECURITY_ERROR,
-                        "Package \""
-                                + packageName
-                                + "\" cannot use nextPageToken: "
-                                + nextPageToken);
-            }
-        }
-    }
-
-    private static void addToMap(
-            Map<String, Set<String>> map, String prefix, String prefixedValue) {
-        Set<String> values = map.get(prefix);
-        if (values == null) {
-            values = new ArraySet<>();
-            map.put(prefix, values);
-        }
-        values.add(prefixedValue);
-    }
-
-    private static void addToMap(
-            Map<String, Map<String, SchemaTypeConfigProto>> map,
-            String prefix,
-            SchemaTypeConfigProto schemaTypeConfigProto) {
-        Map<String, SchemaTypeConfigProto> schemaTypeMap = map.get(prefix);
-        if (schemaTypeMap == null) {
-            schemaTypeMap = new ArrayMap<>();
-            map.put(prefix, schemaTypeMap);
-        }
-        schemaTypeMap.put(schemaTypeConfigProto.getSchemaType(), schemaTypeConfigProto);
-    }
-
-    private static void removeFromMap(
-            Map<String, Map<String, SchemaTypeConfigProto>> map, String prefix, String schemaType) {
-        Map<String, SchemaTypeConfigProto> schemaTypeMap = map.get(prefix);
-        if (schemaTypeMap != null) {
-            schemaTypeMap.remove(schemaType);
-        }
-    }
-
-    /**
-     * Checks the given status code and throws an {@link AppSearchException} if code is an error.
-     *
-     * @throws AppSearchException on error codes.
-     */
-    private static void checkSuccess(StatusProto statusProto) throws AppSearchException {
-        checkCodeOneOf(statusProto, StatusProto.Code.OK);
-    }
-
-    /**
-     * Checks the given status code is one of the provided codes, and throws an {@link
-     * AppSearchException} if it is not.
-     */
-    private static void checkCodeOneOf(StatusProto statusProto, StatusProto.Code... codes)
-            throws AppSearchException {
-        for (int i = 0; i < codes.length; i++) {
-            if (codes[i] == statusProto.getCode()) {
-                // Everything's good
-                return;
-            }
-        }
-
-        if (statusProto.getCode() == StatusProto.Code.WARNING_DATA_LOSS) {
-            // TODO: May want to propagate WARNING_DATA_LOSS up to AppSearchSession so they can
-            //  choose to log the error or potentially pass it on to clients.
-            Log.w(TAG, "Encountered WARNING_DATA_LOSS: " + statusProto.getMessage());
-            return;
-        }
-
-        throw new AppSearchException(
-                ResultCodeToProtoConverter.toResultCode(statusProto.getCode()),
-                statusProto.getMessage());
-    }
-
-    /**
-     * Checks whether {@link IcingSearchEngine#optimize()} should be called to release resources.
-     *
-     * <p>This method should be only called after a mutation to local storage backend which deletes
-     * a mass of data and could release lots resources after {@link IcingSearchEngine#optimize()}.
-     *
-     * <p>This method will trigger {@link IcingSearchEngine#getOptimizeInfo()} to check resources
-     * that could be released for every {@link #CHECK_OPTIMIZE_INTERVAL} mutations.
-     *
-     * <p>{@link IcingSearchEngine#optimize()} should be called only if {@link
-     * GetOptimizeInfoResultProto} shows there is enough resources could be released.
-     *
-     * @param mutationSize The number of how many mutations have been executed for current request.
-     *     An inside counter will accumulates it. Once the counter reaches {@link
-     *     #CHECK_OPTIMIZE_INTERVAL}, {@link IcingSearchEngine#getOptimizeInfo()} will be triggered
-     *     and the counter will be reset.
-     */
-    public void checkForOptimize(int mutationSize, @Nullable OptimizeStats.Builder builder)
-            throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            mOptimizeIntervalCountLocked += mutationSize;
-            if (mOptimizeIntervalCountLocked >= CHECK_OPTIMIZE_INTERVAL) {
-                checkForOptimize(builder);
-            }
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /**
-     * Checks whether {@link IcingSearchEngine#optimize()} should be called to release resources.
-     *
-     * <p>This method will directly trigger {@link IcingSearchEngine#getOptimizeInfo()} to check
-     * resources that could be released.
-     *
-     * <p>{@link IcingSearchEngine#optimize()} should be called only if {@link
-     * OptimizeStrategy#shouldOptimize(GetOptimizeInfoResultProto)} return true.
-     */
-    public void checkForOptimize(@Nullable OptimizeStats.Builder builder)
-            throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            GetOptimizeInfoResultProto optimizeInfo = getOptimizeInfoResultLocked();
-            checkSuccess(optimizeInfo.getStatus());
-            mOptimizeIntervalCountLocked = 0;
-            if (mOptimizeStrategy.shouldOptimize(optimizeInfo)) {
-                optimize(builder);
-            }
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-        // TODO(b/147699081): Return OptimizeResultProto & log lost data detail once we add
-        //  a field to indicate lost_schema and lost_documents in OptimizeResultProto.
-        //  go/icing-library-apis.
-    }
-
-    /** Triggers {@link IcingSearchEngine#optimize()} directly. */
-    public void optimize(@Nullable OptimizeStats.Builder builder) throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
-        try {
-            mLogUtil.piiTrace("optimize, request");
-            OptimizeResultProto optimizeResultProto = mIcingSearchEngineLocked.optimize();
-            mLogUtil.piiTrace(
-                    "optimize, response", optimizeResultProto.getStatus(), optimizeResultProto);
-            if (builder != null) {
-                builder.setStatusCode(statusProtoToResultCode(optimizeResultProto.getStatus()));
-                AppSearchLoggerHelper.copyNativeStats(
-                        optimizeResultProto.getOptimizeStats(), builder);
-            }
-            checkSuccess(optimizeResultProto.getStatus());
-        } finally {
-            mReadWriteLock.writeLock().unlock();
-        }
-    }
-
-    /** Remove the rewritten schema types from any result documents. */
-    @NonNull
-    @VisibleForTesting
-    static SearchResultPage rewriteSearchResultProto(
-            @NonNull SearchResultProto searchResultProto,
-            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap)
-            throws AppSearchException {
-        // Parallel array of package names for each document search result.
-        List<String> packageNames = new ArrayList<>(searchResultProto.getResultsCount());
-
-        // Parallel array of database names for each document search result.
-        List<String> databaseNames = new ArrayList<>(searchResultProto.getResultsCount());
-
-        SearchResultProto.Builder resultsBuilder = searchResultProto.toBuilder();
-        for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
-            SearchResultProto.ResultProto.Builder resultBuilder =
-                    searchResultProto.getResults(i).toBuilder();
-            DocumentProto.Builder documentBuilder = resultBuilder.getDocument().toBuilder();
-            String prefix = removePrefixesFromDocument(documentBuilder);
-            packageNames.add(getPackageName(prefix));
-            databaseNames.add(getDatabaseName(prefix));
-            resultBuilder.setDocument(documentBuilder);
-            resultsBuilder.setResults(i, resultBuilder);
-        }
-        return SearchResultToProtoConverter.toSearchResultPage(
-                resultsBuilder, packageNames, databaseNames, schemaMap);
-    }
-
-    @GuardedBy("mReadWriteLock")
-    @VisibleForTesting
-    GetOptimizeInfoResultProto getOptimizeInfoResultLocked() {
-        mLogUtil.piiTrace("getOptimizeInfo, request");
-        GetOptimizeInfoResultProto result = mIcingSearchEngineLocked.getOptimizeInfo();
-        mLogUtil.piiTrace("getOptimizeInfo, response", result.getStatus(), result);
-        return result;
-    }
-
-    /**
-     * Converts an erroneous status code from the Icing status enums to the AppSearchResult enums.
-     *
-     * <p>Callers should ensure that the status code is not OK or WARNING_DATA_LOSS.
-     *
-     * @param statusProto StatusProto with error code to translate into an {@link AppSearchResult}
-     *     code.
-     * @return {@link AppSearchResult} error code
-     */
-    private static @AppSearchResult.ResultCode int statusProtoToResultCode(
-            @NonNull StatusProto statusProto) {
-        return ResultCodeToProtoConverter.toResultCode(statusProto.getCode());
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLogger.java
deleted file mode 100644
index 98cedc7..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLogger.java
+++ /dev/null
@@ -1,58 +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 com.android.server.appsearch.external.localstorage;
-
-import android.annotation.NonNull;
-
-import com.android.server.appsearch.external.localstorage.stats.CallStats;
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
-import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
-import com.android.server.appsearch.external.localstorage.stats.SearchStats;
-
-/**
- * An interface for implementing client-defined logging AppSearch operations stats.
- *
- * <p>Any implementation needs to provide general information on how to log all the stats types.
- * (e.g. {@link CallStats})
- *
- * <p>All implementations of this interface must be thread safe.
- *
- * @hide
- */
-public interface AppSearchLogger {
-    /** Logs {@link CallStats} */
-    void logStats(@NonNull CallStats stats);
-
-    /** Logs {@link PutDocumentStats} */
-    void logStats(@NonNull PutDocumentStats stats);
-
-    /** Logs {@link InitializeStats} */
-    void logStats(@NonNull InitializeStats stats);
-
-    /** Logs {@link SearchStats} */
-    void logStats(@NonNull SearchStats stats);
-
-    /** Logs {@link RemoveStats} */
-    void logStats(@NonNull RemoveStats stats);
-
-    /** Logs {@link OptimizeStats} */
-    void logStats(@NonNull OptimizeStats stats);
-
-    // TODO(b/173532925) Add remaining logStats once we add all the stats.
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java
deleted file mode 100644
index cd653e5..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage;
-
-import android.annotation.NonNull;
-
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
-import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
-import com.android.server.appsearch.external.localstorage.stats.SearchStats;
-
-import com.google.android.icing.proto.DeleteStatsProto;
-import com.google.android.icing.proto.InitializeStatsProto;
-import com.google.android.icing.proto.OptimizeStatsProto;
-import com.google.android.icing.proto.PutDocumentStatsProto;
-import com.google.android.icing.proto.QueryStatsProto;
-
-import java.util.Objects;
-
-/**
- * Class contains helper functions for logging.
- *
- * <p>E.g. we need to have helper functions to copy numbers from IcingLib to stats classes.
- *
- * @hide
- */
-public final class AppSearchLoggerHelper {
-    private AppSearchLoggerHelper() {}
-
-    /**
-     * Copies native PutDocument stats to builder.
-     *
-     * @param fromNativeStats stats copied from
-     * @param toStatsBuilder stats copied to
-     */
-    static void copyNativeStats(
-            @NonNull PutDocumentStatsProto fromNativeStats,
-            @NonNull PutDocumentStats.Builder toStatsBuilder) {
-        Objects.requireNonNull(fromNativeStats);
-        Objects.requireNonNull(toStatsBuilder);
-        toStatsBuilder
-                .setNativeLatencyMillis(fromNativeStats.getLatencyMs())
-                .setNativeDocumentStoreLatencyMillis(fromNativeStats.getDocumentStoreLatencyMs())
-                .setNativeIndexLatencyMillis(fromNativeStats.getIndexLatencyMs())
-                .setNativeIndexMergeLatencyMillis(fromNativeStats.getIndexMergeLatencyMs())
-                .setNativeDocumentSizeBytes(fromNativeStats.getDocumentSize())
-                .setNativeNumTokensIndexed(
-                        fromNativeStats.getTokenizationStats().getNumTokensIndexed())
-                .setNativeExceededMaxNumTokens(
-                        fromNativeStats.getTokenizationStats().getExceededMaxTokenNum());
-    }
-
-    /**
-     * Copies native Initialize stats to builder.
-     *
-     * @param fromNativeStats stats copied from
-     * @param toStatsBuilder stats copied to
-     */
-    static void copyNativeStats(
-            @NonNull InitializeStatsProto fromNativeStats,
-            @NonNull InitializeStats.Builder toStatsBuilder) {
-        Objects.requireNonNull(fromNativeStats);
-        Objects.requireNonNull(toStatsBuilder);
-        toStatsBuilder
-                .setNativeLatencyMillis(fromNativeStats.getLatencyMs())
-                .setDocumentStoreRecoveryCause(
-                        fromNativeStats.getDocumentStoreRecoveryCause().getNumber())
-                .setIndexRestorationCause(fromNativeStats.getIndexRestorationCause().getNumber())
-                .setSchemaStoreRecoveryCause(
-                        fromNativeStats.getSchemaStoreRecoveryCause().getNumber())
-                .setDocumentStoreRecoveryLatencyMillis(
-                        fromNativeStats.getDocumentStoreRecoveryLatencyMs())
-                .setIndexRestorationLatencyMillis(fromNativeStats.getIndexRestorationLatencyMs())
-                .setSchemaStoreRecoveryLatencyMillis(
-                        fromNativeStats.getSchemaStoreRecoveryLatencyMs())
-                .setDocumentStoreDataStatus(
-                        fromNativeStats.getDocumentStoreDataStatus().getNumber())
-                .setDocumentCount(fromNativeStats.getNumDocuments())
-                .setSchemaTypeCount(fromNativeStats.getNumSchemaTypes());
-    }
-
-    /**
-     * Copies native Query stats to builder.
-     *
-     * @param fromNativeStats Stats copied from.
-     * @param toStatsBuilder Stats copied to.
-     */
-    static void copyNativeStats(
-            @NonNull QueryStatsProto fromNativeStats, @NonNull SearchStats.Builder toStatsBuilder) {
-        Objects.requireNonNull(fromNativeStats);
-        Objects.requireNonNull(toStatsBuilder);
-        toStatsBuilder
-                .setNativeLatencyMillis(fromNativeStats.getLatencyMs())
-                .setTermCount(fromNativeStats.getNumTerms())
-                .setQueryLength(fromNativeStats.getQueryLength())
-                .setFilteredNamespaceCount(fromNativeStats.getNumNamespacesFiltered())
-                .setFilteredSchemaTypeCount(fromNativeStats.getNumSchemaTypesFiltered())
-                .setRequestedPageSize(fromNativeStats.getRequestedPageSize())
-                .setCurrentPageReturnedResultCount(
-                        fromNativeStats.getNumResultsReturnedCurrentPage())
-                .setIsFirstPage(fromNativeStats.getIsFirstPage())
-                .setParseQueryLatencyMillis(fromNativeStats.getParseQueryLatencyMs())
-                .setRankingStrategy(fromNativeStats.getRankingStrategy().getNumber())
-                .setScoredDocumentCount(fromNativeStats.getNumDocumentsScored())
-                .setScoringLatencyMillis(fromNativeStats.getScoringLatencyMs())
-                .setRankingLatencyMillis(fromNativeStats.getRankingLatencyMs())
-                .setResultWithSnippetsCount(fromNativeStats.getNumResultsWithSnippets())
-                .setDocumentRetrievingLatencyMillis(
-                        fromNativeStats.getDocumentRetrievalLatencyMs());
-    }
-
-    /**
-     * Copies native Delete stats to builder.
-     *
-     * @param fromNativeStats Stats copied from.
-     * @param toStatsBuilder Stats copied to.
-     */
-    static void copyNativeStats(
-            @NonNull DeleteStatsProto fromNativeStats,
-            @NonNull RemoveStats.Builder toStatsBuilder) {
-        Objects.requireNonNull(fromNativeStats);
-        Objects.requireNonNull(toStatsBuilder);
-        toStatsBuilder
-                .setNativeLatencyMillis(fromNativeStats.getLatencyMs())
-                .setDeleteType(fromNativeStats.getDeleteType().getNumber())
-                .setDeletedDocumentCount(fromNativeStats.getNumDocumentsDeleted());
-    }
-
-    /**
-     * Copies native {@link OptimizeStatsProto} to builder.
-     *
-     * @param fromNativeStats Stats copied from.
-     * @param toStatsBuilder Stats copied to.
-     */
-    static void copyNativeStats(
-            @NonNull OptimizeStatsProto fromNativeStats,
-            @NonNull OptimizeStats.Builder toStatsBuilder) {
-        Objects.requireNonNull(fromNativeStats);
-        Objects.requireNonNull(toStatsBuilder);
-        toStatsBuilder
-                .setNativeLatencyMillis(fromNativeStats.getLatencyMs())
-                .setDocumentStoreOptimizeLatencyMillis(
-                        fromNativeStats.getDocumentStoreOptimizeLatencyMs())
-                .setIndexRestorationLatencyMillis(fromNativeStats.getIndexRestorationLatencyMs())
-                .setOriginalDocumentCount(fromNativeStats.getNumOriginalDocuments())
-                .setDeletedDocumentCount(fromNativeStats.getNumDeletedDocuments())
-                .setExpiredDocumentCount(fromNativeStats.getNumExpiredDocuments())
-                .setStorageSizeBeforeBytes(fromNativeStats.getStorageSizeBefore())
-                .setStorageSizeAfterBytes(fromNativeStats.getStorageSizeAfter())
-                .setTimeSinceLastOptimizeMillis(fromNativeStats.getTimeSinceLastOptimizeMs());
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/LimitConfig.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/LimitConfig.java
deleted file mode 100644
index 3f5723e..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/LimitConfig.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage;
-
-
-/**
- * Defines limits placed on users of AppSearch and enforced by {@link AppSearchImpl}.
- *
- * @hide
- */
-public interface LimitConfig {
-    /**
-     * The maximum number of bytes a single document is allowed to be.
-     *
-     * <p>Enforced at the time of serializing the document into a proto.
-     *
-     * <p>This limit has two purposes:
-     *
-     * <ol>
-     *   <li>Prevent the system service from using too much memory during indexing or querying by
-     *       capping the size of the data structures it needs to buffer
-     *   <li>Prevent apps from using a very large amount of data by storing exceptionally large
-     *       documents.
-     * </ol>
-     */
-    int getMaxDocumentSizeBytes();
-
-    /**
-     * The maximum number of documents a single app is allowed to index.
-     *
-     * <p>Enforced at indexing time.
-     *
-     * <p>This limit has two purposes:
-     *
-     * <ol>
-     *   <li>Protect icing lib's docid space from being overwhelmed by a single app. The overall
-     *       docid limit is currently 2^20 (~1 million)
-     *   <li>Prevent apps from using a very large amount of data on the system by storing too many
-     *       documents.
-     * </ol>
-     */
-    int getMaxDocumentCount();
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java
deleted file mode 100644
index 6cb84bc..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage;
-
-import android.annotation.NonNull;
-
-import com.google.android.icing.proto.GetOptimizeInfoResultProto;
-
-/**
- * An interface class for implementing a strategy to determine when to trigger {@link
- * AppSearchImpl#optimize()}.
- *
- * @hide
- */
-public interface OptimizeStrategy {
-
-    /**
-     * Determines whether {@link AppSearchImpl#optimize()} need to be triggered to release garbage
-     * resources in AppSearch base on the given information.
-     *
-     * @param optimizeInfo The proto object indicates the number of garbage resources in AppSearch.
-     * @return {@code true} if {@link AppSearchImpl#optimize()} need to be triggered.
-     */
-    boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo);
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/UnlimitedLimitConfig.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/UnlimitedLimitConfig.java
deleted file mode 100644
index 0fabab0..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/UnlimitedLimitConfig.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage;
-
-
-/**
- * In Jetpack, AppSearch doesn't enforce artificial limits on number of documents or size of
- * documents, since the app is the only user of the Icing instance. Icing still enforces a docid
- * limit of 1M docs.
- *
- * @hide
- */
-public class UnlimitedLimitConfig implements LimitConfig {
-    @Override
-    public int getMaxDocumentSizeBytes() {
-        return Integer.MAX_VALUE;
-    }
-
-    @Override
-    public int getMaxDocumentCount() {
-        return Integer.MAX_VALUE;
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
deleted file mode 100644
index 9ce916f..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
+++ /dev/null
@@ -1,221 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-
-import com.google.android.icing.proto.DocumentProto;
-import com.google.android.icing.proto.PropertyProto;
-import com.google.android.icing.proto.SchemaTypeConfigProto;
-import com.google.protobuf.ByteString;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Translates a {@link GenericDocument} into a {@link DocumentProto}.
- *
- * @hide
- */
-public final class GenericDocumentToProtoConverter {
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-    private static final long[] EMPTY_LONG_ARRAY = new long[0];
-    private static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
-    private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
-    private static final byte[][] EMPTY_BYTES_ARRAY = new byte[0][0];
-    private static final GenericDocument[] EMPTY_DOCUMENT_ARRAY = new GenericDocument[0];
-
-    private GenericDocumentToProtoConverter() {}
-
-    /** Converts a {@link GenericDocument} into a {@link DocumentProto}. */
-    @NonNull
-    @SuppressWarnings("unchecked")
-    public static DocumentProto toDocumentProto(@NonNull GenericDocument document) {
-        Objects.requireNonNull(document);
-        DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder();
-        mProtoBuilder
-                .setUri(document.getId())
-                .setSchema(document.getSchemaType())
-                .setNamespace(document.getNamespace())
-                .setScore(document.getScore())
-                .setTtlMs(document.getTtlMillis())
-                .setCreationTimestampMs(document.getCreationTimestampMillis());
-        ArrayList<String> keys = new ArrayList<>(document.getPropertyNames());
-        Collections.sort(keys);
-        for (int i = 0; i < keys.size(); i++) {
-            String name = keys.get(i);
-            PropertyProto.Builder propertyProto = PropertyProto.newBuilder().setName(name);
-            Object property = document.getProperty(name);
-            if (property instanceof String[]) {
-                String[] stringValues = (String[]) property;
-                for (int j = 0; j < stringValues.length; j++) {
-                    propertyProto.addStringValues(stringValues[j]);
-                }
-            } else if (property instanceof long[]) {
-                long[] longValues = (long[]) property;
-                for (int j = 0; j < longValues.length; j++) {
-                    propertyProto.addInt64Values(longValues[j]);
-                }
-            } else if (property instanceof double[]) {
-                double[] doubleValues = (double[]) property;
-                for (int j = 0; j < doubleValues.length; j++) {
-                    propertyProto.addDoubleValues(doubleValues[j]);
-                }
-            } else if (property instanceof boolean[]) {
-                boolean[] booleanValues = (boolean[]) property;
-                for (int j = 0; j < booleanValues.length; j++) {
-                    propertyProto.addBooleanValues(booleanValues[j]);
-                }
-            } else if (property instanceof byte[][]) {
-                byte[][] bytesValues = (byte[][]) property;
-                for (int j = 0; j < bytesValues.length; j++) {
-                    propertyProto.addBytesValues(ByteString.copyFrom(bytesValues[j]));
-                }
-            } else if (property instanceof GenericDocument[]) {
-                GenericDocument[] documentValues = (GenericDocument[]) property;
-                for (int j = 0; j < documentValues.length; j++) {
-                    DocumentProto proto = toDocumentProto(documentValues[j]);
-                    propertyProto.addDocumentValues(proto);
-                }
-            } else {
-                throw new IllegalStateException(
-                        String.format(
-                                "Property \"%s\" has unsupported value type %s",
-                                name, property.getClass().toString()));
-            }
-            mProtoBuilder.addProperties(propertyProto);
-        }
-        return mProtoBuilder.build();
-    }
-
-    /**
-     * Converts a {@link DocumentProto} into a {@link GenericDocument}.
-     *
-     * <p>In the case that the {@link DocumentProto} object proto has no values set, the converter
-     * searches for the matching property name in the {@link SchemaTypeConfigProto} object for the
-     * document, and infers the correct default value to set for the empty property based on the
-     * data type of the property defined by the schema type.
-     *
-     * @param proto the document to convert to a {@link GenericDocument} instance. The document
-     *     proto should have its package + database prefix stripped from its fields.
-     * @param prefix the package + database prefix used searching the {@code schemaTypeMap}.
-     * @param schemaTypeMap map of prefixed schema type to {@link SchemaTypeConfigProto}, used for
-     *     looking up the default empty value to set for a document property that has all empty
-     *     values.
-     */
-    @NonNull
-    public static GenericDocument toGenericDocument(
-            @NonNull DocumentProto proto,
-            @NonNull String prefix,
-            @NonNull Map<String, SchemaTypeConfigProto> schemaTypeMap) {
-        Objects.requireNonNull(proto);
-        GenericDocument.Builder<?> documentBuilder =
-                new GenericDocument.Builder<>(
-                                proto.getNamespace(), proto.getUri(), proto.getSchema())
-                        .setScore(proto.getScore())
-                        .setTtlMillis(proto.getTtlMs())
-                        .setCreationTimestampMillis(proto.getCreationTimestampMs());
-        String prefixedSchemaType = prefix + proto.getSchema();
-
-        for (int i = 0; i < proto.getPropertiesCount(); i++) {
-            PropertyProto property = proto.getProperties(i);
-            String name = property.getName();
-            if (property.getStringValuesCount() > 0) {
-                String[] values = new String[property.getStringValuesCount()];
-                for (int j = 0; j < values.length; j++) {
-                    values[j] = property.getStringValues(j);
-                }
-                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.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.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.getBooleanValues(j);
-                }
-                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.setPropertyBytes(name, values);
-            } else if (property.getDocumentValuesCount() > 0) {
-                GenericDocument[] values = new GenericDocument[property.getDocumentValuesCount()];
-                for (int j = 0; j < values.length; j++) {
-                    values[j] =
-                            toGenericDocument(property.getDocumentValues(j), prefix, schemaTypeMap);
-                }
-                documentBuilder.setPropertyDocument(name, values);
-            } else {
-                // TODO(b/184966497): Optimize by caching PropertyConfigProto
-                setEmptyProperty(name, documentBuilder, schemaTypeMap.get(prefixedSchemaType));
-            }
-        }
-        return documentBuilder.build();
-    }
-
-    private static void setEmptyProperty(
-            @NonNull String propertyName,
-            @NonNull GenericDocument.Builder<?> documentBuilder,
-            @NonNull SchemaTypeConfigProto schema) {
-        @AppSearchSchema.PropertyConfig.DataType int dataType = 0;
-        for (int i = 0; i < schema.getPropertiesCount(); ++i) {
-            if (propertyName.equals(schema.getProperties(i).getPropertyName())) {
-                dataType = schema.getProperties(i).getDataType().getNumber();
-                break;
-            }
-        }
-
-        switch (dataType) {
-            case AppSearchSchema.PropertyConfig.DATA_TYPE_STRING:
-                documentBuilder.setPropertyString(propertyName, EMPTY_STRING_ARRAY);
-                break;
-            case AppSearchSchema.PropertyConfig.DATA_TYPE_LONG:
-                documentBuilder.setPropertyLong(propertyName, EMPTY_LONG_ARRAY);
-                break;
-            case AppSearchSchema.PropertyConfig.DATA_TYPE_DOUBLE:
-                documentBuilder.setPropertyDouble(propertyName, EMPTY_DOUBLE_ARRAY);
-                break;
-            case AppSearchSchema.PropertyConfig.DATA_TYPE_BOOLEAN:
-                documentBuilder.setPropertyBoolean(propertyName, EMPTY_BOOLEAN_ARRAY);
-                break;
-            case AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES:
-                documentBuilder.setPropertyBytes(propertyName, EMPTY_BYTES_ARRAY);
-                break;
-            case AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT:
-                documentBuilder.setPropertyDocument(propertyName, EMPTY_DOCUMENT_ARRAY);
-                break;
-            default:
-                throw new IllegalStateException("Unknown type of value: " + propertyName);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/ResultCodeToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/ResultCodeToProtoConverter.java
deleted file mode 100644
index e340de0..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/ResultCodeToProtoConverter.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.converter;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.util.Log;
-
-import com.google.android.icing.proto.StatusProto;
-
-/**
- * Translates an {@link StatusProto.Code} into a {@link AppSearchResult.ResultCode}
- *
- * @hide
- */
-public final class ResultCodeToProtoConverter {
-
-    private static final String TAG = "AppSearchResultCodeToPr";
-
-    private ResultCodeToProtoConverter() {}
-
-    /** Converts an {@link StatusProto.Code} into a {@link AppSearchResult.ResultCode}. */
-    public static @AppSearchResult.ResultCode int toResultCode(
-            @NonNull StatusProto.Code statusCode) {
-        switch (statusCode) {
-            case OK:
-                return AppSearchResult.RESULT_OK;
-            case OUT_OF_SPACE:
-                return AppSearchResult.RESULT_OUT_OF_SPACE;
-            case INTERNAL:
-                return AppSearchResult.RESULT_INTERNAL_ERROR;
-            case UNKNOWN:
-                return AppSearchResult.RESULT_UNKNOWN_ERROR;
-            case NOT_FOUND:
-                return AppSearchResult.RESULT_NOT_FOUND;
-            case INVALID_ARGUMENT:
-                return AppSearchResult.RESULT_INVALID_ARGUMENT;
-            default:
-                // Some unknown/unsupported error
-                Log.e(
-                        TAG,
-                        "Cannot convert IcingSearchEngine status code: "
-                                + statusCode
-                                + " to AppSearchResultCode.");
-                return AppSearchResult.RESULT_INTERNAL_ERROR;
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
deleted file mode 100644
index 3e4e7d2..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
+++ /dev/null
@@ -1,227 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchSchema;
-import android.util.Log;
-
-import com.google.android.icing.proto.DocumentIndexingConfig;
-import com.google.android.icing.proto.PropertyConfigProto;
-import com.google.android.icing.proto.SchemaTypeConfigProto;
-import com.google.android.icing.proto.SchemaTypeConfigProtoOrBuilder;
-import com.google.android.icing.proto.StringIndexingConfig;
-import com.google.android.icing.proto.TermMatchType;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Translates an {@link AppSearchSchema} into a {@link SchemaTypeConfigProto}.
- *
- * @hide
- */
-public final class SchemaToProtoConverter {
-    private static final String TAG = "AppSearchSchemaToProtoC";
-
-    private SchemaToProtoConverter() {}
-
-    /**
-     * Converts an {@link android.app.appsearch.AppSearchSchema} into a {@link
-     * SchemaTypeConfigProto}.
-     */
-    @NonNull
-    public static SchemaTypeConfigProto toSchemaTypeConfigProto(
-            @NonNull AppSearchSchema schema, int version) {
-        Objects.requireNonNull(schema);
-        SchemaTypeConfigProto.Builder protoBuilder =
-                SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType(schema.getSchemaType())
-                        .setVersion(version);
-        List<AppSearchSchema.PropertyConfig> properties = schema.getProperties();
-        for (int i = 0; i < properties.size(); i++) {
-            PropertyConfigProto propertyProto = toPropertyConfigProto(properties.get(i));
-            protoBuilder.addProperties(propertyProto);
-        }
-        return protoBuilder.build();
-    }
-
-    @NonNull
-    private static PropertyConfigProto toPropertyConfigProto(
-            @NonNull AppSearchSchema.PropertyConfig property) {
-        Objects.requireNonNull(property);
-        PropertyConfigProto.Builder builder =
-                PropertyConfigProto.newBuilder().setPropertyName(property.getName());
-
-        // Set dataType
-        @AppSearchSchema.PropertyConfig.DataType int dataType = property.getDataType();
-        PropertyConfigProto.DataType.Code dataTypeProto =
-                PropertyConfigProto.DataType.Code.forNumber(dataType);
-        if (dataTypeProto == null) {
-            throw new IllegalArgumentException("Invalid dataType: " + dataType);
-        }
-        builder.setDataType(dataTypeProto);
-
-        // Set cardinality
-        @AppSearchSchema.PropertyConfig.Cardinality int cardinality = property.getCardinality();
-        PropertyConfigProto.Cardinality.Code cardinalityProto =
-                PropertyConfigProto.Cardinality.Code.forNumber(cardinality);
-        if (cardinalityProto == null) {
-            throw new IllegalArgumentException("Invalid cardinality: " + dataType);
-        }
-        builder.setCardinality(cardinalityProto);
-
-        if (property instanceof AppSearchSchema.StringPropertyConfig) {
-            AppSearchSchema.StringPropertyConfig stringProperty =
-                    (AppSearchSchema.StringPropertyConfig) property;
-            StringIndexingConfig stringIndexingConfig =
-                    StringIndexingConfig.newBuilder()
-                            .setTermMatchType(
-                                    convertTermMatchTypeToProto(stringProperty.getIndexingType()))
-                            .setTokenizerType(
-                                    convertTokenizerTypeToProto(stringProperty.getTokenizerType()))
-                            .build();
-            builder.setStringIndexingConfig(stringIndexingConfig);
-
-        } else if (property instanceof AppSearchSchema.DocumentPropertyConfig) {
-            AppSearchSchema.DocumentPropertyConfig documentProperty =
-                    (AppSearchSchema.DocumentPropertyConfig) property;
-            builder.setSchemaType(documentProperty.getSchemaType())
-                    .setDocumentIndexingConfig(
-                            DocumentIndexingConfig.newBuilder()
-                                    .setIndexNestedProperties(
-                                            documentProperty.shouldIndexNestedProperties()));
-        }
-        return builder.build();
-    }
-
-    /**
-     * Converts a {@link SchemaTypeConfigProto} into an {@link
-     * android.app.appsearch.AppSearchSchema}.
-     */
-    @NonNull
-    public static AppSearchSchema toAppSearchSchema(@NonNull SchemaTypeConfigProtoOrBuilder proto) {
-        Objects.requireNonNull(proto);
-        AppSearchSchema.Builder builder = new AppSearchSchema.Builder(proto.getSchemaType());
-        List<PropertyConfigProto> properties = proto.getPropertiesList();
-        for (int i = 0; i < properties.size(); i++) {
-            AppSearchSchema.PropertyConfig propertyConfig = toPropertyConfig(properties.get(i));
-            builder.addProperty(propertyConfig);
-        }
-        return builder.build();
-    }
-
-    @NonNull
-    private static AppSearchSchema.PropertyConfig toPropertyConfig(
-            @NonNull PropertyConfigProto proto) {
-        Objects.requireNonNull(proto);
-        switch (proto.getDataType()) {
-            case STRING:
-                return toStringPropertyConfig(proto);
-            case INT64:
-                return new AppSearchSchema.LongPropertyConfig.Builder(proto.getPropertyName())
-                        .setCardinality(proto.getCardinality().getNumber())
-                        .build();
-            case DOUBLE:
-                return new AppSearchSchema.DoublePropertyConfig.Builder(proto.getPropertyName())
-                        .setCardinality(proto.getCardinality().getNumber())
-                        .build();
-            case BOOLEAN:
-                return new AppSearchSchema.BooleanPropertyConfig.Builder(proto.getPropertyName())
-                        .setCardinality(proto.getCardinality().getNumber())
-                        .build();
-            case BYTES:
-                return new AppSearchSchema.BytesPropertyConfig.Builder(proto.getPropertyName())
-                        .setCardinality(proto.getCardinality().getNumber())
-                        .build();
-            case DOCUMENT:
-                return toDocumentPropertyConfig(proto);
-            default:
-                throw new IllegalArgumentException("Invalid dataType: " + proto.getDataType());
-        }
-    }
-
-    @NonNull
-    private static AppSearchSchema.StringPropertyConfig toStringPropertyConfig(
-            @NonNull PropertyConfigProto proto) {
-        AppSearchSchema.StringPropertyConfig.Builder builder =
-                new AppSearchSchema.StringPropertyConfig.Builder(proto.getPropertyName())
-                        .setCardinality(proto.getCardinality().getNumber())
-                        .setTokenizerType(
-                                proto.getStringIndexingConfig().getTokenizerType().getNumber());
-
-        // Set indexingType
-        TermMatchType.Code termMatchTypeProto = proto.getStringIndexingConfig().getTermMatchType();
-        builder.setIndexingType(convertTermMatchTypeFromProto(termMatchTypeProto));
-
-        return builder.build();
-    }
-
-    @NonNull
-    private static AppSearchSchema.DocumentPropertyConfig toDocumentPropertyConfig(
-            @NonNull PropertyConfigProto proto) {
-        return new AppSearchSchema.DocumentPropertyConfig.Builder(
-                        proto.getPropertyName(), proto.getSchemaType())
-                .setCardinality(proto.getCardinality().getNumber())
-                .setShouldIndexNestedProperties(
-                        proto.getDocumentIndexingConfig().getIndexNestedProperties())
-                .build();
-    }
-
-    @NonNull
-    private static TermMatchType.Code convertTermMatchTypeToProto(
-            @AppSearchSchema.StringPropertyConfig.IndexingType int indexingType) {
-        switch (indexingType) {
-            case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE:
-                return TermMatchType.Code.UNKNOWN;
-            case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS:
-                return TermMatchType.Code.EXACT_ONLY;
-            case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES:
-                return TermMatchType.Code.PREFIX;
-            default:
-                throw new IllegalArgumentException("Invalid indexingType: " + indexingType);
-        }
-    }
-
-    @AppSearchSchema.StringPropertyConfig.IndexingType
-    private static int convertTermMatchTypeFromProto(@NonNull TermMatchType.Code termMatchType) {
-        switch (termMatchType) {
-            case UNKNOWN:
-                return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
-            case EXACT_ONLY:
-                return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS;
-            case PREFIX:
-                return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES;
-            default:
-                // Avoid crashing in the 'read' path; we should try to interpret the document to the
-                // extent possible.
-                Log.w(TAG, "Invalid indexingType: " + termMatchType.getNumber());
-                return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
-        }
-    }
-
-    @NonNull
-    private static StringIndexingConfig.TokenizerType.Code convertTokenizerTypeToProto(
-            @AppSearchSchema.StringPropertyConfig.TokenizerType int tokenizerType) {
-        StringIndexingConfig.TokenizerType.Code tokenizerTypeProto =
-                StringIndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
-        if (tokenizerTypeProto == null) {
-            throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType);
-        }
-        return tokenizerTypeProto;
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
deleted file mode 100644
index 6b443b3..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
+++ /dev/null
@@ -1,141 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.createPrefix;
-
-import android.annotation.NonNull;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResultPage;
-import android.os.Bundle;
-
-import com.android.internal.util.Preconditions;
-
-import com.google.android.icing.proto.SchemaTypeConfigProto;
-import com.google.android.icing.proto.SearchResultProto;
-import com.google.android.icing.proto.SearchResultProtoOrBuilder;
-import com.google.android.icing.proto.SnippetMatchProto;
-import com.google.android.icing.proto.SnippetProto;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Translates a {@link SearchResultProto} into {@link SearchResult}s.
- *
- * @hide
- */
-public class SearchResultToProtoConverter {
-    private SearchResultToProtoConverter() {}
-
-    /**
-     * Translate a {@link SearchResultProto} into {@link SearchResultPage}.
-     *
-     * @param proto The {@link SearchResultProto} containing results.
-     * @param packageNames A parallel array of package names. The package name at index 'i' of this
-     *     list should be the package that indexed the document at index 'i' of proto.getResults(i).
-     * @param databaseNames A parallel array of database names. The database name at index 'i' of
-     *     this list shold be the database that indexed the document at index 'i' of
-     *     proto.getResults(i).
-     * @param schemaMap A map of prefixes to an inner-map of prefixed schema type to
-     *     SchemaTypeConfigProtos, used for setting a default value for results with DocumentProtos
-     *     that have empty values.
-     * @return {@link SearchResultPage} of results.
-     */
-    @NonNull
-    public static SearchResultPage toSearchResultPage(
-            @NonNull SearchResultProtoOrBuilder proto,
-            @NonNull List<String> packageNames,
-            @NonNull List<String> databaseNames,
-            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap) {
-        Preconditions.checkArgument(
-                proto.getResultsCount() == packageNames.size(),
-                "Size of results does not match the number of package names.");
-        Bundle bundle = new Bundle();
-        bundle.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, proto.getNextPageToken());
-        ArrayList<Bundle> resultBundles = new ArrayList<>(proto.getResultsCount());
-        for (int i = 0; i < proto.getResultsCount(); i++) {
-            String prefix = createPrefix(packageNames.get(i), databaseNames.get(i));
-            Map<String, SchemaTypeConfigProto> schemaTypeMap = schemaMap.get(prefix);
-            SearchResult result =
-                    toSearchResult(
-                            proto.getResults(i),
-                            packageNames.get(i),
-                            databaseNames.get(i),
-                            schemaTypeMap);
-            resultBundles.add(result.getBundle());
-        }
-        bundle.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles);
-        return new SearchResultPage(bundle);
-    }
-
-    /**
-     * Translate a {@link SearchResultProto.ResultProto} into {@link SearchResult}.
-     *
-     * @param proto The proto to be converted.
-     * @param packageName The package name associated with the document in {@code proto}.
-     * @param databaseName The database name associated with the document in {@code proto}.
-     * @param schemaTypeToProtoMap A map of prefixed schema types to their corresponding
-     *     SchemaTypeConfigProto, used for setting a default value for results with DocumentProtos
-     *     that have empty values.
-     * @return A {@link SearchResult} bundle.
-     */
-    @NonNull
-    private static SearchResult toSearchResult(
-            @NonNull SearchResultProto.ResultProtoOrBuilder proto,
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Map<String, SchemaTypeConfigProto> schemaTypeToProtoMap) {
-        String prefix = createPrefix(packageName, databaseName);
-        GenericDocument document =
-                GenericDocumentToProtoConverter.toGenericDocument(
-                        proto.getDocument(), prefix, schemaTypeToProtoMap);
-        SearchResult.Builder builder =
-                new SearchResult.Builder(packageName, databaseName)
-                        .setGenericDocument(document)
-                        .setRankingSignal(proto.getScore());
-        if (proto.hasSnippet()) {
-            for (int i = 0; i < proto.getSnippet().getEntriesCount(); i++) {
-                SnippetProto.EntryProto entry = proto.getSnippet().getEntries(i);
-                for (int j = 0; j < entry.getSnippetMatchesCount(); j++) {
-                    SearchResult.MatchInfo matchInfo =
-                            toMatchInfo(entry.getSnippetMatches(j), entry.getPropertyName());
-                    builder.addMatchInfo(matchInfo);
-                }
-            }
-        }
-        return builder.build();
-    }
-
-    private static SearchResult.MatchInfo toMatchInfo(
-            @NonNull SnippetMatchProto snippetMatchProto, @NonNull String propertyPath) {
-        return new SearchResult.MatchInfo.Builder(propertyPath)
-                .setExactMatchRange(
-                        new SearchResult.MatchRange(
-                                snippetMatchProto.getExactMatchUtf16Position(),
-                                snippetMatchProto.getExactMatchUtf16Position()
-                                        + snippetMatchProto.getExactMatchUtf16Length()))
-                .setSnippetRange(
-                        new SearchResult.MatchRange(
-                                snippetMatchProto.getWindowUtf16Position(),
-                                snippetMatchProto.getWindowUtf16Position()
-                                        + snippetMatchProto.getWindowUtf16Length()))
-                .build();
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
deleted file mode 100644
index 8f9e9bd..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
+++ /dev/null
@@ -1,116 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import android.annotation.NonNull;
-import android.app.appsearch.SearchSpec;
-
-import com.google.android.icing.proto.ResultSpecProto;
-import com.google.android.icing.proto.ScoringSpecProto;
-import com.google.android.icing.proto.SearchSpecProto;
-import com.google.android.icing.proto.TermMatchType;
-
-import java.util.Objects;
-
-/**
- * Translates a {@link SearchSpec} into icing search protos.
- *
- * @hide
- */
-public final class SearchSpecToProtoConverter {
-    private SearchSpecToProtoConverter() {}
-
-    /** Extracts {@link SearchSpecProto} information from a {@link SearchSpec}. */
-    @NonNull
-    public static SearchSpecProto toSearchSpecProto(@NonNull SearchSpec spec) {
-        Objects.requireNonNull(spec);
-        SearchSpecProto.Builder protoBuilder =
-                SearchSpecProto.newBuilder()
-                        .addAllSchemaTypeFilters(spec.getFilterSchemas())
-                        .addAllNamespaceFilters(spec.getFilterNamespaces());
-
-        @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);
-
-        return protoBuilder.build();
-    }
-
-    /** Extracts {@link ResultSpecProto} information from a {@link SearchSpec}. */
-    @NonNull
-    public static ResultSpecProto toResultSpecProto(@NonNull SearchSpec spec) {
-        Objects.requireNonNull(spec);
-        return ResultSpecProto.newBuilder()
-                .setNumPerPage(spec.getResultCountPerPage())
-                .setSnippetSpec(
-                        ResultSpecProto.SnippetSpecProto.newBuilder()
-                                .setNumToSnippet(spec.getSnippetCount())
-                                .setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
-                                .setMaxWindowBytes(spec.getMaxSnippetSize()))
-                .addAllTypePropertyMasks(
-                        TypePropertyPathToProtoConverter.toTypePropertyMaskList(
-                                spec.getProjections()))
-                .build();
-    }
-
-    /** Extracts {@link ScoringSpecProto} information from a {@link SearchSpec}. */
-    @NonNull
-    public static ScoringSpecProto toScoringSpecProto(@NonNull SearchSpec spec) {
-        Objects.requireNonNull(spec);
-        ScoringSpecProto.Builder protoBuilder = ScoringSpecProto.newBuilder();
-
-        @SearchSpec.Order int orderCode = spec.getOrder();
-        ScoringSpecProto.Order.Code orderCodeProto =
-                ScoringSpecProto.Order.Code.forNumber(orderCode);
-        if (orderCodeProto == null) {
-            throw new IllegalArgumentException("Invalid result ranking order: " + orderCode);
-        }
-        protoBuilder
-                .setOrderBy(orderCodeProto)
-                .setRankBy(toProtoRankingStrategy(spec.getRankingStrategy()));
-
-        return protoBuilder.build();
-    }
-
-    private static ScoringSpecProto.RankingStrategy.Code toProtoRankingStrategy(
-            @SearchSpec.RankingStrategy int rankingStrategyCode) {
-        switch (rankingStrategyCode) {
-            case SearchSpec.RANKING_STRATEGY_NONE:
-                return ScoringSpecProto.RankingStrategy.Code.NONE;
-            case SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE:
-                return ScoringSpecProto.RankingStrategy.Code.DOCUMENT_SCORE;
-            case SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP:
-                return ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP;
-            case SearchSpec.RANKING_STRATEGY_RELEVANCE_SCORE:
-                return ScoringSpecProto.RankingStrategy.Code.RELEVANCE_SCORE;
-            case SearchSpec.RANKING_STRATEGY_USAGE_COUNT:
-                return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE1_COUNT;
-            case SearchSpec.RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP:
-                return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE1_LAST_USED_TIMESTAMP;
-            case SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT:
-                return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE2_COUNT;
-            case SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP:
-                return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE2_LAST_USED_TIMESTAMP;
-            default:
-                throw new IllegalArgumentException(
-                        "Invalid result ranking strategy: " + rankingStrategyCode);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SetSchemaResponseToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SetSchemaResponseToProtoConverter.java
deleted file mode 100644
index ed73593..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SetSchemaResponseToProtoConverter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.converter;
-
-import android.annotation.NonNull;
-import android.app.appsearch.SetSchemaResponse;
-
-import com.google.android.icing.proto.SetSchemaResultProto;
-
-import java.util.Objects;
-
-/**
- * Translates a {@link SetSchemaResultProto} into {@link SetSchemaResponse}.
- *
- * @hide
- */
-public class SetSchemaResponseToProtoConverter {
-
-    private SetSchemaResponseToProtoConverter() {}
-
-    /**
-     * Translate a {@link SetSchemaResultProto} into {@link SetSchemaResponse}.
-     *
-     * @param proto The {@link SetSchemaResultProto} containing results.
-     * @param prefix The prefix need to removed from schemaTypes
-     * @return The {@link SetSchemaResponse} object.
-     */
-    @NonNull
-    public static SetSchemaResponse toSetSchemaResponse(
-            @NonNull SetSchemaResultProto proto, @NonNull String prefix) {
-        Objects.requireNonNull(proto);
-        Objects.requireNonNull(prefix);
-        SetSchemaResponse.Builder builder = new SetSchemaResponse.Builder();
-
-        for (int i = 0; i < proto.getDeletedSchemaTypesCount(); i++) {
-            builder.addDeletedType(proto.getDeletedSchemaTypes(i).substring(prefix.length()));
-        }
-
-        for (int i = 0; i < proto.getIncompatibleSchemaTypesCount(); i++) {
-            builder.addIncompatibleType(
-                    proto.getIncompatibleSchemaTypes(i).substring(prefix.length()));
-        }
-
-        return builder.build();
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/TypePropertyPathToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/TypePropertyPathToProtoConverter.java
deleted file mode 100644
index acf04ef..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/TypePropertyPathToProtoConverter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.converter;
-
-import android.annotation.NonNull;
-
-import com.google.android.icing.proto.TypePropertyMask;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Translates a <code>Map<String, List<String>></code> into <code>List<TypePropertyMask></code>.
- *
- * @hide
- */
-public final class TypePropertyPathToProtoConverter {
-    private TypePropertyPathToProtoConverter() {}
-
-    /** Extracts {@link TypePropertyMask} information from a {@link Map}. */
-    @NonNull
-    public static List<TypePropertyMask> toTypePropertyMaskList(
-            @NonNull Map<String, List<String>> typePropertyPaths) {
-        Objects.requireNonNull(typePropertyPaths);
-        List<TypePropertyMask> typePropertyMasks = new ArrayList<>(typePropertyPaths.size());
-        for (Map.Entry<String, List<String>> e : typePropertyPaths.entrySet()) {
-            typePropertyMasks.add(
-                    TypePropertyMask.newBuilder()
-                            .setSchemaType(e.getKey())
-                            .addAllPaths(e.getValue())
-                            .build());
-        }
-        return typePropertyMasks;
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
deleted file mode 100644
index 81fb418..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchResult;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * A class for setting basic information to log for all function calls.
- *
- * <p>This class can set which stats to log for both batch and non-batch {@link
- * android.app.appsearch.AppSearchSession} calls.
- *
- * <p>Some function calls may have their own detailed stats class like {@link PutDocumentStats}.
- * However, {@link CallStats} can still be used along with the detailed stats class for easy
- * aggregation/analysis with other function calls.
- *
- * @hide
- */
-public class CallStats {
-    @IntDef(
-            value = {
-                CALL_TYPE_UNKNOWN,
-                CALL_TYPE_INITIALIZE,
-                CALL_TYPE_SET_SCHEMA,
-                CALL_TYPE_PUT_DOCUMENTS,
-                CALL_TYPE_GET_DOCUMENTS,
-                CALL_TYPE_REMOVE_DOCUMENTS_BY_ID,
-                CALL_TYPE_PUT_DOCUMENT,
-                CALL_TYPE_GET_DOCUMENT,
-                CALL_TYPE_REMOVE_DOCUMENT_BY_ID,
-                CALL_TYPE_SEARCH,
-                CALL_TYPE_OPTIMIZE,
-                CALL_TYPE_FLUSH,
-                CALL_TYPE_GLOBAL_SEARCH,
-                CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH,
-                CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallType {}
-
-    public static final int CALL_TYPE_UNKNOWN = 0;
-    public static final int CALL_TYPE_INITIALIZE = 1;
-    public static final int CALL_TYPE_SET_SCHEMA = 2;
-    public static final int CALL_TYPE_PUT_DOCUMENTS = 3;
-    public static final int CALL_TYPE_GET_DOCUMENTS = 4;
-    public static final int CALL_TYPE_REMOVE_DOCUMENTS_BY_ID = 5;
-    public static final int CALL_TYPE_PUT_DOCUMENT = 6;
-    public static final int CALL_TYPE_GET_DOCUMENT = 7;
-    public static final int CALL_TYPE_REMOVE_DOCUMENT_BY_ID = 8;
-    public static final int CALL_TYPE_SEARCH = 9;
-    public static final int CALL_TYPE_OPTIMIZE = 10;
-    public static final int CALL_TYPE_FLUSH = 11;
-    public static final int CALL_TYPE_GLOBAL_SEARCH = 12;
-    public static final int CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH = 13;
-    public static final int CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH = 14;
-
-    @Nullable private final String mPackageName;
-    @Nullable private final String mDatabase;
-    /**
-     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
-     * state.
-     */
-    @AppSearchResult.ResultCode private final int mStatusCode;
-
-    private final int mTotalLatencyMillis;
-
-    @CallType private final int mCallType;
-    private final int mEstimatedBinderLatencyMillis;
-    private final int mNumOperationsSucceeded;
-    private final int mNumOperationsFailed;
-
-    CallStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mPackageName = builder.mPackageName;
-        mDatabase = builder.mDatabase;
-        mStatusCode = builder.mStatusCode;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mCallType = builder.mCallType;
-        mEstimatedBinderLatencyMillis = builder.mEstimatedBinderLatencyMillis;
-        mNumOperationsSucceeded = builder.mNumOperationsSucceeded;
-        mNumOperationsFailed = builder.mNumOperationsFailed;
-    }
-
-    /** Returns calling package name. */
-    @Nullable
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /** Returns calling database name. */
-    @Nullable
-    public String getDatabase() {
-        return mDatabase;
-    }
-
-    /** Returns status code for this api call. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /** Returns total latency of this api call in millis. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /** Returns type of the call. */
-    @CallType
-    public int getCallType() {
-        return mCallType;
-    }
-
-    /** Returns estimated binder latency, in milliseconds */
-    public int getEstimatedBinderLatencyMillis() {
-        return mEstimatedBinderLatencyMillis;
-    }
-
-    /**
-     * Returns number of operations succeeded.
-     *
-     * <p>For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
-     * number of individual successful put operations. In this case, how many documents are
-     * successfully indexed.
-     *
-     * <p>For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema}, the
-     * sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
-     * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
-     */
-    public int getNumOperationsSucceeded() {
-        return mNumOperationsSucceeded;
-    }
-
-    /**
-     * Returns number of operations failed.
-     *
-     * <p>For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
-     * number of individual failed put operations. In this case, how many documents are failed to be
-     * indexed.
-     *
-     * <p>For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema}, the
-     * sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
-     * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
-     */
-    public int getNumOperationsFailed() {
-        return mNumOperationsFailed;
-    }
-
-    /** Builder for {@link CallStats}. */
-    public static class Builder {
-        @Nullable String mPackageName;
-        @Nullable String mDatabase;
-        @AppSearchResult.ResultCode int mStatusCode;
-        int mTotalLatencyMillis;
-        @CallType int mCallType;
-        int mEstimatedBinderLatencyMillis;
-        int mNumOperationsSucceeded;
-        int mNumOperationsFailed;
-
-        /** Sets the PackageName used by the session. */
-        @NonNull
-        public Builder setPackageName(@NonNull String packageName) {
-            mPackageName = Objects.requireNonNull(packageName);
-            return this;
-        }
-
-        /** Sets the database used by the session. */
-        @NonNull
-        public Builder setDatabase(@NonNull String database) {
-            mDatabase = Objects.requireNonNull(database);
-            return this;
-        }
-
-        /** Sets the status code. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets total latency in millis. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /** Sets type of the call. */
-        @NonNull
-        public Builder setCallType(@CallType int callType) {
-            mCallType = callType;
-            return this;
-        }
-
-        /** Sets estimated binder latency, in milliseconds. */
-        @NonNull
-        public Builder setEstimatedBinderLatencyMillis(int estimatedBinderLatencyMillis) {
-            mEstimatedBinderLatencyMillis = estimatedBinderLatencyMillis;
-            return this;
-        }
-
-        /**
-         * Sets number of operations succeeded.
-         *
-         * <p>For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
-         * number of individual successful put operations. In this case, how many documents are
-         * successfully indexed.
-         *
-         * <p>For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema},
-         * the sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
-         * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
-         */
-        @NonNull
-        public Builder setNumOperationsSucceeded(int numOperationsSucceeded) {
-            mNumOperationsSucceeded = numOperationsSucceeded;
-            return this;
-        }
-
-        /**
-         * Sets number of operations failed.
-         *
-         * <p>For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
-         * number of individual failed put operations. In this case, how many documents are failed
-         * to be indexed.
-         *
-         * <p>For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema},
-         * the sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
-         * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
-         */
-        @NonNull
-        public Builder setNumOperationsFailed(int numOperationsFailed) {
-            mNumOperationsFailed = numOperationsFailed;
-            return this;
-        }
-
-        /** Creates {@link CallStats} object from {@link Builder} instance. */
-        @NonNull
-        public CallStats build() {
-            return new CallStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/InitializeStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/InitializeStats.java
deleted file mode 100644
index 72befa7..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/InitializeStats.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Class holds detailed stats for initialization
- *
- * @hide
- */
-public final class InitializeStats {
-    /**
-     * The cause of IcingSearchEngine recovering from a previous bad state during initialization.
-     */
-    @IntDef(
-            value = {
-                // It needs to be sync with RecoveryCause in
-                // external/icing/proto/icing/proto/logging.proto#InitializeStatsProto
-                RECOVERY_CAUSE_NONE,
-                RECOVERY_CAUSE_DATA_LOSS,
-                RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH,
-                RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH,
-                RECOVERY_CAUSE_IO_ERROR,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RecoveryCause {}
-
-    // No recovery happened.
-    public static final int RECOVERY_CAUSE_NONE = 0;
-    // Data loss in ground truth.
-    public static final int RECOVERY_CAUSE_DATA_LOSS = 1;
-    // Data in index is inconsistent with ground truth.
-    public static final int RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH = 2;
-    // Total checksum of all the components does not match.
-    public static final int RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH = 3;
-    // Random I/O errors.
-    public static final int RECOVERY_CAUSE_IO_ERROR = 4;
-
-    /** Status regarding how much data is lost during the initialization. */
-    @IntDef(
-            value = {
-                // It needs to be sync with DocumentStoreDataStatus in
-                // external/icing/proto/icing/proto/logging.proto#InitializeStatsProto
-
-                DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS,
-                DOCUMENT_STORE_DATA_STATUS_PARTIAL_LOSS,
-                DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DocumentStoreDataStatus {}
-
-    // Document store is successfully initialized or fully recovered.
-    public static final int DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS = 0;
-    // Ground truth data is partially lost.
-    public static final int DOCUMENT_STORE_DATA_STATUS_PARTIAL_LOSS = 1;
-    // Ground truth data is completely lost.
-    public static final int DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS = 2;
-
-    @AppSearchResult.ResultCode private final int mStatusCode;
-    private final int mTotalLatencyMillis;
-    /** Whether the initialize() detects deSync. */
-    private final boolean mHasDeSync;
-    /** Time used to read and process the schema and namespaces. */
-    private final int mPrepareSchemaAndNamespacesLatencyMillis;
-    /** Time used to read and process the visibility store. */
-    private final int mPrepareVisibilityStoreLatencyMillis;
-    /** Overall time used for the native function call. */
-    private final int mNativeLatencyMillis;
-
-    @RecoveryCause private final int mNativeDocumentStoreRecoveryCause;
-    @RecoveryCause private final int mNativeIndexRestorationCause;
-    @RecoveryCause private final int mNativeSchemaStoreRecoveryCause;
-    /** Time used to recover the document store. */
-    private final int mNativeDocumentStoreRecoveryLatencyMillis;
-    /** Time used to restore the index. */
-    private final int mNativeIndexRestorationLatencyMillis;
-    /** Time used to recover the schema store. */
-    private final int mNativeSchemaStoreRecoveryLatencyMillis;
-    /** Status regarding how much data is lost during the initialization. */
-    private final int mNativeDocumentStoreDataStatus;
-    /**
-     * Returns number of documents currently in document store. Those may include alive, deleted,
-     * and expired documents.
-     */
-    private final int mNativeNumDocuments;
-    /** Returns number of schema types currently in the schema store. */
-    private final int mNativeNumSchemaTypes;
-    /** Whether we had to reset the index, losing all data, during initialization. */
-    private final boolean mHasReset;
-    /** If we had to reset, contains the status code of the reset operation. */
-    @AppSearchResult.ResultCode private final int mResetStatusCode;
-
-    /** Returns the status of the initialization. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /** Returns the total latency in milliseconds for the initialization. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /**
-     * Returns whether the initialize() detects deSync.
-     *
-     * <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent view
-     * of what data should exist.
-     */
-    public boolean hasDeSync() {
-        return mHasDeSync;
-    }
-
-    /** Returns time used to read and process the schema and namespaces. */
-    public int getPrepareSchemaAndNamespacesLatencyMillis() {
-        return mPrepareSchemaAndNamespacesLatencyMillis;
-    }
-
-    /** Returns time used to read and process the visibility file. */
-    public int getPrepareVisibilityStoreLatencyMillis() {
-        return mPrepareVisibilityStoreLatencyMillis;
-    }
-
-    /** Returns overall time used for the native function call. */
-    public int getNativeLatencyMillis() {
-        return mNativeLatencyMillis;
-    }
-
-    /**
-     * Returns recovery cause for document store.
-     *
-     * <p>Possible recovery causes for document store:
-     * <li>{@link InitializeStats#RECOVERY_CAUSE_DATA_LOSS}
-     * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
-     * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
-     */
-    @RecoveryCause
-    public int getDocumentStoreRecoveryCause() {
-        return mNativeDocumentStoreRecoveryCause;
-    }
-
-    /**
-     * Returns restoration cause for index store.
-     *
-     * <p>Possible causes:
-     * <li>{@link InitializeStats#RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH}
-     * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
-     * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
-     */
-    @RecoveryCause
-    public int getIndexRestorationCause() {
-        return mNativeIndexRestorationCause;
-    }
-
-    /**
-     * Returns recovery cause for schema store.
-     *
-     * <p>Possible causes:
-     * <li>IO_ERROR
-     */
-    @RecoveryCause
-    public int getSchemaStoreRecoveryCause() {
-        return mNativeSchemaStoreRecoveryCause;
-    }
-
-    /** Returns time used to recover the document store. */
-    public int getDocumentStoreRecoveryLatencyMillis() {
-        return mNativeDocumentStoreRecoveryLatencyMillis;
-    }
-
-    /** Returns time used to restore the index. */
-    public int getIndexRestorationLatencyMillis() {
-        return mNativeIndexRestorationLatencyMillis;
-    }
-
-    /** Returns time used to recover the schema store. */
-    public int getSchemaStoreRecoveryLatencyMillis() {
-        return mNativeSchemaStoreRecoveryLatencyMillis;
-    }
-
-    /** Returns status about how much data is lost during the initialization. */
-    @DocumentStoreDataStatus
-    public int getDocumentStoreDataStatus() {
-        return mNativeDocumentStoreDataStatus;
-    }
-
-    /**
-     * Returns number of documents currently in document store. Those may include alive, deleted,
-     * and expired documents.
-     */
-    public int getDocumentCount() {
-        return mNativeNumDocuments;
-    }
-
-    /** Returns number of schema types currently in the schema store. */
-    public int getSchemaTypeCount() {
-        return mNativeNumSchemaTypes;
-    }
-
-    /** Returns whether we had to reset the index, losing all data, as part of initialization. */
-    public boolean hasReset() {
-        return mHasReset;
-    }
-
-    /**
-     * Returns the status of the reset, if one was performed according to {@link #hasReset}.
-     *
-     * <p>If no value has been set, the default value is {@link AppSearchResult#RESULT_OK}.
-     */
-    @AppSearchResult.ResultCode
-    public int getResetStatusCode() {
-        return mResetStatusCode;
-    }
-
-    InitializeStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mStatusCode = builder.mStatusCode;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mHasDeSync = builder.mHasDeSync;
-        mPrepareSchemaAndNamespacesLatencyMillis = builder.mPrepareSchemaAndNamespacesLatencyMillis;
-        mPrepareVisibilityStoreLatencyMillis = builder.mPrepareVisibilityStoreLatencyMillis;
-        mNativeLatencyMillis = builder.mNativeLatencyMillis;
-        mNativeDocumentStoreRecoveryCause = builder.mNativeDocumentStoreRecoveryCause;
-        mNativeIndexRestorationCause = builder.mNativeIndexRestorationCause;
-        mNativeSchemaStoreRecoveryCause = builder.mNativeSchemaStoreRecoveryCause;
-        mNativeDocumentStoreRecoveryLatencyMillis =
-                builder.mNativeDocumentStoreRecoveryLatencyMillis;
-        mNativeIndexRestorationLatencyMillis = builder.mNativeIndexRestorationLatencyMillis;
-        mNativeSchemaStoreRecoveryLatencyMillis = builder.mNativeSchemaStoreRecoveryLatencyMillis;
-        mNativeDocumentStoreDataStatus = builder.mNativeDocumentStoreDataStatus;
-        mNativeNumDocuments = builder.mNativeNumDocuments;
-        mNativeNumSchemaTypes = builder.mNativeNumSchemaTypes;
-        mHasReset = builder.mHasReset;
-        mResetStatusCode = builder.mResetStatusCode;
-    }
-
-    /** Builder for {@link InitializeStats}. */
-    public static class Builder {
-        @AppSearchResult.ResultCode int mStatusCode;
-
-        int mTotalLatencyMillis;
-        boolean mHasDeSync;
-        int mPrepareSchemaAndNamespacesLatencyMillis;
-        int mPrepareVisibilityStoreLatencyMillis;
-        int mNativeLatencyMillis;
-        @RecoveryCause int mNativeDocumentStoreRecoveryCause;
-        @RecoveryCause int mNativeIndexRestorationCause;
-        @RecoveryCause int mNativeSchemaStoreRecoveryCause;
-        int mNativeDocumentStoreRecoveryLatencyMillis;
-        int mNativeIndexRestorationLatencyMillis;
-        int mNativeSchemaStoreRecoveryLatencyMillis;
-        @DocumentStoreDataStatus int mNativeDocumentStoreDataStatus;
-        int mNativeNumDocuments;
-        int mNativeNumSchemaTypes;
-        boolean mHasReset;
-        @AppSearchResult.ResultCode int mResetStatusCode;
-
-        /** Sets the status of the initialization. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets the total latency of the initialization in milliseconds. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /**
-         * Sets whether the initialize() detects deSync.
-         *
-         * <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent
-         * view of what data should exist.
-         */
-        @NonNull
-        public Builder setHasDeSync(boolean hasDeSync) {
-            mHasDeSync = hasDeSync;
-            return this;
-        }
-
-        /** Sets time used to read and process the schema and namespaces. */
-        @NonNull
-        public Builder setPrepareSchemaAndNamespacesLatencyMillis(
-                int prepareSchemaAndNamespacesLatencyMillis) {
-            mPrepareSchemaAndNamespacesLatencyMillis = prepareSchemaAndNamespacesLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to read and process the visibility file. */
-        @NonNull
-        public Builder setPrepareVisibilityStoreLatencyMillis(
-                int prepareVisibilityStoreLatencyMillis) {
-            mPrepareVisibilityStoreLatencyMillis = prepareVisibilityStoreLatencyMillis;
-            return this;
-        }
-
-        /** Sets overall time used for the native function call. */
-        @NonNull
-        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
-            mNativeLatencyMillis = nativeLatencyMillis;
-            return this;
-        }
-
-        /**
-         * Sets recovery cause for document store.
-         *
-         * <p>Possible recovery causes for document store:
-         * <li>{@link InitializeStats#RECOVERY_CAUSE_DATA_LOSS}
-         * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
-         * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
-         */
-        @NonNull
-        public Builder setDocumentStoreRecoveryCause(
-                @RecoveryCause int documentStoreRecoveryCause) {
-            mNativeDocumentStoreRecoveryCause = documentStoreRecoveryCause;
-            return this;
-        }
-
-        /**
-         * Sets restoration cause for index store.
-         *
-         * <p>Possible causes:
-         * <li>{@link InitializeStats#DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS}
-         * <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
-         * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
-         */
-        @NonNull
-        public Builder setIndexRestorationCause(@RecoveryCause int indexRestorationCause) {
-            mNativeIndexRestorationCause = indexRestorationCause;
-            return this;
-        }
-
-        /**
-         * Returns recovery cause for schema store.
-         *
-         * <p>Possible causes:
-         * <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
-         */
-        @NonNull
-        public Builder setSchemaStoreRecoveryCause(@RecoveryCause int schemaStoreRecoveryCause) {
-            mNativeSchemaStoreRecoveryCause = schemaStoreRecoveryCause;
-            return this;
-        }
-
-        /** Sets time used to recover the document store. */
-        @NonNull
-        public Builder setDocumentStoreRecoveryLatencyMillis(
-                int documentStoreRecoveryLatencyMillis) {
-            mNativeDocumentStoreRecoveryLatencyMillis = documentStoreRecoveryLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to restore the index. */
-        @NonNull
-        public Builder setIndexRestorationLatencyMillis(int indexRestorationLatencyMillis) {
-            mNativeIndexRestorationLatencyMillis = indexRestorationLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to recover the schema store. */
-        @NonNull
-        public Builder setSchemaStoreRecoveryLatencyMillis(int schemaStoreRecoveryLatencyMillis) {
-            mNativeSchemaStoreRecoveryLatencyMillis = schemaStoreRecoveryLatencyMillis;
-            return this;
-        }
-
-        /**
-         * Sets Native Document Store Data status. status is defined in
-         * external/icing/proto/icing/proto/logging.proto
-         */
-        @NonNull
-        public Builder setDocumentStoreDataStatus(
-                @DocumentStoreDataStatus int documentStoreDataStatus) {
-            mNativeDocumentStoreDataStatus = documentStoreDataStatus;
-            return this;
-        }
-
-        /**
-         * Sets number of documents currently in document store. Those may include alive, deleted,
-         * and expired documents.
-         */
-        @NonNull
-        public Builder setDocumentCount(int numDocuments) {
-            mNativeNumDocuments = numDocuments;
-            return this;
-        }
-
-        /** Sets number of schema types currently in the schema store. */
-        @NonNull
-        public Builder setSchemaTypeCount(int numSchemaTypes) {
-            mNativeNumSchemaTypes = numSchemaTypes;
-            return this;
-        }
-
-        /** Sets whether we had to reset the index, losing all data, as part of initialization. */
-        @NonNull
-        public Builder setHasReset(boolean hasReset) {
-            mHasReset = hasReset;
-            return this;
-        }
-
-        /** Sets the status of the reset, if one was performed according to {@link #setHasReset}. */
-        @NonNull
-        public Builder setResetStatusCode(@AppSearchResult.ResultCode int resetStatusCode) {
-            mResetStatusCode = resetStatusCode;
-            return this;
-        }
-
-        /**
-         * Constructs a new {@link InitializeStats} from the contents of this {@link
-         * InitializeStats.Builder}
-         */
-        @NonNull
-        public InitializeStats build() {
-            return new InitializeStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/OptimizeStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/OptimizeStats.java
deleted file mode 100644
index 83bd50f..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/OptimizeStats.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-
-import java.util.Objects;
-
-/**
- * Class holds detailed stats for Optimize.
- *
- * @hide
- */
-public final class OptimizeStats {
-    /**
-     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
-     * state.
-     */
-    @AppSearchResult.ResultCode private final int mStatusCode;
-
-    private final int mTotalLatencyMillis;
-    private final int mNativeLatencyMillis;
-
-    // Time used to optimize the document store in millis.
-    private final int mNativeDocumentStoreOptimizeLatencyMillis;
-
-    // Time used to restore the index in millis.
-    private final int mNativeIndexRestorationLatencyMillis;
-
-    // Number of documents before the optimization.
-    private final int mNativeOriginalDocumentCount;
-
-    // Number of documents deleted during the optimization.
-    private final int mNativeDeletedDocumentCount;
-
-    // Number of documents expired during the optimization.
-    private final int mNativeExpiredDocumentCount;
-
-    // Size of storage in bytes before the optimization.
-    private final long mNativeStorageSizeBeforeBytes;
-
-    // Size of storage in bytes after the optimization.
-    private final long mNativeStorageSizeAfterBytes;
-
-    // The amount of time in millis since the last optimization ran calculated using wall clock time
-    private final long mNativeTimeSinceLastOptimizeMillis;
-
-    OptimizeStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mStatusCode = builder.mStatusCode;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mNativeLatencyMillis = builder.mNativeLatencyMillis;
-        mNativeDocumentStoreOptimizeLatencyMillis =
-                builder.mNativeDocumentStoreOptimizeLatencyMillis;
-        mNativeIndexRestorationLatencyMillis = builder.mNativeIndexRestorationLatencyMillis;
-        mNativeOriginalDocumentCount = builder.mNativeOriginalDocumentCount;
-        mNativeDeletedDocumentCount = builder.mNativeDeletedDocumentCount;
-        mNativeExpiredDocumentCount = builder.mNativeExpiredDocumentCount;
-        mNativeStorageSizeBeforeBytes = builder.mNativeStorageSizeBeforeBytes;
-        mNativeStorageSizeAfterBytes = builder.mNativeStorageSizeAfterBytes;
-        mNativeTimeSinceLastOptimizeMillis = builder.mNativeTimeSinceLastOptimizeMillis;
-    }
-
-    /** Returns status code for this optimization. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /** Returns total latency of this optimization in millis. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /** Returns how much time in millis spent in the native code. */
-    public int getNativeLatencyMillis() {
-        return mNativeLatencyMillis;
-    }
-
-    /** Returns time used to optimize the document store in millis. */
-    public int getDocumentStoreOptimizeLatencyMillis() {
-        return mNativeDocumentStoreOptimizeLatencyMillis;
-    }
-
-    /** Returns time used to restore the index in millis. */
-    public int getIndexRestorationLatencyMillis() {
-        return mNativeIndexRestorationLatencyMillis;
-    }
-
-    /** Returns number of documents before the optimization. */
-    public int getOriginalDocumentCount() {
-        return mNativeOriginalDocumentCount;
-    }
-
-    /** Returns number of documents deleted during the optimization. */
-    public int getDeletedDocumentCount() {
-        return mNativeDeletedDocumentCount;
-    }
-
-    /** Returns number of documents expired during the optimization. */
-    public int getExpiredDocumentCount() {
-        return mNativeExpiredDocumentCount;
-    }
-
-    /** Returns size of storage in bytes before the optimization. */
-    public long getStorageSizeBeforeBytes() {
-        return mNativeStorageSizeBeforeBytes;
-    }
-
-    /** Returns size of storage in bytes after the optimization. */
-    public long getStorageSizeAfterBytes() {
-        return mNativeStorageSizeAfterBytes;
-    }
-
-    /**
-     * Returns the amount of time in millis since the last optimization ran calculated using wall
-     * clock time.
-     */
-    public long getTimeSinceLastOptimizeMillis() {
-        return mNativeTimeSinceLastOptimizeMillis;
-    }
-
-    /** Builder for {@link RemoveStats}. */
-    public static class Builder {
-        /**
-         * The status code returned by {@link AppSearchResult#getResultCode()} for the call or
-         * internal state.
-         */
-        @AppSearchResult.ResultCode int mStatusCode;
-
-        int mTotalLatencyMillis;
-        int mNativeLatencyMillis;
-        int mNativeDocumentStoreOptimizeLatencyMillis;
-        int mNativeIndexRestorationLatencyMillis;
-        int mNativeOriginalDocumentCount;
-        int mNativeDeletedDocumentCount;
-        int mNativeExpiredDocumentCount;
-        long mNativeStorageSizeBeforeBytes;
-        long mNativeStorageSizeAfterBytes;
-        long mNativeTimeSinceLastOptimizeMillis;
-
-        /** Sets the status code. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets total latency in millis. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /** Sets native latency in millis. */
-        @NonNull
-        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
-            mNativeLatencyMillis = nativeLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to optimize the document store. */
-        @NonNull
-        public Builder setDocumentStoreOptimizeLatencyMillis(
-                int documentStoreOptimizeLatencyMillis) {
-            mNativeDocumentStoreOptimizeLatencyMillis = documentStoreOptimizeLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to restore the index. */
-        @NonNull
-        public Builder setIndexRestorationLatencyMillis(int indexRestorationLatencyMillis) {
-            mNativeIndexRestorationLatencyMillis = indexRestorationLatencyMillis;
-            return this;
-        }
-
-        /** Sets number of documents before the optimization. */
-        @NonNull
-        public Builder setOriginalDocumentCount(int originalDocumentCount) {
-            mNativeOriginalDocumentCount = originalDocumentCount;
-            return this;
-        }
-
-        /** Sets number of documents deleted during the optimization. */
-        @NonNull
-        public Builder setDeletedDocumentCount(int deletedDocumentCount) {
-            mNativeDeletedDocumentCount = deletedDocumentCount;
-            return this;
-        }
-
-        /** Sets number of documents expired during the optimization. */
-        @NonNull
-        public Builder setExpiredDocumentCount(int expiredDocumentCount) {
-            mNativeExpiredDocumentCount = expiredDocumentCount;
-            return this;
-        }
-
-        /** Sets Storage size in bytes before optimization. */
-        @NonNull
-        public Builder setStorageSizeBeforeBytes(long storageSizeBeforeBytes) {
-            mNativeStorageSizeBeforeBytes = storageSizeBeforeBytes;
-            return this;
-        }
-
-        /** Sets storage size in bytes after optimization. */
-        @NonNull
-        public Builder setStorageSizeAfterBytes(long storageSizeAfterBytes) {
-            mNativeStorageSizeAfterBytes = storageSizeAfterBytes;
-            return this;
-        }
-
-        /**
-         * Sets the amount the time since the last optimize ran calculated using wall clock time.
-         */
-        @NonNull
-        public Builder setTimeSinceLastOptimizeMillis(long timeSinceLastOptimizeMillis) {
-            mNativeTimeSinceLastOptimizeMillis = timeSinceLastOptimizeMillis;
-            return this;
-        }
-
-        /** Creates a {@link OptimizeStats}. */
-        @NonNull
-        public OptimizeStats build() {
-            return new OptimizeStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
deleted file mode 100644
index 7ba1816..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-
-import java.util.Objects;
-
-/**
- * A class for holding detailed stats to log for each individual document put by a {@link
- * android.app.appsearch.AppSearchSession#put} call.
- *
- * @hide
- */
-public final class PutDocumentStats {
-    @NonNull private final String mPackageName;
-    @NonNull private final String mDatabase;
-    /**
-     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
-     * state.
-     */
-    @AppSearchResult.ResultCode private final int mStatusCode;
-
-    private final int mTotalLatencyMillis;
-
-    /** Time used to generate a document proto from a Bundle. */
-    private final int mGenerateDocumentProtoLatencyMillis;
-
-    /** Time used to rewrite types and namespaces in the document. */
-    private final int mRewriteDocumentTypesLatencyMillis;
-
-    /** Overall time used for the native function call. */
-    private final int mNativeLatencyMillis;
-
-    /** Time used to store the document. */
-    private final int mNativeDocumentStoreLatencyMillis;
-
-    /** Time used to index the document. It doesn't include the time to merge indices. */
-    private final int mNativeIndexLatencyMillis;
-
-    /** Time used to merge the indices. */
-    private final int mNativeIndexMergeLatencyMillis;
-
-    /** Document size in bytes. */
-    private final int mNativeDocumentSizeBytes;
-
-    /** Number of tokens added to the index. */
-    private final int mNativeNumTokensIndexed;
-
-    /**
-     * Whether the number of tokens to be indexed exceeded the max number of tokens per document.
-     */
-    private final boolean mNativeExceededMaxNumTokens;
-
-    PutDocumentStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mPackageName = builder.mPackageName;
-        mDatabase = builder.mDatabase;
-        mStatusCode = builder.mStatusCode;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mGenerateDocumentProtoLatencyMillis = builder.mGenerateDocumentProtoLatencyMillis;
-        mRewriteDocumentTypesLatencyMillis = builder.mRewriteDocumentTypesLatencyMillis;
-        mNativeLatencyMillis = builder.mNativeLatencyMillis;
-        mNativeDocumentStoreLatencyMillis = builder.mNativeDocumentStoreLatencyMillis;
-        mNativeIndexLatencyMillis = builder.mNativeIndexLatencyMillis;
-        mNativeIndexMergeLatencyMillis = builder.mNativeIndexMergeLatencyMillis;
-        mNativeDocumentSizeBytes = builder.mNativeDocumentSizeBytes;
-        mNativeNumTokensIndexed = builder.mNativeNumTokensIndexed;
-        mNativeExceededMaxNumTokens = builder.mNativeExceededMaxNumTokens;
-    }
-
-    /** Returns calling package name. */
-    @NonNull
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /** Returns calling database name. */
-    @NonNull
-    public String getDatabase() {
-        return mDatabase;
-    }
-
-    /** Returns status code for this putDocument. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /** Returns total latency of this putDocument in millis. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /** Returns time spent on generating document proto, in milliseconds. */
-    public int getGenerateDocumentProtoLatencyMillis() {
-        return mGenerateDocumentProtoLatencyMillis;
-    }
-
-    /** Returns time spent on rewriting types and namespaces in document, in milliseconds. */
-    public int getRewriteDocumentTypesLatencyMillis() {
-        return mRewriteDocumentTypesLatencyMillis;
-    }
-
-    /** Returns time spent in native, in milliseconds. */
-    public int getNativeLatencyMillis() {
-        return mNativeLatencyMillis;
-    }
-
-    /** Returns time spent on document store, in milliseconds. */
-    public int getNativeDocumentStoreLatencyMillis() {
-        return mNativeDocumentStoreLatencyMillis;
-    }
-
-    /** Returns time spent on indexing, in milliseconds. */
-    public int getNativeIndexLatencyMillis() {
-        return mNativeIndexLatencyMillis;
-    }
-
-    /** Returns time spent on merging indices, in milliseconds. */
-    public int getNativeIndexMergeLatencyMillis() {
-        return mNativeIndexMergeLatencyMillis;
-    }
-
-    /** Returns document size, in bytes. */
-    public int getNativeDocumentSizeBytes() {
-        return mNativeDocumentSizeBytes;
-    }
-
-    /** Returns number of tokens indexed. */
-    public int getNativeNumTokensIndexed() {
-        return mNativeNumTokensIndexed;
-    }
-
-    /**
-     * Returns whether the number of tokens to be indexed exceeded the max number of tokens per
-     * document.
-     */
-    public boolean getNativeExceededMaxNumTokens() {
-        return mNativeExceededMaxNumTokens;
-    }
-
-    /** Builder for {@link PutDocumentStats}. */
-    public static class Builder {
-        @NonNull final String mPackageName;
-        @NonNull final String mDatabase;
-        @AppSearchResult.ResultCode int mStatusCode;
-        int mTotalLatencyMillis;
-        int mGenerateDocumentProtoLatencyMillis;
-        int mRewriteDocumentTypesLatencyMillis;
-        int mNativeLatencyMillis;
-        int mNativeDocumentStoreLatencyMillis;
-        int mNativeIndexLatencyMillis;
-        int mNativeIndexMergeLatencyMillis;
-        int mNativeDocumentSizeBytes;
-        int mNativeNumTokensIndexed;
-        boolean mNativeExceededMaxNumTokens;
-
-        /** Builder for {@link PutDocumentStats} */
-        public Builder(@NonNull String packageName, @NonNull String database) {
-            mPackageName = Objects.requireNonNull(packageName);
-            mDatabase = Objects.requireNonNull(database);
-        }
-
-        /** Sets the status code. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets total latency in millis. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /** Sets how much time we spend for generating document proto, in milliseconds. */
-        @NonNull
-        public Builder setGenerateDocumentProtoLatencyMillis(
-                int generateDocumentProtoLatencyMillis) {
-            mGenerateDocumentProtoLatencyMillis = generateDocumentProtoLatencyMillis;
-            return this;
-        }
-
-        /**
-         * Sets how much time we spend for rewriting types and namespaces in document, in
-         * milliseconds.
-         */
-        @NonNull
-        public Builder setRewriteDocumentTypesLatencyMillis(int rewriteDocumentTypesLatencyMillis) {
-            mRewriteDocumentTypesLatencyMillis = rewriteDocumentTypesLatencyMillis;
-            return this;
-        }
-
-        /** Sets the native latency, in milliseconds. */
-        @NonNull
-        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
-            mNativeLatencyMillis = nativeLatencyMillis;
-            return this;
-        }
-
-        /** Sets how much time we spend on document store, in milliseconds. */
-        @NonNull
-        public Builder setNativeDocumentStoreLatencyMillis(int nativeDocumentStoreLatencyMillis) {
-            mNativeDocumentStoreLatencyMillis = nativeDocumentStoreLatencyMillis;
-            return this;
-        }
-
-        /** Sets the native index latency, in milliseconds. */
-        @NonNull
-        public Builder setNativeIndexLatencyMillis(int nativeIndexLatencyMillis) {
-            mNativeIndexLatencyMillis = nativeIndexLatencyMillis;
-            return this;
-        }
-
-        /** Sets how much time we spend on merging indices, in milliseconds. */
-        @NonNull
-        public Builder setNativeIndexMergeLatencyMillis(int nativeIndexMergeLatencyMillis) {
-            mNativeIndexMergeLatencyMillis = nativeIndexMergeLatencyMillis;
-            return this;
-        }
-
-        /** Sets document size, in bytes. */
-        @NonNull
-        public Builder setNativeDocumentSizeBytes(int nativeDocumentSizeBytes) {
-            mNativeDocumentSizeBytes = nativeDocumentSizeBytes;
-            return this;
-        }
-
-        /** Sets number of tokens indexed in native. */
-        @NonNull
-        public Builder setNativeNumTokensIndexed(int nativeNumTokensIndexed) {
-            mNativeNumTokensIndexed = nativeNumTokensIndexed;
-            return this;
-        }
-
-        /**
-         * Sets whether the number of tokens to be indexed exceeded the max number of tokens per
-         * document.
-         */
-        @NonNull
-        public Builder setNativeExceededMaxNumTokens(boolean nativeExceededMaxNumTokens) {
-            mNativeExceededMaxNumTokens = nativeExceededMaxNumTokens;
-            return this;
-        }
-
-        /**
-         * Creates a new {@link PutDocumentStats} object from the contents of this {@link Builder}
-         * instance.
-         */
-        @NonNull
-        public PutDocumentStats build() {
-            return new PutDocumentStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/RemoveStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/RemoveStats.java
deleted file mode 100644
index b900c49..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/RemoveStats.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.RemoveByDocumentIdRequest;
-import android.app.appsearch.SearchSpec;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Class holds detailed stats for {@link
- * android.app.appsearch.AppSearchSession#remove(RemoveByDocumentIdRequest)} and {@link
- * android.app.appsearch.AppSearchSession#remove(String, SearchSpec)}
- *
- * @hide
- */
-public final class RemoveStats {
-    @IntDef(
-            value = {
-                // It needs to be sync with DeleteType.Code in
-                // external/icing/proto/icing/proto/logging.proto#DeleteStatsProto
-                UNKNOWN,
-                SINGLE,
-                QUERY,
-                NAMESPACE,
-                SCHEMA_TYPE,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DeleteType {}
-
-    /** Default. Should never be used. */
-    public static final int UNKNOWN = 0;
-    /** Delete by namespace + id. */
-    public static final int SINGLE = 1;
-    /** Delete by query. */
-    public static final int QUERY = 2;
-    /** Delete by namespace. */
-    public static final int NAMESPACE = 3;
-    /** Delete by schema type. */
-    public static final int SCHEMA_TYPE = 4;
-
-    @NonNull private final String mPackageName;
-    @NonNull private final String mDatabase;
-    /**
-     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
-     * state.
-     */
-    @AppSearchResult.ResultCode private final int mStatusCode;
-
-    private final int mTotalLatencyMillis;
-    private final int mNativeLatencyMillis;
-    @DeleteType private final int mNativeDeleteType;
-    private final int mNativeNumDocumentsDeleted;
-
-    RemoveStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mPackageName = builder.mPackageName;
-        mDatabase = builder.mDatabase;
-        mStatusCode = builder.mStatusCode;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mNativeLatencyMillis = builder.mNativeLatencyMillis;
-        mNativeDeleteType = builder.mNativeDeleteType;
-        mNativeNumDocumentsDeleted = builder.mNativeNumDocumentsDeleted;
-    }
-
-    /** Returns calling package name. */
-    @NonNull
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /** Returns calling database name. */
-    @NonNull
-    public String getDatabase() {
-        return mDatabase;
-    }
-
-    /** Returns status code for this remove. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /** Returns total latency of this remove in millis. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /** Returns how much time in millis spent in the native code. */
-    public int getNativeLatencyMillis() {
-        return mNativeLatencyMillis;
-    }
-
-    /** Returns what type of delete for this remove call. */
-    @DeleteType
-    public int getDeleteType() {
-        return mNativeDeleteType;
-    }
-
-    /** Returns how many documents get deleted in this call. */
-    public int getDeletedDocumentCount() {
-        return mNativeNumDocumentsDeleted;
-    }
-
-    /** Builder for {@link RemoveStats}. */
-    public static class Builder {
-        @NonNull final String mPackageName;
-        @NonNull final String mDatabase;
-        @AppSearchResult.ResultCode int mStatusCode;
-        int mTotalLatencyMillis;
-        int mNativeLatencyMillis;
-        @DeleteType int mNativeDeleteType;
-        int mNativeNumDocumentsDeleted;
-
-        /** Constructor for the {@link Builder}. */
-        public Builder(@NonNull String packageName, @NonNull String database) {
-            mPackageName = Objects.requireNonNull(packageName);
-            mDatabase = Objects.requireNonNull(database);
-        }
-
-        /** Sets the status code. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets total latency in millis. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /** Sets native latency in millis. */
-        @NonNull
-        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
-            mNativeLatencyMillis = nativeLatencyMillis;
-            return this;
-        }
-
-        /** Sets delete type for this call. */
-        @NonNull
-        public Builder setDeleteType(@DeleteType int nativeDeleteType) {
-            mNativeDeleteType = nativeDeleteType;
-            return this;
-        }
-
-        /** Sets how many documents get deleted for this call. */
-        @NonNull
-        public Builder setDeletedDocumentCount(int nativeNumDocumentsDeleted) {
-            mNativeNumDocumentsDeleted = nativeNumDocumentsDeleted;
-            return this;
-        }
-
-        /** Creates a {@link RemoveStats}. */
-        @NonNull
-        public RemoveStats build() {
-            return new RemoveStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SchemaMigrationStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SchemaMigrationStats.java
deleted file mode 100644
index 6e1e2d5..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SchemaMigrationStats.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.NonNull;
-import android.app.appsearch.SetSchemaRequest;
-
-import java.util.Objects;
-
-/**
- * Class holds detailed stats for Schema migration.
- *
- * @hide
- */
-// TODO(b/173532925): Hides getter and setter functions for accessing {@code
-//  mFirstSetSchemaLatencyMillis} and {@code mSecondSetSchemaLatencyMillis} field.
-
-public final class SchemaMigrationStats {
-    /** GetSchema latency in milliseconds. */
-    private final int mGetSchemaLatencyMillis;
-
-    /**
-     * Latency of querying all documents that need to be migrated to new version and transforming
-     * documents to new version in milliseconds.
-     */
-    private final int mQueryAndTransformLatencyMillis;
-
-    private final int mFirstSetSchemaLatencyMillis;
-
-    private final int mSecondSetSchemaLatencyMillis;
-
-    /** Latency of putting migrated document to Icing lib in milliseconds. */
-    private final int mSaveDocumentLatencyMillis;
-
-    private final int mMigratedDocumentCount;
-
-    private final int mSavedDocumentCount;
-
-    SchemaMigrationStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mGetSchemaLatencyMillis = builder.mGetSchemaLatencyMillis;
-        mQueryAndTransformLatencyMillis = builder.mQueryAndTransformLatencyMillis;
-        mFirstSetSchemaLatencyMillis = builder.mFirstSetSchemaLatencyMillis;
-        mSecondSetSchemaLatencyMillis = builder.mSecondSetSchemaLatencyMillis;
-        mSaveDocumentLatencyMillis = builder.mSaveDocumentLatencyMillis;
-        mMigratedDocumentCount = builder.mMigratedDocumentCount;
-        mSavedDocumentCount = builder.mSavedDocumentCount;
-    }
-
-    /** Returns GetSchema latency in milliseconds. */
-    public int getGetSchemaLatencyMillis() {
-        return mGetSchemaLatencyMillis;
-    }
-
-    /**
-     * Returns latency of querying all documents that need to be migrated to new version and
-     * transforming documents to new version in milliseconds.
-     */
-    public int getQueryAndTransformLatencyMillis() {
-        return mQueryAndTransformLatencyMillis;
-    }
-
-    /**
-     * Returns latency of first SetSchema action in milliseconds.
-     *
-     * <p>If all schema fields are backward compatible, the schema will be successful set to Icing.
-     * Otherwise, we will retrieve incompatible types here.
-     *
-     * <p>Please see {@link SetSchemaRequest} for what is "incompatible".
-     */
-    public int getFirstSetSchemaLatencyMillis() {
-        return mFirstSetSchemaLatencyMillis;
-    }
-
-    /**
-     * Returns latency of second SetSchema action in milliseconds.
-     *
-     * <p>If all schema fields are backward compatible, the schema will be successful set to Icing
-     * in the first setSchema action and this value will be 0. Otherwise, schema types will be set
-     * to Icing by this action.
-     */
-    public int getSecondSetSchemaLatencyMillis() {
-        return mSecondSetSchemaLatencyMillis;
-    }
-
-    /** Returns latency of putting migrated document to Icing lib in milliseconds. */
-    public int getSaveDocumentLatencyMillis() {
-        return mSaveDocumentLatencyMillis;
-    }
-
-    /** Returns number of migrated documents. */
-    public int getMigratedDocumentCount() {
-        return mMigratedDocumentCount;
-    }
-
-    /** Returns number of updated documents which are saved in Icing lib. */
-    public int getSavedDocumentCount() {
-        return mSavedDocumentCount;
-    }
-
-    /** Builder for {@link SchemaMigrationStats}. */
-    public static class Builder {
-        int mGetSchemaLatencyMillis;
-        int mQueryAndTransformLatencyMillis;
-        int mFirstSetSchemaLatencyMillis;
-        int mSecondSetSchemaLatencyMillis;
-        int mSaveDocumentLatencyMillis;
-        int mMigratedDocumentCount;
-        int mSavedDocumentCount;
-
-        /** Sets latency for the GetSchema action in milliseconds. */
-        @NonNull
-        public SchemaMigrationStats.Builder setGetSchemaLatencyMillis(int getSchemaLatencyMillis) {
-            mGetSchemaLatencyMillis = getSchemaLatencyMillis;
-            return this;
-        }
-
-        /**
-         * Sets latency for querying all documents that need to be migrated to new version and
-         * transforming documents to new version in milliseconds.
-         */
-        @NonNull
-        public SchemaMigrationStats.Builder setQueryAndTransformLatencyMillis(
-                int queryAndTransformLatencyMillis) {
-            mQueryAndTransformLatencyMillis = queryAndTransformLatencyMillis;
-            return this;
-        }
-
-        /** Sets latency of first SetSchema action in milliseconds. */
-        @NonNull
-        public SchemaMigrationStats.Builder setFirstSetSchemaLatencyMillis(
-                int firstSetSchemaLatencyMillis) {
-            mFirstSetSchemaLatencyMillis = firstSetSchemaLatencyMillis;
-            return this;
-        }
-
-        /** Sets latency of second SetSchema action in milliseconds. */
-        @NonNull
-        public SchemaMigrationStats.Builder setSecondSetSchemaLatencyMillis(
-                int secondSetSchemaLatencyMillis) {
-            mSecondSetSchemaLatencyMillis = secondSetSchemaLatencyMillis;
-            return this;
-        }
-
-        /** Sets latency for putting migrated document to Icing lib in milliseconds. */
-        @NonNull
-        public SchemaMigrationStats.Builder setSaveDocumentLatencyMillis(
-                int saveDocumentLatencyMillis) {
-            mSaveDocumentLatencyMillis = saveDocumentLatencyMillis;
-            return this;
-        }
-
-        /** Sets number of migrated documents. */
-        @NonNull
-        public SchemaMigrationStats.Builder setMigratedDocumentCount(int migratedDocumentCount) {
-            mMigratedDocumentCount = migratedDocumentCount;
-            return this;
-        }
-
-        /** Sets number of updated documents which are saved in Icing lib. */
-        @NonNull
-        public SchemaMigrationStats.Builder setSavedDocumentCount(int savedDocumentCount) {
-            mSavedDocumentCount = savedDocumentCount;
-            return this;
-        }
-
-        /**
-         * Builds a new {@link SchemaMigrationStats} from the {@link SchemaMigrationStats.Builder}.
-         */
-        @NonNull
-        public SchemaMigrationStats build() {
-            return new SchemaMigrationStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SearchStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SearchStats.java
deleted file mode 100644
index d7904f3..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SearchStats.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.SearchSpec;
-
-import com.android.internal.util.Preconditions;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Class holds detailed stats for {@link android.app.appsearch.AppSearchSession#search(String,
- * SearchSpec)}
- *
- * @hide
- */
-public final class SearchStats {
-    @IntDef(
-            value = {
-                // Searches apps' own documents.
-                VISIBILITY_SCOPE_LOCAL,
-                // Searches the global documents. Including platform surfaceable and 3p-access.
-                VISIBILITY_SCOPE_GLOBAL,
-                // TODO(b/173532925) Add THIRD_PARTY_ACCESS once we can distinguish platform
-                //  surfaceable from 3p access(right both of them are categorized as
-                //  VISIBILITY_SCOPE_GLOBAL)
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface VisibilityScope {}
-
-    // Searches apps' own documents.
-    public static final int VISIBILITY_SCOPE_LOCAL = 1;
-    // Searches the global documents. Including platform surfaceable and 3p-access.
-    public static final int VISIBILITY_SCOPE_GLOBAL = 2;
-
-    // TODO(b/173532925): Add a field searchType to indicate where the search is used(normal
-    //  query vs in removeByQuery vs during migration)
-
-    @NonNull private final String mPackageName;
-    @Nullable private final String mDatabase;
-    /**
-     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
-     * state.
-     */
-    @AppSearchResult.ResultCode private final int mStatusCode;
-
-    private final int mTotalLatencyMillis;
-    /** Time used to rewrite the search spec. */
-    private final int mRewriteSearchSpecLatencyMillis;
-    /** Time used to rewrite the search results. */
-    private final int mRewriteSearchResultLatencyMillis;
-    /** Defines the scope the query is searching over */
-    @VisibilityScope private final int mVisibilityScope;
-    /** Overall time used for the native function call. */
-    private final int mNativeLatencyMillis;
-    /** Number of terms in the query string. */
-    private final int mNativeNumTerms;
-    /** Length of the query string. */
-    private final int mNativeQueryLength;
-    /** Number of namespaces filtered. */
-    private final int mNativeNumNamespacesFiltered;
-    /** Number of schema types filtered. */
-    private final int mNativeNumSchemaTypesFiltered;
-    /** The requested number of results in one page. */
-    private final int mNativeRequestedPageSize;
-    /** The actual number of results returned in the current page. */
-    private final int mNativeNumResultsReturnedCurrentPage;
-    /**
-     * Whether the function call is querying the first page. If it's not, Icing will fetch the
-     * results from cache so that some steps may be skipped.
-     */
-    private final boolean mNativeIsFirstPage;
-    /**
-     * Time used to parse the query, including 2 parts: tokenizing and transforming tokens into an
-     * iterator tree.
-     */
-    private final int mNativeParseQueryLatencyMillis;
-    /** Strategy of scoring and ranking. */
-    @SearchSpec.RankingStrategy private final int mNativeRankingStrategy;
-    /** Number of documents scored. */
-    private final int mNativeNumDocumentsScored;
-    /** Time used to score the raw results. */
-    private final int mNativeScoringLatencyMillis;
-    /** Time used to rank the scored results. */
-    private final int mNativeRankingLatencyMillis;
-    /**
-     * Time used to fetch the document protos. Note that it includes the time to snippet if {@link
-     * SearchStats#mNativeNumResultsWithSnippets} is greater than 0.
-     */
-    private final int mNativeDocumentRetrievingLatencyMillis;
-    /** How many snippets are calculated. */
-    private final int mNativeNumResultsWithSnippets;
-
-    SearchStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mPackageName = builder.mPackageName;
-        mDatabase = builder.mDatabase;
-        mStatusCode = builder.mStatusCode;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mRewriteSearchSpecLatencyMillis = builder.mRewriteSearchSpecLatencyMillis;
-        mRewriteSearchResultLatencyMillis = builder.mRewriteSearchResultLatencyMillis;
-        mVisibilityScope = builder.mVisibilityScope;
-        mNativeLatencyMillis = builder.mNativeLatencyMillis;
-        mNativeNumTerms = builder.mNativeNumTerms;
-        mNativeQueryLength = builder.mNativeQueryLength;
-        mNativeNumNamespacesFiltered = builder.mNativeNumNamespacesFiltered;
-        mNativeNumSchemaTypesFiltered = builder.mNativeNumSchemaTypesFiltered;
-        mNativeRequestedPageSize = builder.mNativeRequestedPageSize;
-        mNativeNumResultsReturnedCurrentPage = builder.mNativeNumResultsReturnedCurrentPage;
-        mNativeIsFirstPage = builder.mNativeIsFirstPage;
-        mNativeParseQueryLatencyMillis = builder.mNativeParseQueryLatencyMillis;
-        mNativeRankingStrategy = builder.mNativeRankingStrategy;
-        mNativeNumDocumentsScored = builder.mNativeNumDocumentsScored;
-        mNativeScoringLatencyMillis = builder.mNativeScoringLatencyMillis;
-        mNativeRankingLatencyMillis = builder.mNativeRankingLatencyMillis;
-        mNativeNumResultsWithSnippets = builder.mNativeNumResultsWithSnippets;
-        mNativeDocumentRetrievingLatencyMillis = builder.mNativeDocumentRetrievingLatencyMillis;
-    }
-
-    /** Returns the package name of the session. */
-    @NonNull
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /**
-     * Returns the database name of the session.
-     *
-     * @return database name used by the session. {@code null} if and only if it is a global
-     *     search(visibilityScope is {@link SearchStats#VISIBILITY_SCOPE_GLOBAL}).
-     */
-    @Nullable
-    public String getDatabase() {
-        return mDatabase;
-    }
-
-    /** Returns status of the search. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /** Returns the total latency of the search. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /** Returns how much time spent on rewriting the {@link SearchSpec}. */
-    public int getRewriteSearchSpecLatencyMillis() {
-        return mRewriteSearchSpecLatencyMillis;
-    }
-
-    /** Returns how much time spent on rewriting the {@link android.app.appsearch.SearchResult}. */
-    public int getRewriteSearchResultLatencyMillis() {
-        return mRewriteSearchResultLatencyMillis;
-    }
-
-    /** Returns the visibility scope of the search. */
-    @VisibilityScope
-    public int getVisibilityScope() {
-        return mVisibilityScope;
-    }
-
-    /** Returns how much time spent on the native calls. */
-    public int getNativeLatencyMillis() {
-        return mNativeLatencyMillis;
-    }
-
-    /** Returns number of terms in the search string. */
-    public int getTermCount() {
-        return mNativeNumTerms;
-    }
-
-    /** Returns the length of the search string. */
-    public int getQueryLength() {
-        return mNativeQueryLength;
-    }
-
-    /** Returns number of namespaces filtered. */
-    public int getFilteredNamespaceCount() {
-        return mNativeNumNamespacesFiltered;
-    }
-
-    /** Returns number of schema types filtered. */
-    public int getFilteredSchemaTypeCount() {
-        return mNativeNumSchemaTypesFiltered;
-    }
-
-    /** Returns the requested number of results in one page. */
-    public int getRequestedPageSize() {
-        return mNativeRequestedPageSize;
-    }
-
-    /** Returns the actual number of results returned in the current page. */
-    public int getCurrentPageReturnedResultCount() {
-        return mNativeNumResultsReturnedCurrentPage;
-    }
-
-    // TODO(b/185184738) Make it an integer to show how many pages having been returned.
-    /** Returns whether the function call is querying the first page. */
-    public boolean isFirstPage() {
-        return mNativeIsFirstPage;
-    }
-
-    /**
-     * Returns time used to parse the query, including 2 parts: tokenizing and transforming tokens
-     * into an iterator tree.
-     */
-    public int getParseQueryLatencyMillis() {
-        return mNativeParseQueryLatencyMillis;
-    }
-
-    /** Returns strategy of scoring and ranking. */
-    @SearchSpec.RankingStrategy
-    public int getRankingStrategy() {
-        return mNativeRankingStrategy;
-    }
-
-    /** Returns number of documents scored. */
-    public int getScoredDocumentCount() {
-        return mNativeNumDocumentsScored;
-    }
-
-    /** Returns time used to score the raw results. */
-    public int getScoringLatencyMillis() {
-        return mNativeScoringLatencyMillis;
-    }
-
-    /** Returns time used to rank the scored results. */
-    public int getRankingLatencyMillis() {
-        return mNativeRankingLatencyMillis;
-    }
-
-    /**
-     * Returns time used to fetch the document protos. Note that it includes the time to snippet if
-     * {@link SearchStats#mNativeNumResultsWithSnippets} is not zero.
-     */
-    public int getDocumentRetrievingLatencyMillis() {
-        return mNativeDocumentRetrievingLatencyMillis;
-    }
-
-    /** Returns the number of the results in the page returned were snippeted. */
-    public int getResultWithSnippetsCount() {
-        return mNativeNumResultsWithSnippets;
-    }
-
-    /** Builder for {@link SearchStats} */
-    public static class Builder {
-        @NonNull final String mPackageName;
-        @Nullable String mDatabase;
-        @AppSearchResult.ResultCode int mStatusCode;
-        int mTotalLatencyMillis;
-        int mRewriteSearchSpecLatencyMillis;
-        int mRewriteSearchResultLatencyMillis;
-        int mVisibilityScope;
-        int mNativeLatencyMillis;
-        int mNativeNumTerms;
-        int mNativeQueryLength;
-        int mNativeNumNamespacesFiltered;
-        int mNativeNumSchemaTypesFiltered;
-        int mNativeRequestedPageSize;
-        int mNativeNumResultsReturnedCurrentPage;
-        boolean mNativeIsFirstPage;
-        int mNativeParseQueryLatencyMillis;
-        int mNativeRankingStrategy;
-        int mNativeNumDocumentsScored;
-        int mNativeScoringLatencyMillis;
-        int mNativeRankingLatencyMillis;
-        int mNativeNumResultsWithSnippets;
-        int mNativeDocumentRetrievingLatencyMillis;
-
-        /**
-         * Constructor
-         *
-         * @param visibilityScope scope for the corresponding search.
-         * @param packageName name of the calling package.
-         */
-        public Builder(@VisibilityScope int visibilityScope, @NonNull String packageName) {
-            mVisibilityScope = visibilityScope;
-            mPackageName = Objects.requireNonNull(packageName);
-        }
-
-        /** Sets the database used by the session. */
-        @NonNull
-        public Builder setDatabase(@NonNull String database) {
-            mDatabase = Objects.requireNonNull(database);
-            return this;
-        }
-
-        /** Sets the status of the search. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets total latency for the search. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to rewrite the search spec. */
-        @NonNull
-        public Builder setRewriteSearchSpecLatencyMillis(int rewriteSearchSpecLatencyMillis) {
-            mRewriteSearchSpecLatencyMillis = rewriteSearchSpecLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to rewrite the search results. */
-        @NonNull
-        public Builder setRewriteSearchResultLatencyMillis(int rewriteSearchResultLatencyMillis) {
-            mRewriteSearchResultLatencyMillis = rewriteSearchResultLatencyMillis;
-            return this;
-        }
-
-        /** Sets overall time used for the native function calls. */
-        @NonNull
-        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
-            mNativeLatencyMillis = nativeLatencyMillis;
-            return this;
-        }
-
-        /** Sets number of terms in the search string. */
-        @NonNull
-        public Builder setTermCount(int termCount) {
-            mNativeNumTerms = termCount;
-            return this;
-        }
-
-        /** Sets length of the search string. */
-        @NonNull
-        public Builder setQueryLength(int queryLength) {
-            mNativeQueryLength = queryLength;
-            return this;
-        }
-
-        /** Sets number of namespaces filtered. */
-        @NonNull
-        public Builder setFilteredNamespaceCount(int filteredNamespaceCount) {
-            mNativeNumNamespacesFiltered = filteredNamespaceCount;
-            return this;
-        }
-
-        /** Sets number of schema types filtered. */
-        @NonNull
-        public Builder setFilteredSchemaTypeCount(int filteredSchemaTypeCount) {
-            mNativeNumSchemaTypesFiltered = filteredSchemaTypeCount;
-            return this;
-        }
-
-        /** Sets the requested number of results in one page. */
-        @NonNull
-        public Builder setRequestedPageSize(int requestedPageSize) {
-            mNativeRequestedPageSize = requestedPageSize;
-            return this;
-        }
-
-        /** Sets the actual number of results returned in the current page. */
-        @NonNull
-        public Builder setCurrentPageReturnedResultCount(int currentPageReturnedResultCount) {
-            mNativeNumResultsReturnedCurrentPage = currentPageReturnedResultCount;
-            return this;
-        }
-
-        /**
-         * Sets whether the function call is querying the first page. If it's not, Icing will fetch
-         * the results from cache so that some steps may be skipped.
-         */
-        @NonNull
-        public Builder setIsFirstPage(boolean nativeIsFirstPage) {
-            mNativeIsFirstPage = nativeIsFirstPage;
-            return this;
-        }
-
-        /**
-         * Sets time used to parse the query, including 2 parts: tokenizing and transforming tokens
-         * into an iterator tree.
-         */
-        @NonNull
-        public Builder setParseQueryLatencyMillis(int parseQueryLatencyMillis) {
-            mNativeParseQueryLatencyMillis = parseQueryLatencyMillis;
-            return this;
-        }
-
-        /** Sets strategy of scoring and ranking. */
-        @NonNull
-        public Builder setRankingStrategy(@SearchSpec.RankingStrategy int rankingStrategy) {
-            mNativeRankingStrategy = rankingStrategy;
-            return this;
-        }
-
-        /** Sets number of documents scored. */
-        @NonNull
-        public Builder setScoredDocumentCount(int scoredDocumentCount) {
-            mNativeNumDocumentsScored = scoredDocumentCount;
-            return this;
-        }
-
-        /** Sets time used to score the raw results. */
-        @NonNull
-        public Builder setScoringLatencyMillis(int scoringLatencyMillis) {
-            mNativeScoringLatencyMillis = scoringLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to rank the scored results. */
-        @NonNull
-        public Builder setRankingLatencyMillis(int rankingLatencyMillis) {
-            mNativeRankingLatencyMillis = rankingLatencyMillis;
-            return this;
-        }
-
-        /** Sets time used to fetch the document protos. */
-        @NonNull
-        public Builder setDocumentRetrievingLatencyMillis(int documentRetrievingLatencyMillis) {
-            mNativeDocumentRetrievingLatencyMillis = documentRetrievingLatencyMillis;
-            return this;
-        }
-
-        /** Sets how many snippets are calculated. */
-        @NonNull
-        public Builder setResultWithSnippetsCount(int resultWithSnippetsCount) {
-            mNativeNumResultsWithSnippets = resultWithSnippetsCount;
-            return this;
-        }
-
-        /**
-         * Constructs a new {@link SearchStats} from the contents of this {@link
-         * SearchStats.Builder}.
-         */
-        @NonNull
-        public SearchStats build() {
-            if (mDatabase == null) {
-                Preconditions.checkState(
-                        mVisibilityScope != SearchStats.VISIBILITY_SCOPE_LOCAL,
-                        "database can not be null if visibilityScope is local.");
-            }
-
-            return new SearchStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
deleted file mode 100644
index 9d789a8..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchResult;
-
-import java.util.Objects;
-
-/**
- * Class holds detailed stats for {@link
- * android.app.appsearch.AppSearchSession#setSchema(SetSchemaRequest)}.
- *
- * @hide
- */
-public final class SetSchemaStats {
-    @NonNull private final String mPackageName;
-
-    @NonNull private final String mDatabase;
-
-    /**
-     * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
-     * state.
-     */
-    @AppSearchResult.ResultCode private final int mStatusCode;
-
-    /**
-     * Stores stats of SchemaMigration in SetSchema process. Is {@code null} if no schema migration
-     * is needed.
-     */
-    @Nullable private final SchemaMigrationStats mSchemaMigrationStats;
-
-    private final int mTotalLatencyMillis;
-
-    /** Overall time used for the native function call. */
-    private final int mNativeLatencyMillis;
-
-    /** Number of newly added schema types. */
-    private final int mNewTypeCount;
-
-    /** Number of deleted schema types. */
-    private final int mDeletedTypeCount;
-
-    /** Number of compatible schema type changes. */
-    private final int mCompatibleTypeChangeCount;
-
-    /** Number of index-incompatible schema type changes. */
-    private final int mIndexIncompatibleTypeChangeCount;
-
-    /** Number of backwards-incompatible schema type changes. */
-    private final int mBackwardsIncompatibleTypeChangeCount;
-
-    SetSchemaStats(@NonNull Builder builder) {
-        Objects.requireNonNull(builder);
-        mPackageName = builder.mPackageName;
-        mDatabase = builder.mDatabase;
-        mStatusCode = builder.mStatusCode;
-        mSchemaMigrationStats = builder.mSchemaMigrationStats;
-        mTotalLatencyMillis = builder.mTotalLatencyMillis;
-        mNativeLatencyMillis = builder.mNativeLatencyMillis;
-        mNewTypeCount = builder.mNewTypeCount;
-        mDeletedTypeCount = builder.mDeletedTypeCount;
-        mCompatibleTypeChangeCount = builder.mCompatibleTypeChangeCount;
-        mIndexIncompatibleTypeChangeCount = builder.mIndexIncompatibleTypeChangeCount;
-        mBackwardsIncompatibleTypeChangeCount = builder.mBackwardsIncompatibleTypeChangeCount;
-    }
-
-    /** Returns calling package name. */
-    @NonNull
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /** Returns calling database name. */
-    @NonNull
-    public String getDatabase() {
-        return mDatabase;
-    }
-
-    /** Returns status of the SetSchema action. */
-    @AppSearchResult.ResultCode
-    public int getStatusCode() {
-        return mStatusCode;
-    }
-
-    /**
-     * Returns the status of schema migration, if migration is executed during the SetSchema
-     * process. Otherwise, returns {@code null}.
-     */
-    @Nullable
-    public SchemaMigrationStats getSchemaMigrationStats() {
-        return mSchemaMigrationStats;
-    }
-
-    /** Returns the total latency of the SetSchema action. */
-    public int getTotalLatencyMillis() {
-        return mTotalLatencyMillis;
-    }
-
-    /** Returns overall time used for the native function call. */
-    public int getNativeLatencyMillis() {
-        return mNativeLatencyMillis;
-    }
-
-    /** Returns number of newly added schema types. */
-    public int getNewTypeCount() {
-        return mNewTypeCount;
-    }
-
-    /** Returns number of deleted schema types. */
-    public int getDeletedTypeCount() {
-        return mDeletedTypeCount;
-    }
-
-    /** Returns number of compatible type changes. */
-    public int getCompatibleTypeChangeCount() {
-        return mCompatibleTypeChangeCount;
-    }
-
-    /**
-     * Returns number of index-incompatible type change.
-     *
-     * <p>An index-incompatible type change is one that affects how pre-existing data should be
-     * searched over, such as modifying the {@code IndexingType} of an existing property.
-     */
-    public int getIndexIncompatibleTypeChangeCount() {
-        return mIndexIncompatibleTypeChangeCount;
-    }
-
-    /**
-     * Returns number of backwards-incompatible type change.
-     *
-     * <p>For details on what constitutes a backward-incompatible type change, please see {@link
-     * android.app.appsearch.SetSchemaRequest}.
-     */
-    public int getBackwardsIncompatibleTypeChangeCount() {
-        return mBackwardsIncompatibleTypeChangeCount;
-    }
-
-    /** Builder for {@link SetSchemaStats}. */
-    public static class Builder {
-        @NonNull final String mPackageName;
-        @NonNull final String mDatabase;
-        @AppSearchResult.ResultCode int mStatusCode;
-        @Nullable SchemaMigrationStats mSchemaMigrationStats;
-        int mTotalLatencyMillis;
-        int mNativeLatencyMillis;
-        int mNewTypeCount;
-        int mDeletedTypeCount;
-        int mCompatibleTypeChangeCount;
-        int mIndexIncompatibleTypeChangeCount;
-        int mBackwardsIncompatibleTypeChangeCount;
-
-        /** Constructor for the {@link Builder}. */
-        public Builder(@NonNull String packageName, @NonNull String database) {
-            mPackageName = Objects.requireNonNull(packageName);
-            mDatabase = Objects.requireNonNull(database);
-        }
-
-        /** Sets the status of the SetSchema action. */
-        @NonNull
-        public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
-            mStatusCode = statusCode;
-            return this;
-        }
-
-        /** Sets the status of schema migration. */
-        @NonNull
-        public Builder setSchemaMigrationStats(@NonNull SchemaMigrationStats schemaMigrationStats) {
-            mSchemaMigrationStats = Objects.requireNonNull(schemaMigrationStats);
-            return this;
-        }
-
-        /** Sets total latency for the SetSchema action in milliseconds. */
-        @NonNull
-        public Builder setTotalLatencyMillis(int totalLatencyMillis) {
-            mTotalLatencyMillis = totalLatencyMillis;
-            return this;
-        }
-
-        /** Sets native latency in milliseconds. */
-        @NonNull
-        public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
-            mNativeLatencyMillis = nativeLatencyMillis;
-            return this;
-        }
-
-        /** Sets number of new types. */
-        @NonNull
-        public Builder setNewTypeCount(int newTypeCount) {
-            mNewTypeCount = newTypeCount;
-            return this;
-        }
-
-        /** Sets number of deleted types. */
-        @NonNull
-        public Builder setDeletedTypeCount(int deletedTypeCount) {
-            mDeletedTypeCount = deletedTypeCount;
-            return this;
-        }
-
-        /** Sets number of compatible type changes. */
-        @NonNull
-        public Builder setCompatibleTypeChangeCount(int compatibleTypeChangeCount) {
-            mCompatibleTypeChangeCount = compatibleTypeChangeCount;
-            return this;
-        }
-
-        /** Sets number of index-incompatible type changes. */
-        @NonNull
-        public Builder setIndexIncompatibleTypeChangeCount(int indexIncompatibleTypeChangeCount) {
-            mIndexIncompatibleTypeChangeCount = indexIncompatibleTypeChangeCount;
-            return this;
-        }
-
-        /** Sets number of backwards-incompatible type changes. */
-        @NonNull
-        public Builder setBackwardsIncompatibleTypeChangeCount(
-                int backwardsIncompatibleTypeChangeCount) {
-            mBackwardsIncompatibleTypeChangeCount = backwardsIncompatibleTypeChangeCount;
-            return this;
-        }
-
-        /** Builds a new {@link SetSchemaStats} from the {@link Builder}. */
-        @NonNull
-        public SetSchemaStats build() {
-            return new SetSchemaStats(/* builder= */ this);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/util/PrefixUtil.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/util/PrefixUtil.java
deleted file mode 100644
index 80cfe89..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/util/PrefixUtil.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.util;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import com.google.android.icing.proto.DocumentProto;
-import com.google.android.icing.proto.PropertyProto;
-
-/**
- * Provides utility functions for working with package + database prefixes.
- *
- * @hide
- */
-public class PrefixUtil {
-    private static final String TAG = "AppSearchPrefixUtil";
-
-    @VisibleForTesting public static final char DATABASE_DELIMITER = '/';
-
-    @VisibleForTesting public static final char PACKAGE_DELIMITER = '$';
-
-    private PrefixUtil() {}
-
-    /** Creates prefix string for given package name and database name. */
-    @NonNull
-    public static String createPrefix(@NonNull String packageName, @NonNull String databaseName) {
-        return packageName + PACKAGE_DELIMITER + databaseName + DATABASE_DELIMITER;
-    }
-    /** Creates prefix string for given package name. */
-    @NonNull
-    public static String createPackagePrefix(@NonNull String packageName) {
-        return packageName + PACKAGE_DELIMITER;
-    }
-
-    /**
-     * Returns the package name that's contained within the {@code prefix}.
-     *
-     * @param prefix Prefix string that contains the package name inside of it. The package name
-     *     must be in the front of the string, and separated from the rest of the string by the
-     *     {@link #PACKAGE_DELIMITER}.
-     * @return Valid package name.
-     */
-    @NonNull
-    public static String getPackageName(@NonNull String prefix) {
-        int delimiterIndex = prefix.indexOf(PACKAGE_DELIMITER);
-        if (delimiterIndex == -1) {
-            // This should never happen if we construct our prefixes properly
-            Log.wtf(TAG, "Malformed prefix doesn't contain package delimiter: " + prefix);
-            return "";
-        }
-        return prefix.substring(0, delimiterIndex);
-    }
-
-    /**
-     * Returns the database name that's contained within the {@code prefix}.
-     *
-     * @param prefix Prefix string that contains the database name inside of it. The database name
-     *     must be between the {@link #PACKAGE_DELIMITER} and {@link #DATABASE_DELIMITER}
-     * @return Valid database name.
-     */
-    @NonNull
-    public static String getDatabaseName(@NonNull String prefix) {
-        // TODO (b/184050178) Start database delimiter index search from after package delimiter
-        int packageDelimiterIndex = prefix.indexOf(PACKAGE_DELIMITER);
-        int databaseDelimiterIndex = prefix.indexOf(DATABASE_DELIMITER);
-        if (packageDelimiterIndex == -1) {
-            // This should never happen if we construct our prefixes properly
-            Log.wtf(TAG, "Malformed prefix doesn't contain package delimiter: " + prefix);
-            return "";
-        }
-        if (databaseDelimiterIndex == -1) {
-            // This should never happen if we construct our prefixes properly
-            Log.wtf(TAG, "Malformed prefix doesn't contain database delimiter: " + prefix);
-            return "";
-        }
-        return prefix.substring(packageDelimiterIndex + 1, databaseDelimiterIndex);
-    }
-
-    /**
-     * Creates a string with the package and database prefix removed from the input string.
-     *
-     * @param prefixedString a string containing a package and database prefix.
-     * @return a string with the package and database prefix removed.
-     * @throws AppSearchException if the prefixed value does not contain a valid database name.
-     */
-    @NonNull
-    public static String removePrefix(@NonNull String prefixedString) throws AppSearchException {
-        // The prefix is made up of the package, then the database. So we only need to find the
-        // database cutoff.
-        int delimiterIndex;
-        if ((delimiterIndex = prefixedString.indexOf(DATABASE_DELIMITER)) != -1) {
-            // Add 1 to include the char size of the DATABASE_DELIMITER
-            return prefixedString.substring(delimiterIndex + 1);
-        }
-        throw new AppSearchException(
-                AppSearchResult.RESULT_INTERNAL_ERROR,
-                "The prefixed value \""
-                        + prefixedString
-                        + "\" doesn't contain a valid "
-                        + "database name");
-    }
-
-    /**
-     * Creates a package and database prefix string from the input string.
-     *
-     * @param prefixedString a string containing a package and database prefix.
-     * @return a string with the package and database prefix
-     * @throws AppSearchException if the prefixed value does not contain a valid database name.
-     */
-    @NonNull
-    public static String getPrefix(@NonNull String prefixedString) throws AppSearchException {
-        int databaseDelimiterIndex = prefixedString.indexOf(DATABASE_DELIMITER);
-        if (databaseDelimiterIndex == -1) {
-            throw new AppSearchException(
-                    AppSearchResult.RESULT_INTERNAL_ERROR,
-                    "The prefixed value \""
-                            + prefixedString
-                            + "\" doesn't contain a valid "
-                            + "database name");
-        }
-
-        // Add 1 to include the char size of the DATABASE_DELIMITER
-        return prefixedString.substring(0, databaseDelimiterIndex + 1);
-    }
-
-    /**
-     * Prepends {@code prefix} to all types and namespaces mentioned anywhere in {@code
-     * documentBuilder}.
-     *
-     * @param documentBuilder The document to mutate
-     * @param prefix The prefix to add
-     */
-    public static void addPrefixToDocument(
-            @NonNull DocumentProto.Builder documentBuilder, @NonNull String prefix) {
-        // Rewrite the type name to include/remove the prefix.
-        String newSchema = prefix + documentBuilder.getSchema();
-        documentBuilder.setSchema(newSchema);
-
-        // Rewrite the namespace to include/remove the prefix.
-        documentBuilder.setNamespace(prefix + documentBuilder.getNamespace());
-
-        // Recurse into derived documents
-        for (int propertyIdx = 0;
-                propertyIdx < documentBuilder.getPropertiesCount();
-                propertyIdx++) {
-            int documentCount = documentBuilder.getProperties(propertyIdx).getDocumentValuesCount();
-            if (documentCount > 0) {
-                PropertyProto.Builder propertyBuilder =
-                        documentBuilder.getProperties(propertyIdx).toBuilder();
-                for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) {
-                    DocumentProto.Builder derivedDocumentBuilder =
-                            propertyBuilder.getDocumentValues(documentIdx).toBuilder();
-                    addPrefixToDocument(derivedDocumentBuilder, prefix);
-                    propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder);
-                }
-                documentBuilder.setProperties(propertyIdx, propertyBuilder);
-            }
-        }
-    }
-
-    /**
-     * Removes any prefixes from types and namespaces mentioned anywhere in {@code documentBuilder}.
-     *
-     * @param documentBuilder The document to mutate
-     * @return Prefix name that was removed from the document.
-     * @throws AppSearchException if there are unexpected database prefixing errors.
-     */
-    @NonNull
-    public static String removePrefixesFromDocument(@NonNull DocumentProto.Builder documentBuilder)
-            throws AppSearchException {
-        // Rewrite the type name and namespace to remove the prefix.
-        String schemaPrefix = getPrefix(documentBuilder.getSchema());
-        String namespacePrefix = getPrefix(documentBuilder.getNamespace());
-
-        if (!schemaPrefix.equals(namespacePrefix)) {
-            throw new AppSearchException(
-                    AppSearchResult.RESULT_INTERNAL_ERROR,
-                    "Found unexpected"
-                            + " multiple prefix names in document: "
-                            + schemaPrefix
-                            + ", "
-                            + namespacePrefix);
-        }
-
-        documentBuilder.setSchema(removePrefix(documentBuilder.getSchema()));
-        documentBuilder.setNamespace(removePrefix(documentBuilder.getNamespace()));
-
-        // Recurse into derived documents
-        for (int propertyIdx = 0;
-                propertyIdx < documentBuilder.getPropertiesCount();
-                propertyIdx++) {
-            int documentCount = documentBuilder.getProperties(propertyIdx).getDocumentValuesCount();
-            if (documentCount > 0) {
-                PropertyProto.Builder propertyBuilder =
-                        documentBuilder.getProperties(propertyIdx).toBuilder();
-                for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) {
-                    DocumentProto.Builder derivedDocumentBuilder =
-                            propertyBuilder.getDocumentValues(documentIdx).toBuilder();
-                    String nestedPrefix = removePrefixesFromDocument(derivedDocumentBuilder);
-                    if (!nestedPrefix.equals(schemaPrefix)) {
-                        throw new AppSearchException(
-                                AppSearchResult.RESULT_INTERNAL_ERROR,
-                                "Found unexpected multiple prefix names in document: "
-                                        + schemaPrefix
-                                        + ", "
-                                        + nestedPrefix);
-                    }
-                    propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder);
-                }
-                documentBuilder.setProperties(propertyIdx, propertyBuilder);
-            }
-        }
-
-        return schemaPrefix;
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java
deleted file mode 100644
index fb89250..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.external.localstorage.visibilitystore;
-
-import android.annotation.NonNull;
-import android.app.appsearch.PackageIdentifier;
-import android.app.appsearch.exceptions.AppSearchException;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An interface for classes that store and validate document visibility data.
- *
- * @hide
- */
-public interface VisibilityStore {
-    /**
-     * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code
-     * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}.
-     */
-    String PACKAGE_NAME = "VS#Pkg";
-
-    @VisibleForTesting String DATABASE_NAME = "VS#Db";
-
-    /**
-     * Sets visibility settings for the given database. Any previous visibility settings will be
-     * overwritten.
-     *
-     * @param packageName Package of app that owns the schemas.
-     * @param databaseName Database that owns the schemas.
-     * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from
-     *     platform surfaces.
-     * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
-     *     have access to the schema.
-     * @throws AppSearchException on AppSearchImpl error.
-     */
-    void setVisibility(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Set<String> schemasNotDisplayedBySystem,
-            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
-            throws AppSearchException;
-
-    /**
-     * Checks whether the given package has access to system-surfaceable schemas.
-     *
-     * @param callerUid UID of the app that wants to see the data.
-     */
-    boolean isSchemaSearchableByCaller(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String prefixedSchema,
-            int callerUid,
-            boolean callerHasSystemAccess);
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
deleted file mode 100644
index fdf6a00..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.stats;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-import android.os.Process;
-import android.os.SystemClock;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.appsearch.AppSearchConfig;
-import com.android.server.appsearch.external.localstorage.AppSearchLogger;
-import com.android.server.appsearch.external.localstorage.stats.CallStats;
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
-import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
-import com.android.server.appsearch.external.localstorage.stats.SearchStats;
-import com.android.server.appsearch.util.PackageUtil;
-
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Random;
-
-/**
- * Logger Implementation for pushed atoms.
- *
- * <p>This class is thread-safe.
- *
- * @hide
- */
-public final class PlatformLogger implements AppSearchLogger {
-    private static final String TAG = "AppSearchPlatformLogger";
-
-    // Context of the user we're logging for.
-    private final Context mUserContext;
-
-    // Manager holding the configuration flags
-    private final AppSearchConfig mConfig;
-
-    private final Random mRng = new Random();
-    private final Object mLock = new Object();
-
-    /**
-     * SparseArray to track how many stats we skipped due to
-     * {@link AppSearchConfig#getCachedMinTimeIntervalBetweenSamplesMillis()}.
-     *
-     * <p> We can have correct extrapolated number by adding those counts back when we log
-     * the same type of stats next time. E.g. the true count of an event could be estimated as:
-     * SUM(sampling_interval * (num_skipped_sample + 1)) as est_count
-     *
-     * <p>The key to the SparseArray is {@link CallStats.CallType}
-     */
-    @GuardedBy("mLock")
-    private final SparseIntArray mSkippedSampleCountLocked =
-            new SparseIntArray();
-
-    /**
-     * Map to cache the packageUid for each package.
-     *
-     * <p>It maps packageName to packageUid.
-     *
-     * <p>The entry will be removed whenever the app gets uninstalled
-     */
-    @GuardedBy("mLock")
-    private final Map<String, Integer> mPackageUidCacheLocked =
-            new ArrayMap<>();
-
-    /**
-     * Elapsed time for last stats logged from boot in millis
-     */
-    @GuardedBy("mLock")
-    private long mLastPushTimeMillisLocked = 0;
-
-    /**
-     * Helper class to hold platform specific stats for statsd.
-     */
-    static final class ExtraStats {
-        // UID for the calling package of the stats.
-        final int mPackageUid;
-        // sampling interval for the call type of the stats.
-        final int mSamplingInterval;
-        // number of samplings skipped before the current one for the same call type.
-        final int mSkippedSampleCount;
-
-        ExtraStats(int packageUid, int samplingInterval, int skippedSampleCount) {
-            mPackageUid = packageUid;
-            mSamplingInterval = samplingInterval;
-            mSkippedSampleCount = skippedSampleCount;
-        }
-    }
-
-    /**
-     * Constructor
-     */
-    public PlatformLogger(
-            @NonNull Context userContext,
-            @NonNull AppSearchConfig config) {
-        mUserContext = Objects.requireNonNull(userContext);
-        mConfig = Objects.requireNonNull(config);
-    }
-
-    /** Logs {@link CallStats}. */
-    @Override
-    public void logStats(@NonNull CallStats stats) {
-        Objects.requireNonNull(stats);
-        synchronized (mLock) {
-            if (shouldLogForTypeLocked(stats.getCallType())) {
-                logStatsImplLocked(stats);
-            }
-        }
-    }
-
-    /** Logs {@link PutDocumentStats}. */
-    @Override
-    public void logStats(@NonNull PutDocumentStats stats) {
-        Objects.requireNonNull(stats);
-        synchronized (mLock) {
-            if (shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)) {
-                logStatsImplLocked(stats);
-            }
-        }
-    }
-
-    @Override
-    public void logStats(@NonNull InitializeStats stats) {
-        Objects.requireNonNull(stats);
-        synchronized (mLock) {
-            if (shouldLogForTypeLocked(CallStats.CALL_TYPE_INITIALIZE)) {
-                logStatsImplLocked(stats);
-            }
-        }
-    }
-
-    @Override
-    public void logStats(@NonNull SearchStats stats) {
-        Objects.requireNonNull(stats);
-        synchronized (mLock) {
-            if (shouldLogForTypeLocked(CallStats.CALL_TYPE_SEARCH)) {
-                logStatsImplLocked(stats);
-            }
-        }
-    }
-
-    @Override
-    public void logStats(@NonNull RemoveStats stats) {
-        // TODO(b/173532925): Log stats
-    }
-
-    @Override
-    public void logStats(@NonNull OptimizeStats stats) {
-        Objects.requireNonNull(stats);
-        synchronized (mLock) {
-            if (shouldLogForTypeLocked(CallStats.CALL_TYPE_OPTIMIZE)) {
-                logStatsImplLocked(stats);
-            }
-        }
-    }
-
-    /**
-     * Removes cached UID for package.
-     *
-     * @return removed UID for the package, or {@code INVALID_UID} if package was not previously
-     * cached.
-     */
-    public int removeCachedUidForPackage(@NonNull String packageName) {
-        // TODO(b/173532925) This needs to be called when we get PACKAGE_REMOVED intent
-        Objects.requireNonNull(packageName);
-        synchronized (mLock) {
-            Integer uid = mPackageUidCacheLocked.remove(packageName);
-            return uid != null ? uid : Process.INVALID_UID;
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void logStatsImplLocked(@NonNull CallStats stats) {
-        mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
-        ExtraStats extraStats = createExtraStatsLocked(stats.getPackageName(), stats.getCallType());
-        String database = stats.getDatabase();
-        try {
-            int hashCodeForDatabase = calculateHashCodeMd5(database);
-            AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_CALL_STATS_REPORTED,
-                    extraStats.mSamplingInterval,
-                    extraStats.mSkippedSampleCount,
-                    extraStats.mPackageUid,
-                    hashCodeForDatabase,
-                    stats.getStatusCode(),
-                    stats.getTotalLatencyMillis(),
-                    stats.getCallType(),
-                    stats.getEstimatedBinderLatencyMillis(),
-                    stats.getNumOperationsSucceeded(),
-                    stats.getNumOperationsFailed());
-        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
-            // TODO(b/184204720) report hashing error to statsd
-            //  We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database,
-            //  so in the dashboard we know there is some error for hashing.
-            //
-            // Something is wrong while calculating the hash code for database
-            // this shouldn't happen since we always use "MD5" and "UTF-8"
-            if (database != null) {
-                Log.e(TAG, "Error calculating hash code for database " + database, e);
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void logStatsImplLocked(@NonNull PutDocumentStats stats) {
-        mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
-        ExtraStats extraStats = createExtraStatsLocked(
-                stats.getPackageName(), CallStats.CALL_TYPE_PUT_DOCUMENT);
-        String database = stats.getDatabase();
-        try {
-            int hashCodeForDatabase = calculateHashCodeMd5(database);
-            AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED,
-                    extraStats.mSamplingInterval,
-                    extraStats.mSkippedSampleCount,
-                    extraStats.mPackageUid,
-                    hashCodeForDatabase,
-                    stats.getStatusCode(),
-                    stats.getTotalLatencyMillis(),
-                    stats.getGenerateDocumentProtoLatencyMillis(),
-                    stats.getRewriteDocumentTypesLatencyMillis(),
-                    stats.getNativeLatencyMillis(),
-                    stats.getNativeDocumentStoreLatencyMillis(),
-                    stats.getNativeIndexLatencyMillis(),
-                    stats.getNativeIndexMergeLatencyMillis(),
-                    stats.getNativeDocumentSizeBytes(),
-                    stats.getNativeNumTokensIndexed(),
-                    stats.getNativeExceededMaxNumTokens());
-        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
-            // TODO(b/184204720) report hashing error to statsd
-            //  We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database,
-            //  so in the dashboard we know there is some error for hashing.
-            //
-            // Something is wrong while calculating the hash code for database
-            // this shouldn't happen since we always use "MD5" and "UTF-8"
-            if (database != null) {
-                Log.e(TAG, "Error calculating hash code for database " + database, e);
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void logStatsImplLocked(@NonNull SearchStats stats) {
-        mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
-        ExtraStats extraStats = createExtraStatsLocked(stats.getPackageName(),
-                CallStats.CALL_TYPE_SEARCH);
-        String database = stats.getDatabase();
-        try {
-            int hashCodeForDatabase = calculateHashCodeMd5(database);
-            AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_QUERY_STATS_REPORTED,
-                    extraStats.mSamplingInterval,
-                    extraStats.mSkippedSampleCount,
-                    extraStats.mPackageUid,
-                    hashCodeForDatabase,
-                    stats.getStatusCode(),
-                    stats.getTotalLatencyMillis(),
-                    stats.getRewriteSearchSpecLatencyMillis(),
-                    stats.getRewriteSearchResultLatencyMillis(),
-                    stats.getVisibilityScope(),
-                    stats.getNativeLatencyMillis(),
-                    stats.getTermCount(),
-                    stats.getQueryLength(),
-                    stats.getFilteredNamespaceCount(),
-                    stats.getFilteredSchemaTypeCount(),
-                    stats.getRequestedPageSize(),
-                    stats.getCurrentPageReturnedResultCount(),
-                    stats.isFirstPage(),
-                    stats.getParseQueryLatencyMillis(),
-                    stats.getRankingStrategy(),
-                    stats.getScoredDocumentCount(),
-                    stats.getScoringLatencyMillis(),
-                    stats.getRankingLatencyMillis(),
-                    stats.getDocumentRetrievingLatencyMillis(),
-                    stats.getResultWithSnippetsCount());
-        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
-            // TODO(b/184204720) report hashing error to statsd
-            //  We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database,
-            //  so in the dashboard we know there is some error for hashing.
-            //
-            // Something is wrong while calculating the hash code for database
-            // this shouldn't happen since we always use "MD5" and "UTF-8"
-            if (database != null) {
-                Log.e(TAG, "Error calculating hash code for database " + database, e);
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void logStatsImplLocked(@NonNull InitializeStats stats) {
-        mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
-        ExtraStats extraStats = createExtraStatsLocked(/*packageName=*/ null,
-                CallStats.CALL_TYPE_INITIALIZE);
-        AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_INITIALIZE_STATS_REPORTED,
-                extraStats.mSamplingInterval,
-                extraStats.mSkippedSampleCount,
-                extraStats.mPackageUid,
-                stats.getStatusCode(),
-                stats.getTotalLatencyMillis(),
-                stats.hasDeSync(),
-                stats.getPrepareSchemaAndNamespacesLatencyMillis(),
-                stats.getPrepareVisibilityStoreLatencyMillis(),
-                stats.getNativeLatencyMillis(),
-                stats.getDocumentStoreRecoveryCause(),
-                stats.getIndexRestorationCause(),
-                stats.getSchemaStoreRecoveryCause(),
-                stats.getDocumentStoreRecoveryLatencyMillis(),
-                stats.getIndexRestorationLatencyMillis(),
-                stats.getSchemaStoreRecoveryLatencyMillis(),
-                stats.getDocumentStoreDataStatus(),
-                stats.getDocumentCount(),
-                stats.getSchemaTypeCount(),
-                stats.hasReset(),
-                stats.getResetStatusCode());
-    }
-
-    @GuardedBy("mLock")
-    private void logStatsImplLocked(@NonNull OptimizeStats stats) {
-        mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
-        ExtraStats extraStats = createExtraStatsLocked(/*packageName=*/ null,
-                CallStats.CALL_TYPE_OPTIMIZE);
-        AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_OPTIMIZE_STATS_REPORTED,
-                extraStats.mSamplingInterval,
-                extraStats.mSkippedSampleCount,
-                stats.getStatusCode(),
-                stats.getTotalLatencyMillis(),
-                stats.getNativeLatencyMillis(),
-                stats.getDocumentStoreOptimizeLatencyMillis(),
-                stats.getIndexRestorationLatencyMillis(),
-                stats.getOriginalDocumentCount(),
-                stats.getDeletedDocumentCount(),
-                stats.getExpiredDocumentCount(),
-                stats.getStorageSizeBeforeBytes(),
-                stats.getStorageSizeAfterBytes(),
-                stats.getTimeSinceLastOptimizeMillis());
-    }
-
-    /**
-     * Calculate the hash code as an integer by returning the last four bytes of its MD5.
-     *
-     * @param str a string
-     * @return hash code as an integer. returns -1 if str is null.
-     * @throws AppSearchException if either algorithm or encoding does not exist.
-     */
-    @VisibleForTesting
-    @NonNull
-    static int calculateHashCodeMd5(@Nullable String str) throws
-            NoSuchAlgorithmException, UnsupportedEncodingException {
-        if (str == null) {
-            // Just return -1 if caller doesn't have database name
-            // For some stats like globalQuery, databaseName can be null.
-            // Since in atom it is an integer, we have to return something here.
-            return -1;
-        }
-
-        MessageDigest md = MessageDigest.getInstance("MD5");
-        md.update(str.getBytes(/*charsetName=*/ "UTF-8"));
-        byte[] digest = md.digest();
-
-        // Since MD5 generates 16 bytes digest, we don't need to check the length here to see
-        // if it is smaller than sizeof(int)(4).
-        //
-        // We generate the same value as BigInteger(digest).intValue().
-        // BigInteger takes bytes[] and treat it as big endian. And its intValue() would get the
-        // lower 4 bytes. So here we take the last 4 bytes and treat them as big endian.
-        return (digest[12] & 0xFF) << 24
-                | (digest[13] & 0xFF) << 16
-                | (digest[14] & 0xFF) << 8
-                | (digest[15] & 0xFF);
-    }
-
-    /**
-     * Creates {@link ExtraStats} to hold additional information generated for logging.
-     *
-     * <p>This method is called by most of logStatsImplLocked functions to reduce code
-     * duplication.
-     */
-    // TODO(b/173532925) Once we add CTS test for logging atoms and can inspect the result, we can
-    // remove this @VisibleForTesting and directly use PlatformLogger.logStats to test sampling and
-    // rate limiting.
-    @VisibleForTesting
-    @GuardedBy("mLock")
-    @NonNull
-    ExtraStats createExtraStatsLocked(@Nullable String packageName,
-            @CallStats.CallType int callType) {
-        int packageUid = Process.INVALID_UID;
-        if (packageName != null) {
-            packageUid = getPackageUidAsUserLocked(packageName);
-        }
-
-        // The sampling ratio here might be different from the one used in
-        // shouldLogForTypeLocked if there is a config change in the middle.
-        // Since it is only one sample, we can just ignore this difference.
-        // Or we can retrieve samplingRatio at beginning and pass along
-        // as function parameter, but it will make code less cleaner with some duplication.
-        int samplingInterval = getSamplingIntervalFromConfig(callType);
-        int skippedSampleCount = mSkippedSampleCountLocked.get(callType,
-                /*valueOfKeyIfNotFound=*/ 0);
-        mSkippedSampleCountLocked.put(callType, 0);
-
-        return new ExtraStats(packageUid, samplingInterval, skippedSampleCount);
-    }
-
-    /**
-     * Checks if this stats should be logged.
-     *
-     * <p>It won't be logged if it is "sampled" out, or it is too close to the previous logged
-     * stats.
-     */
-    @GuardedBy("mLock")
-    // TODO(b/173532925) Once we add CTS test for logging atoms and can inspect the result, we can
-    // remove this @VisibleForTesting and directly use PlatformLogger.logStats to test sampling and
-    // rate limiting.
-    @VisibleForTesting
-    boolean shouldLogForTypeLocked(@CallStats.CallType int callType) {
-        int samplingInterval = getSamplingIntervalFromConfig(callType);
-        // Sampling
-        if (!shouldSample(samplingInterval)) {
-            return false;
-        }
-
-        // Rate limiting
-        // Check the timestamp to see if it is too close to last logged sample
-        long currentTimeMillis = SystemClock.elapsedRealtime();
-        if (mLastPushTimeMillisLocked
-                > currentTimeMillis - mConfig.getCachedMinTimeIntervalBetweenSamplesMillis()) {
-            int count = mSkippedSampleCountLocked.get(callType, /*valueOfKeyIfNotFound=*/ 0);
-            ++count;
-            mSkippedSampleCountLocked.put(callType, count);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Checks if the stats should be "sampled"
-     *
-     * @param samplingInterval sampling interval
-     * @return if the stats should be sampled
-     */
-    private boolean shouldSample(int samplingInterval) {
-        if (samplingInterval <= 0) {
-            return false;
-        }
-
-        return mRng.nextInt((int) samplingInterval) == 0;
-    }
-
-    /**
-     * Finds the UID of the {@code packageName}. Returns {@link Process#INVALID_UID} if unable to
-     * find the UID.
-     */
-    @GuardedBy("mLock")
-    private int getPackageUidAsUserLocked(@NonNull String packageName) {
-        Integer packageUid = mPackageUidCacheLocked.get(packageName);
-        if (packageUid == null) {
-            packageUid = PackageUtil.getPackageUid(mUserContext, packageName);
-            if (packageUid != Process.INVALID_UID) {
-                mPackageUidCacheLocked.put(packageName, packageUid);
-            }
-        }
-        return packageUid;
-    }
-
-    /** Returns sampling ratio for stats type specified form {@link AppSearchConfig}. */
-    private int getSamplingIntervalFromConfig(@CallStats.CallType int statsType) {
-        switch (statsType) {
-            case CallStats.CALL_TYPE_PUT_DOCUMENTS:
-            case CallStats.CALL_TYPE_GET_DOCUMENTS:
-            case CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID:
-            case CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH:
-                return mConfig.getCachedSamplingIntervalForBatchCallStats();
-            case CallStats.CALL_TYPE_PUT_DOCUMENT:
-                return mConfig.getCachedSamplingIntervalForPutDocumentStats();
-            case CallStats.CALL_TYPE_INITIALIZE:
-                return mConfig.getCachedSamplingIntervalForInitializeStats();
-            case CallStats.CALL_TYPE_SEARCH:
-                return mConfig.getCachedSamplingIntervalForSearchStats();
-            case CallStats.CALL_TYPE_GLOBAL_SEARCH:
-                return mConfig.getCachedSamplingIntervalForGlobalSearchStats();
-            case CallStats.CALL_TYPE_OPTIMIZE:
-                return mConfig.getCachedSamplingIntervalForOptimizeStats();
-            case CallStats.CALL_TYPE_UNKNOWN:
-            case CallStats.CALL_TYPE_SET_SCHEMA:
-            case CallStats.CALL_TYPE_GET_DOCUMENT:
-            case CallStats.CALL_TYPE_REMOVE_DOCUMENT_BY_ID:
-            case CallStats.CALL_TYPE_FLUSH:
-            case CallStats.CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH:
-                // TODO(b/173532925) Some of them above will have dedicated sampling ratio config
-            default:
-                return mConfig.getCachedSamplingIntervalDefault();
-        }
-    }
-
-    //
-    // Functions below are used for tests only
-    //
-    @VisibleForTesting
-    @GuardedBy("mLock")
-    void setLastPushTimeMillisLocked(long lastPushElapsedTimeMillis) {
-        mLastPushTimeMillisLocked = lastPushElapsedTimeMillis;
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/StatsCollector.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/StatsCollector.java
deleted file mode 100644
index dd56739..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/StatsCollector.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.stats;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.app.StatsManager;
-import android.content.Context;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.StatsEvent;
-
-import com.android.server.appsearch.AppSearchUserInstance;
-import com.android.server.appsearch.AppSearchUserInstanceManager;
-
-import com.google.android.icing.proto.DocumentStorageInfoProto;
-import com.google.android.icing.proto.IndexStorageInfoProto;
-import com.google.android.icing.proto.SchemaStoreStorageInfoProto;
-import com.google.android.icing.proto.StorageInfoProto;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Implements statsd pullers for AppSearch.
- *
- * <p>This class registers pullers to statsd, which will be called once a day to obtain AppSearch
- * statistics that cannot be sent to statsd in real time by {@link PlatformLogger}.
- *
- * @hide
- */
-public final class StatsCollector implements StatsManager.StatsPullAtomCallback {
-    private static final String TAG = "AppSearchStatsCollector";
-
-    private static volatile StatsCollector sStatsCollector;
-    private final StatsManager mStatsManager;
-
-    /**
-     * Gets an instance of {@link StatsCollector} to be used.
-     *
-     * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
-     * existing instance will be returned.
-     */
-    @NonNull
-    public static StatsCollector getInstance(@NonNull Context context,
-            @NonNull Executor executor) {
-        Objects.requireNonNull(context);
-        Objects.requireNonNull(executor);
-        if (sStatsCollector == null) {
-            synchronized (StatsCollector.class) {
-                if (sStatsCollector == null) {
-                    sStatsCollector = new StatsCollector(context, executor);
-                }
-            }
-        }
-        return sStatsCollector;
-    }
-
-    private StatsCollector(@NonNull Context context, @NonNull Executor executor) {
-        mStatsManager = context.getSystemService(StatsManager.class);
-        if (mStatsManager != null) {
-            registerAtom(AppSearchStatsLog.APP_SEARCH_STORAGE_INFO, /*policy=*/ null, executor);
-            Log.d(TAG, "atoms registered");
-        } else {
-            Log.e(TAG, "could not get StatsManager, atoms not registered");
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @return {@link StatsManager#PULL_SUCCESS} with list of atoms (potentially empty) if pull
-     * succeeded, {@link StatsManager#PULL_SKIP} if pull was too frequent or atom ID is
-     * unexpected.
-     */
-    @Override
-    public int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
-        Objects.requireNonNull(data);
-        switch (atomTag) {
-            case AppSearchStatsLog.APP_SEARCH_STORAGE_INFO:
-                return pullAppSearchStorageInfo(data);
-            default:
-                Log.e(TAG, "unexpected atom ID " + atomTag);
-                return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private static int pullAppSearchStorageInfo(@NonNull List<StatsEvent> data) {
-        AppSearchUserInstanceManager userInstanceManager =
-                AppSearchUserInstanceManager.getInstance();
-        List<UserHandle> userHandles = userInstanceManager.getAllUserHandles();
-        for (int i = 0; i < userHandles.size(); i++) {
-            UserHandle userHandle = userHandles.get(i);
-            try {
-                AppSearchUserInstance userInstance = userInstanceManager.getUserInstance(
-                        userHandle);
-                StorageInfoProto storageInfoProto =
-                        userInstance.getAppSearchImpl().getRawStorageInfoProto();
-                data.add(buildStatsEvent(userHandle.getIdentifier(), storageInfoProto));
-            } catch (Throwable t) {
-                Log.e(TAG,
-                        "Failed to pull the storage info for user " + userHandle.toString(),
-                        t);
-            }
-        }
-
-        // Skip the report if there is no data.
-        if (data.isEmpty()) {
-            return StatsManager.PULL_SKIP;
-        }
-
-        return StatsManager.PULL_SUCCESS;
-    }
-
-    /**
-     * Registers and configures the callback for the pulled atom.
-     *
-     * @param atomId   The id of the atom
-     * @param policy   Optional metadata specifying the timeout, cool down time etc. statsD would
-     *                 use default values if it is null
-     * @param executor The executor in which to run the callback
-     */
-    private void registerAtom(int atomId, @Nullable StatsManager.PullAtomMetadata policy,
-            @NonNull Executor executor) {
-        mStatsManager.setPullAtomCallback(atomId, policy, executor, /*callback=*/this);
-    }
-
-    private static StatsEvent buildStatsEvent(@UserIdInt int userId,
-            @NonNull StorageInfoProto storageInfoProto) {
-        return AppSearchStatsLog.buildStatsEvent(
-                AppSearchStatsLog.APP_SEARCH_STORAGE_INFO,
-                userId,
-                storageInfoProto.getTotalStorageSize(),
-                getDocumentStorageInfoBytes(storageInfoProto.getDocumentStorageInfo()),
-                getSchemaStoreStorageInfoBytes(storageInfoProto.getSchemaStoreStorageInfo()),
-                getIndexStorageInfoBytes(storageInfoProto.getIndexStorageInfo()));
-    }
-
-    private static byte[] getDocumentStorageInfoBytes(
-            @NonNull DocumentStorageInfoProto proto) {
-        // Make sure we only log the fields defined in the atom in case new fields are added in
-        // IcingLib
-        DocumentStorageInfoProto.Builder builder = DocumentStorageInfoProto.newBuilder();
-        builder.setNumAliveDocuments(proto.getNumAliveDocuments())
-                .setNumDeletedDocuments(proto.getNumDeletedDocuments())
-                .setNumExpiredDocuments(proto.getNumExpiredDocuments())
-                .setDocumentStoreSize(proto.getDocumentStoreSize())
-                .setDocumentLogSize(proto.getDocumentLogSize())
-                .setKeyMapperSize(proto.getKeyMapperSize())
-                .setDocumentIdMapperSize(proto.getDocumentIdMapperSize())
-                .setScoreCacheSize(proto.getScoreCacheSize())
-                .setFilterCacheSize(proto.getFilterCacheSize())
-                .setCorpusMapperSize(proto.getCorpusMapperSize())
-                .setCorpusScoreCacheSize(proto.getCorpusScoreCacheSize())
-                .setNamespaceIdMapperSize(proto.getNamespaceIdMapperSize())
-                .setNumNamespaces(proto.getNumNamespaces());
-        return builder.build().toByteArray();
-    }
-
-    private static byte[] getSchemaStoreStorageInfoBytes(
-            @NonNull SchemaStoreStorageInfoProto proto) {
-        // Make sure we only log the fields defined in the atom in case new fields are added in
-        // IcingLib
-        SchemaStoreStorageInfoProto.Builder builder = SchemaStoreStorageInfoProto.newBuilder();
-        builder.setSchemaStoreSize(proto.getSchemaStoreSize())
-                .setNumSchemaTypes(proto.getNumSchemaTypes())
-                .setNumTotalSections(proto.getNumTotalSections())
-                .setNumSchemaTypesSectionsExhausted(proto.getNumSchemaTypesSectionsExhausted());
-        return builder.build().toByteArray();
-    }
-
-    private static byte[] getIndexStorageInfoBytes(
-            @NonNull IndexStorageInfoProto proto) {
-        // Make sure we only log the fields defined in the atom in case new fields are added in
-        // IcingLib
-        IndexStorageInfoProto.Builder builder = IndexStorageInfoProto.newBuilder();
-        builder.setIndexSize(proto.getIndexSize())
-                .setLiteIndexLexiconSize(proto.getLiteIndexLexiconSize())
-                .setLiteIndexHitBufferSize(proto.getLiteIndexHitBufferSize())
-                .setMainIndexLexiconSize(proto.getMainIndexLexiconSize())
-                .setMainIndexStorageSize(proto.getMainIndexStorageSize())
-                .setMainIndexBlockSize(proto.getMainIndexBlockSize())
-                .setNumBlocks(proto.getNumBlocks())
-                .setMinFreeFraction(proto.getMinFreeFraction());
-        return builder.build().toByteArray();
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java b/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java
deleted file mode 100644
index 714ffb6..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.util;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Process;
-
-/**
- * Utilities for interacting with {@link android.content.pm.PackageManager},
- * {@link android.os.UserHandle}, and other parts of dealing with apps and binder.
- *
- * @hide
- */
-public class PackageUtil {
-    private PackageUtil() {}
-
-    /**
-     * Finds the UID of the {@code packageName} in the given {@code context}. Returns
-     * {@link Process#INVALID_UID} if unable to find the UID.
-     */
-    public static int getPackageUid(@NonNull Context context, @NonNull String packageName) {
-        try {
-            return context.getPackageManager().getPackageUid(packageName, /*flags=*/ 0);
-        } catch (PackageManager.NameNotFoundException e) {
-            return Process.INVALID_UID;
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotDisplayedBySystemMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotDisplayedBySystemMap.java
deleted file mode 100644
index 95905af..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotDisplayedBySystemMap.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.visibilitystore;
-
-import android.annotation.NonNull;
-import android.util.ArrayMap;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Stores information about what types are hidden from platform surfaces through the
- * {@link android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem} API.
- *
- * This object is not thread safe.
- */
-class NotDisplayedBySystemMap {
-    /**
-     * Maps packages to databases to the set of prefixed schemas that are platform-hidden within
-     * that database.
-     */
-    private final Map<String, Map<String, Set<String>>> mMap = new ArrayMap<>();
-
-    /**
-     * Sets the prefixed schemas that are opted out of platform surfacing for the database.
-     *
-     * <p>Any existing mappings for this prefix are overwritten.
-     */
-    public void setNotDisplayedBySystem(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Set<String> prefixedSchemas) {
-        Map<String, Set<String>> databaseToSchemas = mMap.get(packageName);
-        if (databaseToSchemas == null) {
-            databaseToSchemas = new ArrayMap<>();
-            mMap.put(packageName, databaseToSchemas);
-        }
-        databaseToSchemas.put(databaseName, prefixedSchemas);
-    }
-
-    /**
-     * Returns whether the given prefixed schema is platform surfaceable (has not opted out) in the
-     * given database.
-     */
-    public boolean isSchemaDisplayedBySystem(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String prefixedSchema) {
-        Map<String, Set<String>> databaseToSchemaType = mMap.get(packageName);
-        if (databaseToSchemaType == null) {
-            // No opt-outs for this package
-            return true;
-        }
-        Set<String> schemaTypes = databaseToSchemaType.get(databaseName);
-        if (schemaTypes == null) {
-            // No opt-outs for this database
-            return true;
-        }
-        // Some schemas were opted out of being platform-surfaced. As long as this schema
-        // isn't one of those opt-outs, it's surfaceable.
-        return !schemaTypes.contains(prefixedSchema);
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java
deleted file mode 100644
index b010870..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.visibilitystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-
-/** Holds the visibility settings that apply to a package's databases. */
-class VisibilityDocument extends GenericDocument {
-    /** Schema type for documents that hold AppSearch's metadata, e.g. visibility settings */
-    public static final String SCHEMA_TYPE = "VisibilityType";
-
-    /**
-     * Property that holds the list of platform-hidden schemas, as part of the visibility settings.
-     */
-    private static final String NOT_DISPLAYED_BY_SYSTEM_PROPERTY = "notPlatformSurfaceable";
-
-    /** Property that holds nested documents of package accessible schemas. */
-    private static final String VISIBLE_TO_PACKAGES_PROPERTY = "packageAccessible";
-
-    /**
-     * Schema for the VisibilityStore's documents.
-     *
-     * <p>NOTE: If you update this, also update
-     * {@link com.android.server.appsearch.external.localstorage.VisibilityStore#SCHEMA_VERSION}
-     */
-    public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
-            .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
-                    NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
-                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
-                    .build())
-            .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
-                    VISIBLE_TO_PACKAGES_PROPERTY, VisibleToPackagesDocument.SCHEMA_TYPE)
-                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
-                    .build())
-            .build();
-
-    public VisibilityDocument(@NonNull GenericDocument genericDocument) {
-        super(genericDocument);
-    }
-
-    @Nullable
-    public String[] getNotDisplayedBySystem() {
-        return getPropertyStringArray(NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
-    }
-
-    @Nullable
-    public GenericDocument[] getVisibleToPackages() {
-        return getPropertyDocumentArray(VISIBLE_TO_PACKAGES_PROPERTY);
-    }
-
-    /** Builder for {@link VisibilityDocument}. */
-    public static class Builder extends GenericDocument.Builder<VisibilityDocument.Builder> {
-        public Builder(@NonNull String namespace, @NonNull String id) {
-            super(namespace, id, SCHEMA_TYPE);
-        }
-
-        /** Sets which prefixed schemas have opted out of platform surfacing. */
-        @NonNull
-        public Builder setNotDisplayedBySystem(@NonNull String[] notDisplayedBySystemSchemas) {
-            return setPropertyString(NOT_DISPLAYED_BY_SYSTEM_PROPERTY, notDisplayedBySystemSchemas);
-        }
-
-        /** Sets which prefixed schemas have configured package access. */
-        @NonNull
-        public Builder setVisibleToPackages(
-                @NonNull VisibleToPackagesDocument[] visibleToPackagesDocuments) {
-            return setPropertyDocument(VISIBLE_TO_PACKAGES_PROPERTY, visibleToPackagesDocuments);
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java
deleted file mode 100644
index ce142d6..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.visibilitystore;
-
-import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetSchemaResponse;
-import android.app.appsearch.PackageIdentifier;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
-import com.android.server.appsearch.util.PackageUtil;
-
-import com.google.android.icing.proto.PersistType;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Manages any visibility settings for all the package's databases that AppSearchImpl knows about.
- * Persists the visibility settings and reloads them on initialization.
- *
- * <p>The VisibilityStore creates a document for each package's databases. This document holds the
- * visibility settings that apply to that package's database. The VisibilityStore also creates a
- * schema for these documents and has its own package and database so that its data doesn't
- * interfere with any clients' data. It persists the document and schema through AppSearchImpl.
- *
- * <p>These visibility settings are used to ensure AppSearch queries respect the clients' settings
- * on who their data is visible to.
- *
- * <p>This class doesn't handle any locking itself. Its callers should handle the locking at a
- * higher level.
- *
- * @hide
- */
-public class VisibilityStoreImpl implements VisibilityStore {
-    /** Version for the visibility schema */
-    private static final int SCHEMA_VERSION = 0;
-
-    /** Namespace of documents that contain visibility settings */
-    private static final String NAMESPACE = "";
-
-    /** Prefix to add to all visibility document ids. IcingSearchEngine doesn't allow empty ids. */
-    private static final String ID_PREFIX = "uri:";
-
-    private final AppSearchImpl mAppSearchImpl;
-
-    // Context of the user that the call is being made as.
-    private final Context mUserContext;
-
-    /** Stores the schemas that are platform-hidden. All values are prefixed. */
-    private final NotDisplayedBySystemMap mNotDisplayedBySystemMap = new NotDisplayedBySystemMap();
-
-    /** Stores the schemas that are visible to 3p packages. All values are prefixed. */
-    private final VisibleToPackagesMap mVisibleToPackagesMap = new VisibleToPackagesMap();
-
-    /**
-     * Creates and initializes VisibilityStore.
-     *
-     * @param appSearchImpl AppSearchImpl instance
-     * @param userContext Context of the user that the call is being made as
-     */
-    @NonNull
-    public static VisibilityStoreImpl create(
-            @NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
-            throws AppSearchException {
-        return new VisibilityStoreImpl(appSearchImpl, userContext);
-    }
-
-    private VisibilityStoreImpl(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
-            throws AppSearchException {
-        mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
-        mUserContext = Objects.requireNonNull(userContext);
-
-        GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(PACKAGE_NAME, DATABASE_NAME);
-        boolean hasVisibilityType = false;
-        boolean hasVisibleToPackagesType = false;
-        for (AppSearchSchema schema : getSchemaResponse.getSchemas()) {
-            if (schema.getSchemaType().equals(VisibilityDocument.SCHEMA_TYPE)) {
-                hasVisibilityType = true;
-            } else if (schema.getSchemaType().equals(VisibleToPackagesDocument.SCHEMA_TYPE)) {
-                hasVisibleToPackagesType = true;
-            }
-
-            if (hasVisibilityType && hasVisibleToPackagesType) {
-                // Found both our types, can exit early.
-                break;
-            }
-        }
-        if (!hasVisibilityType || !hasVisibleToPackagesType) {
-            // Schema type doesn't exist yet. Add it.
-            mAppSearchImpl.setSchema(
-                    PACKAGE_NAME,
-                    DATABASE_NAME,
-                    Arrays.asList(VisibilityDocument.SCHEMA, VisibleToPackagesDocument.SCHEMA),
-                    /*visibilityStore=*/ null,  // Avoid recursive calls
-                    /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                    /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                    /*forceOverride=*/ false,
-                    /*version=*/ SCHEMA_VERSION);
-        }
-
-        // Populate visibility settings set
-        for (Map.Entry<String, Set<String>> entry :
-                mAppSearchImpl.getPackageToDatabases().entrySet()) {
-            String packageName = entry.getKey();
-            if (packageName.equals(PACKAGE_NAME)) {
-                continue; // Our own package. Skip.
-            }
-
-            for (String databaseName : entry.getValue()) {
-                VisibilityDocument visibilityDocument;
-                try {
-                    // Note: We use the other clients' prefixed names as ids
-                    visibilityDocument =
-                            new VisibilityDocument(
-                                    mAppSearchImpl.getDocument(
-                                            PACKAGE_NAME,
-                                            DATABASE_NAME,
-                                            NAMESPACE,
-                                            /*id=*/ getVisibilityDocumentId(
-                                                    packageName, databaseName),
-                                            /*typePropertyPaths=*/ Collections.emptyMap()));
-                } catch (AppSearchException e) {
-                    if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) {
-                        // TODO(b/172068212): This indicates some desync error. We were expecting a
-                        //  document, but didn't find one. Should probably reset AppSearch instead
-                        //  of ignoring it.
-                        continue;
-                    }
-                    // Otherwise, this is some other error we should pass up.
-                    throw e;
-                }
-
-                // Update platform visibility settings
-                String[] notDisplayedBySystemSchemas = visibilityDocument.getNotDisplayedBySystem();
-                if (notDisplayedBySystemSchemas != null) {
-                    mNotDisplayedBySystemMap.setNotDisplayedBySystem(
-                            packageName,
-                            databaseName,
-                            new ArraySet<>(notDisplayedBySystemSchemas));
-                }
-
-                // Update 3p package visibility settings
-                Map<String, Set<PackageIdentifier>> schemaToPackageIdentifierMap = new ArrayMap<>();
-                GenericDocument[] visibleToPackagesDocuments =
-                        visibilityDocument.getVisibleToPackages();
-                if (visibleToPackagesDocuments != null) {
-                    for (int i = 0; i < visibleToPackagesDocuments.length; i++) {
-                        VisibleToPackagesDocument visibleToPackagesDocument =
-                                new VisibleToPackagesDocument(visibleToPackagesDocuments[i]);
-                        PackageIdentifier packageIdentifier =
-                                visibleToPackagesDocument.getPackageIdentifier();
-                        String prefixedSchema = visibleToPackagesDocument.getAccessibleSchemaType();
-                        Set<PackageIdentifier> packageIdentifiers =
-                                schemaToPackageIdentifierMap.get(prefixedSchema);
-                        if (packageIdentifiers == null) {
-                            packageIdentifiers = new ArraySet<>();
-                        }
-                        packageIdentifiers.add(packageIdentifier);
-                        schemaToPackageIdentifierMap.put(prefixedSchema, packageIdentifiers);
-                    }
-                }
-                mVisibleToPackagesMap.setVisibleToPackages(
-                        packageName, databaseName, schemaToPackageIdentifierMap);
-            }
-        }
-    }
-
-    @Override
-    public void setVisibility(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Set<String> schemasNotDisplayedBySystem,
-            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
-            throws AppSearchException {
-        Objects.requireNonNull(packageName);
-        Objects.requireNonNull(databaseName);
-        Objects.requireNonNull(schemasNotDisplayedBySystem);
-        Objects.requireNonNull(schemasVisibleToPackages);
-
-        // Persist the document
-        VisibilityDocument.Builder visibilityDocument =
-                new VisibilityDocument.Builder(
-                        NAMESPACE, /*id=*/ getVisibilityDocumentId(packageName, databaseName));
-        if (!schemasNotDisplayedBySystem.isEmpty()) {
-            visibilityDocument.setNotDisplayedBySystem(
-                    schemasNotDisplayedBySystem.toArray(new String[0]));
-        }
-
-        Map<String, Set<PackageIdentifier>> schemaToPackageIdentifierMap = new ArrayMap<>();
-        List<VisibleToPackagesDocument> visibleToPackagesDocuments = new ArrayList<>();
-        for (Map.Entry<String, List<PackageIdentifier>> entry :
-                schemasVisibleToPackages.entrySet()) {
-            for (int i = 0; i < entry.getValue().size(); i++) {
-                VisibleToPackagesDocument visibleToPackagesDocument =
-                        new VisibleToPackagesDocument.Builder(NAMESPACE, /*id=*/ "")
-                                .setAccessibleSchemaType(entry.getKey())
-                                .setPackageIdentifier(entry.getValue().get(i))
-                                .build();
-                visibleToPackagesDocuments.add(visibleToPackagesDocument);
-            }
-            schemaToPackageIdentifierMap.put(entry.getKey(), new ArraySet<>(entry.getValue()));
-        }
-        if (!visibleToPackagesDocuments.isEmpty()) {
-            visibilityDocument.setVisibleToPackages(
-                    visibleToPackagesDocuments.toArray(new VisibleToPackagesDocument[0]));
-        }
-
-        mAppSearchImpl.putDocument(
-                PACKAGE_NAME, DATABASE_NAME, visibilityDocument.build(), /*logger=*/ null);
-        // Now that the visibility document has been written. Persist the newly written data.
-        mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
-
-        // Update derived data structures.
-        mNotDisplayedBySystemMap.setNotDisplayedBySystem(
-                packageName, databaseName, schemasNotDisplayedBySystem);
-        mVisibleToPackagesMap.setVisibleToPackages(
-                packageName, databaseName, schemaToPackageIdentifierMap);
-    }
-
-    /**
-     * Checks whether the given package has access to system-surfaceable schemas.
-     *
-     * @param callerPackageName Package name of the caller.
-     */
-    public boolean doesCallerHaveSystemAccess(@NonNull String callerPackageName) {
-        Objects.requireNonNull(callerPackageName);
-        return mUserContext.getPackageManager()
-                .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, callerPackageName)
-                == PackageManager.PERMISSION_GRANTED;
-    }
-
-    @Override
-    public boolean isSchemaSearchableByCaller(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String prefixedSchema,
-            int callerUid,
-            boolean callerHasSystemAccess) {
-        Objects.requireNonNull(packageName);
-        Objects.requireNonNull(databaseName);
-        Objects.requireNonNull(prefixedSchema);
-
-        if (packageName.equals(PACKAGE_NAME)) {
-            return false; // VisibilityStore schemas are for internal bookkeeping.
-        }
-
-        if (callerHasSystemAccess
-                && mNotDisplayedBySystemMap.isSchemaDisplayedBySystem(
-                packageName, databaseName, prefixedSchema)) {
-            return true;
-        }
-
-        // May not be platform surfaceable, but might still be accessible through 3p access.
-        return isSchemaVisibleToPackages(packageName, databaseName, prefixedSchema, callerUid);
-    }
-
-    /**
-     * Returns whether the schema is accessible by the {@code callerUid}. Checks that the callerUid
-     * has one of the allowed PackageIdentifier's package. And if so, that the package also has the
-     * matching certificate.
-     *
-     * <p>This supports packages that have certificate rotation. As long as the specified
-     * certificate was once used to sign the package, the package will still be granted access. This
-     * does not handle packages that have been signed by multiple certificates.
-     */
-    private boolean isSchemaVisibleToPackages(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String prefixedSchema,
-            int callerUid) {
-        Set<PackageIdentifier> packageIdentifiers =
-                mVisibleToPackagesMap.getAccessiblePackages(
-                        packageName, databaseName, prefixedSchema);
-        if (packageIdentifiers.isEmpty()) {
-            return false;
-        }
-        for (PackageIdentifier packageIdentifier : packageIdentifiers) {
-            // TODO(b/169883602): Consider caching the UIDs of packages. Looking this up in the
-            // package manager could be costly. We would also need to update the cache on
-            // package-removals.
-
-            // 'callerUid' is the uid of the caller. The 'user' doesn't have to be the same one as
-            // the callerUid since clients can createContextAsUser with some other user, and then
-            // make calls to us. So just check if the appId portion of the uid is the same. This is
-            // essentially UserHandle.isSameApp, but that's not a system API for us to use.
-            int callerAppId = UserHandle.getAppId(callerUid);
-            int packageUid =
-                    PackageUtil.getPackageUid(mUserContext, packageIdentifier.getPackageName());
-            int userAppId = UserHandle.getAppId(packageUid);
-            if (callerAppId != userAppId) {
-                continue;
-            }
-
-            // Check that the package also has the matching certificate
-            if (mUserContext
-                    .getPackageManager()
-                    .hasSigningCertificate(
-                            packageIdentifier.getPackageName(),
-                            packageIdentifier.getSha256Certificate(),
-                            PackageManager.CERT_INPUT_SHA256)) {
-                // The caller has the right package name and right certificate!
-                return true;
-            }
-        }
-        // If we can't verify the schema is package accessible, default to no access.
-        return false;
-    }
-
-    /**
-     * Adds a prefix to create a visibility store document's id.
-     *
-     * @param packageName Package to which the visibility doc refers
-     * @param databaseName Database to which the visibility doc refers
-     * @return Prefixed id
-     */
-    @NonNull
-    private static String getVisibilityDocumentId(
-            @NonNull String packageName, @NonNull String databaseName) {
-        return ID_PREFIX + PrefixUtil.createPrefix(packageName, databaseName);
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesDocument.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesDocument.java
deleted file mode 100644
index 8d50339..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesDocument.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.visibilitystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.PackageIdentifier;
-
-/**
- * Holds configuration about a package+cert that can access a schema.
- *
- * @see android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage
- */
-class VisibleToPackagesDocument extends GenericDocument {
-    /** Schema type for nested documents that hold package accessible information. */
-    public static final String SCHEMA_TYPE = "PackageAccessibleType";
-
-    /** Property that holds the package name that can access a schema. */
-    private static final String PACKAGE_NAME_PROPERTY = "packageName";
-
-    /** Property that holds the SHA 256 certificate of the app that can access a schema. */
-    private static final String SHA_256_CERT_PROPERTY = "sha256Cert";
-
-    /** Property that holds the prefixed schema type that is accessible by some package. */
-    private static final String ACCESSIBLE_SCHEMA_PROPERTY = "accessibleSchema";
-
-    /**
-     * Schema for package accessible documents, these will be nested in a top-level
-     * {@link VisibilityDocument}.
-     *
-     * <p>NOTE: If you update this, also update
-     * {@link com.android.server.appsearch.external.localstorage.VisibilityStore#SCHEMA_VERSION}
-     */
-    public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
-            .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
-                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                    .build())
-            .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(SHA_256_CERT_PROPERTY)
-                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                    .build())
-            .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
-                    ACCESSIBLE_SCHEMA_PROPERTY)
-                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                    .build())
-            .build();
-
-    VisibleToPackagesDocument(@NonNull GenericDocument genericDocument) {
-        super(genericDocument);
-    }
-
-    @Nullable
-    public String getAccessibleSchemaType() {
-        return getPropertyString(ACCESSIBLE_SCHEMA_PROPERTY);
-    }
-
-    /** Gets which package is able to access {@link #getAccessibleSchemaType} */
-    @NonNull
-    public PackageIdentifier getPackageIdentifier() {
-        String packageName = getPropertyString(PACKAGE_NAME_PROPERTY);
-        byte[] sha256Cert = getPropertyBytes(SHA_256_CERT_PROPERTY);
-        return new PackageIdentifier(packageName, sha256Cert);
-    }
-
-    /** Builder for {@link VisibleToPackagesDocument} instances. */
-    public static class Builder extends GenericDocument.Builder<VisibleToPackagesDocument.Builder> {
-        Builder(@NonNull String namespace, @NonNull String id) {
-            super(namespace, id, SCHEMA_TYPE);
-        }
-
-        /** Sets which prefixed schema type is accessible by the package */
-        @NonNull
-        public Builder setAccessibleSchemaType(@NonNull String schemaType) {
-            return setPropertyString(ACCESSIBLE_SCHEMA_PROPERTY, schemaType);
-        }
-
-        /** Sets which package is able to access the {@link #setAccessibleSchemaType}. */
-        @NonNull
-        public Builder setPackageIdentifier(@NonNull PackageIdentifier packageIdentifier) {
-            return setPropertyString(PACKAGE_NAME_PROPERTY, packageIdentifier.getPackageName())
-                    .setPropertyBytes(SHA_256_CERT_PROPERTY,
-                            packageIdentifier.getSha256Certificate());
-        }
-
-        @Override
-        @NonNull
-        public VisibleToPackagesDocument build() {
-            return new VisibleToPackagesDocument(super.build());
-        }
-    }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesMap.java
deleted file mode 100644
index e2b51a7..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesMap.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch.visibilitystore;
-
-import android.annotation.NonNull;
-import android.app.appsearch.PackageIdentifier;
-import android.util.ArrayMap;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Stores information about what types are accessible to which packages through the
- * {@link android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage} API.
- *
- * This object is not thread safe.
- */
-class VisibleToPackagesMap {
-    /**
-     * Maps packages to databases to prefixed schemas to PackageIdentifiers that have access to that
-     * schema.
-     */
-    private final Map<String, Map<String, Map<String, Set<PackageIdentifier>>>> mMap =
-            new ArrayMap<>();
-
-    /**
-     * Sets the prefixed schemas that have package visibility in the given database.
-     *
-     * <p>Any existing mappings for this prefix are overwritten.
-     */
-    public void setVisibleToPackages(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Map<String, Set<PackageIdentifier>> schemaToPackageIdentifier) {
-        Map<String, Map<String, Set<PackageIdentifier>>> databaseToSchemaTypeToVisibility =
-                mMap.get(packageName);
-        if (databaseToSchemaTypeToVisibility == null) {
-            databaseToSchemaTypeToVisibility = new ArrayMap<>();
-            mMap.put(packageName, databaseToSchemaTypeToVisibility);
-        }
-        databaseToSchemaTypeToVisibility.put(databaseName, schemaToPackageIdentifier);
-    }
-
-    /**
-     * Returns the set of all {@link android.app.appsearch.PackageIdentifier}s which can access the
-     * given schema type.
-     *
-     * <p>If no such settings exist, returns the empty set.
-     */
-    @NonNull
-    public Set<PackageIdentifier> getAccessiblePackages(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String prefixedSchema) {
-        Map<String, Map<String, Set<PackageIdentifier>>> databaseToSchemaTypeToVisibility =
-                mMap.get(packageName);
-        if (databaseToSchemaTypeToVisibility == null) {
-            return Collections.emptySet();
-        }
-        Map<String, Set<PackageIdentifier>> schemaTypeToVisibility =
-                databaseToSchemaTypeToVisibility.get(databaseName);
-        if (schemaTypeToVisibility == null) {
-            return Collections.emptySet();
-        }
-        Set<PackageIdentifier> accessiblePackages = schemaTypeToVisibility.get(prefixedSchema);
-        if (accessiblePackages == null) {
-            return Collections.emptySet();
-        }
-        return accessiblePackages;
-    }
-}
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
deleted file mode 100644
index a81d7d80..0000000
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ /dev/null
@@ -1 +0,0 @@
-Ie04f1ecc033faae8085afcb51eb9e40a298998d5
diff --git a/apex/appsearch/testing/Android.bp b/apex/appsearch/testing/Android.bp
deleted file mode 100644
index 5407cb4..0000000
--- a/apex/appsearch/testing/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library {
-    name: "AppSearchTestUtils",
-    srcs: ["java/**/*.java"],
-    libs: [
-        "androidx.test.ext.junit",
-        "framework",
-        "framework-appsearch",
-        "guava",
-        "truth-prebuilt",
-    ],
-    visibility: [
-        "//frameworks/base/core/tests/coretests",
-        "//cts/hostsidetests/appsearch",
-        "//cts/tests:__subpackages__",
-        "//vendor:__subpackages__",
-    ],
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
deleted file mode 100644
index 71b4f36..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
+++ /dev/null
@@ -1,229 +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 com.android.server.appsearch.testing;
-
-import android.annotation.NonNull;
-import android.annotation.UserIdInt;
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSession;
-import android.app.appsearch.AppSearchSessionShim;
-import android.app.appsearch.BatchResultCallback;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByDocumentIdRequest;
-import android.app.appsearch.GetSchemaResponse;
-import android.app.appsearch.PutDocumentsRequest;
-import android.app.appsearch.RemoveByDocumentIdRequest;
-import android.app.appsearch.ReportUsageRequest;
-import android.app.appsearch.SearchResults;
-import android.app.appsearch.SearchResultsShim;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.SetSchemaRequest;
-import android.app.appsearch.SetSchemaResponse;
-import android.app.appsearch.StorageInfo;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-import android.os.UserHandle;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * This test class adapts the AppSearch Framework API to ListenableFuture, so it can be tested via
- * a consistent interface.
- * @hide
- */
-public class AppSearchSessionShimImpl implements AppSearchSessionShim {
-    private final AppSearchSession mAppSearchSession;
-    private final ExecutorService mExecutor;
-
-    /** Creates the SearchSessionShim with given SearchContext. */
-    @NonNull
-    public static ListenableFuture<AppSearchSessionShim> createSearchSession(
-            @NonNull AppSearchManager.SearchContext searchContext) {
-        Context context = ApplicationProvider.getApplicationContext();
-        return createSearchSession(context, searchContext, Executors.newCachedThreadPool());
-    }
-
-    /** Creates the SearchSessionShim with given SearchContext for the given user. */
-    @NonNull
-    public static ListenableFuture<AppSearchSessionShim> createSearchSession(
-            @NonNull AppSearchManager.SearchContext searchContext, @UserIdInt int userId) {
-        Context context = ApplicationProvider.getApplicationContext()
-                .createContextAsUser(new UserHandle(userId), /*flags=*/ 0);
-        return createSearchSession(context, searchContext, Executors.newCachedThreadPool());
-    }
-
-    /**  Creates the SearchSession with given Context and ExecutorService. */
-    @NonNull
-    public static ListenableFuture<AppSearchSessionShim> createSearchSession(
-            @NonNull Context context,
-            @NonNull AppSearchManager.SearchContext searchContext,
-            @NonNull ExecutorService executor) {
-        AppSearchManager appSearchManager = context.getSystemService(AppSearchManager.class);
-        SettableFuture<AppSearchResult<AppSearchSession>> future = SettableFuture.create();
-        appSearchManager.createSearchSession(searchContext, executor, future::set);
-        return Futures.transform(
-                future,
-                instance -> new AppSearchSessionShimImpl(instance.getResultValue(), executor),
-                executor);
-    }
-
-    private AppSearchSessionShimImpl(
-            @NonNull AppSearchSession session, @NonNull ExecutorService executor) {
-        mAppSearchSession = Objects.requireNonNull(session);
-        mExecutor = Objects.requireNonNull(executor);
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request) {
-        SettableFuture<AppSearchResult<SetSchemaResponse>> future = SettableFuture.create();
-        mAppSearchSession.setSchema(request, mExecutor, mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<GetSchemaResponse> getSchema() {
-        SettableFuture<AppSearchResult<GetSchemaResponse>> future = SettableFuture.create();
-        mAppSearchSession.getSchema(mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @NonNull
-    @Override
-    public ListenableFuture<Set<String>> getNamespaces() {
-        SettableFuture<AppSearchResult<Set<String>>> future = SettableFuture.create();
-        mAppSearchSession.getNamespaces(mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, Void>> put(
-            @NonNull PutDocumentsRequest request) {
-        SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
-        mAppSearchSession.put(
-                request, mExecutor, new BatchResultCallbackAdapter<>(future));
-        return future;
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
-            @NonNull GetByDocumentIdRequest request) {
-        SettableFuture<AppSearchBatchResult<String, GenericDocument>> future =
-                SettableFuture.create();
-        mAppSearchSession.getByDocumentId(
-                request, mExecutor, new BatchResultCallbackAdapter<>(future));
-        return future;
-    }
-
-    @Override
-    @NonNull
-    public SearchResultsShim search(
-            @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
-        SearchResults searchResults = mAppSearchSession.search(queryExpression, searchSpec);
-        return new SearchResultsShimImpl(searchResults, mExecutor);
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request) {
-        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
-        mAppSearchSession.reportUsage(request, mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, Void>> remove(
-            @NonNull RemoveByDocumentIdRequest request) {
-        SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
-        mAppSearchSession.remove(request, mExecutor, new BatchResultCallbackAdapter<>(future));
-        return future;
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<Void> remove(
-            @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
-        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
-        mAppSearchSession.remove(queryExpression, searchSpec, mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @NonNull
-    @Override
-    public ListenableFuture<StorageInfo> getStorageInfo() {
-        SettableFuture<AppSearchResult<StorageInfo>> future = SettableFuture.create();
-        mAppSearchSession.getStorageInfo(mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @Override
-    public void close() {
-        mAppSearchSession.close();
-    }
-
-    @Override
-    @NonNull
-    public ListenableFuture<Void> requestFlush() {
-        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
-        // The data in platform will be flushed by scheduled task. AppSearchSession won't do
-        // anything extra flush.
-        future.set(AppSearchResult.newSuccessfulResult(null));
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    private <T> ListenableFuture<T> transformResult(
-            @NonNull AppSearchResult<T> result) throws AppSearchException {
-        if (!result.isSuccess()) {
-            throw new AppSearchException(result.getResultCode(), result.getErrorMessage());
-        }
-        return Futures.immediateFuture(result.getResultValue());
-    }
-
-    private static final class BatchResultCallbackAdapter<K, V>
-            implements BatchResultCallback<K, V> {
-        private final SettableFuture<AppSearchBatchResult<K, V>> mFuture;
-
-        BatchResultCallbackAdapter(SettableFuture<AppSearchBatchResult<K, V>> future) {
-            mFuture = future;
-        }
-
-        @Override
-        public void onResult(AppSearchBatchResult<K, V> result) {
-            mFuture.set(result);
-        }
-
-        @Override
-        public void onSystemError(Throwable t) {
-            mFuture.setException(t);
-        }
-    }
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
deleted file mode 100644
index c35849d..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
+++ /dev/null
@@ -1,104 +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 com.android.server.appsearch.testing;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.GlobalSearchSession;
-import android.app.appsearch.GlobalSearchSessionShim;
-import android.app.appsearch.ReportSystemUsageRequest;
-import android.app.appsearch.SearchResults;
-import android.app.appsearch.SearchResultsShim;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
-import java.util.Objects;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * This test class adapts the AppSearch Framework API to ListenableFuture, so it can be tested via a
- * consistent interface.
- *
- * @hide
- */
-public class GlobalSearchSessionShimImpl implements GlobalSearchSessionShim {
-    private final GlobalSearchSession mGlobalSearchSession;
-    private final ExecutorService mExecutor;
-
-    @NonNull
-    public static ListenableFuture<GlobalSearchSessionShim> createGlobalSearchSession() {
-        return createGlobalSearchSession(ApplicationProvider.getApplicationContext());
-    }
-
-    /** Only for use when called from a non-instrumented context. */
-    @NonNull
-    public static ListenableFuture<GlobalSearchSessionShim> createGlobalSearchSession(
-            @NonNull Context context) {
-        AppSearchManager appSearchManager = context.getSystemService(AppSearchManager.class);
-        SettableFuture<AppSearchResult<GlobalSearchSession>> future = SettableFuture.create();
-        ExecutorService executor = Executors.newCachedThreadPool();
-        appSearchManager.createGlobalSearchSession(executor, future::set);
-        return Futures.transform(
-                future,
-                instance -> new GlobalSearchSessionShimImpl(instance.getResultValue(), executor),
-                executor);
-    }
-
-    private GlobalSearchSessionShimImpl(
-            @NonNull GlobalSearchSession session, @NonNull ExecutorService executor) {
-        mGlobalSearchSession = Objects.requireNonNull(session);
-        mExecutor = Objects.requireNonNull(executor);
-    }
-
-    @NonNull
-    @Override
-    public SearchResultsShim search(
-            @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
-        SearchResults searchResults = mGlobalSearchSession.search(queryExpression, searchSpec);
-        return new SearchResultsShimImpl(searchResults, mExecutor);
-    }
-
-    @NonNull
-    @Override
-    public ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request) {
-        SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
-        mGlobalSearchSession.reportSystemUsage(request, mExecutor, future::set);
-        return Futures.transformAsync(future, this::transformResult, mExecutor);
-    }
-
-    @Override
-    public void close() {
-        mGlobalSearchSession.close();
-    }
-
-    private <T> ListenableFuture<T> transformResult(
-            @NonNull AppSearchResult<T> result) throws AppSearchException {
-        if (!result.isSuccess()) {
-            throw new AppSearchException(result.getResultCode(), result.getErrorMessage());
-        }
-        return Futures.immediateFuture(result.getResultValue());
-    }
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java
deleted file mode 100644
index 72078f8..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java
+++ /dev/null
@@ -1,58 +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 com.android.server.appsearch.testing;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResults;
-import android.app.appsearch.SearchResultsShim;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * This test class adapts the AppSearch Framework API to ListenableFuture, so it can be tested via
- * a consistent interface.
- * @hide
- */
-public class SearchResultsShimImpl implements SearchResultsShim {
-    private final Executor mExecutor;
-    private final SearchResults mSearchResults;
-
-    SearchResultsShimImpl(@NonNull SearchResults searchResults, @NonNull Executor executor) {
-        mExecutor = Objects.requireNonNull(executor);
-        mSearchResults = Objects.requireNonNull(searchResults);
-    }
-
-    @NonNull
-    public ListenableFuture<List<SearchResult>> getNextPage() {
-        SettableFuture<AppSearchResult<List<SearchResult>>> future = SettableFuture.create();
-        mSearchResults.getNextPage(mExecutor, future::set);
-        return Futures.transform(future, AppSearchResult::getResultValue, mExecutor);
-    }
-
-    @Override
-    public void close() {
-        mSearchResults.close();
-    }
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java
deleted file mode 100644
index d28d4ac..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchEmail.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.testing;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.AppSearchSchema.PropertyConfig;
-import android.app.appsearch.AppSearchSchema.StringPropertyConfig;
-import android.app.appsearch.GenericDocument;
-
-/**
- * Encapsulates a {@link GenericDocument} that represent an email.
- *
- * <p>This class is a higher level implement of {@link GenericDocument}.
- */
-public class AppSearchEmail extends GenericDocument {
-    /** The name of the schema type for {@link AppSearchEmail} documents. */
-    public static final String SCHEMA_TYPE = "builtin:Email";
-
-    private static final String KEY_FROM = "from";
-    private static final String KEY_TO = "to";
-    private static final String KEY_CC = "cc";
-    private static final String KEY_BCC = "bcc";
-    private static final String KEY_SUBJECT = "subject";
-    private static final String KEY_BODY = "body";
-
-    public static final AppSearchSchema SCHEMA =
-            new AppSearchSchema.Builder(SCHEMA_TYPE)
-                    .addProperty(
-                            new StringPropertyConfig.Builder(KEY_FROM)
-                                    .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                    .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                    .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                    .build())
-                    .addProperty(
-                            new StringPropertyConfig.Builder(KEY_TO)
-                                    .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
-                                    .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                    .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                    .build())
-                    .addProperty(
-                            new StringPropertyConfig.Builder(KEY_CC)
-                                    .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
-                                    .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                    .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                    .build())
-                    .addProperty(
-                            new StringPropertyConfig.Builder(KEY_BCC)
-                                    .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
-                                    .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                    .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                    .build())
-                    .addProperty(
-                            new StringPropertyConfig.Builder(KEY_SUBJECT)
-                                    .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                    .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                    .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                    .build())
-                    .addProperty(
-                            new StringPropertyConfig.Builder(KEY_BODY)
-                                    .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                    .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                    .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                    .build())
-                    .build();
-
-    /**
-     * Creates a new {@link AppSearchEmail} from the contents of an existing {@link
-     * GenericDocument}.
-     *
-     * @param document The {@link GenericDocument} containing the email content.
-     */
-    public AppSearchEmail(@NonNull GenericDocument document) {
-        super(document);
-    }
-
-    /**
-     * Gets the from address of {@link AppSearchEmail}.
-     *
-     * @return The subject of {@link AppSearchEmail} or {@code null} if it's not been set yet.
-     */
-    @Nullable
-    public String getFrom() {
-        return getPropertyString(KEY_FROM);
-    }
-
-    /**
-     * Gets the destination addresses of {@link AppSearchEmail}.
-     *
-     * @return The destination addresses of {@link AppSearchEmail} or {@code null} if it's not been
-     *     set yet.
-     */
-    @Nullable
-    public String[] getTo() {
-        return getPropertyStringArray(KEY_TO);
-    }
-
-    /**
-     * Gets the CC list of {@link AppSearchEmail}.
-     *
-     * @return The CC list of {@link AppSearchEmail} or {@code null} if it's not been set yet.
-     */
-    @Nullable
-    public String[] getCc() {
-        return getPropertyStringArray(KEY_CC);
-    }
-
-    /**
-     * Gets the BCC list of {@link AppSearchEmail}.
-     *
-     * @return The BCC list of {@link AppSearchEmail} or {@code null} if it's not been set yet.
-     */
-    @Nullable
-    public String[] getBcc() {
-        return getPropertyStringArray(KEY_BCC);
-    }
-
-    /**
-     * Gets the subject of {@link AppSearchEmail}.
-     *
-     * @return The value subject of {@link AppSearchEmail} or {@code null} if it's not been set yet.
-     */
-    @Nullable
-    public String getSubject() {
-        return getPropertyString(KEY_SUBJECT);
-    }
-
-    /**
-     * Gets the body of {@link AppSearchEmail}.
-     *
-     * @return The body of {@link AppSearchEmail} or {@code null} if it's not been set yet.
-     */
-    @Nullable
-    public String getBody() {
-        return getPropertyString(KEY_BODY);
-    }
-
-    /** The builder class for {@link AppSearchEmail}. */
-    public static class Builder extends GenericDocument.Builder<Builder> {
-        /**
-         * Creates a new {@link Builder}
-         *
-         * @param namespace The namespace of the Email.
-         * @param id The ID of the Email.
-         */
-        public Builder(@NonNull String namespace, @NonNull String id) {
-            super(namespace, id, SCHEMA_TYPE);
-        }
-
-        /** Sets the from address of {@link AppSearchEmail} */
-        @NonNull
-        public Builder setFrom(@NonNull String from) {
-            return setPropertyString(KEY_FROM, from);
-        }
-
-        /** Sets the destination address of {@link AppSearchEmail} */
-        @NonNull
-        public Builder setTo(@NonNull String... to) {
-            return setPropertyString(KEY_TO, to);
-        }
-
-        /** Sets the CC list of {@link AppSearchEmail} */
-        @NonNull
-        public Builder setCc(@NonNull String... cc) {
-            return setPropertyString(KEY_CC, cc);
-        }
-
-        /** Sets the BCC list of {@link AppSearchEmail} */
-        @NonNull
-        public Builder setBcc(@NonNull String... bcc) {
-            return setPropertyString(KEY_BCC, bcc);
-        }
-
-        /** Sets the subject of {@link AppSearchEmail} */
-        @NonNull
-        public Builder setSubject(@NonNull String subject) {
-            return setPropertyString(KEY_SUBJECT, subject);
-        }
-
-        /** Sets the body of {@link AppSearchEmail} */
-        @NonNull
-        public Builder setBody(@NonNull String body) {
-            return setPropertyString(KEY_BODY, body);
-        }
-
-        /** Builds the {@link AppSearchEmail} object. */
-        @NonNull
-        @Override
-        public AppSearchEmail build() {
-            return new AppSearchEmail(super.build());
-        }
-    }
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
deleted file mode 100644
index 7b74578..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
+++ /dev/null
@@ -1,261 +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 android.annotation.NonNull;
-import android.annotation.SuppressLint;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.io.Closeable;
-import java.util.Set;
-
-/**
- * Provides a connection to a single AppSearch database.
- *
- * <p>An {@link AppSearchSessionShim} instance provides access to database operations such as
- * setting a schema, adding documents, and searching.
- *
- * <p>Instances of this interface are usually obtained from a storage implementation, e.g. {@code
- * AppSearchManager.createSearchSession()} or {@code PlatformStorage.createSearchSession()}.
- *
- * <p>All implementations of this interface must be thread safe.
- *
- * @see GlobalSearchSessionShim
- */
-public interface AppSearchSessionShim extends Closeable {
-
-    /**
-     * Sets the schema that represents the organizational structure of data within the AppSearch
-     * database.
-     *
-     * <p>Upon creating an {@link AppSearchSessionShim}, {@link #setSchema} should be called. If the
-     * schema needs to be updated, or it has not been previously set, then the provided schema will
-     * be saved and persisted to disk. Otherwise, {@link #setSchema} is handled efficiently as a
-     * no-op call.
-     *
-     * @param request the schema to set or update the AppSearch database to.
-     * @return a {@link ListenableFuture} which resolves to a {@link SetSchemaResponse} object.
-     */
-    @NonNull
-    ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request);
-
-    /**
-     * Retrieves the schema most recently successfully provided to {@link #setSchema}.
-     *
-     * @return The pending {@link GetSchemaResponse} of performing this operation.
-     */
-    // This call hits disk; async API prevents us from treating these calls as properties.
-    @SuppressLint("KotlinPropertyAccess")
-    @NonNull
-    ListenableFuture<GetSchemaResponse> getSchema();
-
-    /**
-     * Retrieves the set of all namespaces in the current database with at least one document.
-     *
-     * @return The pending result of performing this operation.
-     */
-    @NonNull
-    ListenableFuture<Set<String>> getNamespaces();
-
-    /**
-     * Indexes documents into the {@link AppSearchSessionShim} database.
-     *
-     * <p>Each {@link GenericDocument} object must have a {@code schemaType} field set to an {@link
-     * AppSearchSchema} type that has been previously registered by calling the {@link #setSchema}
-     * method.
-     *
-     * @param request containing documents to be indexed.
-     * @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
-     *     keys of the returned {@link AppSearchBatchResult} are the IDs of the input documents. The
-     *     values are either {@code null} if the corresponding document was successfully indexed, or
-     *     a failed {@link AppSearchResult} otherwise.
-     */
-    @NonNull
-    ListenableFuture<AppSearchBatchResult<String, Void>> put(@NonNull PutDocumentsRequest request);
-
-    /**
-     * Gets {@link GenericDocument} objects by document IDs in a namespace from the {@link
-     * AppSearchSessionShim} database.
-     *
-     * @param request a request containing a namespace and IDs to get documents for.
-     * @return A {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
-     *     keys of the {@link AppSearchBatchResult} represent the input document IDs from the {@link
-     *     GetByDocumentIdRequest} object. The values are either the corresponding {@link
-     *     GenericDocument} object for the ID on success, or an {@link AppSearchResult} object on
-     *     failure. For example, if an ID is not found, the value for that ID will be set to an
-     *     {@link AppSearchResult} object with result code: {@link
-     *     AppSearchResult#RESULT_NOT_FOUND}.
-     */
-    @NonNull
-    ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
-            @NonNull GetByDocumentIdRequest request);
-
-    /**
-     * Retrieves documents from the open {@link AppSearchSessionShim} that match a given query
-     * string and type of search provided.
-     *
-     * <p>Query strings can be empty, contain one term with no operators, or contain multiple terms
-     * and operators.
-     *
-     * <p>For query strings that are empty, all documents that match the {@link SearchSpec} will be
-     * returned.
-     *
-     * <p>For query strings with a single term and no operators, documents that match the provided
-     * query string and {@link SearchSpec} will be returned.
-     *
-     * <p>The following operators are supported:
-     *
-     * <ul>
-     *   <li>AND (implicit)
-     *       <p>AND is an operator that matches documents that contain <i>all</i> provided terms.
-     *       <p><b>NOTE:</b> A space between terms is treated as an "AND" operator. Explicitly
-     *       including "AND" in a query string will treat "AND" as a term, returning documents that
-     *       also contain "AND".
-     *       <p>Example: "apple AND banana" matches documents that contain the terms "apple", "and",
-     *       "banana".
-     *       <p>Example: "apple banana" matches documents that contain both "apple" and "banana".
-     *       <p>Example: "apple banana cherry" matches documents that contain "apple", "banana", and
-     *       "cherry".
-     *   <li>OR
-     *       <p>OR is an operator that matches documents that contain <i>any</i> provided term.
-     *       <p>Example: "apple OR banana" matches documents that contain either "apple" or
-     *       "banana".
-     *       <p>Example: "apple OR banana OR cherry" matches documents that contain any of "apple",
-     *       "banana", or "cherry".
-     *   <li>Exclusion (-)
-     *       <p>Exclusion (-) is an operator that matches documents that <i>do not</i> contain the
-     *       provided term.
-     *       <p>Example: "-apple" matches documents that do not contain "apple".
-     *   <li>Grouped Terms
-     *       <p>For queries that require multiple operators and terms, terms can be grouped into
-     *       subqueries. Subqueries are contained within an open "(" and close ")" parenthesis.
-     *       <p>Example: "(donut OR bagel) (coffee OR tea)" matches documents that contain either
-     *       "donut" or "bagel" and either "coffee" or "tea".
-     *   <li>Property Restricts
-     *       <p>For queries that require a term to match a specific {@link AppSearchSchema} property
-     *       of a document, a ":" must be included between the property name and the term.
-     *       <p>Example: "subject:important" matches documents that contain the term "important" in
-     *       the "subject" property.
-     * </ul>
-     *
-     * <p>Additional search specifications, such as filtering by {@link AppSearchSchema} type or
-     * adding projection, can be set by calling the corresponding {@link SearchSpec.Builder} setter.
-     *
-     * <p>This method is lightweight. The heavy work will be done in {@link
-     * SearchResultsShim#getNextPage}.
-     *
-     * @param queryExpression query string to search.
-     * @param searchSpec spec for setting document filters, adding projection, setting term match
-     *     type, etc.
-     * @return a {@link SearchResultsShim} object for retrieved matched documents.
-     */
-    @NonNull
-    SearchResultsShim search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
-
-    /**
-     * Reports usage of a particular document by namespace and ID.
-     *
-     * <p>A usage report represents an event in which a user interacted with or viewed a document.
-     *
-     * <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
-     * metrics for that particular document. These metrics are used for ordering {@link #search}
-     * results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and {@link
-     * SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
-     *
-     * <p>Reporting usage of a document is optional.
-     *
-     * @param request The usage reporting request.
-     * @return The pending result of performing this operation which resolves to {@code null} on
-     *     success.
-     */
-    @NonNull
-    ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request);
-
-    /**
-     * Removes {@link GenericDocument} objects by document IDs in a namespace from the {@link
-     * AppSearchSessionShim} database.
-     *
-     * <p>Removed documents will no longer be surfaced by {@link #search} or {@link
-     * #getByDocumentId} calls.
-     *
-     * <p>Once the database crosses the document count or byte usage threshold, removed documents
-     * will be deleted from disk.
-     *
-     * @param request {@link RemoveByDocumentIdRequest} with IDs in a namespace to remove from the
-     *     index.
-     * @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
-     *     keys of the {@link AppSearchBatchResult} represent the input IDs from the {@link
-     *     RemoveByDocumentIdRequest} object. The values are either {@code null} on success, or a
-     *     failed {@link AppSearchResult} otherwise. IDs that are not found will return a failed
-     *     {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
-     */
-    @NonNull
-    ListenableFuture<AppSearchBatchResult<String, Void>> remove(
-            @NonNull RemoveByDocumentIdRequest request);
-
-    /**
-     * Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
-     * match the {@code queryExpression} in given namespaces and schemaTypes which is set via {@link
-     * SearchSpec.Builder#addFilterNamespaces} and {@link SearchSpec.Builder#addFilterSchemas}.
-     *
-     * <p>An empty {@code queryExpression} matches all documents.
-     *
-     * <p>An empty set of namespaces or schemaTypes matches all namespaces or schemaTypes in the
-     * current database.
-     *
-     * @param queryExpression Query String to search.
-     * @param searchSpec Spec containing schemaTypes, namespaces and query expression indicates how
-     *     document will be removed. All specific about how to scoring, ordering, snippeting and
-     *     resulting will be ignored.
-     * @return The pending result of performing this operation.
-     */
-    @NonNull
-    ListenableFuture<Void> remove(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
-
-    /**
-     * Gets the storage info for this {@link AppSearchSessionShim} database.
-     *
-     * <p>This may take time proportional to the number of documents and may be inefficient to call
-     * repeatedly.
-     *
-     * @return a {@link ListenableFuture} which resolves to a {@link StorageInfo} object.
-     */
-    @NonNull
-    ListenableFuture<StorageInfo> getStorageInfo();
-
-    /**
-     * Flush all schema and document updates, additions, and deletes to disk if possible.
-     *
-     * <p>The request is not guaranteed to be handled and may be ignored by some implementations of
-     * AppSearchSessionShim.
-     *
-     * @return The pending result of performing this operation. {@link
-     *     android.app.appsearch.exceptions.AppSearchException} with {@link
-     *     AppSearchResult#RESULT_INTERNAL_ERROR} will be set to the future if we hit error when
-     *     save to disk.
-     */
-    @NonNull
-    ListenableFuture<Void> requestFlush();
-
-    /**
-     * Closes the {@link AppSearchSessionShim} to persist all schema and document updates,
-     * additions, and deletes to disk.
-     */
-    @Override
-    void close();
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
deleted file mode 100644
index ec9a42ea..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchTestUtils.java
+++ /dev/null
@@ -1,94 +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 com.android.server.appsearch.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchSessionShim;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByDocumentIdRequest;
-import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResultsShim;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-public class AppSearchTestUtils {
-
-    public static <K, V> AppSearchBatchResult<K, V> checkIsBatchResultSuccess(
-            Future<AppSearchBatchResult<K, V>> future) throws Exception {
-        AppSearchBatchResult<K, V> result = future.get();
-        assertWithMessage("AppSearchBatchResult not successful: " + result)
-                .that(result.isSuccess())
-                .isTrue();
-        return result;
-    }
-
-    public static List<GenericDocument> doGet(
-            AppSearchSessionShim session, String namespace, String... ids) throws Exception {
-        AppSearchBatchResult<String, GenericDocument> result =
-                checkIsBatchResultSuccess(
-                        session.getByDocumentId(
-                                new GetByDocumentIdRequest.Builder(namespace).addIds(ids).build()));
-        assertThat(result.getSuccesses()).hasSize(ids.length);
-        assertThat(result.getFailures()).isEmpty();
-        List<GenericDocument> list = new ArrayList<>(ids.length);
-        for (String id : ids) {
-            list.add(result.getSuccesses().get(id));
-        }
-        return list;
-    }
-
-    public static List<GenericDocument> doGet(
-            AppSearchSessionShim session, GetByDocumentIdRequest request) throws Exception {
-        AppSearchBatchResult<String, GenericDocument> result =
-                checkIsBatchResultSuccess(session.getByDocumentId(request));
-        Set<String> ids = request.getIds();
-        assertThat(result.getSuccesses()).hasSize(ids.size());
-        assertThat(result.getFailures()).isEmpty();
-        List<GenericDocument> list = new ArrayList<>(ids.size());
-        for (String id : ids) {
-            list.add(result.getSuccesses().get(id));
-        }
-        return list;
-    }
-
-    public static List<GenericDocument> convertSearchResultsToDocuments(
-            SearchResultsShim searchResults) throws Exception {
-        List<SearchResult> results = retrieveAllSearchResults(searchResults);
-        List<GenericDocument> documents = new ArrayList<>(results.size());
-        for (SearchResult result : results) {
-            documents.add(result.getGenericDocument());
-        }
-        return documents;
-    }
-
-    public static List<SearchResult> retrieveAllSearchResults(SearchResultsShim searchResults)
-            throws Exception {
-        List<SearchResult> page = searchResults.getNextPage().get();
-        List<SearchResult> results = new ArrayList<>();
-        while (!page.isEmpty()) {
-            results.addAll(page);
-            page = searchResults.getNextPage().get();
-        }
-        return results;
-    }
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
deleted file mode 100644
index 892f84e..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
+++ /dev/null
@@ -1,82 +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 android.annotation.NonNull;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.io.Closeable;
-
-/**
- * Provides a connection to all AppSearch databases the querying application has been granted access
- * to.
- *
- * <p>All implementations of this interface must be thread safe.
- *
- * @see AppSearchSessionShim
- */
-public interface GlobalSearchSessionShim extends Closeable {
-    /**
-     * Retrieves documents from all AppSearch databases that the querying application has access to.
-     *
-     * <p>Applications can be granted access to documents by specifying {@link
-     * SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage}, or {@link
-     * SetSchemaRequest.Builder#setDocumentClassVisibilityForPackage} when building a schema.
-     *
-     * <p>Document access can also be granted to system UIs by specifying {@link
-     * SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem}, or {@link
-     * SetSchemaRequest.Builder#setDocumentClassDisplayedBySystem} when building a schema.
-     *
-     * <p>See {@link AppSearchSessionShim#search} for a detailed explanation on forming a query
-     * string.
-     *
-     * <p>This method is lightweight. The heavy work will be done in {@link
-     * SearchResultsShim#getNextPage}.
-     *
-     * @param queryExpression query string to search.
-     * @param searchSpec spec for setting document filters, adding projection, setting term match
-     *     type, etc.
-     * @return a {@link SearchResultsShim} object for retrieved matched documents.
-     */
-    @NonNull
-    SearchResultsShim search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
-
-    /**
-     * Reports that a particular document has been used from a system surface.
-     *
-     * <p>See {@link AppSearchSessionShim#reportUsage} for a general description of document usage,
-     * as well as an API that can be used by the app itself.
-     *
-     * <p>Usage reported via this method is accounted separately from usage reported via {@link
-     * AppSearchSessionShim#reportUsage} and may be accessed using the constants {@link
-     * SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_COUNT} and {@link
-     * SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP}.
-     *
-     * @return The pending result of performing this operation which resolves to {@code null} on
-     *     success. The pending result will be completed with an {@link
-     *     android.app.appsearch.exceptions.AppSearchException} with a code of {@link
-     *     AppSearchResult#RESULT_SECURITY_ERROR} if this API is invoked by an app which is not part
-     *     of the system.
-     */
-    @NonNull
-    ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request);
-
-    /** Closes the {@link GlobalSearchSessionShim}. */
-    @Override
-    void close();
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java
deleted file mode 100644
index 38f61f8..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java
+++ /dev/null
@@ -1,56 +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 android.annotation.NonNull;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.io.Closeable;
-import java.util.List;
-
-/**
- * Encapsulates results of a search operation.
- *
- * <p>Each {@link AppSearchSessionShim#search} operation returns a list of {@link SearchResult}
- * objects, referred to as a "page", limited by the size configured by {@link
- * SearchSpec.Builder#setResultCountPerPage}.
- *
- * <p>To fetch a page of results, call {@link #getNextPage()}.
- *
- * <p>All instances of {@link SearchResultsShim} must call {@link SearchResultsShim#close()} after
- * the results are fetched.
- *
- * <p>This class is not thread safe.
- */
-public interface SearchResultsShim extends Closeable {
-    /**
-     * Retrieves the next page of {@link SearchResult} objects.
-     *
-     * <p>The page size is configured by {@link SearchSpec.Builder#setResultCountPerPage}.
-     *
-     * <p>Continue calling this method to access results until it returns an empty list, signifying
-     * there are no more results.
-     *
-     * @return a {@link ListenableFuture} which resolves to a list of {@link SearchResult} objects.
-     */
-    @NonNull
-    ListenableFuture<List<SearchResult>> getNextPage();
-
-    @Override
-    void close();
-}
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/package-info.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/package-info.java
deleted file mode 100644
index 5c919b4..0000000
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/package-info.java
+++ /dev/null
@@ -1,20 +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.
- */
-
-/**
- * @hide
- */
-package com.android.server.appsearch.testing;
diff --git a/core/api/current.txt b/core/api/current.txt
index 49a8cb8..e2167c7 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -31444,12 +31444,15 @@
     method public int readInt();
     method public void readIntArray(@NonNull int[]);
     method public void readList(@NonNull java.util.List, @Nullable ClassLoader);
+    method public <T> void readList(@NonNull java.util.List<? super T>, @Nullable ClassLoader, @NonNull Class<T>);
     method public long readLong();
     method public void readLongArray(@NonNull long[]);
     method public void readMap(@NonNull java.util.Map, @Nullable ClassLoader);
     method @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader);
+    method @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader, @NonNull Class<T>);
     method @Nullable public android.os.Parcelable[] readParcelableArray(@Nullable ClassLoader);
     method @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
+    method @Nullable public <T> android.os.Parcelable.Creator<T> readParcelableCreator(@Nullable ClassLoader, @NonNull Class<T>);
     method @NonNull public <T extends android.os.Parcelable> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader);
     method @Nullable public android.os.PersistableBundle readPersistableBundle();
     method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
@@ -31588,7 +31591,7 @@
 
   public interface Parcelable {
     method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int CONTENTS_FILE_DESCRIPTOR = 1; // 0x1
     field public static final int PARCELABLE_WRITE_RETURN_VALUE = 1; // 0x1
   }
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index f72c3a7..b574d04 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -42,7 +42,7 @@
   }
 
   public static interface PendingIntent.CancelListener {
-    method public void onCancelled(@NonNull android.app.PendingIntent);
+    method public void onCanceled(@NonNull android.app.PendingIntent);
   }
 
   public class StatusBarManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6a57c24..ba7903b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1981,8 +1981,10 @@
   public final class BluetoothDevice implements android.os.Parcelable {
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean canBondWithoutDialog();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean cancelBondProcess();
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public int connect();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect();
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean fetchUuidsWithSdp(int);
     method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getSimAccessPermission();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 9505aad..6ccdf91 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -321,7 +321,7 @@
   }
 
   public static interface PendingIntent.CancelListener {
-    method public void onCancelled(@NonNull android.app.PendingIntent);
+    method public void onCanceled(@NonNull android.app.PendingIntent);
   }
 
   public final class PictureInPictureParams implements android.os.Parcelable {
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 9b9eed4..2c0f983 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -1081,12 +1081,12 @@
     public void registerCancelListener(@NonNull CancelListener cancelListener) {
         if (!addCancelListener(Runnable::run, cancelListener)) {
             // Call the callback right away synchronously, if the PI has been canceled already.
-            cancelListener.onCancelled(this);
+            cancelListener.onCanceled(this);
         }
     }
 
     /**
-     * Register a listener to when this pendingIntent is cancelled.
+     * Register a listener to when this pendingIntent is canceled.
      *
      * @return true if the listener has been set successfully. false if the {@link PendingIntent}
      * has already been canceled.
@@ -1138,7 +1138,7 @@
         int size = cancelListeners.size();
         for (int i = 0; i < size; i++) {
             final Pair<Executor, CancelListener> pair = cancelListeners.valueAt(i);
-            pair.first.execute(() -> pair.second.onCancelled(this));
+            pair.first.execute(() -> pair.second.onCanceled(this));
         }
     }
 
@@ -1152,7 +1152,7 @@
     }
 
     /**
-     * Un-register a listener to when this pendingIntent is cancelled.
+     * Un-register a listener to when this pendingIntent is canceled.
      *
      * @hide
      */
@@ -1462,7 +1462,7 @@
     }
 
     /**
-     * A listener to when a pending intent is cancelled
+     * A listener to when a pending intent is canceled
      *
      * @hide
      */
@@ -1470,11 +1470,11 @@
     @TestApi
     public interface CancelListener {
         /**
-         * Called when a Pending Intent is cancelled.
+         * Called when a Pending Intent is canceled.
          *
-         * @param intent The intent that was cancelled.
+         * @param intent The intent that was canceled.
          */
-        void onCancelled(@NonNull PendingIntent intent);
+        void onCanceled(@NonNull PendingIntent intent);
     }
 
     private PendingIntentInfo getCachedInfo() {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 77abbe9..e9be0ec 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2005,71 +2005,6 @@
     }
 
     /**
-     * Connects all enabled and supported bluetooth profiles between the local and remote device.
-     * Connection is asynchronous and you should listen to each profile's broadcast intent
-     * ACTION_CONNECTION_STATE_CHANGED to verify whether connection was successful. For example,
-     * to verify a2dp is connected, you would listen for
-     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
-     *
-     * @param device is the remote device with which to connect these profiles
-     * @return true if message sent to try to connect all profiles, false if an error occurred
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) {
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.connectAllEnabledProfiles(device, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-
-        return false;
-    }
-
-    /**
-     * Disconnects all enabled and supported bluetooth profiles between the local and remote device.
-     * Disconnection is asynchronous and you should listen to each profile's broadcast intent
-     * ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
-     * to verify a2dp is disconnected, you would listen for
-     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
-     *
-     * @param device is the remote device with which to disconnect these profiles
-     * @return true if message sent to try to disconnect all profiles, false if an error occurred
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) {
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.disconnectAllEnabledProfiles(device, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-
-        return false;
-    }
-
-    /**
      * Return true if the multi advertisement is supported by the chipset
      *
      * @return true if Multiple Advertisement feature is supported
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 437d9ff..c71fcc6 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1680,6 +1680,90 @@
         return false;
     }
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            BluetoothStatusCodes.SUCCESS,
+            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
+            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED,
+            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
+            BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED
+    })
+    public @interface ConnectionReturnValues{}
+
+    /**
+     * Connects all user enabled and supported bluetooth profiles between the local and remote
+     * device. If no profiles are user enabled (e.g. first connection), we connect all supported
+     * profiles. If the device is not already connected, this will page the device before initiating
+     * profile connections. Connection is asynchronous and you should listen to each profile's
+     * broadcast intent ACTION_CONNECTION_STATE_CHANGED to verify whether connection was successful.
+     * For example, to verify a2dp is connected, you would listen for
+     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
+     *
+     * @return whether the messages were successfully sent to try to connect all profiles
+     * @throws IllegalArgumentException if the device address is invalid
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresBluetoothConnectPermission
+    @RequiresPermission(allOf = {
+            android.Manifest.permission.BLUETOOTH_CONNECT,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+            android.Manifest.permission.MODIFY_PHONE_STATE,
+    })
+    public @ConnectionReturnValues int connect() {
+        if (!BluetoothAdapter.checkBluetoothAddress(getAddress())) {
+            throw new IllegalArgumentException("device cannot have an invalid address");
+        }
+
+        try {
+            if (sService == null) {
+                Log.e(TAG, "BT not enabled. Cannot connect to remote device.");
+                return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+            }
+            return sService.connectAllEnabledProfiles(this, mAttributionSource);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Disconnects all connected bluetooth profiles between the local and remote device.
+     * Disconnection is asynchronous and you should listen to each profile's broadcast intent
+     * ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
+     * to verify a2dp is disconnected, you would listen for
+     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
+     *
+     * @return whether the messages were successfully sent to try to disconnect all profiles
+     * @throws IllegalArgumentException if the device address is invalid
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresBluetoothConnectPermission
+    @RequiresPermission(allOf = {
+            android.Manifest.permission.BLUETOOTH_CONNECT,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+    })
+    public @ConnectionReturnValues int disconnect() {
+        if (!BluetoothAdapter.checkBluetoothAddress(getAddress())) {
+            throw new IllegalArgumentException("device cannot have an invalid address");
+        }
+
+        try {
+            if (sService == null) {
+                Log.e(TAG, "BT not enabled. Cannot disconnect from remote device.");
+                return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+            }
+            return sService.disconnectAllEnabledProfiles(this, mAttributionSource);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Returns whether there is an open connection to this device.
      *
diff --git a/core/java/android/bluetooth/BluetoothStatusCodes.java b/core/java/android/bluetooth/BluetoothStatusCodes.java
index 31bb0f6..3e46c49 100644
--- a/core/java/android/bluetooth/BluetoothStatusCodes.java
+++ b/core/java/android/bluetooth/BluetoothStatusCodes.java
@@ -21,7 +21,7 @@
 /**
  * A class with constants representing possible return values for Bluetooth APIs. General return
  * values occupy the range 0 to 99. Profile-specific return values occupy the range 100-999.
- * API-specific return values start at 1000. The exception to this is the "other" error code which
+ * API-specific return values start at 1000. The exception to this is the "UNKNOWN" error code which
  * occupies the max integer value.
  */
 public final class BluetoothStatusCodes {
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index fb21ce3..7ce8d72 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -431,7 +431,7 @@
      *
      * @hide
      */
-    public static boolean kindofEquals(BaseBundle a, BaseBundle b) {
+    public static boolean kindofEquals(@Nullable BaseBundle a, @Nullable BaseBundle b) {
         return (a == b) || (a != null && a.kindofEquals(b));
     }
 
@@ -1048,7 +1048,7 @@
      */
     char getChar(String key, char defaultValue) {
         unparcel();
-        Object o = getValue(key);
+        Object o = mMap.get(key);
         if (o == null) {
             return defaultValue;
         }
@@ -1451,7 +1451,7 @@
     @Nullable
     short[] getShortArray(@Nullable String key) {
         unparcel();
-        Object o = getValue(key);
+        Object o = mMap.get(key);
         if (o == null) {
             return null;
         }
@@ -1474,7 +1474,7 @@
     @Nullable
     char[] getCharArray(@Nullable String key) {
         unparcel();
-        Object o = getValue(key);
+        Object o = mMap.get(key);
         if (o == null) {
             return null;
         }
@@ -1543,7 +1543,7 @@
     @Nullable
     float[] getFloatArray(@Nullable String key) {
         unparcel();
-        Object o = getValue(key);
+        Object o = mMap.get(key);
         if (o == null) {
             return null;
         }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 2be9533..bd36772 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -285,6 +285,10 @@
     private static final int VAL_SIZE = 26;
     private static final int VAL_SIZEF = 27;
     private static final int VAL_DOUBLEARRAY = 28;
+    private static final int VAL_CHAR = 29;
+    private static final int VAL_SHORTARRAY = 30;
+    private static final int VAL_CHARARRAY = 31;
+    private static final int VAL_FLOATARRAY = 32;
 
     // The initial int32 in a Binder call's reply Parcel header:
     // Keep these in sync with libbinder's binder/Status.h.
@@ -476,6 +480,23 @@
     }
 
     /**
+     * Retrieve a new Parcel object from the pool for use with a specific binder.
+     *
+     * Associate this parcel with a binder object. This marks the parcel as being prepared for a
+     * transaction on this specific binder object. Based on this, the format of the wire binder
+     * protocol may change. For future compatibility, it is recommended to use this for all
+     * Parcels.
+     *
+     * @hide
+     */
+    @NonNull
+    public static Parcel obtain(@NonNull IBinder binder) {
+        Parcel parcel = Parcel.obtain();
+        parcel.markForBinder(binder);
+        return parcel;
+    }
+
+    /**
      * Put a Parcel object back into the pool.  You must not touch
      * the object after this call.
      */
@@ -549,16 +570,9 @@
     }
 
     /**
-     * Associate this parcel with a binder object. This marks the parcel as being prepared for a
-     * transaction on this specific binder object. Based on this, the format of the wire binder
-     * protocol may change. This should be called before any data is written to the parcel. If this
-     * is called multiple times, this will only be marked for the last binder. For future
-     * compatibility, it is recommended to call this on all parcels which are being sent over
-     * binder.
-     *
      * @hide
      */
-    public void markForBinder(@NonNull IBinder binder) {
+    private void markForBinder(@NonNull IBinder binder) {
         nativeMarkForBinder(mNativePtr, binder);
     }
 
@@ -1346,6 +1360,46 @@
         }
     }
 
+    /** @hide */
+    public void writeShortArray(@Nullable short[] val) {
+        if (val != null) {
+            int n = val.length;
+            writeInt(n);
+            for (int i = 0; i < n; i++) {
+                writeInt(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    /** @hide */
+    @Nullable
+    public short[] createShortArray() {
+        int n = readInt();
+        if (n >= 0 && n <= (dataAvail() >> 2)) {
+            short[] val = new short[n];
+            for (int i = 0; i < n; i++) {
+                val[i] = (short) readInt();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    /** @hide */
+    public void readShortArray(@NonNull short[] val) {
+        int n = readInt();
+        if (n == val.length) {
+            for (int i = 0; i < n; i++) {
+                val[i] = (short) readInt();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
     public final void writeCharArray(@Nullable char[] val) {
         if (val != null) {
             int N = val.length;
@@ -2011,6 +2065,14 @@
             return VAL_SIZE;
         } else if (v instanceof double[]) {
             return VAL_DOUBLEARRAY;
+        } else if (v instanceof Character) {
+            return VAL_CHAR;
+        } else if (v instanceof short[]) {
+            return VAL_SHORTARRAY;
+        } else if (v instanceof char[]) {
+            return VAL_CHARARRAY;
+        } else  if (v instanceof float[]) {
+            return VAL_FLOATARRAY;
         } else {
             Class<?> clazz = v.getClass();
             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -2113,6 +2175,18 @@
             case VAL_DOUBLEARRAY:
                 writeDoubleArray((double[]) v);
                 break;
+            case VAL_CHAR:
+                writeInt((Character) v);
+                break;
+            case VAL_SHORTARRAY:
+                writeShortArray((short[]) v);
+                break;
+            case VAL_CHARARRAY:
+                writeCharArray((char[]) v);
+                break;
+            case VAL_FLOATARRAY:
+                writeFloatArray((float[]) v);
+                break;
             case VAL_OBJECTARRAY:
                 writeArray((Object[]) v);
                 break;
@@ -2797,7 +2871,20 @@
      */
     public final void readList(@NonNull List outVal, @Nullable ClassLoader loader) {
         int N = readInt();
-        readListInternal(outVal, N, loader);
+        readListInternal(outVal, N, loader, /* clazz */ null);
+    }
+
+    /**
+     * Same as {@link #readList(List, ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item. If the item to be deserialized is not an instance
+     * of that class or any of its children class
+     * a {@link BadParcelableException} will be thrown.
+     */
+    public <T> void readList(@NonNull List<? super T> outVal,
+            @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        Objects.requireNonNull(clazz);
+        int n = readInt();
+        readListInternal(outVal, n, loader, clazz);
     }
 
     /**
@@ -2996,7 +3083,7 @@
             return null;
         }
         ArrayList l = new ArrayList(N);
-        readListInternal(l, N, loader);
+        readListInternal(l, N, loader, /* clazz */ null);
         return l;
     }
 
@@ -3396,20 +3483,29 @@
      */
     @Nullable
     public final Object readValue(@Nullable ClassLoader loader) {
+        return readValue(loader, /* clazz */ null);
+    }
+
+
+    /**
+     * @param clazz The type of the object expected or {@code null} for performing no checks.
+     */
+    @Nullable
+    private <T> T readValue(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
         int type = readInt();
-        final Object object;
+        final T object;
         if (isLengthPrefixed(type)) {
             int length = readInt();
             int start = dataPosition();
-            object = readValue(type, loader);
+            object = readValue(type, loader, clazz);
             int actual = dataPosition() - start;
             if (actual != length) {
-                Log.w(TAG,
+                Slog.wtfStack(TAG,
                         "Unparcelling of " + object + " of type " + Parcel.valueTypeToString(type)
                                 + "  consumed " + actual + " bytes, but " + length + " expected.");
             }
         } else {
-            object = readValue(type, loader);
+            object = readValue(type, loader, clazz);
         }
         return object;
     }
@@ -3446,7 +3542,7 @@
             setDataPosition(MathUtils.addOrThrow(dataPosition(), length));
             return new LazyValue(this, start, length, type, loader);
         } else {
-            return readValue(type, loader);
+            return readValue(type, loader, /* clazz */ null);
         }
     }
 
@@ -3578,114 +3674,175 @@
     /**
      * Reads a value from the parcel of type {@code type}. Does NOT read the int representing the
      * type first.
+     * @param clazz The type of the object expected or {@code null} for performing no checks.
      */
+    @SuppressWarnings("unchecked")
     @Nullable
-    private Object readValue(int type, @Nullable ClassLoader loader) {
+    private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
+        final Object object;
         switch (type) {
-        case VAL_NULL:
-            return null;
+            case VAL_NULL:
+                object = null;
+                break;
 
-        case VAL_STRING:
-            return readString();
+            case VAL_STRING:
+                object = readString();
+                break;
 
-        case VAL_INTEGER:
-            return readInt();
+            case VAL_INTEGER:
+                object = readInt();
+                break;
 
-        case VAL_MAP:
-            return readHashMap(loader);
+            case VAL_MAP:
+                object = readHashMap(loader);
+                break;
 
-        case VAL_PARCELABLE:
-            return readParcelable(loader);
+            case VAL_PARCELABLE:
+                object = readParcelableInternal(loader, clazz);
+                break;
 
-        case VAL_SHORT:
-            return (short) readInt();
+            case VAL_SHORT:
+                object = (short) readInt();
+                break;
 
-        case VAL_LONG:
-            return readLong();
+            case VAL_LONG:
+                object = readLong();
+                break;
 
-        case VAL_FLOAT:
-            return readFloat();
+            case VAL_FLOAT:
+                object = readFloat();
+                break;
 
-        case VAL_DOUBLE:
-            return readDouble();
+            case VAL_DOUBLE:
+                object = readDouble();
+                break;
 
-        case VAL_BOOLEAN:
-            return readInt() == 1;
+            case VAL_BOOLEAN:
+                object = readInt() == 1;
+                break;
 
-        case VAL_CHARSEQUENCE:
-            return readCharSequence();
+            case VAL_CHARSEQUENCE:
+                object = readCharSequence();
+                break;
 
-        case VAL_LIST:
-            return readArrayList(loader);
+            case VAL_LIST:
+                object = readArrayList(loader);
+                break;
 
-        case VAL_BOOLEANARRAY:
-            return createBooleanArray();
+            case VAL_BOOLEANARRAY:
+                object = createBooleanArray();
+                break;
 
-        case VAL_BYTEARRAY:
-            return createByteArray();
+            case VAL_BYTEARRAY:
+                object = createByteArray();
+                break;
 
-        case VAL_STRINGARRAY:
-            return readStringArray();
+            case VAL_STRINGARRAY:
+                object = readStringArray();
+                break;
 
-        case VAL_CHARSEQUENCEARRAY:
-            return readCharSequenceArray();
+            case VAL_CHARSEQUENCEARRAY:
+                object = readCharSequenceArray();
+                break;
 
-        case VAL_IBINDER:
-            return readStrongBinder();
+            case VAL_IBINDER:
+                object = readStrongBinder();
+                break;
 
-        case VAL_OBJECTARRAY:
-            return readArray(loader);
+            case VAL_OBJECTARRAY:
+                object = readArray(loader);
+                break;
 
-        case VAL_INTARRAY:
-            return createIntArray();
+            case VAL_INTARRAY:
+                object = createIntArray();
+                break;
 
-        case VAL_LONGARRAY:
-            return createLongArray();
+            case VAL_LONGARRAY:
+                object = createLongArray();
+                break;
 
-        case VAL_BYTE:
-            return readByte();
+            case VAL_BYTE:
+                object = readByte();
+                break;
 
-        case VAL_SERIALIZABLE:
-            return readSerializable(loader);
+            case VAL_SERIALIZABLE:
+                object = readSerializable(loader);
+                break;
 
-        case VAL_PARCELABLEARRAY:
-            return readParcelableArray(loader);
+            case VAL_PARCELABLEARRAY:
+                object = readParcelableArray(loader);
+                break;
 
-        case VAL_SPARSEARRAY:
-            return readSparseArray(loader);
+            case VAL_SPARSEARRAY:
+                object = readSparseArray(loader);
+                break;
 
-        case VAL_SPARSEBOOLEANARRAY:
-            return readSparseBooleanArray();
+            case VAL_SPARSEBOOLEANARRAY:
+                object = readSparseBooleanArray();
+                break;
 
-        case VAL_BUNDLE:
-            return readBundle(loader); // loading will be deferred
+            case VAL_BUNDLE:
+                object = readBundle(loader); // loading will be deferred
+                break;
 
-        case VAL_PERSISTABLEBUNDLE:
-            return readPersistableBundle(loader);
+            case VAL_PERSISTABLEBUNDLE:
+                object = readPersistableBundle(loader);
+                break;
 
-        case VAL_SIZE:
-            return readSize();
+            case VAL_SIZE:
+                object = readSize();
+                break;
 
-        case VAL_SIZEF:
-            return readSizeF();
+            case VAL_SIZEF:
+                object = readSizeF();
+                break;
 
-        case VAL_DOUBLEARRAY:
-            return createDoubleArray();
+            case VAL_DOUBLEARRAY:
+                object = createDoubleArray();
+                break;
 
-        default:
-            int off = dataPosition() - 4;
-            throw new RuntimeException(
-                "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off);
+            case VAL_CHAR:
+                object = (char) readInt();
+                break;
+
+            case VAL_SHORTARRAY:
+                object = createShortArray();
+                break;
+
+            case VAL_CHARARRAY:
+                object = createCharArray();
+                break;
+
+            case VAL_FLOATARRAY:
+                object = createFloatArray();
+                break;
+
+            default:
+                int off = dataPosition() - 4;
+                throw new RuntimeException(
+                    "Parcel " + this + ": Unmarshalling unknown type code " + type
+                            + " at offset " + off);
         }
+        if (clazz != null && !clazz.isInstance(object)) {
+            throw new BadParcelableException("Unparcelled object " + object
+                    + " is not an instance of required class " + clazz.getName()
+                    + " provided in the parameter");
+        }
+        return (T) object;
     }
 
     private boolean isLengthPrefixed(int type) {
+        // In general, we want custom types and containers of custom types to be length-prefixed,
+        // this allows clients (eg. Bundle) to skip their content during deserialization. The
+        // exception to this is Bundle, since Bundle is already length-prefixed and already copies
+        // the correspondent section of the parcel internally.
         switch (type) {
+            case VAL_MAP:
             case VAL_PARCELABLE:
-            case VAL_PARCELABLEARRAY:
             case VAL_LIST:
             case VAL_SPARSEARRAY:
-            case VAL_BUNDLE:
+            case VAL_PARCELABLEARRAY:
+            case VAL_OBJECTARRAY:
             case VAL_SERIALIZABLE:
                 return true;
             default:
@@ -3704,17 +3861,42 @@
      * @throws BadParcelableException Throws BadParcelableException if there
      * was an error trying to instantiate the Parcelable.
      */
-    @SuppressWarnings("unchecked")
     @Nullable
     public final <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader) {
-        Parcelable.Creator<?> creator = readParcelableCreator(loader);
+        return readParcelableInternal(loader, /* clazz */ null);
+    }
+
+    /**
+     * Same as {@link #readParcelable(ClassLoader)} but accepts {@code clazz} parameter as the type
+     * required for each item. If the item to be deserialized is not an instance of that class or
+     * any of its children classes a {@link BadParcelableException} will be thrown.
+     */
+    @Nullable
+    public <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader,
+            @NonNull Class<T> clazz) {
+        Objects.requireNonNull(clazz);
+        return readParcelableInternal(loader, clazz);
+    }
+
+    /**
+     *
+     * @param clazz The type of the parcelable expected or {@code null} for performing no checks.
+     */
+    @SuppressWarnings("unchecked")
+    @Nullable
+    private <T> T readParcelableInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
+        if (clazz != null && !Parcelable.class.isAssignableFrom(clazz)) {
+            throw new BadParcelableException("About to unparcel a parcelable object "
+                    + " but class required " + clazz.getName() + " is not Parcelable");
+        }
+        Parcelable.Creator<?> creator = readParcelableCreatorInternal(loader, clazz);
         if (creator == null) {
             return null;
         }
         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
-          Parcelable.ClassLoaderCreator<?> classLoaderCreator =
-              (Parcelable.ClassLoaderCreator<?>) creator;
-          return (T) classLoaderCreator.createFromParcel(this, loader);
+            Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+                    (Parcelable.ClassLoaderCreator<?>) creator;
+            return (T) classLoaderCreator.createFromParcel(this, loader);
         }
         return (T) creator.createFromParcel(this);
     }
@@ -3748,6 +3930,28 @@
      */
     @Nullable
     public final Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader loader) {
+        return readParcelableCreatorInternal(loader, /* clazz */ null);
+    }
+
+    /**
+     * Same as {@link #readParcelableCreator(ClassLoader)} but accepts {@code clazz} parameter
+     * as the required type. If the item to be deserialized is not an instance of that class
+     * or any of its children classes a {@link BadParcelableException} will be thrown.
+     */
+    @Nullable
+    public <T> Parcelable.Creator<T> readParcelableCreator(
+            @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        Objects.requireNonNull(clazz);
+        return readParcelableCreatorInternal(loader, clazz);
+    }
+
+    /**
+     * @param clazz The type of the parcelable expected or {@code null} for performing no checks.
+     */
+    @SuppressWarnings("unchecked")
+    @Nullable
+    private <T> Parcelable.Creator<T> readParcelableCreatorInternal(
+            @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
         String name = readString();
         if (name == null) {
             return null;
@@ -3763,7 +3967,15 @@
             creator = map.get(name);
         }
         if (creator != null) {
-            return creator;
+            if (clazz != null) {
+                Class<?> parcelableClass = creator.getClass().getEnclosingClass();
+                if (!clazz.isAssignableFrom(parcelableClass)) {
+                    throw new BadParcelableException("Parcelable creator " + name + " is not "
+                            + "a subclass of required class " + clazz.getName()
+                            + " provided in the parameter");
+                }
+            }
+            return (Parcelable.Creator<T>) creator;
         }
 
         try {
@@ -3779,6 +3991,14 @@
                 throw new BadParcelableException("Parcelable protocol requires subclassing "
                         + "from Parcelable on class " + name);
             }
+            if (clazz != null) {
+                if (!clazz.isAssignableFrom(parcelableClass)) {
+                    throw new BadParcelableException("Parcelable creator " + name + " is not "
+                            + "a subclass of required class " + clazz.getName()
+                            + " provided in the parameter");
+                }
+            }
+
             Field f = parcelableClass.getField("CREATOR");
             if ((f.getModifiers() & Modifier.STATIC) == 0) {
                 throw new BadParcelableException("Parcelable protocol requires "
@@ -3816,7 +4036,7 @@
             map.put(name, creator);
         }
 
-        return creator;
+        return (Parcelable.Creator<T>) creator;
     }
 
     /**
@@ -4066,13 +4286,21 @@
         return result;
     }
 
-    private void readListInternal(@NonNull List outVal, int N,
+    private void readListInternal(@NonNull List outVal, int n,
             @Nullable ClassLoader loader) {
-        while (N > 0) {
-            Object value = readValue(loader);
+        readListInternal(outVal, n, loader, null);
+    }
+
+    /**
+     * @param clazz The type of the object expected or {@code null} for performing no checks.
+     */
+    private <T> void readListInternal(@NonNull List<? super T> outVal, int n,
+            @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
+        while (n > 0) {
+            T value = readValue(loader, clazz);
             //Log.d(TAG, "Unmarshalling value=" + value);
             outVal.add(value);
-            N--;
+            n--;
         }
     }
 
@@ -4151,6 +4379,10 @@
             case VAL_SIZE: return "VAL_SIZE";
             case VAL_SIZEF: return "VAL_SIZEF";
             case VAL_DOUBLEARRAY: return "VAL_DOUBLEARRAY";
+            case VAL_CHAR: return "VAL_CHAR";
+            case VAL_SHORTARRAY: return "VAL_SHORTARRAY";
+            case VAL_CHARARRAY: return "VAL_CHARARRAY";
+            case VAL_FLOATARRAY: return "VAL_FLOATARRAY";
             case VAL_OBJECTARRAY: return "VAL_OBJECTARRAY";
             case VAL_SERIALIZABLE: return "VAL_SERIALIZABLE";
             default: return "UNKNOWN(" + type + ")";
diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java
index a537c98..a396211 100644
--- a/core/java/android/os/Parcelable.java
+++ b/core/java/android/os/Parcelable.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.NonNull;
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
 
@@ -202,7 +203,7 @@
      * @param flags Additional flags about how the object should be written.
      * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
      */
-    public void writeToParcel(Parcel dest, @WriteFlags int flags);
+    public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags);
 
     /**
      * Interface that must be implemented and provided as a public CREATOR
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 4edff27..0b50192 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -646,7 +646,7 @@
             e.fillInStackTrace();
             Log.w(TAG, "New hash " + hash
                     + " is before end of array hash " + mHashes[index-1]
-                    + " at index " + index + " key " + key, e);
+                    + " at index " + index + (DEBUG ? " key " + key : ""), e);
             put(key, value);
             return;
         }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index db43b5b..aa05b13 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3188,6 +3188,11 @@
          and one pSIM) -->
     <integer name="config_num_physical_slots">1</integer>
 
+    <!-- When a radio power off request is received, we will delay completing the request until
+         either IMS moves to the deregistered state or the timeout defined by this configuration
+         elapses. If 0, this feature is disabled and we do not delay radio power off requests.-->
+    <integer name="config_delay_for_ims_dereg_millis">0</integer>
+
     <!--Thresholds for LTE dbm in status bar-->
     <integer-array translatable="false" name="config_lteDbmThresholds">
         <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index adb046e..092be40 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -484,6 +484,7 @@
   <java-symbol type="string" name="config_deviceSpecificDevicePolicyManagerService" />
   <java-symbol type="string" name="config_deviceSpecificAudioService" />
   <java-symbol type="integer" name="config_num_physical_slots" />
+  <java-symbol type="integer" name="config_delay_for_ims_dereg_millis" />
   <java-symbol type="array" name="config_integrityRuleProviderPackages" />
   <java-symbol type="bool" name="config_useAssistantVolume" />
   <java-symbol type="string" name="config_bandwidthEstimateSource" />
diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
deleted file mode 100644
index 07e4333..0000000
--- a/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import static android.app.appsearch.SearchSpec.TERM_MATCH_PREFIX;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.expectThrows;
-
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.appsearch.testing.AppSearchEmail;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-
-public class AppSearchSessionUnitTest {
-    private final Context mContext = ApplicationProvider.getApplicationContext();
-    private final AppSearchManager mAppSearch = mContext.getSystemService(AppSearchManager.class);
-    private final Executor mExecutor = mContext.getMainExecutor();
-    private AppSearchSession mSearchSession;
-
-    @Before
-    public void setUp() throws Exception {
-        // Remove all documents from any instances that may have been created in the tests.
-        Objects.requireNonNull(mAppSearch);
-        AppSearchManager.SearchContext searchContext =
-                new AppSearchManager.SearchContext.Builder("testDb").build();
-        CompletableFuture<AppSearchResult<AppSearchSession>> future = new CompletableFuture<>();
-        mAppSearch.createSearchSession(searchContext, mExecutor, future::complete);
-        mSearchSession = future.get().getResultValue();
-
-        CompletableFuture<AppSearchResult<SetSchemaResponse>> schemaFuture =
-                new CompletableFuture<>();
-        mSearchSession.setSchema(
-                new SetSchemaRequest.Builder().setForceOverride(true).build(), mExecutor, mExecutor,
-                schemaFuture::complete);
-
-        schemaFuture.get().getResultValue();
-    }
-
-    @Test
-    public void testPutDocument_throwsNullException() throws Exception {
-        // Create a document
-        AppSearchEmail inEmail =
-                new AppSearchEmail.Builder("namespace", "uri1")
-                        .setFrom("from@example.com")
-                        .setTo("to1@example.com", "to2@example.com")
-                        .setSubject("testPut example")
-                        .setBody("This is the body of the testPut email")
-                        .build();
-
-        // clear the document bundle to make our service crash and throw an NullPointerException.
-        inEmail.getBundle().clear();
-        CompletableFuture<AppSearchBatchResult<String, Void>> putDocumentsFuture =
-                new CompletableFuture<>();
-
-        // Index the broken document.
-        mSearchSession.put(
-                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build(),
-                mExecutor, new BatchResultCallback<String, Void>() {
-                    @Override
-                    public void onResult(AppSearchBatchResult<String, Void> result) {
-                        putDocumentsFuture.complete(result);
-                    }
-
-                    @Override
-                    public void onSystemError(Throwable throwable) {
-                        putDocumentsFuture.completeExceptionally(throwable);
-                    }
-                });
-
-        // Verify the NullPointException has been thrown.
-        ExecutionException executionException =
-                expectThrows(ExecutionException.class, putDocumentsFuture::get);
-        assertThat(executionException.getCause()).isInstanceOf(AppSearchException.class);
-        AppSearchException appSearchException = (AppSearchException) executionException.getCause();
-        assertThat(appSearchException.getResultCode())
-                .isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
-        assertThat(appSearchException.getMessage()).startsWith("NullPointerException");
-    }
-
-    @Test
-    public void testGetEmptyNextPage() throws Exception {
-        // Set the schema.
-        CompletableFuture<AppSearchResult<SetSchemaResponse>> schemaFuture =
-                new CompletableFuture<>();
-        mSearchSession.setSchema(
-                new SetSchemaRequest.Builder()
-                        .addSchemas(new AppSearchSchema.Builder("schema1").build())
-                        .setForceOverride(true).build(),
-                mExecutor, mExecutor, schemaFuture::complete);
-        schemaFuture.get().getResultValue();
-
-        // Create a document and index it.
-        GenericDocument document1 = new GenericDocument.Builder<>("namespace", "id1",
-                "schema1").build();
-        CompletableFuture<AppSearchBatchResult<String, Void>> putDocumentsFuture =
-                new CompletableFuture<>();
-        mSearchSession.put(
-                new PutDocumentsRequest.Builder().addGenericDocuments(document1).build(),
-                mExecutor, new BatchResultCallback<String, Void>() {
-                    @Override
-                    public void onResult(AppSearchBatchResult<String, Void> result) {
-                        putDocumentsFuture.complete(result);
-                    }
-
-                    @Override
-                    public void onSystemError(Throwable throwable) {
-                        putDocumentsFuture.completeExceptionally(throwable);
-                    }
-                });
-        putDocumentsFuture.get();
-
-        // Search and get the first page.
-        SearchSpec searchSpec = new SearchSpec.Builder()
-                .setTermMatch(TERM_MATCH_PREFIX)
-                .setResultCountPerPage(1)
-                .build();
-        SearchResults searchResults = mSearchSession.search("", searchSpec);
-
-        CompletableFuture<AppSearchResult<List<SearchResult>>> getNextPageFuture =
-                new CompletableFuture<>();
-        searchResults.getNextPage(mExecutor, getNextPageFuture::complete);
-        List<SearchResult> results = getNextPageFuture.get().getResultValue();
-        assertThat(results).hasSize(1);
-        assertThat(results.get(0).getGenericDocument()).isEqualTo(document1);
-
-        // We get all documents, and it shouldn't fail if we keep calling getNextPage().
-        getNextPageFuture = new CompletableFuture<>();
-        searchResults.getNextPage(mExecutor, getNextPageFuture::complete);
-        results = getNextPageFuture.get().getResultValue();
-        assertThat(results).isEmpty();
-    }
-
-    @Test
-    public void testGetEmptyNextPage_multiPages() throws Exception {
-        // Set the schema.
-        CompletableFuture<AppSearchResult<SetSchemaResponse>> schemaFuture =
-                new CompletableFuture<>();
-        mSearchSession.setSchema(
-                new SetSchemaRequest.Builder()
-                        .addSchemas(new AppSearchSchema.Builder("schema1").build())
-                        .setForceOverride(true).build(),
-                mExecutor, mExecutor, schemaFuture::complete);
-        schemaFuture.get().getResultValue();
-
-        // Create a document and insert 3 package1 documents
-        GenericDocument document1 = new GenericDocument.Builder<>("namespace", "id1",
-                "schema1").build();
-        GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
-                "schema1").build();
-        GenericDocument document3 = new GenericDocument.Builder<>("namespace", "id3",
-                "schema1").build();
-        CompletableFuture<AppSearchBatchResult<String, Void>> putDocumentsFuture =
-                new CompletableFuture<>();
-        mSearchSession.put(
-                new PutDocumentsRequest.Builder()
-                        .addGenericDocuments(document1, document2, document3).build(),
-                mExecutor, new BatchResultCallback<String, Void>() {
-                    @Override
-                    public void onResult(AppSearchBatchResult<String, Void> result) {
-                        putDocumentsFuture.complete(result);
-                    }
-
-                    @Override
-                    public void onSystemError(Throwable throwable) {
-                        putDocumentsFuture.completeExceptionally(throwable);
-                    }
-                });
-        putDocumentsFuture.get();
-
-        // Search for only 2 result per page
-        SearchSpec searchSpec = new SearchSpec.Builder()
-                .setTermMatch(TERM_MATCH_PREFIX)
-                .setResultCountPerPage(2)
-                .build();
-        SearchResults searchResults = mSearchSession.search("", searchSpec);
-
-        // Get the first page, it contains 2 results.
-        List<GenericDocument> outDocs = new ArrayList<>();
-        CompletableFuture<AppSearchResult<List<SearchResult>>> getNextPageFuture =
-                new CompletableFuture<>();
-        searchResults.getNextPage(mExecutor, getNextPageFuture::complete);
-        List<SearchResult> results = getNextPageFuture.get().getResultValue();
-        assertThat(results).hasSize(2);
-        outDocs.add(results.get(0).getGenericDocument());
-        outDocs.add(results.get(1).getGenericDocument());
-
-        // Get the second page, it contains only 1 result.
-        getNextPageFuture = new CompletableFuture<>();
-        searchResults.getNextPage(mExecutor, getNextPageFuture::complete);
-        results = getNextPageFuture.get().getResultValue();
-        assertThat(results).hasSize(1);
-        outDocs.add(results.get(0).getGenericDocument());
-
-        assertThat(outDocs).containsExactly(document1, document2, document3);
-
-        // We get all documents, and it shouldn't fail if we keep calling getNextPage().
-        getNextPageFuture = new CompletableFuture<>();
-        searchResults.getNextPage(mExecutor, getNextPageFuture::complete);
-        results = getNextPageFuture.get().getResultValue();
-        assertThat(results).isEmpty();
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/OWNERS b/core/tests/coretests/src/android/app/appsearch/OWNERS
deleted file mode 100644
index 24f6b0b..0000000
--- a/core/tests/coretests/src/android/app/appsearch/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /apex/appsearch/OWNERS
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
deleted file mode 100644
index 29b0228..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
+++ /dev/null
@@ -1,56 +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 com.google.common.truth.Truth.assertThat;
-
-import com.android.server.appsearch.testing.AppSearchEmail;
-
-import org.junit.Test;
-
-public class AppSearchEmailTest {
-
-    @Test
-    public void testBuildEmailAndGetValue() {
-        AppSearchEmail email =
-                new AppSearchEmail.Builder("namespace", "id")
-                        .setFrom("FakeFromAddress")
-                        .setCc("CC1", "CC2")
-                        // Score and Property are mixed into the middle to make sure
-                        // DocumentBuilder's
-                        // methods can be interleaved with EmailBuilder's methods.
-                        .setScore(1)
-                        .setPropertyString("propertyKey", "propertyValue1", "propertyValue2")
-                        .setSubject("subject")
-                        .setBody("EmailBody")
-                        .build();
-
-        assertThat(email.getNamespace()).isEqualTo("namespace");
-        assertThat(email.getId()).isEqualTo("id");
-        assertThat(email.getFrom()).isEqualTo("FakeFromAddress");
-        assertThat(email.getTo()).isNull();
-        assertThat(email.getCc()).asList().containsExactly("CC1", "CC2");
-        assertThat(email.getBcc()).isNull();
-        assertThat(email.getScore()).isEqualTo(1);
-        assertThat(email.getPropertyString("propertyKey")).isEqualTo("propertyValue1");
-        assertThat(email.getPropertyStringArray("propertyKey"))
-                .asList()
-                .containsExactly("propertyValue1", "propertyValue2");
-        assertThat(email.getSubject()).isEqualTo("subject");
-        assertThat(email.getBody()).isEqualTo("EmailBody");
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java
deleted file mode 100644
index 228a061..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java
+++ /dev/null
@@ -1,41 +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 com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import org.junit.Test;
-
-public class AppSearchResultTest {
-    @Test
-    public void testMapNullPointerException() {
-        NullPointerException e =
-                assertThrows(
-                        NullPointerException.class,
-                        () -> {
-                            Object o = null;
-                            o.toString();
-                        });
-        AppSearchResult<?> result = AppSearchResult.throwableToFailedResult(e);
-        assertThat(result.getResultCode()).isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
-        // Makes sure the exception name is included in the string. Some exceptions have terse or
-        // missing strings so it's confusing to read the output without the exception name.
-        assertThat(result.getErrorMessage()).startsWith("NullPointerException");
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
deleted file mode 100644
index 3d820ac..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
+++ /dev/null
@@ -1,79 +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 com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-import android.os.Parcel;
-
-import org.junit.Test;
-
-public class GenericDocumentTest {
-    @Test
-    public void testRecreateFromParcel() {
-        GenericDocument inDoc =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1")
-                        .setScore(42)
-                        .setPropertyString("propString", "Hello")
-                        .setPropertyBytes("propBytes", new byte[][] {{1, 2}})
-                        .setPropertyDocument(
-                                "propDocument",
-                                new GenericDocument.Builder<>("namespace", "id2", "schema2")
-                                        .setPropertyString("propString", "Goodbye")
-                                        .setPropertyBytes("propBytes", new byte[][] {{3, 4}})
-                                        .build())
-                        .build();
-
-        // Serialize the document
-        Parcel inParcel = Parcel.obtain();
-        inParcel.writeBundle(inDoc.getBundle());
-        byte[] data = inParcel.marshall();
-        inParcel.recycle();
-
-        // Deserialize the document
-        Parcel outParcel = Parcel.obtain();
-        outParcel.unmarshall(data, 0, data.length);
-        outParcel.setDataPosition(0);
-        Bundle outBundle = outParcel.readBundle();
-        outParcel.recycle();
-
-        // Compare results
-        GenericDocument outDoc = new GenericDocument(outBundle);
-        assertThat(inDoc).isEqualTo(outDoc);
-        assertThat(outDoc.getPropertyString("propString")).isEqualTo("Hello");
-        assertThat(outDoc.getPropertyBytesArray("propBytes")).isEqualTo(new byte[][] {{1, 2}});
-        assertThat(outDoc.getPropertyDocument("propDocument").getPropertyString("propString"))
-                .isEqualTo("Goodbye");
-        assertThat(outDoc.getPropertyDocument("propDocument").getPropertyBytesArray("propBytes"))
-                .isEqualTo(new byte[][] {{3, 4}});
-    }
-
-    @Test
-    public void testPutLargeDocument_exceedLimit() throws Exception {
-        // Create a String property that has a very large property.
-        char[] chars = new char[10_000_000];
-        String property = new StringBuilder().append(chars).append("the end.").toString();
-
-        GenericDocument doc =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1")
-                        .setPropertyString("propString", property)
-                        .build();
-
-        assertThat(doc.getPropertyString("propString")).isEqualTo(property);
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
deleted file mode 100644
index a613e77..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
+++ /dev/null
@@ -1,60 +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 com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-
-import org.junit.Test;
-
-public class SearchSpecTest {
-
-    @Test
-    public void testGetBundle() {
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
-                        .addFilterNamespaces("namespace1", "namespace2")
-                        .addFilterSchemas("schemaTypes1", "schemaTypes2")
-                        .addFilterPackageNames("package1", "package2")
-                        .setSnippetCount(5)
-                        .setSnippetCountPerProperty(10)
-                        .setMaxSnippetSize(15)
-                        .setResultCountPerPage(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_FIELD))
-                .containsExactly("schemaTypes1", "schemaTypes2");
-        assertThat(bundle.getStringArrayList(SearchSpec.PACKAGE_NAME_FIELD))
-                .containsExactly("package1", "package2");
-        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/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaResponseTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaResponseTest.java
deleted file mode 100644
index 0bbea42..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaResponseTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-
-public class SetSchemaResponseTest {
-    @Test
-    public void testRebuild() {
-        SetSchemaResponse.MigrationFailure failure1 =
-                new SetSchemaResponse.MigrationFailure(
-                        "namespace",
-                        "failure1",
-                        "schemaType",
-                        AppSearchResult.newFailedResult(
-                                AppSearchResult.RESULT_INTERNAL_ERROR, "errorMessage"));
-        SetSchemaResponse.MigrationFailure failure2 =
-                new SetSchemaResponse.MigrationFailure(
-                        "namespace",
-                        "failure2",
-                        "schemaType",
-                        AppSearchResult.newFailedResult(
-                                AppSearchResult.RESULT_INTERNAL_ERROR, "errorMessage"));
-
-        SetSchemaResponse original =
-                new SetSchemaResponse.Builder()
-                        .addDeletedType("delete1")
-                        .addIncompatibleType("incompatible1")
-                        .addMigratedType("migrated1")
-                        .addMigrationFailure(failure1)
-                        .build();
-        assertThat(original.getDeletedTypes()).containsExactly("delete1");
-        assertThat(original.getIncompatibleTypes()).containsExactly("incompatible1");
-        assertThat(original.getMigratedTypes()).containsExactly("migrated1");
-        assertThat(original.getMigrationFailures()).containsExactly(failure1);
-
-        SetSchemaResponse rebuild =
-                original.toBuilder()
-                        .addDeletedType("delete2")
-                        .addIncompatibleType("incompatible2")
-                        .addMigratedType("migrated2")
-                        .addMigrationFailure(failure2)
-                        .build();
-
-        // rebuild won't effect the original object
-        assertThat(original.getDeletedTypes()).containsExactly("delete1");
-        assertThat(original.getIncompatibleTypes()).containsExactly("incompatible1");
-        assertThat(original.getMigratedTypes()).containsExactly("migrated1");
-        assertThat(original.getMigrationFailures()).containsExactly(failure1);
-
-        assertThat(rebuild.getDeletedTypes()).containsExactly("delete1", "delete2");
-        assertThat(rebuild.getIncompatibleTypes())
-                .containsExactly("incompatible1", "incompatible2");
-        assertThat(rebuild.getMigratedTypes()).containsExactly("migrated1", "migrated2");
-        assertThat(rebuild.getMigrationFailures()).containsExactly(failure1, failure2);
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/exceptions/IllegalSchemaExceptionTest.java b/core/tests/coretests/src/android/app/appsearch/external/exceptions/IllegalSchemaExceptionTest.java
deleted file mode 100644
index 1774d72..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/exceptions/IllegalSchemaExceptionTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.exceptions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-
-public class IllegalSchemaExceptionTest {
-    @Test
-    public void testExceptionWithMessage() {
-        IllegalSchemaException e = new IllegalSchemaException("ERROR MESSAGE");
-        assertThat(e.getMessage()).isEqualTo("ERROR MESSAGE");
-        assertThat(e).isInstanceOf(IllegalArgumentException.class);
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java b/core/tests/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
deleted file mode 100644
index 680ce52..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
+++ /dev/null
@@ -1,277 +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.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Build;
-import android.os.Bundle;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-import android.util.Size;
-import android.util.SizeF;
-import android.util.SparseArray;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Test;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.UUID;
-
-public class BundleUtilTest {
-    @Test
-    public void testDeepEquals_self() {
-        Bundle one = new Bundle();
-        one.putString("a", "a");
-        assertThat(BundleUtil.deepEquals(one, one)).isTrue();
-    }
-
-    @Test
-    public void testDeepEquals_simple() {
-        Bundle one = new Bundle();
-        one.putString("a", "a");
-
-        Bundle two = new Bundle();
-        two.putString("a", "a");
-
-        assertThat(one).isNotEqualTo(two);
-        assertThat(BundleUtil.deepEquals(one, two)).isTrue();
-    }
-
-    @Test
-    public void testDeepEquals_keyMismatch() {
-        Bundle one = new Bundle();
-        one.putString("a", "a");
-
-        Bundle two = new Bundle();
-        two.putString("a", "a");
-        two.putString("b", "b");
-        assertThat(BundleUtil.deepEquals(one, two)).isFalse();
-    }
-
-    @Test
-    public void testDeepEquals_thorough_equal() {
-        Bundle[] inputs = new Bundle[2];
-        for (int i = 0; i < 2; i++) {
-            inputs[i] = createThoroughBundle();
-        }
-        assertThat(inputs[0]).isNotEqualTo(inputs[1]);
-        assertThat(BundleUtil.deepEquals(inputs[0], inputs[1])).isTrue();
-    }
-
-    @Test
-    public void testDeepEquals_thorough_notEqual() {
-        Bundle[] inputs = new Bundle[2];
-        for (int i = 0; i < 2; i++) {
-            Bundle b = createThoroughBundle();
-            // Create a difference
-            assertThat(b.containsKey("doubleArray")).isTrue();
-            b.putDoubleArray("doubleArray", new double[] {18., i});
-            inputs[i] = b;
-        }
-        assertThat(inputs[0]).isNotEqualTo(inputs[1]);
-        assertThat(BundleUtil.deepEquals(inputs[0], inputs[1])).isFalse();
-    }
-
-    @Test
-    public void testDeepEquals_nestedNotEquals() {
-        Bundle one = new Bundle();
-        one.putString("a", "a");
-        Bundle two = new Bundle();
-        two.putBundle("b", one);
-        Bundle twoClone = new Bundle();
-        twoClone.putBundle("b", one);
-        Bundle three = new Bundle();
-        three.putBundle("b", two);
-
-        ArrayList<Bundle> listOne = new ArrayList<>(ImmutableList.of(one, two, three));
-        ArrayList<Bundle> listOneClone = new ArrayList<>(ImmutableList.of(one, twoClone, three));
-        ArrayList<Bundle> listTwo = new ArrayList<>(ImmutableList.of(one, three, two));
-        Bundle b1 = new Bundle();
-        b1.putParcelableArrayList("key", listOne);
-        Bundle b1Clone = new Bundle();
-        b1Clone.putParcelableArrayList("key", listOneClone);
-        Bundle b2 = new Bundle();
-        b2.putParcelableArrayList("key", listTwo);
-
-        assertThat(b1).isNotEqualTo(b1Clone);
-        assertThat(BundleUtil.deepEquals(b1, b1Clone)).isTrue();
-        assertThat(BundleUtil.deepEquals(b1, b2)).isFalse();
-        assertThat(BundleUtil.deepEquals(b1Clone, b2)).isFalse();
-    }
-
-    @Test
-    public void testDeepEquals_sparseArray() {
-        Parcelable parcelable1 = new ParcelUuid(UUID.randomUUID());
-        Parcelable parcelable2 = new ParcelUuid(UUID.randomUUID());
-        Parcelable parcelable3 = new ParcelUuid(UUID.randomUUID());
-
-        SparseArray<Parcelable> array1 = new SparseArray<>();
-        array1.put(1, parcelable1);
-        array1.put(10, parcelable2);
-
-        SparseArray<Parcelable> array1Clone = new SparseArray<>();
-        array1Clone.put(1, parcelable1);
-        array1Clone.put(10, parcelable2);
-
-        SparseArray<Parcelable> array2 = new SparseArray<>();
-        array2.put(1, parcelable1);
-        array2.put(10, parcelable3); // Different
-
-        Bundle b1 = new Bundle();
-        b1.putSparseParcelableArray("array1", array1);
-        Bundle b1Clone = new Bundle();
-        b1Clone.putSparseParcelableArray("array1", array1Clone);
-        Bundle b2 = new Bundle();
-        b2.putSparseParcelableArray("array1", array2);
-
-        assertThat(b1).isNotEqualTo(b1Clone);
-        assertThat(BundleUtil.deepEquals(b1, b1Clone)).isTrue();
-        assertThat(BundleUtil.deepEquals(b1, b2)).isFalse();
-        assertThat(BundleUtil.deepEquals(b1Clone, b2)).isFalse();
-    }
-
-    @Test
-    public void testDeepHashCode_same() {
-        Bundle[] inputs = new Bundle[2];
-        for (int i = 0; i < 2; i++) {
-            inputs[i] = createThoroughBundle();
-        }
-        assertThat(BundleUtil.deepHashCode(inputs[0]))
-                .isEqualTo(BundleUtil.deepHashCode(inputs[1]));
-    }
-
-    @Test
-    public void testDeepHashCode_different() {
-        Bundle[] inputs = new Bundle[2];
-        for (int i = 0; i < 2; i++) {
-            Bundle b = createThoroughBundle();
-            // Create a difference
-            assertThat(b.containsKey("doubleArray")).isTrue();
-            b.putDoubleArray("doubleArray", new double[] {18., i});
-            inputs[i] = b;
-        }
-        assertThat(BundleUtil.deepHashCode(inputs[0]))
-                .isNotEqualTo(BundleUtil.deepHashCode(inputs[1]));
-    }
-
-    @Test
-    public void testHashCode_sparseArray() {
-        Parcelable parcelable1 = new ParcelUuid(UUID.randomUUID());
-        Parcelable parcelable2 = new ParcelUuid(UUID.randomUUID());
-        Parcelable parcelable3 = new ParcelUuid(UUID.randomUUID());
-
-        SparseArray<Parcelable> array1 = new SparseArray<>();
-        array1.put(1, parcelable1);
-        array1.put(10, parcelable2);
-
-        SparseArray<Parcelable> array1Clone = new SparseArray<>();
-        array1Clone.put(1, parcelable1);
-        array1Clone.put(10, parcelable2);
-
-        SparseArray<Parcelable> array2 = new SparseArray<>();
-        array2.put(1, parcelable1);
-        array2.put(10, parcelable3); // Different
-
-        Bundle b1 = new Bundle();
-        b1.putSparseParcelableArray("array1", array1);
-        Bundle b1Clone = new Bundle();
-        b1Clone.putSparseParcelableArray("array1", array1Clone);
-        Bundle b2 = new Bundle();
-        b2.putSparseParcelableArray("array1", array2);
-
-        assertThat(b1.hashCode()).isNotEqualTo(b1Clone.hashCode());
-        assertThat(BundleUtil.deepHashCode(b1)).isEqualTo(BundleUtil.deepHashCode(b1Clone));
-        assertThat(BundleUtil.deepHashCode(b1)).isNotEqualTo(BundleUtil.deepHashCode(b2));
-    }
-
-    @Test
-    public void testDeepHashCode_differentKeys() {
-        Bundle[] inputs = new Bundle[2];
-        for (int i = 0; i < 2; i++) {
-            Bundle b = new Bundle();
-            b.putString("key" + i, "value");
-            inputs[i] = b;
-        }
-        assertThat(BundleUtil.deepHashCode(inputs[0]))
-                .isNotEqualTo(BundleUtil.deepHashCode(inputs[1]));
-    }
-
-    @Test
-    public void testDeepCopy() {
-        Bundle input = createThoroughBundle();
-        Bundle output = BundleUtil.deepCopy(input);
-        assertThat(input).isNotSameInstanceAs(output);
-        assertThat(BundleUtil.deepEquals(input, output)).isTrue();
-
-        output.getIntegerArrayList("integerArrayList").add(5);
-        assertThat(BundleUtil.deepEquals(input, output)).isFalse();
-    }
-
-    private static Bundle createThoroughBundle() {
-        Bundle toy1 = new Bundle();
-        toy1.putString("a", "a");
-        Bundle toy2 = new Bundle();
-        toy2.putInt("b", 2);
-
-        Bundle b = new Bundle();
-        // BaseBundle stuff
-        b.putBoolean("boolean", true);
-        b.putByte("byte", (byte) 1);
-        b.putChar("char", 'a');
-        b.putShort("short", (short) 2);
-        b.putInt("int", 3);
-        b.putLong("long", 4L);
-        b.putFloat("float", 5f);
-        b.putDouble("double", 6f);
-        b.putString("string", "b");
-        b.putCharSequence("charSequence", "c");
-        b.putIntegerArrayList("integerArrayList", new ArrayList<>(ImmutableList.of(7, 8)));
-        b.putStringArrayList("stringArrayList", new ArrayList<>(ImmutableList.of("d", "e")));
-        b.putCharSequenceArrayList(
-                "charSequenceArrayList", new ArrayList<>(ImmutableList.of("f", "g")));
-        b.putSerializable("serializable", new BigDecimal(9));
-        b.putBooleanArray("booleanArray", new boolean[] {true, false, true});
-        b.putByteArray("byteArray", new byte[] {(byte) 10, (byte) 11});
-        b.putShortArray("shortArray", new short[] {(short) 12, (short) 13});
-        b.putCharArray("charArray", new char[] {'h', 'i'});
-        b.putLongArray("longArray", new long[] {14L, 15L});
-        b.putFloatArray("floatArray", new float[] {16f, 17f});
-        b.putDoubleArray("doubleArray", new double[] {18., 19.});
-        b.putStringArray("stringArray", new String[] {"j", "k"});
-        b.putCharSequenceArray("charSequenceArrayList", new CharSequence[] {"l", "m"});
-
-        // Bundle stuff
-        b.putParcelable("parcelable", toy1);
-        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
-            b.putSize("size", new Size(20, 21));
-            b.putSizeF("sizeF", new SizeF(22f, 23f));
-        }
-        b.putParcelableArray("parcelableArray", new Parcelable[] {toy1, toy2});
-        b.putParcelableArrayList(
-                "parcelableArrayList", new ArrayList<>(ImmutableList.of(toy1, toy2)));
-        SparseArray<Parcelable> sparseArray = new SparseArray<>();
-        sparseArray.put(24, toy1);
-        sparseArray.put(1025, toy2);
-        b.putSparseParcelableArray("sparceParcelableArray", sparseArray);
-        b.putBundle("bundle", toy1);
-
-        return b;
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java b/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java
deleted file mode 100644
index 057ecbd..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.appsearch.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import org.junit.Test;
-
-public class IndentingStringBuilderTest {
-    @Test
-    public void testAppendIndentedStrings() {
-        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-        stringBuilder
-                .increaseIndentLevel()
-                .append("\nIndentLevel1\nIndentLevel1\n")
-                .decreaseIndentLevel()
-                .append("IndentLevel0,\n");
-
-        String str = stringBuilder.toString();
-        String expectedString = "\n  IndentLevel1\n  IndentLevel1\nIndentLevel0,\n";
-
-        assertThat(str).isEqualTo(expectedString);
-    }
-
-    @Test
-    public void testDecreaseIndentLevel_throwsException() {
-        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-
-        Exception e =
-                assertThrows(
-                        IllegalStateException.class, () -> stringBuilder.decreaseIndentLevel());
-        assertThat(e).hasMessageThat().contains("Cannot set indent level below 0.");
-    }
-
-    @Test
-    public void testAppendIndentedObjects() {
-        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-        Object stringProperty = "String";
-        Object longProperty = 1L;
-        Object booleanProperty = true;
-
-        stringBuilder
-                .append(stringProperty)
-                .append("\n")
-                .increaseIndentLevel()
-                .append(longProperty)
-                .append("\n")
-                .decreaseIndentLevel()
-                .append(booleanProperty);
-
-        String str = stringBuilder.toString();
-        String expectedString = "String\n  1\ntrue";
-
-        assertThat(str).isEqualTo(expectedString);
-    }
-
-    @Test
-    public void testAppendIndentedStrings_doesNotIndentLineBreak() {
-        IndentingStringBuilder stringBuilder = new IndentingStringBuilder();
-
-        stringBuilder
-                .append("\n")
-                .increaseIndentLevel()
-                .append("\n\n")
-                .decreaseIndentLevel()
-                .append("\n");
-
-        String str = stringBuilder.toString();
-        String expectedString = "\n\n\n\n";
-
-        assertThat(str).isEqualTo(expectedString);
-    }
-}
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index 4cc70ba..9d2cab3 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -16,16 +16,24 @@
 
 package android.os;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
+import android.util.Log;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Objects;
+
 /**
  * Unit tests for bundle that requires accessing hidden APS.  Tests that can be written only with
  * public APIs should go in the CTS counterpart.
@@ -35,6 +43,14 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BundleTest {
+    private Log.TerribleFailureHandler mWtfHandler;
+
+    @After
+    public void tearDown() throws Exception {
+        if (mWtfHandler != null) {
+            Log.setWtfHandler(mWtfHandler);
+        }
+    }
 
     /**
      * Take a bundle, write it to a parcel and return the parcel.
@@ -217,4 +233,193 @@
         // return true
         assertTrue(BaseBundle.kindofEquals(bundle1, bundle2));
     }
+
+    @Test
+    public void kindofEquals_lazyValues() {
+        Parcelable p1 = new CustomParcelable(13, "Tiramisu");
+        Parcelable p2 = new CustomParcelable(13, "Tiramisu");
+
+        // 2 maps with live objects
+        Bundle a = new Bundle();
+        a.putParcelable("key1", p1);
+        Bundle b = new Bundle();
+        b.putParcelable("key1", p2);
+        assertTrue(Bundle.kindofEquals(a, b));
+
+        // 2 identical parcels
+        a.readFromParcel(getParcelledBundle(a));
+        a.setClassLoader(getClass().getClassLoader());
+        b.readFromParcel(getParcelledBundle(b));
+        b.setClassLoader(getClass().getClassLoader());
+        assertTrue(Bundle.kindofEquals(a, b));
+
+        // 2 lazy values with identical parcels inside
+        a.isEmpty();
+        b.isEmpty();
+        assertTrue(Bundle.kindofEquals(a, b));
+
+        // 1 lazy value vs 1 live object
+        a.getParcelable("key1");
+        assertFalse(Bundle.kindofEquals(a, b));
+
+        // 2 live objects
+        b.getParcelable("key1");
+        assertTrue(Bundle.kindofEquals(a, b));
+    }
+
+    @Test
+    public void kindofEquals_lazyValuesWithIdenticalParcels_returnsTrue() {
+        Parcelable p1 = new CustomParcelable(13, "Tiramisu");
+        Parcelable p2 = new CustomParcelable(13, "Tiramisu");
+        Bundle a = new Bundle();
+        a.putParcelable("key", p1);
+        a.readFromParcel(getParcelledBundle(a));
+        a.setClassLoader(getClass().getClassLoader());
+        Bundle b = new Bundle();
+        b.putParcelable("key", p2);
+        b.readFromParcel(getParcelledBundle(b));
+        b.setClassLoader(getClass().getClassLoader());
+        // 2 lazy values with identical parcels inside
+        a.isEmpty();
+        b.isEmpty();
+
+        assertTrue(Bundle.kindofEquals(a, b));
+    }
+
+    @Test
+    public void kindofEquals_lazyValuesAndDifferentClassLoaders_returnsFalse() {
+        Parcelable p1 = new CustomParcelable(13, "Tiramisu");
+        Parcelable p2 = new CustomParcelable(13, "Tiramisu");
+        Bundle a = new Bundle();
+        a.putParcelable("key", p1);
+        a.readFromParcel(getParcelledBundle(a));
+        a.setClassLoader(getClass().getClassLoader());
+        Bundle b = new Bundle();
+        b.putParcelable("key", p2);
+        b.readFromParcel(getParcelledBundle(b));
+        b.setClassLoader(Bundle.class.getClassLoader()); // BCP
+        // 2 lazy values with identical parcels inside
+        a.isEmpty();
+        b.isEmpty();
+
+        assertFalse(Bundle.kindofEquals(a, b));
+    }
+
+    @Test
+    public void kindofEquals_lazyValuesOfDifferentTypes_returnsFalse() {
+        Parcelable p = new CustomParcelable(13, "Tiramisu");
+        Parcelable[] ps = {p};
+        Bundle a = new Bundle();
+        a.putParcelable("key", p);
+        a.readFromParcel(getParcelledBundle(a));
+        a.setClassLoader(getClass().getClassLoader());
+        Bundle b = new Bundle();
+        b.putParcelableArray("key", ps);
+        b.readFromParcel(getParcelledBundle(b));
+        b.setClassLoader(getClass().getClassLoader());
+        a.isEmpty();
+        b.isEmpty();
+
+        assertFalse(Bundle.kindofEquals(a, b));
+    }
+
+    @Test
+    public void kindofEquals_lazyValuesWithDifferentLengths_returnsFalse() {
+        Parcelable p1 = new CustomParcelable(13, "Tiramisu");
+        Parcelable p2 = new CustomParcelable(13, "Tiramisuuuuuuuu");
+        Bundle a = new Bundle();
+        a.putParcelable("key", p1);
+        a.readFromParcel(getParcelledBundle(a));
+        a.setClassLoader(getClass().getClassLoader());
+        Bundle b = new Bundle();
+        b.putParcelable("key", p2);
+        b.readFromParcel(getParcelledBundle(b));
+        b.setClassLoader(getClass().getClassLoader());
+        a.isEmpty();
+        b.isEmpty();
+
+        assertFalse(Bundle.kindofEquals(a, b));
+    }
+
+    @Test
+    public void readWriteLengthMismatch_logsWtf() throws Exception {
+        mWtfHandler = Log.setWtfHandler((tag, e, system) -> {
+            throw new RuntimeException(e);
+        });
+        Parcelable parcelable = new CustomParcelable(13, "Tiramisu").setHasLengthMismatch(true);
+        Bundle bundle = new Bundle();
+        bundle.putParcelable("p", parcelable);
+        bundle.readFromParcel(getParcelledBundle(bundle));
+        bundle.setClassLoader(getClass().getClassLoader());
+        RuntimeException e = assertThrows(RuntimeException.class, () -> bundle.getParcelable("p"));
+        assertThat(e.getCause()).isInstanceOf(Log.TerribleFailure.class);
+    }
+
+    private static class CustomParcelable implements Parcelable {
+        public final int integer;
+        public final String string;
+        public boolean hasLengthMismatch;
+
+        CustomParcelable(int integer, String string) {
+            this.integer = integer;
+            this.string = string;
+        }
+
+        protected CustomParcelable(Parcel in) {
+            integer = in.readInt();
+            string = in.readString();
+            hasLengthMismatch = in.readBoolean();
+        }
+
+        public CustomParcelable setHasLengthMismatch(boolean hasLengthMismatch) {
+            this.hasLengthMismatch = hasLengthMismatch;
+            return this;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(integer);
+            out.writeString(string);
+            out.writeBoolean(hasLengthMismatch);
+            if (hasLengthMismatch) {
+                out.writeString("extra-write");
+            }
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+            if (!(other instanceof CustomParcelable)) {
+                return false;
+            }
+            CustomParcelable
+                    that = (CustomParcelable) other;
+            return integer == that.integer
+                    && hasLengthMismatch == that.hasLengthMismatch
+                    && string.equals(that.string);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(integer, string, hasLengthMismatch);
+        }
+
+        public static final Creator<CustomParcelable> CREATOR = new Creator<CustomParcelable>() {
+            @Override
+            public CustomParcelable createFromParcel(Parcel in) {
+                return new CustomParcelable(in);
+            }
+            @Override
+            public CustomParcelable[] newArray(int size) {
+                return new CustomParcelable[size];
+            }
+        };
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 5ecff44..7ce9b51 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -273,7 +273,7 @@
 
     public void disconnect() {
         synchronized (mProfileLock) {
-            mLocalAdapter.disconnectAllEnabledProfiles(mDevice);
+            mDevice.disconnect();
         }
         // Disconnect  PBAP server in case its connected
         // This is to ensure all the profiles are disconnected as some CK/Hs do not
@@ -314,7 +314,7 @@
         }
 
         mConnectAttempted = SystemClock.elapsedRealtime();
-        connectAllEnabledProfiles();
+        connectDevice();
     }
 
     public long getHiSyncId() {
@@ -371,7 +371,7 @@
         connect();
     }
 
-    private void connectAllEnabledProfiles() {
+    private void connectDevice() {
         synchronized (mProfileLock) {
             // Try to initialize the profiles if they were not.
             if (mProfiles.isEmpty()) {
@@ -386,7 +386,7 @@
                 return;
             }
 
-            mLocalAdapter.connectAllEnabledProfiles(mDevice);
+            mDevice.connect();
         }
     }
 
@@ -769,8 +769,8 @@
          * Otherwise, allow the connect on UUID change.
          */
         if ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
-            Log.d(TAG, "onUuidChanged: triggering connectAllEnabledProfiles");
-            connectAllEnabledProfiles();
+            Log.d(TAG, "onUuidChanged: triggering connectDevice");
+            connectDevice();
         }
 
         dispatchAttributesChanged();
diff --git a/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java b/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java
index 0aafb29..240ac01 100644
--- a/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java
+++ b/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java
@@ -80,7 +80,7 @@
     }
 
     @Override
-    public void onCancelled(PendingIntent intent) {
+    public void onCanceled(PendingIntent intent) {
         if (Log.isLoggable(getOwner().getTag(), Log.DEBUG)) {
             Log.d(getOwner().getTag(),
                     "pending intent registration " + getIdentity() + " canceled");
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 8955c28..d882705 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -1089,9 +1089,9 @@
         }
 
         @Override
-        public void onCancelled(PendingIntent intent) {
+        public void onCanceled(PendingIntent intent) {
             if (D) {
-                Log.d(TAG, mName + " provider registration " + getIdentity() + " cancelled");
+                Log.d(TAG, mName + " provider registration " + getIdentity() + " canceled");
             }
 
             synchronized (mLock) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java
deleted file mode 100644
index 9926953..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch;
-
-import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.provider.DeviceConfig;
-
-import com.android.server.testables.TestableDeviceConfig;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-
-/**
- * Tests for {@link AppSearchConfig}.
- *
- * <p>Build/Install/Run: atest FrameworksMockingServicesTests:AppSearchConfigTest
- */
-public class AppSearchConfigTest {
-    @Rule
-    public final TestableDeviceConfig.TestableDeviceConfigRule
-            mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
-
-    @Test
-    public void testDefaultValues_allCachedValue() {
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        assertThat(appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis()).isEqualTo(
-                AppSearchConfig.DEFAULT_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS);
-        assertThat(appSearchConfig.getCachedSamplingIntervalDefault()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForInitializeStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForSearchStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForGlobalSearchStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForOptimizeStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-        assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentSizeBytes()).isEqualTo(
-                AppSearchConfig.DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES);
-        assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentCount()).isEqualTo(
-                AppSearchConfig.DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT);
-        assertThat(appSearchConfig.getCachedBytesOptimizeThreshold()).isEqualTo(
-                AppSearchConfig.DEFAULT_BYTES_OPTIMIZE_THRESHOLD);
-        assertThat(appSearchConfig.getCachedTimeOptimizeThresholdMs()).isEqualTo(
-                AppSearchConfig.DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS);
-        assertThat(appSearchConfig.getCachedDocCountOptimizeThreshold()).isEqualTo(
-                AppSearchConfig.DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD);
-    }
-
-    @Test
-    public void testCustomizedValue_minTimeIntervalBetweenSamplesMillis() {
-        final long minTimeIntervalBetweenSamplesMillis = -1;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(minTimeIntervalBetweenSamplesMillis),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        assertThat(appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis()).isEqualTo(
-                minTimeIntervalBetweenSamplesMillis);
-    }
-
-    @Test
-    public void testCustomizedValueOverride_minTimeIntervalBetweenSamplesMillis() {
-        long minTimeIntervalBetweenSamplesMillis = -1;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(minTimeIntervalBetweenSamplesMillis),
-                false);
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        minTimeIntervalBetweenSamplesMillis = -2;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(minTimeIntervalBetweenSamplesMillis),
-                false);
-
-        assertThat(appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis()).isEqualTo(
-                minTimeIntervalBetweenSamplesMillis);
-    }
-
-    @Test
-    public void testCustomizedValue_allSamplingIntervals() {
-        final int samplingIntervalDefault = -1;
-        final int samplingIntervalPutDocumentStats = -2;
-        final int samplingIntervalBatchCallStats = -3;
-        final int samplingIntervalInitializeStats = -4;
-        final int samplingIntervalSearchStats = -5;
-        final int samplingIntervalGlobalSearchStats = -6;
-        final int samplingIntervalOptimizeStats = -7;
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-                Integer.toString(samplingIntervalBatchCallStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS,
-                Integer.toString(samplingIntervalInitializeStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS,
-                Integer.toString(samplingIntervalSearchStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS,
-                Integer.toString(samplingIntervalGlobalSearchStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS,
-                Integer.toString(samplingIntervalOptimizeStats),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        assertThat(appSearchConfig.getCachedSamplingIntervalDefault()).isEqualTo(
-                samplingIntervalDefault);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
-                samplingIntervalPutDocumentStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                samplingIntervalBatchCallStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForInitializeStats()).isEqualTo(
-                samplingIntervalInitializeStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForSearchStats()).isEqualTo(
-                samplingIntervalSearchStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForGlobalSearchStats()).isEqualTo(
-                samplingIntervalGlobalSearchStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForOptimizeStats()).isEqualTo(
-                samplingIntervalOptimizeStats);
-    }
-
-    @Test
-    public void testCustomizedValueOverride_allSamplingIntervals() {
-        int samplingIntervalDefault = -1;
-        int samplingIntervalPutDocumentStats = -2;
-        int samplingIntervalBatchCallStats = -3;
-        int samplingIntervalInitializeStats = -4;
-        int samplingIntervalSearchStats = -5;
-        int samplingIntervalGlobalSearchStats = -6;
-        int samplingIntervalOptimizeStats = -7;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-                Integer.toString(samplingIntervalBatchCallStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS,
-                Integer.toString(samplingIntervalInitializeStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS,
-                Integer.toString(samplingIntervalSearchStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS,
-                Integer.toString(samplingIntervalGlobalSearchStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS,
-                Integer.toString(samplingIntervalOptimizeStats),
-                false);
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        // Overrides
-        samplingIntervalDefault = -4;
-        samplingIntervalPutDocumentStats = -5;
-        samplingIntervalBatchCallStats = -6;
-        samplingIntervalInitializeStats = -7;
-        samplingIntervalSearchStats = -8;
-        samplingIntervalGlobalSearchStats = -9;
-        samplingIntervalOptimizeStats = -10;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-                Integer.toString(samplingIntervalBatchCallStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_INITIALIZE_STATS,
-                Integer.toString(samplingIntervalInitializeStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_SEARCH_STATS,
-                Integer.toString(samplingIntervalSearchStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_GLOBAL_SEARCH_STATS,
-                Integer.toString(samplingIntervalGlobalSearchStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_OPTIMIZE_STATS,
-                Integer.toString(samplingIntervalOptimizeStats),
-                false);
-
-        assertThat(appSearchConfig.getCachedSamplingIntervalDefault()).isEqualTo(
-                samplingIntervalDefault);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
-                samplingIntervalPutDocumentStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                samplingIntervalBatchCallStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForInitializeStats()).isEqualTo(
-                samplingIntervalInitializeStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForSearchStats()).isEqualTo(
-                samplingIntervalSearchStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForGlobalSearchStats()).isEqualTo(
-                samplingIntervalGlobalSearchStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForOptimizeStats()).isEqualTo(
-                samplingIntervalOptimizeStats);
-    }
-
-    /**
-     * Tests if we fall back to {@link AppSearchConfig#DEFAULT_SAMPLING_INTERVAL} if both default
-     * sampling interval and custom value are not set in DeviceConfig, and there is some other
-     * sampling interval set.
-     */
-    @Test
-    public void testFallbackToDefaultSamplingValue_useHardCodedDefault() {
-        final int samplingIntervalPutDocumentStats = -1;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
-                samplingIntervalPutDocumentStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                AppSearchConfig.DEFAULT_SAMPLING_INTERVAL);
-    }
-
-    // Tests if we fall back to configured default sampling interval if custom value is not set in
-    // DeviceConfig.
-    @Test
-    public void testFallbackDefaultSamplingValue_useConfiguredDefault() {
-        final int samplingIntervalPutDocumentStats = -1;
-        final int samplingIntervalDefault = -2;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
-                samplingIntervalPutDocumentStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                samplingIntervalDefault);
-    }
-
-    // Tests that cached values should reflect latest values in DeviceConfig.
-    @Test
-    public void testFallbackDefaultSamplingValue_defaultValueChanged() {
-        int samplingIntervalPutDocumentStats = -1;
-        int samplingIntervalDefault = -2;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        // Sampling values changed.
-        samplingIntervalPutDocumentStats = -3;
-        samplingIntervalDefault = -4;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(samplingIntervalPutDocumentStats),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-
-        assertThat(appSearchConfig.getCachedSamplingIntervalForPutDocumentStats()).isEqualTo(
-                samplingIntervalPutDocumentStats);
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                samplingIntervalDefault);
-    }
-
-    // Tests default sampling interval won't affect custom sampling intervals if they are set.
-    @Test
-    public void testShouldNotFallBack_ifValueConfigured() {
-        int samplingIntervalDefault = -1;
-        int samplingIntervalBatchCallStats = -2;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-                Integer.toString(samplingIntervalBatchCallStats),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        // Default sampling interval changed.
-        samplingIntervalDefault = -3;
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(samplingIntervalDefault),
-                false);
-
-        assertThat(appSearchConfig.getCachedSamplingIntervalForBatchCallStats()).isEqualTo(
-                samplingIntervalBatchCallStats);
-    }
-
-    @Test
-    public void testCustomizedValue_maxDocument() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES,
-                Integer.toString(2001),
-                /*makeDefault=*/ false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT,
-                Integer.toString(2002),
-                /*makeDefault=*/ false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-        assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentSizeBytes()).isEqualTo(2001);
-        assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentCount()).isEqualTo(2002);
-    }
-
-    @Test
-    public void testCustomizedValue_optimizeThreshold() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_BYTES_OPTIMIZE_THRESHOLD,
-                Integer.toString(147147),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
-                Integer.toString(258258),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
-                Integer.toString(369369),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        assertThat(appSearchConfig.getCachedBytesOptimizeThreshold()).isEqualTo(147147);
-        assertThat(appSearchConfig.getCachedTimeOptimizeThresholdMs()).isEqualTo(258258);
-        assertThat(appSearchConfig.getCachedDocCountOptimizeThreshold()).isEqualTo(369369);
-    }
-
-    @Test
-    public void testCustomizedValueOverride_optimizeThreshold() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_BYTES_OPTIMIZE_THRESHOLD,
-                Integer.toString(147147),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
-                Integer.toString(258258),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
-                Integer.toString(369369),
-                false);
-
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        // Override
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_BYTES_OPTIMIZE_THRESHOLD,
-                Integer.toString(741741),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
-                Integer.toString(852852),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
-                Integer.toString(963963),
-                false);
-
-        assertThat(appSearchConfig.getCachedBytesOptimizeThreshold()).isEqualTo(741741);
-        assertThat(appSearchConfig.getCachedTimeOptimizeThresholdMs()).isEqualTo(852852);
-        assertThat(appSearchConfig.getCachedDocCountOptimizeThreshold()).isEqualTo(963963);
-    }
-
-    @Test
-    public void testNotUsable_afterClose() {
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-
-        appSearchConfig.close();
-
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedMinTimeIntervalBetweenSamplesMillis());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalDefault());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalForBatchCallStats());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalForPutDocumentStats());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalForInitializeStats());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalForSearchStats());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalForGlobalSearchStats());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedSamplingIntervalForOptimizeStats());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedBytesOptimizeThreshold());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedTimeOptimizeThresholdMs());
-        Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
-                IllegalStateException.class,
-                () -> appSearchConfig.getCachedDocCountOptimizeThreshold());
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/FrameworkLimitConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/appsearch/FrameworkLimitConfigTest.java
deleted file mode 100644
index 088ed27..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/appsearch/FrameworkLimitConfigTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch;
-
-import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.provider.DeviceConfig;
-
-import com.android.server.testables.TestableDeviceConfig;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-/**
- * Tests for {@link FrameworkLimitConfig}.
- *
- * <p>Build/Install/Run: atest FrameworksMockingServicesTests:AppSearchConfigTest
- */
-public class FrameworkLimitConfigTest {
-    @Rule
-    public final TestableDeviceConfig.TestableDeviceConfigRule
-            mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
-
-    @Test
-    public void testDefaultValues() {
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-        FrameworkLimitConfig config = new FrameworkLimitConfig(appSearchConfig);
-        assertThat(config.getMaxDocumentSizeBytes()).isEqualTo(
-                AppSearchConfig.DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES);
-        assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentCount()).isEqualTo(
-                AppSearchConfig.DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT);
-    }
-
-    @Test
-    public void testCustomizedValues() {
-        AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-        FrameworkLimitConfig config = new FrameworkLimitConfig(appSearchConfig);
-        DeviceConfig.setProperty(
-                DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES,
-                "2001",
-                /*makeDefault=*/ false);
-        DeviceConfig.setProperty(
-                DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT,
-                "2002",
-                /*makeDefault=*/ false);
-
-        assertThat(config.getMaxDocumentSizeBytes()).isEqualTo(2001);
-        assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentCount()).isEqualTo(2002);
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/OWNERS b/services/tests/mockingservicestests/src/com/android/server/appsearch/OWNERS
deleted file mode 100644
index 24f6b0b..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/appsearch/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /apex/appsearch/OWNERS
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
deleted file mode 100644
index 28fcaee..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.stats;
-
-import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.SystemClock;
-import android.provider.DeviceConfig;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.appsearch.AppSearchConfig;
-import com.android.server.appsearch.external.localstorage.stats.CallStats;
-import com.android.server.testables.TestableDeviceConfig;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnitRunner;
-
-/**
- * Tests covering the functionalities in {@link PlatformLogger} requiring overriding some flags
- * in {@link DeviceConfig}.
- *
- * <p>To add tests NOT rely on overriding the configs, please add them in
- * the tests for {@link PlatformLogger} in servicetests.
- */
-@RunWith(MockitoJUnitRunner.class)
-public class PlatformLoggerTest {
-    private static final int TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
-    private static final int TEST_DEFAULT_SAMPLING_INTERVAL = 10;
-    private static final String TEST_PACKAGE_NAME = "packageName";
-    private AppSearchConfig mAppSearchConfig;
-
-    @Rule
-    public final TestableDeviceConfig.TestableDeviceConfigRule
-            mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
-
-    @Before
-    public void setUp() throws Exception {
-        mAppSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-    }
-
-    @Test
-    public void testCreateExtraStatsLocked_samplingIntervalNotSet_returnsDefault() {
-        PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(),
-                mAppSearchConfig);
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(TEST_DEFAULT_SAMPLING_INTERVAL),
-                false);
-
-        // Make sure default sampling interval is used if there is no config set.
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_UNKNOWN).mSamplingInterval).isEqualTo(
-                TEST_DEFAULT_SAMPLING_INTERVAL);
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
-                TEST_DEFAULT_SAMPLING_INTERVAL);
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_SEARCH).mSamplingInterval).isEqualTo(
-                TEST_DEFAULT_SAMPLING_INTERVAL);
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
-                TEST_DEFAULT_SAMPLING_INTERVAL);
-    }
-
-
-    @Test
-    public void testCreateExtraStatsLocked_samplingIntervalSet_returnsConfigured() {
-        int putDocumentSamplingInterval = 1;
-        int batchCallSamplingInterval = 2;
-        PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(), mAppSearchConfig);
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Integer.toString(TEST_DEFAULT_SAMPLING_INTERVAL),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
-                Integer.toString(putDocumentSamplingInterval),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_FOR_BATCH_CALL_STATS,
-                Integer.toString(batchCallSamplingInterval),
-                false);
-
-        // The default sampling interval should be used if no sampling interval is
-        // provided for certain call type.
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_INITIALIZE).mSamplingInterval).isEqualTo(
-                TEST_DEFAULT_SAMPLING_INTERVAL);
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_FLUSH).mSamplingInterval).isEqualTo(
-                TEST_DEFAULT_SAMPLING_INTERVAL);
-
-        // The configured sampling interval is used if sampling interval is available
-        // for certain call type.
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_PUT_DOCUMENT).mSamplingInterval).isEqualTo(
-                putDocumentSamplingInterval);
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_PUT_DOCUMENTS).mSamplingInterval).isEqualTo(
-                batchCallSamplingInterval);
-        assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
-                CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH).mSamplingInterval).isEqualTo(
-                batchCallSamplingInterval);
-    }
-
-    @Test
-    public void testShouldLogForTypeLocked_trueWhenSampleIntervalIsOne() {
-        final String testPackageName = "packageName";
-        PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(),
-                mAppSearchConfig);
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Long.toString(1),
-                false);
-
-        // Sample should always be logged for the first time if sampling is disabled(value is one).
-        assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
-        assertThat(logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
-    }
-
-    @Test
-    public void testShouldLogForTypeLocked_falseWhenSampleIntervalIsNegative() {
-        final String testPackageName = "packageName";
-        PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(),
-                mAppSearchConfig);
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Long.toString(-1),
-                false);
-
-        // Makes sure sample will be excluded due to sampling if sample interval is negative.
-        assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
-        // Skipped count should be 0 since it doesn't pass the sampling.
-        assertThat(logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
-    }
-
-    @Test
-    public void testShouldLogForTypeLocked_falseWhenWithinCoolOffInterval() {
-        // Next sample won't be excluded due to sampling.
-        final int samplingInterval = 1;
-        // Next sample would guaranteed to be too close.
-        final int minTimeIntervalBetweenSamplesMillis = Integer.MAX_VALUE;
-        final String testPackageName = "packageName";
-        PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(),
-                mAppSearchConfig);
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Long.toString(samplingInterval),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(minTimeIntervalBetweenSamplesMillis),
-                false);
-        logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
-
-        // Makes sure sample will be excluded due to rate limiting if samples are too close.
-        assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
-        assertThat(logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(1);
-    }
-
-    @Test
-    public void testShouldLogForTypeLocked_trueWhenOutsideOfCoolOffInterval() {
-        // Next sample won't be excluded due to sampling.
-        final int samplingInterval = 1;
-        // Next sample would guaranteed to be included.
-        final int minTimeIntervalBetweenSamplesMillis = 0;
-        final String testPackageName = "packageName";
-        PlatformLogger logger = new PlatformLogger(
-                ApplicationProvider.getApplicationContext(),
-                mAppSearchConfig);
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_SAMPLING_INTERVAL_DEFAULT,
-                Long.toString(samplingInterval),
-                false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
-                AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
-                Long.toString(minTimeIntervalBetweenSamplesMillis),
-                false);
-        logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
-
-        // Makes sure sample will be logged if it is not too close to previous sample.
-        assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
-        assertThat(logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT).mSkippedSampleCount).isEqualTo(0);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
deleted file mode 100644
index 0d475c0..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/169883602): This is purposely a different package from the path so that it can access
-// AppSearchImpl's methods without having to make them public. This should be replaced by proper
-// global query integration tests that can test AppSearchImpl-VisibilityStore integration logic.
-package com.android.server.appsearch.external.localstorage;
-
-import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.PackageIdentifier;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.PackageManager;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.compatibility.common.util.SystemUtil;
-import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.Mockito;
-
-import java.util.Collections;
-import java.util.Map;
-
-/** This tests AppSearchImpl when it's running with a platform-backed VisibilityStore. */
-public class AppSearchImplPlatformTest {
-    /**
-     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
-     */
-    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
-
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-    private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
-    private Context mContext;
-    private AppSearchImpl mAppSearchImpl;
-    private VisibilityStoreImpl mVisibilityStore;
-    private int mGlobalQuerierUid;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = ApplicationProvider.getApplicationContext();
-        mContext = new ContextWrapper(context) {
-            @Override
-            public Context createContextAsUser(UserHandle user, int flags) {
-                return new ContextWrapper(super.createContextAsUser(user, flags)) {
-                    @Override
-                    public PackageManager getPackageManager() {
-                        return getMockPackageManager(user);
-                    }
-                };
-            }
-
-            @Override
-            public PackageManager getPackageManager() {
-                return createContextAsUser(getUser(), /*flags=*/ 0).getPackageManager();
-            }
-        };
-
-        // Give ourselves global query permissions
-        mAppSearchImpl = AppSearchImpl.create(
-                mTemporaryFolder.newFolder(),
-                new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
-        mVisibilityStore = VisibilityStoreImpl.create(mAppSearchImpl, mContext);
-        mGlobalQuerierUid =
-                mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
-    }
-
-    @Test
-    public void testSetSchema_existingSchemaRetainsVisibilitySetting() throws Exception {
-        // Values for a "foo" client
-        String packageNameFoo = "packageFoo";
-        byte[] sha256CertFoo = new byte[] {10};
-        int uidFoo = 1;
-
-        // Make sure foo package will pass package manager checks.
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-
-        // Make sure we have global query privileges and "foo" doesn't
-        when(mockPackageManager.checkPermission(
-                READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-        when(mockPackageManager.checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo))
-                .thenReturn(PERMISSION_DENIED);
-
-        // Set schema1
-        String prefix = PrefixUtil.createPrefix("package", "database");
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "schema1",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-
-        // "schema1" is platform hidden now and package visible to package1
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                mGlobalQuerierUid,
-                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-
-        // Add a new schema, and include the already-existing "schema1"
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("schema1").build(),
-                        new AppSearchSchema.Builder("schema2").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "schema1",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-
-        // Check that "schema1" still has the same visibility settings
-        SystemUtil.runWithShellPermissionIdentity(() -> assertThat(
-                mVisibilityStore.isSchemaSearchableByCaller(
-                        "package",
-                        "database",
-                        prefix + "schema1",
-                        mGlobalQuerierUid,
-                        /*callerHasSystemAccess=*/ true))
-                        .isFalse(),
-                READ_GLOBAL_APP_SEARCH_DATA);
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-
-        // "schema2" has default visibility settings
-        SystemUtil.runWithShellPermissionIdentity(() -> assertThat(
-                mVisibilityStore.isSchemaSearchableByCaller(
-                        "package",
-                        "database",
-                        prefix + "schema2",
-                        mGlobalQuerierUid,
-                        /*callerHasSystemAccess=*/ true))
-                        .isTrue(),
-                READ_GLOBAL_APP_SEARCH_DATA);
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema2",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-    }
-
-    @Test
-    public void testRemoveSchema_removedFromVisibilityStore() throws Exception {
-        // Values for a "foo" client
-        String packageNameFoo = "packageFoo";
-        byte[] sha256CertFoo = new byte[] {10};
-        int uidFoo = 1;
-
-        // Make sure foo package will pass package manager checks.
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-
-        // Make sure we have global query privileges and "foo" doesn't
-        when(mockPackageManager.checkPermission(
-                READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-        when(mockPackageManager.checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo))
-                .thenReturn(PERMISSION_DENIED);
-
-        String prefix = PrefixUtil.createPrefix("package", "database");
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "schema1",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-
-        // "schema1" is platform hidden now and package accessible
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                mGlobalQuerierUid,
-                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-
-        // Remove "schema1" by force overriding
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                /*schemas=*/ Collections.emptyList(),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ true,
-                /*schemaVersion=*/ 0);
-
-        // Check that "schema1" is no longer considered platform hidden or package accessible
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                mGlobalQuerierUid,
-                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-
-        // Add "schema1" back, it gets default visibility settings which means it's not platform
-        // hidden and not package accessible
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                mGlobalQuerierUid,
-                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "schema1",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-    }
-
-    @Test
-    public void testSetSchema_defaultPlatformVisible() throws Exception {
-        // Make sure we have global query privileges
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.checkPermission(
-                READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-
-        String prefix = PrefixUtil.createPrefix("package", "database");
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "Schema",
-                mGlobalQuerierUid,
-                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-    }
-
-    @Test
-    public void testSetSchema_platformHidden() throws Exception {
-        // Make sure we have global query privileges
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.checkPermission(
-                READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-
-        String prefix = PrefixUtil.createPrefix("package", "database");
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.singletonList("Schema"),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                prefix + "Schema",
-                mGlobalQuerierUid,
-                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-    }
-
-    @Test
-    public void testSetSchema_defaultNotVisibleToPackages() throws Exception {
-        String packageName = "com.package";
-
-        // Make sure package doesn't global query privileges
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.checkPermission(
-                READ_GLOBAL_APP_SEARCH_DATA, packageName)).thenReturn(PERMISSION_DENIED);
-
-        String prefix = PrefixUtil.createPrefix("package", "database");
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-        assertThat(mVisibilityStore
-                                .isSchemaSearchableByCaller(
-                                        "package",
-                                        "database",
-                                        prefix + "Schema",
-                                        /*callerUid=*/ 42,
-                                        /*callerHasSystemAccess=*/ false))
-                .isFalse();
-    }
-
-    @Test
-    public void testSetSchema_visibleToPackages() throws Exception {
-        // Values for a "foo" client
-        String packageNameFoo = "packageFoo";
-        byte[] sha256CertFoo = new byte[] {10};
-        int uidFoo = 1;
-
-        // Make sure foo package will pass package manager checks.
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-
-        // Make sure foo doesn't have global query privileges
-        when(mockPackageManager.checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo))
-                .thenReturn(PERMISSION_DENIED);
-
-        String prefix = PrefixUtil.createPrefix("package", "database");
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
-                mVisibilityStore,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "Schema",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
-                /*forceOverride=*/ false,
-                /*schemaVersion=*/ 0);
-        assertThat(mVisibilityStore
-                                .isSchemaSearchableByCaller(
-                                        "package",
-                                        "database",
-                                        prefix + "Schema",
-                                        uidFoo,
-                                        /*callerHasSystemAccess=*/ false))
-                .isTrue();
-    }
-
-    @NonNull
-    private PackageManager getMockPackageManager(@NonNull UserHandle user) {
-        PackageManager pm = mMockPackageManagers.get(user);
-        if (pm == null) {
-            pm = Mockito.mock(PackageManager.class);
-            mMockPackageManagers.put(user, pm);
-        }
-        return pm;
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/FrameworkOptimizeStrategyTest.java b/services/tests/servicestests/src/com/android/server/appsearch/FrameworkOptimizeStrategyTest.java
deleted file mode 100644
index 8389c85..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/FrameworkOptimizeStrategyTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.appsearch;
-
-import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.server.appsearch.icing.proto.GetOptimizeInfoResultProto;
-import com.android.server.appsearch.icing.proto.StatusProto;
-
-import org.junit.Test;
-
-public class FrameworkOptimizeStrategyTest {
-    AppSearchConfig mAppSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
-    FrameworkOptimizeStrategy mFrameworkOptimizeStrategy =
-            new FrameworkOptimizeStrategy(mAppSearchConfig);
-
-    @Test
-    public void testShouldOptimize_byteThreshold() {
-        GetOptimizeInfoResultProto optimizeInfo =
-                GetOptimizeInfoResultProto.newBuilder()
-                        .setTimeSinceLastOptimizeMs(0)
-                        .setEstimatedOptimizableBytes(
-                                mAppSearchConfig.getCachedBytesOptimizeThreshold())
-                        .setOptimizableDocs(0)
-                        .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
-                        .build();
-        assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
-    }
-
-    @Test
-    public void testShouldNotOptimize_timeThreshold() {
-        GetOptimizeInfoResultProto optimizeInfo =
-                GetOptimizeInfoResultProto.newBuilder()
-                        .setTimeSinceLastOptimizeMs(
-                                mAppSearchConfig.getCachedTimeOptimizeThresholdMs())
-                        .setEstimatedOptimizableBytes(0)
-                        .setOptimizableDocs(0)
-                        .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
-                        .build();
-        assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
-    }
-
-    @Test
-    public void testShouldOptimize_docCountThreshold() {
-        GetOptimizeInfoResultProto optimizeInfo =
-                GetOptimizeInfoResultProto.newBuilder()
-                        .setTimeSinceLastOptimizeMs(0)
-                        .setEstimatedOptimizableBytes(0)
-                        .setOptimizableDocs(
-                                mAppSearchConfig.getCachedDocCountOptimizeThreshold())
-                        .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
-                        .build();
-        assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/OWNERS b/services/tests/servicestests/src/com/android/server/appsearch/OWNERS
deleted file mode 100644
index ebe9e4e..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /apex/appsearch/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
deleted file mode 100644
index f40a5ad..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ /dev/null
@@ -1,3272 +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 com.android.server.appsearch.external.localstorage;
-
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.addPrefixToDocument;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.createPrefix;
-import static com.android.server.appsearch.external.localstorage.util.PrefixUtil.removePrefixesFromDocument;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResultPage;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.SetSchemaResponse;
-import android.app.appsearch.StorageInfo;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.content.Context;
-import android.os.Process;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.icing.proto.DocumentProto;
-import com.android.server.appsearch.icing.proto.GetOptimizeInfoResultProto;
-import com.android.server.appsearch.icing.proto.PersistType;
-import com.android.server.appsearch.icing.proto.PropertyConfigProto;
-import com.android.server.appsearch.icing.proto.PropertyProto;
-import com.android.server.appsearch.icing.proto.PutResultProto;
-import com.android.server.appsearch.icing.proto.SchemaProto;
-import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto;
-import com.android.server.appsearch.icing.proto.SearchResultProto;
-import com.android.server.appsearch.icing.proto.SearchSpecProto;
-import com.android.server.appsearch.icing.proto.StatusProto;
-import com.android.server.appsearch.icing.proto.StorageInfoProto;
-import com.android.server.appsearch.icing.proto.StringIndexingConfig;
-import com.android.server.appsearch.icing.proto.TermMatchType;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class AppSearchImplTest {
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-    private AppSearchImpl mAppSearchImpl;
-    /**
-     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
-     */
-    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
-
-    @Before
-    public void setUp() throws Exception {
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-    }
-
-    /**
-     * Ensure that we can rewrite an incoming schema type by adding the database as a prefix. While
-     * also keeping any other existing schema types that may already be part of Icing's persisted
-     * schema.
-     */
-    @Test
-    public void testRewriteSchema_addType() throws Exception {
-        SchemaProto.Builder existingSchemaBuilder =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$existingDatabase/Foo")
-                                        .build());
-
-        // Create a copy so we can modify it.
-        List<SchemaTypeConfigProto> existingTypes =
-                new ArrayList<>(existingSchemaBuilder.getTypesList());
-        SchemaTypeConfigProto schemaTypeConfigProto1 =
-                SchemaTypeConfigProto.newBuilder().setSchemaType("Foo").build();
-        SchemaTypeConfigProto schemaTypeConfigProto2 =
-                SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType("TestType")
-                        .addProperties(
-                                PropertyConfigProto.newBuilder()
-                                        .setPropertyName("subject")
-                                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                        .setCardinality(
-                                                PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                        .setStringIndexingConfig(
-                                                StringIndexingConfig.newBuilder()
-                                                        .setTokenizerType(
-                                                                StringIndexingConfig.TokenizerType
-                                                                        .Code.PLAIN)
-                                                        .setTermMatchType(TermMatchType.Code.PREFIX)
-                                                        .build())
-                                        .build())
-                        .addProperties(
-                                PropertyConfigProto.newBuilder()
-                                        .setPropertyName("link")
-                                        .setDataType(PropertyConfigProto.DataType.Code.DOCUMENT)
-                                        .setCardinality(
-                                                PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                        .setSchemaType("RefType")
-                                        .build())
-                        .build();
-        SchemaTypeConfigProto schemaTypeConfigProto3 =
-                SchemaTypeConfigProto.newBuilder().setSchemaType("RefType").build();
-        SchemaProto newSchema =
-                SchemaProto.newBuilder()
-                        .addTypes(schemaTypeConfigProto1)
-                        .addTypes(schemaTypeConfigProto2)
-                        .addTypes(schemaTypeConfigProto3)
-                        .build();
-
-        AppSearchImpl.RewrittenSchemaResults rewrittenSchemaResults =
-                AppSearchImpl.rewriteSchema(
-                        createPrefix("package", "newDatabase"), existingSchemaBuilder, newSchema);
-
-        // We rewrote all the new types that were added. And nothing was removed.
-        assertThat(rewrittenSchemaResults.mRewrittenPrefixedTypes.keySet())
-                .containsExactly(
-                        "package$newDatabase/Foo",
-                        "package$newDatabase/TestType",
-                        "package$newDatabase/RefType");
-        assertThat(
-                        rewrittenSchemaResults
-                                .mRewrittenPrefixedTypes
-                                .get("package$newDatabase/Foo")
-                                .getSchemaType())
-                .isEqualTo("package$newDatabase/Foo");
-        assertThat(
-                        rewrittenSchemaResults
-                                .mRewrittenPrefixedTypes
-                                .get("package$newDatabase/TestType")
-                                .getSchemaType())
-                .isEqualTo("package$newDatabase/TestType");
-        assertThat(
-                        rewrittenSchemaResults
-                                .mRewrittenPrefixedTypes
-                                .get("package$newDatabase/RefType")
-                                .getSchemaType())
-                .isEqualTo("package$newDatabase/RefType");
-        assertThat(rewrittenSchemaResults.mDeletedPrefixedTypes).isEmpty();
-
-        SchemaProto expectedSchema =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$newDatabase/Foo")
-                                        .build())
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$newDatabase/TestType")
-                                        .addProperties(
-                                                PropertyConfigProto.newBuilder()
-                                                        .setPropertyName("subject")
-                                                        .setDataType(
-                                                                PropertyConfigProto.DataType.Code
-                                                                        .STRING)
-                                                        .setCardinality(
-                                                                PropertyConfigProto.Cardinality.Code
-                                                                        .OPTIONAL)
-                                                        .setStringIndexingConfig(
-                                                                StringIndexingConfig.newBuilder()
-                                                                        .setTokenizerType(
-                                                                                StringIndexingConfig
-                                                                                        .TokenizerType
-                                                                                        .Code.PLAIN)
-                                                                        .setTermMatchType(
-                                                                                TermMatchType.Code
-                                                                                        .PREFIX)
-                                                                        .build())
-                                                        .build())
-                                        .addProperties(
-                                                PropertyConfigProto.newBuilder()
-                                                        .setPropertyName("link")
-                                                        .setDataType(
-                                                                PropertyConfigProto.DataType.Code
-                                                                        .DOCUMENT)
-                                                        .setCardinality(
-                                                                PropertyConfigProto.Cardinality.Code
-                                                                        .OPTIONAL)
-                                                        .setSchemaType(
-                                                                "package$newDatabase/RefType")
-                                                        .build())
-                                        .build())
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$newDatabase/RefType")
-                                        .build())
-                        .build();
-
-        existingTypes.addAll(expectedSchema.getTypesList());
-        assertThat(existingSchemaBuilder.getTypesList()).containsExactlyElementsIn(existingTypes);
-    }
-
-    /**
-     * Ensure that we track all types that were rewritten in the input schema. Even if they were not
-     * technically "added" to the existing schema.
-     */
-    @Test
-    public void testRewriteSchema_rewriteType() throws Exception {
-        SchemaProto.Builder existingSchemaBuilder =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$existingDatabase/Foo")
-                                        .build());
-
-        SchemaProto newSchema =
-                SchemaProto.newBuilder()
-                        .addTypes(SchemaTypeConfigProto.newBuilder().setSchemaType("Foo").build())
-                        .build();
-
-        AppSearchImpl.RewrittenSchemaResults rewrittenSchemaResults =
-                AppSearchImpl.rewriteSchema(
-                        createPrefix("package", "existingDatabase"),
-                        existingSchemaBuilder,
-                        newSchema);
-
-        // Nothing was removed, but the method did rewrite the type name.
-        assertThat(rewrittenSchemaResults.mRewrittenPrefixedTypes.keySet())
-                .containsExactly("package$existingDatabase/Foo");
-        assertThat(rewrittenSchemaResults.mDeletedPrefixedTypes).isEmpty();
-
-        // Same schema since nothing was added.
-        SchemaProto expectedSchema = existingSchemaBuilder.build();
-        assertThat(existingSchemaBuilder.getTypesList())
-                .containsExactlyElementsIn(expectedSchema.getTypesList());
-    }
-
-    /**
-     * Ensure that we track which types from the existing schema are deleted when a new schema is
-     * set.
-     */
-    @Test
-    public void testRewriteSchema_deleteType() throws Exception {
-        SchemaProto.Builder existingSchemaBuilder =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$existingDatabase/Foo")
-                                        .build());
-
-        SchemaProto newSchema =
-                SchemaProto.newBuilder()
-                        .addTypes(SchemaTypeConfigProto.newBuilder().setSchemaType("Bar").build())
-                        .build();
-
-        AppSearchImpl.RewrittenSchemaResults rewrittenSchemaResults =
-                AppSearchImpl.rewriteSchema(
-                        createPrefix("package", "existingDatabase"),
-                        existingSchemaBuilder,
-                        newSchema);
-
-        // Bar type was rewritten, but Foo ended up being deleted since it wasn't included in the
-        // new schema.
-        assertThat(rewrittenSchemaResults.mRewrittenPrefixedTypes)
-                .containsKey("package$existingDatabase/Bar");
-        assertThat(rewrittenSchemaResults.mRewrittenPrefixedTypes.keySet().size()).isEqualTo(1);
-        assertThat(rewrittenSchemaResults.mDeletedPrefixedTypes)
-                .containsExactly("package$existingDatabase/Foo");
-
-        // Same schema since nothing was added.
-        SchemaProto expectedSchema =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$existingDatabase/Bar")
-                                        .build())
-                        .build();
-
-        assertThat(existingSchemaBuilder.getTypesList())
-                .containsExactlyElementsIn(expectedSchema.getTypesList());
-    }
-
-    @Test
-    public void testAddDocumentTypePrefix() {
-        DocumentProto insideDocument =
-                DocumentProto.newBuilder()
-                        .setUri("inside-id")
-                        .setSchema("type")
-                        .setNamespace("namespace")
-                        .build();
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id")
-                        .setSchema("type")
-                        .setNamespace("namespace")
-                        .addProperties(PropertyProto.newBuilder().addDocumentValues(insideDocument))
-                        .build();
-
-        DocumentProto expectedInsideDocument =
-                DocumentProto.newBuilder()
-                        .setUri("inside-id")
-                        .setSchema("package$databaseName/type")
-                        .setNamespace("package$databaseName/namespace")
-                        .build();
-        DocumentProto expectedDocumentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id")
-                        .setSchema("package$databaseName/type")
-                        .setNamespace("package$databaseName/namespace")
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .addDocumentValues(expectedInsideDocument))
-                        .build();
-
-        DocumentProto.Builder actualDocument = documentProto.toBuilder();
-        addPrefixToDocument(actualDocument, createPrefix("package", "databaseName"));
-        assertThat(actualDocument.build()).isEqualTo(expectedDocumentProto);
-    }
-
-    @Test
-    public void testRemoveDocumentTypePrefixes() throws Exception {
-        DocumentProto insideDocument =
-                DocumentProto.newBuilder()
-                        .setUri("inside-id")
-                        .setSchema("package$databaseName/type")
-                        .setNamespace("package$databaseName/namespace")
-                        .build();
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id")
-                        .setSchema("package$databaseName/type")
-                        .setNamespace("package$databaseName/namespace")
-                        .addProperties(PropertyProto.newBuilder().addDocumentValues(insideDocument))
-                        .build();
-
-        DocumentProto expectedInsideDocument =
-                DocumentProto.newBuilder()
-                        .setUri("inside-id")
-                        .setSchema("type")
-                        .setNamespace("namespace")
-                        .build();
-
-        DocumentProto expectedDocumentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id")
-                        .setSchema("type")
-                        .setNamespace("namespace")
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .addDocumentValues(expectedInsideDocument))
-                        .build();
-
-        DocumentProto.Builder actualDocument = documentProto.toBuilder();
-        assertThat(removePrefixesFromDocument(actualDocument)).isEqualTo("package$databaseName/");
-        assertThat(actualDocument.build()).isEqualTo(expectedDocumentProto);
-    }
-
-    @Test
-    public void testRemoveDatabasesFromDocumentThrowsException() {
-        // Set two different database names in the document, which should never happen
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id")
-                        .setSchema("prefix1/type")
-                        .setNamespace("prefix2/namespace")
-                        .build();
-
-        DocumentProto.Builder actualDocument = documentProto.toBuilder();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class, () -> removePrefixesFromDocument(actualDocument));
-        assertThat(e).hasMessageThat().contains("Found unexpected multiple prefix names");
-    }
-
-    @Test
-    public void testNestedRemoveDatabasesFromDocumentThrowsException() {
-        // Set two different database names in the outer and inner document, which should never
-        // happen.
-        DocumentProto insideDocument =
-                DocumentProto.newBuilder()
-                        .setUri("inside-id")
-                        .setSchema("prefix1/type")
-                        .setNamespace("prefix1/namespace")
-                        .build();
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id")
-                        .setSchema("prefix2/type")
-                        .setNamespace("prefix2/namespace")
-                        .addProperties(PropertyProto.newBuilder().addDocumentValues(insideDocument))
-                        .build();
-
-        DocumentProto.Builder actualDocument = documentProto.toBuilder();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class, () -> removePrefixesFromDocument(actualDocument));
-        assertThat(e).hasMessageThat().contains("Found unexpected multiple prefix names");
-    }
-
-    @Test
-    public void testTriggerCheckOptimizeByMutationSize() throws Exception {
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert a document and then remove it to generate garbage.
-        GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
-        mAppSearchImpl.remove(
-                "package", "database", "namespace", "id", /*removeStatsBuilder=*/ null);
-
-        // Verify there is garbage documents.
-        GetOptimizeInfoResultProto optimizeInfo = mAppSearchImpl.getOptimizeInfoResultLocked();
-        assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(1);
-
-        // Increase mutation counter and stop before reach the threshold
-        mAppSearchImpl.checkForOptimize(
-                AppSearchImpl.CHECK_OPTIMIZE_INTERVAL - 1, /*builder=*/ null);
-
-        // Verify the optimize() isn't triggered.
-        optimizeInfo = mAppSearchImpl.getOptimizeInfoResultLocked();
-        assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(1);
-
-        // Increase the counter and reach the threshold, optimize() should be triggered.
-        OptimizeStats.Builder builder = new OptimizeStats.Builder();
-        mAppSearchImpl.checkForOptimize(/*mutateBatchSize=*/ 1, builder);
-
-        // Verify optimize() is triggered.
-        optimizeInfo = mAppSearchImpl.getOptimizeInfoResultLocked();
-        assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(0);
-        assertThat(optimizeInfo.getEstimatedOptimizableBytes()).isEqualTo(0);
-
-        // Verify the stats have been set.
-        OptimizeStats oStats = builder.build();
-        assertThat(oStats.getOriginalDocumentCount()).isEqualTo(1);
-        assertThat(oStats.getDeletedDocumentCount()).isEqualTo(1);
-    }
-
-    @Test
-    public void testReset() throws Exception {
-        // Setup the index
-        Context context = ApplicationProvider.getApplicationContext();
-        File appsearchDir = mTemporaryFolder.newFolder();
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("Type1").build(),
-                        new AppSearchSchema.Builder("Type2").build());
-        appSearchImpl.setSchema(
-                context.getPackageName(),
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert a valid doc
-        GenericDocument validDoc =
-                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build();
-        appSearchImpl.putDocument(
-                context.getPackageName(), "database1", validDoc, /*logger=*/ null);
-
-        // Query it via global query. We use the same code again later so this is to make sure we
-        // have our global query configured right.
-        SearchResultPage results =
-                appSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        new SearchSpec.Builder().addFilterSchemas("Type1").build(),
-                        context.getPackageName(),
-                        /*visibilityStore=*/ null,
-                        Process.INVALID_UID,
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-        assertThat(results.getResults()).hasSize(1);
-        assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
-
-        // Create a doc with a malformed namespace
-        DocumentProto invalidDoc =
-                DocumentProto.newBuilder()
-                        .setNamespace("invalidNamespace")
-                        .setUri("id2")
-                        .setSchema(context.getPackageName() + "$database1/Type1")
-                        .build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> PrefixUtil.getPrefix(invalidDoc.getNamespace()));
-        assertThat(e)
-                .hasMessageThat()
-                .isEqualTo(
-                        "The prefixed value \"invalidNamespace\" doesn't contain a valid database"
-                            + " name");
-
-        // Insert the invalid doc with an invalid namespace right into icing
-        PutResultProto putResultProto = appSearchImpl.mIcingSearchEngineLocked.put(invalidDoc);
-        assertThat(putResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.OK);
-
-        // Initialize AppSearchImpl. This should cause a reset.
-        InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
-        appSearchImpl.close();
-        appSearchImpl =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        initStatsBuilder,
-                        ALWAYS_OPTIMIZE);
-
-        // Check recovery state
-        InitializeStats initStats = initStatsBuilder.build();
-        assertThat(initStats).isNotNull();
-        assertThat(initStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
-        assertThat(initStats.hasDeSync()).isFalse();
-        assertThat(initStats.getDocumentStoreRecoveryCause())
-                .isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
-        assertThat(initStats.getIndexRestorationCause())
-                .isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
-        assertThat(initStats.getSchemaStoreRecoveryCause())
-                .isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
-        assertThat(initStats.getDocumentStoreDataStatus())
-                .isEqualTo(InitializeStats.DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS);
-        assertThat(initStats.hasReset()).isTrue();
-        assertThat(initStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-
-        // Make sure all our data is gone
-        assertThat(appSearchImpl.getSchema(context.getPackageName(), "database1").getSchemas())
-                .isEmpty();
-        results =
-                appSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        new SearchSpec.Builder().addFilterSchemas("Type1").build(),
-                        context.getPackageName(),
-                        /*visibilityStore=*/ null,
-                        Process.INVALID_UID,
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-        assertThat(results.getResults()).isEmpty();
-
-        // Make sure the index can now be used successfully
-        appSearchImpl.setSchema(
-                context.getPackageName(),
-                "database1",
-                Collections.singletonList(new AppSearchSchema.Builder("Type1").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert a valid doc
-        appSearchImpl.putDocument(
-                context.getPackageName(), "database1", validDoc, /*logger=*/ null);
-
-        // Query it via global query.
-        results =
-                appSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        new SearchSpec.Builder().addFilterSchemas("Type1").build(),
-                        context.getPackageName(),
-                        /*visibilityStore=*/ null,
-                        Process.INVALID_UID,
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-        assertThat(results.getResults()).hasSize(1);
-        assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
-    }
-
-    @Test
-    public void testRewriteSearchSpec_oneInstance() throws Exception {
-        SearchSpecProto.Builder searchSpecProto = SearchSpecProto.newBuilder().setQuery("");
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert document
-        GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
-
-        // Rewrite SearchSpec
-        mAppSearchImpl.rewriteSearchSpecForPrefixesLocked(
-                searchSpecProto,
-                Collections.singleton(createPrefix("package", "database")),
-                ImmutableSet.of("package$database/type"));
-        assertThat(searchSpecProto.getSchemaTypeFiltersList())
-                .containsExactly("package$database/type");
-        assertThat(searchSpecProto.getNamespaceFiltersList())
-                .containsExactly("package$database/namespace");
-    }
-
-    @Test
-    public void testRewriteSearchSpec_twoInstances() throws Exception {
-        SearchSpecProto.Builder searchSpecProto = SearchSpecProto.newBuilder().setQuery("");
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("typeA").build(),
-                        new AppSearchSchema.Builder("typeB").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "package",
-                "database2",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id", "typeA").build();
-        mAppSearchImpl.putDocument("package", "database1", document1, /*logger=*/ null);
-
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id", "typeB").build();
-        mAppSearchImpl.putDocument("package", "database2", document2, /*logger=*/ null);
-
-        // Rewrite SearchSpec
-        mAppSearchImpl.rewriteSearchSpecForPrefixesLocked(
-                searchSpecProto,
-                ImmutableSet.of(
-                        createPrefix("package", "database1"), createPrefix("package", "database2")),
-                ImmutableSet.of(
-                        "package$database1/typeA", "package$database1/typeB",
-                        "package$database2/typeA", "package$database2/typeB"));
-        assertThat(searchSpecProto.getSchemaTypeFiltersList())
-                .containsExactly(
-                        "package$database1/typeA",
-                        "package$database1/typeB",
-                        "package$database2/typeA",
-                        "package$database2/typeB");
-        assertThat(searchSpecProto.getNamespaceFiltersList())
-                .containsExactly("package$database1/namespace", "package$database2/namespace");
-    }
-
-    @Test
-    public void testRewriteSearchSpec_ignoresSearchSpecSchemaFilters() throws Exception {
-        SearchSpecProto.Builder searchSpecProto =
-                SearchSpecProto.newBuilder().setQuery("").addSchemaTypeFilters("type");
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert document
-        GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
-
-        // If 'allowedPrefixedSchemas' is empty, this returns false since there's nothing to
-        // search over. Despite the searchSpecProto having schema type filters.
-        assertThat(
-                        mAppSearchImpl.rewriteSearchSpecForPrefixesLocked(
-                                searchSpecProto,
-                                Collections.singleton(createPrefix("package", "database")),
-                                /*allowedPrefixedSchemas=*/ Collections.emptySet()))
-                .isFalse();
-    }
-
-    @Test
-    public void testQueryEmptyDatabase() throws Exception {
-        SearchSpec searchSpec =
-                new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package", "EmptyDatabase", "", searchSpec, /*logger=*/ null);
-        assertThat(searchResultPage.getResults()).isEmpty();
-    }
-
-    /**
-     * TODO(b/169883602): This should be an integration test at the cts-level. This is a short-term
-     * test until we have official support for multiple-apps indexing at once.
-     */
-    @Test
-    public void testQueryWithMultiplePackages_noPackageFilters() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert package2 schema
-        List<AppSearchSchema> schema2 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema2").build());
-        mAppSearchImpl.setSchema(
-                "package2",
-                "database2",
-                schema2,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert package1 document
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace", "id", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
-
-        // No query filters specified, package2 shouldn't be able to query for package1's documents.
-        SearchSpec searchSpec =
-                new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=*/ null);
-        assertThat(searchResultPage.getResults()).isEmpty();
-
-        // Insert package2 document
-        document = new GenericDocument.Builder<>("namespace", "id", "schema2").build();
-        mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
-
-        // No query filters specified. package2 should only get its own documents back.
-        searchResultPage =
-                mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=
-         */ null);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
-    }
-
-    /**
-     * TODO(b/169883602): This should be an integration test at the cts-level. This is a short-term
-     * test until we have official support for multiple-apps indexing at once.
-     */
-    @Test
-    public void testQueryWithMultiplePackages_withPackageFilters() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert package2 schema
-        List<AppSearchSchema> schema2 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema2").build());
-        mAppSearchImpl.setSchema(
-                "package2",
-                "database2",
-                schema2,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert package1 document
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace", "id", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
-
-        // "package1" filter specified, but package2 shouldn't be able to query for package1's
-        // documents.
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .addFilterPackageNames("package1")
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=*/ null);
-        assertThat(searchResultPage.getResults()).isEmpty();
-
-        // Insert package2 document
-        document = new GenericDocument.Builder<>("namespace", "id", "schema2").build();
-        mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
-
-        // "package2" filter specified, package2 should only get its own documents back.
-        searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .addFilterPackageNames("package2")
-                        .build();
-        searchResultPage =
-                mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=
-         */ null);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
-    }
-
-    @Test
-    public void testGlobalQueryEmptyDatabase() throws Exception {
-        SearchSpec searchSpec =
-                new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.globalQuery(
-                        "",
-                        searchSpec,
-                        /*callerPackageName=*/ "",
-                        /*visibilityStore=*/ null,
-                        Process.INVALID_UID,
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-        assertThat(searchResultPage.getResults()).isEmpty();
-    }
-
-    @Test
-    public void testGetNextPageToken_query() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-        searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
-    }
-
-    @Test
-    public void testGetNextPageWithDifferentPackage_query() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-
-        // Try getting next page with the wrong package, package2
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.getNextPage("package2", nextPageToken));
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-
-        // Can continue getting next page for package1
-        searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
-    }
-
-    @Test
-    public void testGetNextPageToken_globalQuery() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        searchSpec,
-                        "package1",
-                        /*visibilityStore=*/ null,
-                        Process.myUid(),
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-        searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
-    }
-
-    @Test
-    public void testGetNextPageWithDifferentPackage_globalQuery() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        searchSpec,
-                        "package1",
-                        /*visibilityStore=*/ null,
-                        Process.myUid(),
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-
-        // Try getting next page with the wrong package, package2
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.getNextPage("package2", nextPageToken));
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-
-        // Can continue getting next page for package1
-        searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
-    }
-
-    @Test
-    public void testInvalidateNextPageToken_query() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-
-        // Invalidate the token
-        mAppSearchImpl.invalidateNextPageToken("package1", nextPageToken);
-
-        // Can't get next page because we invalidated the token.
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.getNextPage("package1", nextPageToken));
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package1\" cannot use nextPageToken: " + nextPageToken);
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-    }
-
-    @Test
-    public void testInvalidateNextPageTokenWithDifferentPackage_query() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-
-        // Try getting next page with the wrong package, package2
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.invalidateNextPageToken("package2", nextPageToken));
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-
-        // Can continue getting next page for package1
-        searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
-    }
-
-    @Test
-    public void testInvalidateNextPageToken_globalQuery() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        searchSpec,
-                        "package1",
-                        /*visibilityStore=*/ null,
-                        Process.myUid(),
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-
-        // Invalidate the token
-        mAppSearchImpl.invalidateNextPageToken("package1", nextPageToken);
-
-        // Can't get next page because we invalidated the token.
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.getNextPage("package1", nextPageToken));
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package1\" cannot use nextPageToken: " + nextPageToken);
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-    }
-
-    @Test
-    public void testInvalidateNextPageTokenWithDifferentPackage_globalQuery() throws Exception {
-        // Insert package1 schema
-        List<AppSearchSchema> schema1 =
-                ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two package1 documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-
-        // Query for only 1 result per page
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setResultCountPerPage(1)
-                        .build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.globalQuery(
-                        /*queryExpression=*/ "",
-                        searchSpec,
-                        "package1",
-                        /*visibilityStore=*/ null,
-                        Process.myUid(),
-                        /*callerHasSystemAccess=*/ false,
-                        /*logger=*/ null);
-
-        // Document2 will come first because it was inserted last and default return order is
-        // most recent.
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-
-        long nextPageToken = searchResultPage.getNextPageToken();
-
-        // Try getting next page with the wrong package, package2
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.invalidateNextPageToken("package2", nextPageToken));
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-
-        // Can continue getting next page for package1
-        searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
-    }
-
-    @Test
-    public void testRemoveEmptyDatabase_noExceptionThrown() throws Exception {
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .addFilterSchemas("FakeType")
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .build();
-        mAppSearchImpl.removeByQuery(
-                "package", "EmptyDatabase", "", searchSpec, /*statsBuilder=*/ null);
-
-        searchSpec =
-                new SearchSpec.Builder()
-                        .addFilterNamespaces("FakeNamespace")
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .build();
-        mAppSearchImpl.removeByQuery(
-                "package", "EmptyDatabase", "", searchSpec, /*statsBuilder=*/ null);
-
-        searchSpec = new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
-        mAppSearchImpl.removeByQuery(
-                "package", "EmptyDatabase", "", searchSpec, /*statsBuilder=*/ null);
-    }
-
-    @Test
-    public void testSetSchema() throws Exception {
-        List<SchemaTypeConfigProto> existingSchemas =
-                mAppSearchImpl.getSchemaProtoLocked().getTypesList();
-
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
-        // Set schema Email to AppSearch database1
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Create expected schemaType proto.
-        SchemaProto expectedProto =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Email")
-                                        .setVersion(0))
-                        .build();
-
-        List<SchemaTypeConfigProto> expectedTypes = new ArrayList<>();
-        expectedTypes.addAll(existingSchemas);
-        expectedTypes.addAll(expectedProto.getTypesList());
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(expectedTypes);
-    }
-
-    @Test
-    public void testSetSchema_incompatible() throws Exception {
-        List<AppSearchSchema> oldSchemas = new ArrayList<>();
-        oldSchemas.add(
-                new AppSearchSchema.Builder("Email")
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("foo")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .build())
-                        .build());
-        oldSchemas.add(new AppSearchSchema.Builder("Text").build());
-        // Set schema Email to AppSearch database1
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                oldSchemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Create incompatible schema
-        List<AppSearchSchema> newSchemas =
-                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
-
-        // set email incompatible and delete text
-        SetSchemaResponse setSchemaResponse =
-                mAppSearchImpl.setSchema(
-                        "package",
-                        "database1",
-                        newSchemas,
-                        /*visibilityStore=*/ null,
-                        /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                        /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                        /*forceOverride=*/ true,
-                        /*version=*/ 0);
-        assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("Text");
-        assertThat(setSchemaResponse.getIncompatibleTypes()).containsExactly("Email");
-    }
-
-    @Test
-    public void testRemoveSchema() throws Exception {
-        List<SchemaTypeConfigProto> existingSchemas =
-                mAppSearchImpl.getSchemaProtoLocked().getTypesList();
-
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("Email").build(),
-                        new AppSearchSchema.Builder("Document").build());
-        // Set schema Email and Document to AppSearch database1
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Create expected schemaType proto.
-        SchemaProto expectedProto =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Email")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Document")
-                                        .setVersion(0))
-                        .build();
-
-        // Check both schema Email and Document saved correctly.
-        List<SchemaTypeConfigProto> expectedTypes = new ArrayList<>();
-        expectedTypes.addAll(existingSchemas);
-        expectedTypes.addAll(expectedProto.getTypesList());
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(expectedTypes);
-
-        final List<AppSearchSchema> finalSchemas =
-                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
-        SetSchemaResponse setSchemaResponse =
-                mAppSearchImpl.setSchema(
-                        "package",
-                        "database1",
-                        finalSchemas,
-                        /*visibilityStore=*/ null,
-                        /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                        /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                        /*forceOverride=*/ false,
-                        /*version=*/ 0);
-
-        // Check the Document type has been deleted.
-        assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("Document");
-
-        // ForceOverride to delete.
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                finalSchemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ true,
-                /*version=*/ 0);
-
-        // Check Document schema is removed.
-        expectedProto =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Email")
-                                        .setVersion(0))
-                        .build();
-
-        expectedTypes = new ArrayList<>();
-        expectedTypes.addAll(existingSchemas);
-        expectedTypes.addAll(expectedProto.getTypesList());
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(expectedTypes);
-    }
-
-    @Test
-    public void testRemoveSchema_differentDataBase() throws Exception {
-        List<SchemaTypeConfigProto> existingSchemas =
-                mAppSearchImpl.getSchemaProtoLocked().getTypesList();
-
-        // Create schemas
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("Email").build(),
-                        new AppSearchSchema.Builder("Document").build());
-
-        // Set schema Email and Document to AppSearch database1 and 2
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "package",
-                "database2",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Create expected schemaType proto.
-        SchemaProto expectedProto =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Email")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Document")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database2/Email")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database2/Document")
-                                        .setVersion(0))
-                        .build();
-
-        // Check Email and Document is saved in database 1 and 2 correctly.
-        List<SchemaTypeConfigProto> expectedTypes = new ArrayList<>();
-        expectedTypes.addAll(existingSchemas);
-        expectedTypes.addAll(expectedProto.getTypesList());
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(expectedTypes);
-
-        // Save only Email to database1 this time.
-        schemas = Collections.singletonList(new AppSearchSchema.Builder("Email").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ true,
-                /*version=*/ 0);
-
-        // Create expected schemaType list, database 1 should only contain Email but database 2
-        // remains in same.
-        expectedProto =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database1/Email")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database2/Email")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("package$database2/Document")
-                                        .setVersion(0))
-                        .build();
-
-        // Check nothing changed in database2.
-        expectedTypes = new ArrayList<>();
-        expectedTypes.addAll(existingSchemas);
-        expectedTypes.addAll(expectedProto.getTypesList());
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(expectedTypes);
-    }
-
-    @Test
-    public void testClearPackageData() throws AppSearchException {
-        List<SchemaTypeConfigProto> existingSchemas =
-                mAppSearchImpl.getSchemaProtoLocked().getTypesList();
-        Map<String, Set<String>> existingDatabases = mAppSearchImpl.getPackageToDatabases();
-
-        // Insert package schema
-        List<AppSearchSchema> schema =
-                ImmutableList.of(new AppSearchSchema.Builder("schema").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schema,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert package document
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace", "id", "schema").build();
-        mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
-
-        // Verify the document is indexed.
-        SearchSpec searchSpec =
-                new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query(
-                        "package",
-                        "database",
-                        /*queryExpression=*/ "",
-                        searchSpec,
-                        /*logger=*/ null);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
-
-        // Remove the package
-        mAppSearchImpl.clearPackageData("package");
-
-        // Verify the document is cleared.
-        searchResultPage =
-                mAppSearchImpl.query(
-                        "package2",
-                        "database2",
-                        /*queryExpression=*/ "",
-                        searchSpec,
-                        /*logger=*/ null);
-        assertThat(searchResultPage.getResults()).isEmpty();
-
-        // Verify the schema is cleared.
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(existingSchemas);
-        assertThat(mAppSearchImpl.getPackageToDatabases())
-                .containsExactlyEntriesIn(existingDatabases);
-    }
-
-    @Test
-    public void testPrunePackageData() throws AppSearchException {
-        List<SchemaTypeConfigProto> existingSchemas =
-                mAppSearchImpl.getSchemaProtoLocked().getTypesList();
-        Map<String, Set<String>> existingDatabases = mAppSearchImpl.getPackageToDatabases();
-
-        Set<String> existingPackages = new ArraySet<>(existingSchemas.size());
-        for (int i = 0; i < existingSchemas.size(); i++) {
-            existingPackages.add(PrefixUtil.getPackageName(existingSchemas.get(i).getSchemaType()));
-        }
-
-        // Insert schema for package A and B.
-        List<AppSearchSchema> schema =
-                ImmutableList.of(new AppSearchSchema.Builder("schema").build());
-        mAppSearchImpl.setSchema(
-                "packageA",
-                "database",
-                schema,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "packageB",
-                "database",
-                schema,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Verify these two packages is stored in AppSearch
-        SchemaProto expectedProto =
-                SchemaProto.newBuilder()
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("packageA$database/schema")
-                                        .setVersion(0))
-                        .addTypes(
-                                SchemaTypeConfigProto.newBuilder()
-                                        .setSchemaType("packageB$database/schema")
-                                        .setVersion(0))
-                        .build();
-        List<SchemaTypeConfigProto> expectedTypes = new ArrayList<>();
-        expectedTypes.addAll(existingSchemas);
-        expectedTypes.addAll(expectedProto.getTypesList());
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(expectedTypes);
-
-        // Prune packages
-        mAppSearchImpl.prunePackageData(existingPackages);
-
-        // Verify the schema is same as beginning.
-        assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
-                .containsExactlyElementsIn(existingSchemas);
-        assertThat(mAppSearchImpl.getPackageToDatabases())
-                .containsExactlyEntriesIn(existingDatabases);
-    }
-
-    @Test
-    public void testGetPackageToDatabases() throws Exception {
-        Map<String, Set<String>> existingMapping = mAppSearchImpl.getPackageToDatabases();
-        Map<String, Set<String>> expectedMapping = new ArrayMap<>();
-        expectedMapping.putAll(existingMapping);
-
-        // Has database1
-        expectedMapping.put("package1", ImmutableSet.of("database1"));
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        assertThat(mAppSearchImpl.getPackageToDatabases())
-                .containsExactlyEntriesIn(expectedMapping);
-
-        // Has both databases
-        expectedMapping.put("package1", ImmutableSet.of("database1", "database2"));
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database2",
-                Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        assertThat(mAppSearchImpl.getPackageToDatabases())
-                .containsExactlyEntriesIn(expectedMapping);
-
-        // Has both packages
-        expectedMapping.put("package2", ImmutableSet.of("database1"));
-        mAppSearchImpl.setSchema(
-                "package2",
-                "database1",
-                Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        assertThat(mAppSearchImpl.getPackageToDatabases())
-                .containsExactlyEntriesIn(expectedMapping);
-    }
-
-    @Test
-    public void testRewriteSearchResultProto() throws Exception {
-        final String prefix =
-                "com.package.foo"
-                        + PrefixUtil.PACKAGE_DELIMITER
-                        + "databaseName"
-                        + PrefixUtil.DATABASE_DELIMITER;
-        final String id = "id";
-        final String namespace = prefix + "namespace";
-        final String schemaType = prefix + "schema";
-
-        // Building the SearchResult received from query.
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri(id)
-                        .setNamespace(namespace)
-                        .setSchema(schemaType)
-                        .build();
-        SearchResultProto.ResultProto resultProto =
-                SearchResultProto.ResultProto.newBuilder().setDocument(documentProto).build();
-        SearchResultProto searchResultProto =
-                SearchResultProto.newBuilder().addResults(resultProto).build();
-        SchemaTypeConfigProto schemaTypeConfigProto =
-                SchemaTypeConfigProto.newBuilder().setSchemaType(schemaType).build();
-        Map<String, Map<String, SchemaTypeConfigProto>> schemaMap =
-                ImmutableMap.of(prefix, ImmutableMap.of(schemaType, schemaTypeConfigProto));
-
-        DocumentProto.Builder strippedDocumentProto = documentProto.toBuilder();
-        removePrefixesFromDocument(strippedDocumentProto);
-        SearchResultPage searchResultPage =
-                AppSearchImpl.rewriteSearchResultProto(searchResultProto, schemaMap);
-        for (SearchResult result : searchResultPage.getResults()) {
-            assertThat(result.getPackageName()).isEqualTo("com.package.foo");
-            assertThat(result.getDatabaseName()).isEqualTo("databaseName");
-            assertThat(result.getGenericDocument())
-                    .isEqualTo(
-                            GenericDocumentToProtoConverter.toGenericDocument(
-                                    strippedDocumentProto.build(), prefix, schemaMap.get(prefix)));
-        }
-    }
-
-    @Test
-    public void testReportUsage() throws Exception {
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two docs
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "type").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
-
-        // Report some usages. id1 has 2 app and 1 system usage, id2 has 1 app and 2 system usage.
-        mAppSearchImpl.reportUsage(
-                "package",
-                "database",
-                "namespace",
-                "id1",
-                /*usageTimestampMillis=*/ 10,
-                /*systemUsage=*/ false);
-        mAppSearchImpl.reportUsage(
-                "package",
-                "database",
-                "namespace",
-                "id1",
-                /*usageTimestampMillis=*/ 20,
-                /*systemUsage=*/ false);
-        mAppSearchImpl.reportUsage(
-                "package",
-                "database",
-                "namespace",
-                "id1",
-                /*usageTimestampMillis=*/ 1000,
-                /*systemUsage=*/ true);
-
-        mAppSearchImpl.reportUsage(
-                "package",
-                "database",
-                "namespace",
-                "id2",
-                /*usageTimestampMillis=*/ 100,
-                /*systemUsage=*/ false);
-        mAppSearchImpl.reportUsage(
-                "package",
-                "database",
-                "namespace",
-                "id2",
-                /*usageTimestampMillis=*/ 200,
-                /*systemUsage=*/ true);
-        mAppSearchImpl.reportUsage(
-                "package",
-                "database",
-                "namespace",
-                "id2",
-                /*usageTimestampMillis=*/ 150,
-                /*systemUsage=*/ true);
-
-        // Sort by app usage count: id1 should win
-        List<SearchResult> page =
-                mAppSearchImpl
-                        .query(
-                                "package",
-                                "database",
-                                "",
-                                new SearchSpec.Builder()
-                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                                        .setRankingStrategy(SearchSpec.RANKING_STRATEGY_USAGE_COUNT)
-                                        .build(),
-                                /*logger=*/ null)
-                        .getResults();
-        assertThat(page).hasSize(2);
-        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
-        assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id2");
-
-        // Sort by app usage timestamp: id2 should win
-        page =
-                mAppSearchImpl
-                        .query(
-                                "package",
-                                "database",
-                                "",
-                                new SearchSpec.Builder()
-                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                                        .setRankingStrategy(
-                                                SearchSpec
-                                                        .RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP)
-                                        .build(),
-                                /*logger=*/ null)
-                        .getResults();
-        assertThat(page).hasSize(2);
-        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
-        assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id1");
-
-        // Sort by system usage count: id2 should win
-        page =
-                mAppSearchImpl
-                        .query(
-                                "package",
-                                "database",
-                                "",
-                                new SearchSpec.Builder()
-                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                                        .setRankingStrategy(
-                                                SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT)
-                                        .build(),
-                                /*logger=*/ null)
-                        .getResults();
-        assertThat(page).hasSize(2);
-        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
-        assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id1");
-
-        // Sort by system usage timestamp: id1 should win
-        page =
-                mAppSearchImpl
-                        .query(
-                                "package",
-                                "database",
-                                "",
-                                new SearchSpec.Builder()
-                                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                                        .setRankingStrategy(
-                                                SearchSpec
-                                                        .RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP)
-                                        .build(),
-                                /*logger=*/ null)
-                        .getResults();
-        assertThat(page).hasSize(2);
-        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
-        assertThat(page.get(1).getGenericDocument().getId()).isEqualTo("id2");
-    }
-
-    @Test
-    public void testGetStorageInfoForPackage_nonexistentPackage() throws Exception {
-        // "package2" doesn't exist yet, so it shouldn't have any storage size
-        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("nonexistent.package");
-        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testGetStorageInfoForPackage_withoutDocument() throws Exception {
-        // Insert schema for "package1"
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Since "package1" doesn't have a document, it get any space attributed to it.
-        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("package1");
-        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testGetStorageInfoForPackage_proportionalToDocuments() throws Exception {
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-
-        // Insert schema for "package1"
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert document for "package1"
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace", "id1", "type").build();
-        mAppSearchImpl.putDocument("package1", "database", document, /*logger=*/ null);
-
-        // Insert schema for "package2"
-        mAppSearchImpl.setSchema(
-                "package2",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert two documents for "package2"
-        document = new GenericDocument.Builder<>("namespace", "id1", "type").build();
-        mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
-        document = new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
-
-        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("package1");
-        long size1 = storageInfo.getSizeBytes();
-        assertThat(size1).isGreaterThan(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(1);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
-
-        storageInfo = mAppSearchImpl.getStorageInfoForPackage("package2");
-        long size2 = storageInfo.getSizeBytes();
-        assertThat(size2).isGreaterThan(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(2);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
-
-        // Size is proportional to number of documents. Since "package2" has twice as many
-        // documents as "package1", its size is twice as much too.
-        assertThat(size2).isAtLeast(2 * size1);
-    }
-
-    @Test
-    public void testGetStorageInfoForDatabase_nonexistentPackage() throws Exception {
-        // "package2" doesn't exist yet, so it shouldn't have any storage size
-        StorageInfo storageInfo =
-                mAppSearchImpl.getStorageInfoForDatabase(
-                        "nonexistent.package", "nonexistentDatabase");
-        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testGetStorageInfoForDatabase_nonexistentDatabase() throws Exception {
-        // Insert schema for "package1"
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // "package2" doesn't exist yet, so it shouldn't have any storage size
-        StorageInfo storageInfo =
-                mAppSearchImpl.getStorageInfoForDatabase("package1", "nonexistentDatabase");
-        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testGetStorageInfoForDatabase_withoutDocument() throws Exception {
-        // Insert schema for "package1"
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Since "package1", "database1" doesn't have a document, it get any space attributed to it.
-        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database1");
-        assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(0);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testGetStorageInfoForDatabase_proportionalToDocuments() throws Exception {
-        // Insert schema for "package1", "database1" and "database2"
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database2",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Add a document for "package1", "database1"
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
-
-        // Add two documents for "package1", "database2"
-        document = new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
-        document = new GenericDocument.Builder<>("namespace1", "id2", "type").build();
-        mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
-
-        StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database1");
-        long size1 = storageInfo.getSizeBytes();
-        assertThat(size1).isGreaterThan(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(1);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
-
-        storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database2");
-        long size2 = storageInfo.getSizeBytes();
-        assertThat(size2).isGreaterThan(0);
-        assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(2);
-        assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(1);
-
-        // Size is proportional to number of documents. Since "database2" has twice as many
-        // documents as "database1", its size is twice as much too.
-        assertThat(size2).isAtLeast(2 * size1);
-    }
-
-    @Test
-    public void testThrowsExceptionIfClosed() throws Exception {
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Initial check that we could do something at first.
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        appSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        appSearchImpl.close();
-
-        // Check all our public APIs
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.setSchema(
-                                "package",
-                                "database",
-                                schemas,
-                                /*visibilityStore=*/ null,
-                                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                                /*forceOverride=*/ false,
-                                /*version=*/ 0));
-
-        assertThrows(
-                IllegalStateException.class, () -> appSearchImpl.getSchema("package", "database"));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.putDocument(
-                                "package",
-                                "database",
-                                new GenericDocument.Builder<>("namespace", "id", "type").build(),
-                                /*logger=*/ null));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.getDocument(
-                                "package", "database", "namespace", "id", Collections.emptyMap()));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.query(
-                                "package",
-                                "database",
-                                "query",
-                                new SearchSpec.Builder().build(),
-                                /*logger=*/ null));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.globalQuery(
-                                "query",
-                                new SearchSpec.Builder().build(),
-                                "package",
-                                /*visibilityStore=*/ null,
-                                Process.INVALID_UID,
-                                /*callerHasSystemAccess=*/ false,
-                                /*logger=*/ null));
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> appSearchImpl.getNextPage("package", /*nextPageToken=*/ 1L));
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> appSearchImpl.invalidateNextPageToken("package", /*nextPageToken=*/ 1L));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.reportUsage(
-                                "package",
-                                "database",
-                                "namespace",
-                                "id",
-                                /*usageTimestampMillis=*/ 1000L,
-                                /*systemUsage=*/ false));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.remove(
-                                "package",
-                                "database",
-                                "namespace",
-                                "id",
-                                /*removeStatsBuilder=*/ null));
-
-        assertThrows(
-                IllegalStateException.class,
-                () ->
-                        appSearchImpl.removeByQuery(
-                                "package",
-                                "database",
-                                "query",
-                                new SearchSpec.Builder().build(),
-                                /*removeStatsBuilder=*/ null));
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> appSearchImpl.getStorageInfoForPackage("package"));
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> appSearchImpl.getStorageInfoForDatabase("package", "database"));
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> appSearchImpl.persistToDisk(PersistType.Code.FULL));
-    }
-
-    @Test
-    public void testPutPersistsWithLiteFlush() throws Exception {
-        // Setup the index
-        File appsearchDir = mTemporaryFolder.newFolder();
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        appSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Add a document and persist it.
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        appSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
-        appSearchImpl.persistToDisk(PersistType.Code.LITE);
-
-        GenericDocument getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace1", "id1", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document);
-
-        // That document should be visible even from another instance.
-        AppSearchImpl appSearchImpl2 =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-        getResult =
-                appSearchImpl2.getDocument(
-                        "package", "database", "namespace1", "id1", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document);
-    }
-
-    @Test
-    public void testDeletePersistsWithLiteFlush() throws Exception {
-        // Setup the index
-        File appsearchDir = mTemporaryFolder.newFolder();
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        appSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Add two documents and persist them.
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        appSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace1", "id2", "type").build();
-        appSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
-        appSearchImpl.persistToDisk(PersistType.Code.LITE);
-
-        GenericDocument getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace1", "id1", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document1);
-        getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace1", "id2", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document2);
-
-        // Delete the first document
-        appSearchImpl.remove("package", "database", "namespace1", "id1", /*statsBuilder=*/ null);
-        appSearchImpl.persistToDisk(PersistType.Code.LITE);
-        assertThrows(
-                AppSearchException.class,
-                () ->
-                        appSearchImpl.getDocument(
-                                "package",
-                                "database",
-                                "namespace1",
-                                "id1",
-                                Collections.emptyMap()));
-        getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace1", "id2", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document2);
-
-        // Only the second document should be retrievable from another instance.
-        AppSearchImpl appSearchImpl2 =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-        assertThrows(
-                AppSearchException.class,
-                () ->
-                        appSearchImpl2.getDocument(
-                                "package",
-                                "database",
-                                "namespace1",
-                                "id1",
-                                Collections.emptyMap()));
-        getResult =
-                appSearchImpl2.getDocument(
-                        "package", "database", "namespace1", "id2", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document2);
-    }
-
-    @Test
-    public void testDeleteByQueryPersistsWithLiteFlush() throws Exception {
-        // Setup the index
-        File appsearchDir = mTemporaryFolder.newFolder();
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        appSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Add two documents and persist them.
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        appSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace2", "id2", "type").build();
-        appSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
-        appSearchImpl.persistToDisk(PersistType.Code.LITE);
-
-        GenericDocument getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace1", "id1", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document1);
-        getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace2", "id2", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document2);
-
-        // Delete the first document
-        appSearchImpl.removeByQuery(
-                "package",
-                "database",
-                "",
-                new SearchSpec.Builder()
-                        .addFilterNamespaces("namespace1")
-                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                        .build(),
-                /*statsBuilder=*/ null);
-        appSearchImpl.persistToDisk(PersistType.Code.LITE);
-        assertThrows(
-                AppSearchException.class,
-                () ->
-                        appSearchImpl.getDocument(
-                                "package",
-                                "database",
-                                "namespace1",
-                                "id1",
-                                Collections.emptyMap()));
-        getResult =
-                appSearchImpl.getDocument(
-                        "package", "database", "namespace2", "id2", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document2);
-
-        // Only the second document should be retrievable from another instance.
-        AppSearchImpl appSearchImpl2 =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-        assertThrows(
-                AppSearchException.class,
-                () ->
-                        appSearchImpl2.getDocument(
-                                "package",
-                                "database",
-                                "namespace1",
-                                "id1",
-                                Collections.emptyMap()));
-        getResult =
-                appSearchImpl2.getDocument(
-                        "package", "database", "namespace2", "id2", Collections.emptyMap());
-        assertThat(getResult).isEqualTo(document2);
-    }
-
-    @Test
-    public void testGetIcingSearchEngineStorageInfo() throws Exception {
-        // Setup the index
-        File appsearchDir = mTemporaryFolder.newFolder();
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        appsearchDir,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        appSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Add two documents
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        appSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace1", "id2", "type").build();
-        appSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
-
-        StorageInfoProto storageInfo = appSearchImpl.getRawStorageInfoProto();
-
-        // Simple checks to verify if we can get correct StorageInfoProto from IcingSearchEngine
-        // No need to cover all the fields
-        assertThat(storageInfo.getTotalStorageSize()).isGreaterThan(0);
-        assertThat(storageInfo.getDocumentStorageInfo().getNumAliveDocuments()).isEqualTo(2);
-        assertThat(storageInfo.getSchemaStoreStorageInfo().getNumSchemaTypes()).isEqualTo(1);
-    }
-
-    @Test
-    public void testLimitConfig_DocumentSize() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return 80;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 1;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert a document which is too large
-        GenericDocument document =
-                new GenericDocument.Builder<>(
-                                "this_namespace_is_long_to_make_the_doc_big", "id", "type")
-                        .build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains(
-                        "Document \"id\" for package \"package\" serialized to 99 bytes, which"
-                            + " exceeds limit of 80 bytes");
-
-        // Make sure this failure didn't increase our document count. We should still be able to
-        // index 1 document.
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
-
-        // Now we should get a failure
-        GenericDocument document3 =
-                new GenericDocument.Builder<>("namespace", "id3", "type").build();
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document3, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 1 documents");
-    }
-
-    @Test
-    public void testLimitConfig_Init() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        File tempFolder = mTemporaryFolder.newFolder();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        tempFolder,
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return 80;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 1;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Index a document
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type").build(),
-                /*logger=*/ null);
-
-        // Now we should get a failure
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document2, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 1 documents");
-
-        // Close and reinitialize AppSearchImpl
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        tempFolder,
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return 80;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 1;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Make sure the limit is maintained
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document2, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 1 documents");
-    }
-
-    @Test
-    public void testLimitConfig_Remove() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 3;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Index 3 documents
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type").build(),
-                /*logger=*/ null);
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id2", "type").build(),
-                /*logger=*/ null);
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id3", "type").build(),
-                /*logger=*/ null);
-
-        // Now we should get a failure
-        GenericDocument document4 =
-                new GenericDocument.Builder<>("namespace", "id4", "type").build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document4, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 3 documents");
-
-        // Remove a document that doesn't exist
-        assertThrows(
-                AppSearchException.class,
-                () ->
-                        mAppSearchImpl.remove(
-                                "package",
-                                "database",
-                                "namespace",
-                                "id4",
-                                /*removeStatsBuilder=*/ null));
-
-        // Should still fail
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document4, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 3 documents");
-
-        // Remove a document that does exist
-        mAppSearchImpl.remove(
-                "package", "database", "namespace", "id2", /*removeStatsBuilder=*/ null);
-
-        // Now doc4 should work
-        mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null);
-
-        // The next one should fail again
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package",
-                                        "database",
-                                        new GenericDocument.Builder<>("namespace", "id5", "type")
-                                                .build(),
-                                        /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 3 documents");
-    }
-
-    @Test
-    public void testLimitConfig_DifferentPackages() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        File tempFolder = mTemporaryFolder.newFolder();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        tempFolder,
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 2;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "package1",
-                "database2",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "package2",
-                "database1",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        mAppSearchImpl.setSchema(
-                "package2",
-                "database2",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Index documents in package1/database1
-        mAppSearchImpl.putDocument(
-                "package1",
-                "database1",
-                new GenericDocument.Builder<>("namespace", "id1", "type").build(),
-                /*logger=*/ null);
-        mAppSearchImpl.putDocument(
-                "package1",
-                "database2",
-                new GenericDocument.Builder<>("namespace", "id2", "type").build(),
-                /*logger=*/ null);
-
-        // Indexing a third doc into package1 should fail (here we use database3)
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package1",
-                                        "database3",
-                                        new GenericDocument.Builder<>("namespace", "id3", "type")
-                                                .build(),
-                                        /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package1\" exceeded limit of 2 documents");
-
-        // Indexing a doc into package2 should succeed
-        mAppSearchImpl.putDocument(
-                "package2",
-                "database1",
-                new GenericDocument.Builder<>("namespace", "id1", "type").build(),
-                /*logger=*/ null);
-
-        // Reinitialize to make sure packages are parsed correctly on init
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        tempFolder,
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 2;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // package1 should still be out of space
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package1",
-                                        "database4",
-                                        new GenericDocument.Builder<>("namespace", "id4", "type")
-                                                .build(),
-                                        /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package1\" exceeded limit of 2 documents");
-
-        // package2 has room for one more
-        mAppSearchImpl.putDocument(
-                "package2",
-                "database2",
-                new GenericDocument.Builder<>("namespace", "id2", "type").build(),
-                /*logger=*/ null);
-
-        // now package2 really is out of space
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package2",
-                                        "database3",
-                                        new GenericDocument.Builder<>("namespace", "id3", "type")
-                                                .build(),
-                                        /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package2\" exceeded limit of 2 documents");
-    }
-
-    @Test
-    public void testLimitConfig_RemoveByQyery() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 3;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(
-                        new AppSearchSchema.Builder("type")
-                                .addProperty(
-                                        new AppSearchSchema.StringPropertyConfig.Builder("body")
-                                                .setIndexingType(
-                                                        AppSearchSchema.StringPropertyConfig
-                                                                .INDEXING_TYPE_PREFIXES)
-                                                .setTokenizerType(
-                                                        AppSearchSchema.StringPropertyConfig
-                                                                .TOKENIZER_TYPE_PLAIN)
-                                                .build())
-                                .build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Index 3 documents
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type")
-                        .setPropertyString("body", "tablet")
-                        .build(),
-                /*logger=*/ null);
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id2", "type")
-                        .setPropertyString("body", "tabby")
-                        .build(),
-                /*logger=*/ null);
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id3", "type")
-                        .setPropertyString("body", "grabby")
-                        .build(),
-                /*logger=*/ null);
-
-        // Now we should get a failure
-        GenericDocument document4 =
-                new GenericDocument.Builder<>("namespace", "id4", "type").build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document4, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 3 documents");
-
-        // Run removebyquery, deleting nothing
-        mAppSearchImpl.removeByQuery(
-                "package",
-                "database",
-                "nothing",
-                new SearchSpec.Builder().build(),
-                /*removeStatsBuilder=*/ null);
-
-        // Should still fail
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document4, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 3 documents");
-
-        // Remove "tab*"
-        mAppSearchImpl.removeByQuery(
-                "package",
-                "database",
-                "tab",
-                new SearchSpec.Builder().build(),
-                /*removeStatsBuilder=*/ null);
-
-        // Now doc4 and doc5 should work
-        mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null);
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id5", "type").build(),
-                /*logger=*/ null);
-
-        // We only deleted 2 docs so the next one should fail again
-        e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package",
-                                        "database",
-                                        new GenericDocument.Builder<>("namespace", "id6", "type")
-                                                .build(),
-                                        /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 3 documents");
-    }
-
-    @Test
-    public void testLimitConfig_Replace() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 2;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(
-                        new AppSearchSchema.Builder("type")
-                                .addProperty(
-                                        new AppSearchSchema.StringPropertyConfig.Builder("body")
-                                                .build())
-                                .build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Index a document
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type")
-                        .setPropertyString("body", "id1.orig")
-                        .build(),
-                /*logger=*/ null);
-        // Replace it with another doc
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type")
-                        .setPropertyString("body", "id1.new")
-                        .build(),
-                /*logger=*/ null);
-
-        // Index id2. This should pass but only because we check for replacements.
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id2", "type").build(),
-                /*logger=*/ null);
-
-        // Now we should get a failure on id3
-        GenericDocument document3 =
-                new GenericDocument.Builder<>("namespace", "id3", "type").build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document3, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 2 documents");
-    }
-
-    @Test
-    public void testLimitConfig_ReplaceReinit() throws Exception {
-        // Create a new mAppSearchImpl with a lower limit
-        mAppSearchImpl.close();
-        File tempFolder = mTemporaryFolder.newFolder();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        tempFolder,
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 2;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Insert schema
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(
-                        new AppSearchSchema.Builder("type")
-                                .addProperty(
-                                        new AppSearchSchema.StringPropertyConfig.Builder("body")
-                                                .build())
-                                .build());
-        mAppSearchImpl.setSchema(
-                "package",
-                "database",
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Index a document
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type")
-                        .setPropertyString("body", "id1.orig")
-                        .build(),
-                /*logger=*/ null);
-        // Replace it with another doc
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id1", "type")
-                        .setPropertyString("body", "id1.new")
-                        .build(),
-                /*logger=*/ null);
-
-        // Reinitialize to make sure replacements are correctly accounted for by init
-        mAppSearchImpl.close();
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        tempFolder,
-                        new LimitConfig() {
-                            @Override
-                            public int getMaxDocumentSizeBytes() {
-                                return Integer.MAX_VALUE;
-                            }
-
-                            @Override
-                            public int getMaxDocumentCount() {
-                                return 2;
-                            }
-                        },
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        // Index id2. This should pass but only because we check for replacements.
-        mAppSearchImpl.putDocument(
-                "package",
-                "database",
-                new GenericDocument.Builder<>("namespace", "id2", "type").build(),
-                /*logger=*/ null);
-
-        // Now we should get a failure on id3
-        GenericDocument document3 =
-                new GenericDocument.Builder<>("namespace", "id3", "type").build();
-        AppSearchException e =
-                assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        "package", "database", document3, /*logger=*/ null));
-        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
-        assertThat(e)
-                .hasMessageThat()
-                .contains("Package \"package\" exceeded limit of 2 documents");
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
deleted file mode 100644
index 7c97687..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSchema;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.SearchResultPage;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.exceptions.AppSearchException;
-
-import com.android.server.appsearch.external.localstorage.stats.CallStats;
-import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
-import com.android.server.appsearch.external.localstorage.stats.OptimizeStats;
-import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
-import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
-import com.android.server.appsearch.external.localstorage.stats.SearchStats;
-import com.android.server.appsearch.icing.proto.DeleteStatsProto;
-import com.android.server.appsearch.icing.proto.DocumentProto;
-import com.android.server.appsearch.icing.proto.InitializeStatsProto;
-import com.android.server.appsearch.icing.proto.OptimizeStatsProto;
-import com.android.server.appsearch.icing.proto.PutDocumentStatsProto;
-import com.android.server.appsearch.icing.proto.PutResultProto;
-import com.android.server.appsearch.icing.proto.QueryStatsProto;
-import com.android.server.appsearch.icing.proto.ScoringSpecProto;
-import com.android.server.appsearch.icing.proto.StatusProto;
-import com.android.server.appsearch.icing.proto.TermMatchType;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-
-public class AppSearchLoggerTest {
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-    private AppSearchImpl mAppSearchImpl;
-    private TestLogger mLogger;
-    /**
-     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
-     */
-    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
-
-    @Before
-    public void setUp() throws Exception {
-        mAppSearchImpl =
-                AppSearchImpl.create(
-                        mTemporaryFolder.newFolder(),
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-        mLogger = new TestLogger();
-    }
-
-    // Test only not thread safe.
-    public static class TestLogger implements AppSearchLogger {
-        @Nullable CallStats mCallStats;
-        @Nullable PutDocumentStats mPutDocumentStats;
-        @Nullable InitializeStats mInitializeStats;
-        @Nullable SearchStats mSearchStats;
-        @Nullable RemoveStats mRemoveStats;
-        @Nullable OptimizeStats mOptimizeStats;
-
-        @Override
-        public void logStats(@NonNull CallStats stats) {
-            mCallStats = stats;
-        }
-
-        @Override
-        public void logStats(@NonNull PutDocumentStats stats) {
-            mPutDocumentStats = stats;
-        }
-
-        @Override
-        public void logStats(@NonNull InitializeStats stats) {
-            mInitializeStats = stats;
-        }
-
-        @Override
-        public void logStats(@NonNull SearchStats stats) {
-            mSearchStats = stats;
-        }
-
-        @Override
-        public void logStats(@NonNull RemoveStats stats) {
-            mRemoveStats = stats;
-        }
-
-        @Override
-        public void logStats(@NonNull OptimizeStats stats) {
-            mOptimizeStats = stats;
-        }
-    }
-
-    @Test
-    public void testAppSearchLoggerHelper_testCopyNativeStats_initialize() {
-        int nativeLatencyMillis = 3;
-        int nativeDocumentStoreRecoveryCause = InitializeStatsProto.RecoveryCause.DATA_LOSS_VALUE;
-        int nativeIndexRestorationCause =
-                InitializeStatsProto.RecoveryCause.INCONSISTENT_WITH_GROUND_TRUTH_VALUE;
-        int nativeSchemaStoreRecoveryCause =
-                InitializeStatsProto.RecoveryCause.SCHEMA_CHANGES_OUT_OF_SYNC_VALUE;
-        int nativeDocumentStoreRecoveryLatencyMillis = 7;
-        int nativeIndexRestorationLatencyMillis = 8;
-        int nativeSchemaStoreRecoveryLatencyMillis = 9;
-        int nativeDocumentStoreDataStatus =
-                InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE;
-        int nativeNumDocuments = 11;
-        int nativeNumSchemaTypes = 12;
-        InitializeStatsProto.Builder nativeInitBuilder =
-                InitializeStatsProto.newBuilder()
-                        .setLatencyMs(nativeLatencyMillis)
-                        .setDocumentStoreRecoveryCause(
-                                InitializeStatsProto.RecoveryCause.forNumber(
-                                        nativeDocumentStoreRecoveryCause))
-                        .setIndexRestorationCause(
-                                InitializeStatsProto.RecoveryCause.forNumber(
-                                        nativeIndexRestorationCause))
-                        .setSchemaStoreRecoveryCause(
-                                InitializeStatsProto.RecoveryCause.forNumber(
-                                        nativeSchemaStoreRecoveryCause))
-                        .setDocumentStoreRecoveryLatencyMs(nativeDocumentStoreRecoveryLatencyMillis)
-                        .setIndexRestorationLatencyMs(nativeIndexRestorationLatencyMillis)
-                        .setSchemaStoreRecoveryLatencyMs(nativeSchemaStoreRecoveryLatencyMillis)
-                        .setDocumentStoreDataStatus(
-                                InitializeStatsProto.DocumentStoreDataStatus.forNumber(
-                                        nativeDocumentStoreDataStatus))
-                        .setNumDocuments(nativeNumDocuments)
-                        .setNumSchemaTypes(nativeNumSchemaTypes);
-        InitializeStats.Builder initBuilder = new InitializeStats.Builder();
-
-        AppSearchLoggerHelper.copyNativeStats(nativeInitBuilder.build(), initBuilder);
-
-        InitializeStats iStats = initBuilder.build();
-        assertThat(iStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(iStats.getDocumentStoreRecoveryCause())
-                .isEqualTo(nativeDocumentStoreRecoveryCause);
-        assertThat(iStats.getIndexRestorationCause()).isEqualTo(nativeIndexRestorationCause);
-        assertThat(iStats.getSchemaStoreRecoveryCause()).isEqualTo(nativeSchemaStoreRecoveryCause);
-        assertThat(iStats.getDocumentStoreRecoveryLatencyMillis())
-                .isEqualTo(nativeDocumentStoreRecoveryLatencyMillis);
-        assertThat(iStats.getIndexRestorationLatencyMillis())
-                .isEqualTo(nativeIndexRestorationLatencyMillis);
-        assertThat(iStats.getSchemaStoreRecoveryLatencyMillis())
-                .isEqualTo(nativeSchemaStoreRecoveryLatencyMillis);
-        assertThat(iStats.getDocumentStoreDataStatus()).isEqualTo(nativeDocumentStoreDataStatus);
-        assertThat(iStats.getDocumentCount()).isEqualTo(nativeNumDocuments);
-        assertThat(iStats.getSchemaTypeCount()).isEqualTo(nativeNumSchemaTypes);
-    }
-
-    @Test
-    public void testAppSearchLoggerHelper_testCopyNativeStats_putDocument() {
-        final int nativeLatencyMillis = 3;
-        final int nativeDocumentStoreLatencyMillis = 4;
-        final int nativeIndexLatencyMillis = 5;
-        final int nativeIndexMergeLatencyMillis = 6;
-        final int nativeDocumentSize = 7;
-        final int nativeNumTokensIndexed = 8;
-        final boolean nativeExceededMaxNumTokens = true;
-        PutDocumentStatsProto nativePutDocumentStats =
-                PutDocumentStatsProto.newBuilder()
-                        .setLatencyMs(nativeLatencyMillis)
-                        .setDocumentStoreLatencyMs(nativeDocumentStoreLatencyMillis)
-                        .setIndexLatencyMs(nativeIndexLatencyMillis)
-                        .setIndexMergeLatencyMs(nativeIndexMergeLatencyMillis)
-                        .setDocumentSize(nativeDocumentSize)
-                        .setTokenizationStats(
-                                PutDocumentStatsProto.TokenizationStats.newBuilder()
-                                        .setNumTokensIndexed(nativeNumTokensIndexed)
-                                        .setExceededMaxTokenNum(nativeExceededMaxNumTokens)
-                                        .build())
-                        .build();
-        PutDocumentStats.Builder pBuilder = new PutDocumentStats.Builder("packageName", "database");
-
-        AppSearchLoggerHelper.copyNativeStats(nativePutDocumentStats, pBuilder);
-
-        PutDocumentStats pStats = pBuilder.build();
-        assertThat(pStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(pStats.getNativeDocumentStoreLatencyMillis())
-                .isEqualTo(nativeDocumentStoreLatencyMillis);
-        assertThat(pStats.getNativeIndexLatencyMillis()).isEqualTo(nativeIndexLatencyMillis);
-        assertThat(pStats.getNativeIndexMergeLatencyMillis())
-                .isEqualTo(nativeIndexMergeLatencyMillis);
-        assertThat(pStats.getNativeDocumentSizeBytes()).isEqualTo(nativeDocumentSize);
-        assertThat(pStats.getNativeNumTokensIndexed()).isEqualTo(nativeNumTokensIndexed);
-        assertThat(pStats.getNativeExceededMaxNumTokens()).isEqualTo(nativeExceededMaxNumTokens);
-    }
-
-    @Test
-    public void testAppSearchLoggerHelper_testCopyNativeStats_search() {
-        int nativeLatencyMillis = 4;
-        int nativeNumTerms = 5;
-        int nativeQueryLength = 6;
-        int nativeNumNamespacesFiltered = 7;
-        int nativeNumSchemaTypesFiltered = 8;
-        int nativeRequestedPageSize = 9;
-        int nativeNumResultsReturnedCurrentPage = 10;
-        boolean nativeIsFirstPage = true;
-        int nativeParseQueryLatencyMillis = 11;
-        int nativeRankingStrategy = ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP_VALUE;
-        int nativeNumDocumentsScored = 13;
-        int nativeScoringLatencyMillis = 14;
-        int nativeRankingLatencyMillis = 15;
-        int nativeNumResultsWithSnippets = 16;
-        int nativeDocumentRetrievingLatencyMillis = 17;
-        QueryStatsProto nativeQueryStats =
-                QueryStatsProto.newBuilder()
-                        .setLatencyMs(nativeLatencyMillis)
-                        .setNumTerms(nativeNumTerms)
-                        .setQueryLength(nativeQueryLength)
-                        .setNumNamespacesFiltered(nativeNumNamespacesFiltered)
-                        .setNumSchemaTypesFiltered(nativeNumSchemaTypesFiltered)
-                        .setRequestedPageSize(nativeRequestedPageSize)
-                        .setNumResultsReturnedCurrentPage(nativeNumResultsReturnedCurrentPage)
-                        .setIsFirstPage(nativeIsFirstPage)
-                        .setParseQueryLatencyMs(nativeParseQueryLatencyMillis)
-                        .setRankingStrategy(
-                                ScoringSpecProto.RankingStrategy.Code.forNumber(
-                                        nativeRankingStrategy))
-                        .setNumDocumentsScored(nativeNumDocumentsScored)
-                        .setScoringLatencyMs(nativeScoringLatencyMillis)
-                        .setRankingLatencyMs(nativeRankingLatencyMillis)
-                        .setNumResultsWithSnippets(nativeNumResultsWithSnippets)
-                        .setDocumentRetrievalLatencyMs(nativeDocumentRetrievingLatencyMillis)
-                        .build();
-        SearchStats.Builder qBuilder =
-                new SearchStats.Builder(SearchStats.VISIBILITY_SCOPE_LOCAL, "packageName")
-                        .setDatabase("database");
-
-        AppSearchLoggerHelper.copyNativeStats(nativeQueryStats, qBuilder);
-
-        SearchStats sStats = qBuilder.build();
-        assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(sStats.getTermCount()).isEqualTo(nativeNumTerms);
-        assertThat(sStats.getQueryLength()).isEqualTo(nativeQueryLength);
-        assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(nativeNumNamespacesFiltered);
-        assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(nativeNumSchemaTypesFiltered);
-        assertThat(sStats.getRequestedPageSize()).isEqualTo(nativeRequestedPageSize);
-        assertThat(sStats.getCurrentPageReturnedResultCount())
-                .isEqualTo(nativeNumResultsReturnedCurrentPage);
-        assertThat(sStats.isFirstPage()).isTrue();
-        assertThat(sStats.getParseQueryLatencyMillis()).isEqualTo(nativeParseQueryLatencyMillis);
-        assertThat(sStats.getRankingStrategy()).isEqualTo(nativeRankingStrategy);
-        assertThat(sStats.getScoredDocumentCount()).isEqualTo(nativeNumDocumentsScored);
-        assertThat(sStats.getScoringLatencyMillis()).isEqualTo(nativeScoringLatencyMillis);
-        assertThat(sStats.getRankingLatencyMillis()).isEqualTo(nativeRankingLatencyMillis);
-        assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(nativeNumResultsWithSnippets);
-        assertThat(sStats.getDocumentRetrievingLatencyMillis())
-                .isEqualTo(nativeDocumentRetrievingLatencyMillis);
-    }
-
-    @Test
-    public void testAppSearchLoggerHelper_testCopyNativeStats_remove() {
-        final int nativeLatencyMillis = 1;
-        final int nativeDeleteType = 2;
-        final int nativeNumDocumentDeleted = 3;
-        DeleteStatsProto nativeDeleteStatsProto =
-                DeleteStatsProto.newBuilder()
-                        .setLatencyMs(nativeLatencyMillis)
-                        .setDeleteType(DeleteStatsProto.DeleteType.Code.forNumber(nativeDeleteType))
-                        .setNumDocumentsDeleted(nativeNumDocumentDeleted)
-                        .build();
-        RemoveStats.Builder rBuilder = new RemoveStats.Builder("packageName", "database");
-
-        AppSearchLoggerHelper.copyNativeStats(nativeDeleteStatsProto, rBuilder);
-
-        RemoveStats rStats = rBuilder.build();
-        assertThat(rStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(rStats.getDeleteType()).isEqualTo(nativeDeleteType);
-        assertThat(rStats.getDeletedDocumentCount()).isEqualTo(nativeNumDocumentDeleted);
-    }
-
-    @Test
-    public void testAppSearchLoggerHelper_testCopyNativeStats_optimize() {
-        int nativeLatencyMillis = 1;
-        int nativeDocumentStoreOptimizeLatencyMillis = 2;
-        int nativeIndexRestorationLatencyMillis = 3;
-        int nativeNumOriginalDocuments = 4;
-        int nativeNumDeletedDocuments = 5;
-        int nativeNumExpiredDocuments = 6;
-        long nativeStorageSizeBeforeBytes = Integer.MAX_VALUE + 1;
-        long nativeStorageSizeAfterBytes = Integer.MAX_VALUE + 2;
-        long nativeTimeSinceLastOptimizeMillis = Integer.MAX_VALUE + 3;
-        OptimizeStatsProto optimizeStatsProto =
-                OptimizeStatsProto.newBuilder()
-                        .setLatencyMs(nativeLatencyMillis)
-                        .setDocumentStoreOptimizeLatencyMs(nativeDocumentStoreOptimizeLatencyMillis)
-                        .setIndexRestorationLatencyMs(nativeIndexRestorationLatencyMillis)
-                        .setNumOriginalDocuments(nativeNumOriginalDocuments)
-                        .setNumDeletedDocuments(nativeNumDeletedDocuments)
-                        .setNumExpiredDocuments(nativeNumExpiredDocuments)
-                        .setStorageSizeBefore(nativeStorageSizeBeforeBytes)
-                        .setStorageSizeAfter(nativeStorageSizeAfterBytes)
-                        .setTimeSinceLastOptimizeMs(nativeTimeSinceLastOptimizeMillis)
-                        .build();
-        OptimizeStats.Builder oBuilder = new OptimizeStats.Builder();
-
-        AppSearchLoggerHelper.copyNativeStats(optimizeStatsProto, oBuilder);
-
-        OptimizeStats oStats = oBuilder.build();
-        assertThat(oStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(oStats.getDocumentStoreOptimizeLatencyMillis())
-                .isEqualTo(nativeDocumentStoreOptimizeLatencyMillis);
-        assertThat(oStats.getIndexRestorationLatencyMillis())
-                .isEqualTo(nativeIndexRestorationLatencyMillis);
-        assertThat(oStats.getOriginalDocumentCount()).isEqualTo(nativeNumOriginalDocuments);
-        assertThat(oStats.getDeletedDocumentCount()).isEqualTo(nativeNumDeletedDocuments);
-        assertThat(oStats.getExpiredDocumentCount()).isEqualTo(nativeNumExpiredDocuments);
-        assertThat(oStats.getStorageSizeBeforeBytes()).isEqualTo(nativeStorageSizeBeforeBytes);
-        assertThat(oStats.getStorageSizeAfterBytes()).isEqualTo(nativeStorageSizeAfterBytes);
-        assertThat(oStats.getTimeSinceLastOptimizeMillis())
-                .isEqualTo(nativeTimeSinceLastOptimizeMillis);
-    }
-
-    //
-    // Testing actual logging
-    //
-    @Test
-    public void testLoggingStats_initializeWithoutDocuments_success() throws Exception {
-        // Create an unused AppSearchImpl to generated an InitializeStats.
-        InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
-        AppSearchImpl.create(
-                mTemporaryFolder.newFolder(),
-                new UnlimitedLimitConfig(),
-                initStatsBuilder,
-                ALWAYS_OPTIMIZE);
-        InitializeStats iStats = initStatsBuilder.build();
-
-        assertThat(iStats).isNotNull();
-        assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        // Total latency captured in LocalStorage
-        assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
-        assertThat(iStats.hasDeSync()).isFalse();
-        assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
-        assertThat(iStats.getDocumentStoreDataStatus())
-                .isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
-        assertThat(iStats.getDocumentCount()).isEqualTo(0);
-        assertThat(iStats.getSchemaTypeCount()).isEqualTo(0);
-        assertThat(iStats.hasReset()).isEqualTo(false);
-        assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-    }
-
-    @Test
-    public void testLoggingStats_initializeWithDocuments_success() throws Exception {
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        final File folder = mTemporaryFolder.newFolder();
-
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        folder,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("Type1").build(),
-                        new AppSearchSchema.Builder("Type2").build());
-        appSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
-        GenericDocument doc2 = new GenericDocument.Builder<>("namespace", "id2", "Type1").build();
-        appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
-        appSearchImpl.putDocument(testPackageName, testDatabase, doc2, mLogger);
-        appSearchImpl.close();
-
-        // Create another appsearchImpl on the same folder
-        InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
-        AppSearchImpl.create(folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE);
-        InitializeStats iStats = initStatsBuilder.build();
-
-        assertThat(iStats).isNotNull();
-        assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        // Total latency captured in LocalStorage
-        assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
-        assertThat(iStats.hasDeSync()).isFalse();
-        assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
-        assertThat(iStats.getDocumentStoreDataStatus())
-                .isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
-        assertThat(iStats.getDocumentCount()).isEqualTo(2);
-        assertThat(iStats.getSchemaTypeCount()).isEqualTo(2);
-        assertThat(iStats.hasReset()).isEqualTo(false);
-        assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-    }
-
-    @Test
-    public void testLoggingStats_initialize_failure() throws Exception {
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        final File folder = mTemporaryFolder.newFolder();
-
-        AppSearchImpl appSearchImpl =
-                AppSearchImpl.create(
-                        folder,
-                        new UnlimitedLimitConfig(),
-                        /*initStatsBuilder=*/ null,
-                        ALWAYS_OPTIMIZE);
-
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("Type1").build(),
-                        new AppSearchSchema.Builder("Type2").build());
-        appSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        // Insert a valid doc
-        GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
-        appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
-
-        // Insert the invalid doc with an invalid namespace right into icing
-        DocumentProto invalidDoc =
-                DocumentProto.newBuilder()
-                        .setNamespace("invalidNamespace")
-                        .setUri("id2")
-                        .setSchema(String.format("%s$%s/Type1", testPackageName, testDatabase))
-                        .build();
-        PutResultProto putResultProto = appSearchImpl.mIcingSearchEngineLocked.put(invalidDoc);
-        assertThat(putResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.OK);
-        appSearchImpl.close();
-
-        // Create another appsearchImpl on the same folder
-        InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
-        AppSearchImpl.create(folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE);
-        InitializeStats iStats = initStatsBuilder.build();
-
-        // Some of other fields are already covered by AppSearchImplTest#testReset()
-        assertThat(iStats).isNotNull();
-        assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
-        assertThat(iStats.hasReset()).isTrue();
-    }
-
-    @Test
-    public void testLoggingStats_putDocument_success() throws Exception {
-        // Insert schema
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        AppSearchSchema testSchema =
-                new AppSearchSchema.Builder("type")
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("subject")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .build())
-                        .build();
-        List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace", "id", "type")
-                        .setPropertyString("subject", "testPut example1")
-                        .build();
-
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
-
-        PutDocumentStats pStats = mLogger.mPutDocumentStats;
-        assertThat(pStats).isNotNull();
-        assertThat(pStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(pStats.getDatabase()).isEqualTo(testDatabase);
-        assertThat(pStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        // The latency related native stats have been tested in testCopyNativeStats
-        assertThat(pStats.getNativeDocumentSizeBytes()).isGreaterThan(0);
-        assertThat(pStats.getNativeNumTokensIndexed()).isGreaterThan(0);
-    }
-
-    @Test
-    public void testLoggingStats_putDocument_failure() throws Exception {
-        // Insert schema
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        AppSearchSchema testSchema =
-                new AppSearchSchema.Builder("type")
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("subject")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .build())
-                        .build();
-        List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        GenericDocument document =
-                new GenericDocument.Builder<>("namespace", "id", "type")
-                        .setPropertyString("nonExist", "testPut example1")
-                        .build();
-
-        AppSearchException exception =
-                Assert.assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.putDocument(
-                                        testPackageName, testDatabase, document, mLogger));
-        assertThat(exception.getResultCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
-
-        PutDocumentStats pStats = mLogger.mPutDocumentStats;
-        assertThat(pStats).isNotNull();
-        assertThat(pStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(pStats.getDatabase()).isEqualTo(testDatabase);
-        assertThat(pStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
-    }
-
-    @Test
-    public void testLoggingStats_search_success() throws Exception {
-        // Insert schema
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        AppSearchSchema testSchema =
-                new AppSearchSchema.Builder("type")
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("subject")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .build())
-                        .build();
-        List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        GenericDocument document1 =
-                new GenericDocument.Builder<>("namespace", "id1", "type")
-                        .setPropertyString("subject", "testPut example1")
-                        .build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>("namespace", "id2", "type")
-                        .setPropertyString("subject", "testPut example2")
-                        .build();
-        GenericDocument document3 =
-                new GenericDocument.Builder<>("namespace", "id3", "type")
-                        .setPropertyString("subject", "testPut 3")
-                        .build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document3, mLogger);
-
-        // No query filters specified. package2 should only get its own documents back.
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
-                        .build();
-        String queryStr = "testPut e";
-        SearchResultPage searchResultPage =
-                mAppSearchImpl.query(
-                        testPackageName, testDatabase, queryStr, searchSpec, /*logger=*/ mLogger);
-
-        assertThat(searchResultPage.getResults()).hasSize(2);
-        // The ranking strategy is LIFO
-        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
-        assertThat(searchResultPage.getResults().get(1).getGenericDocument()).isEqualTo(document1);
-
-        SearchStats sStats = mLogger.mSearchStats;
-
-        assertThat(sStats).isNotNull();
-        assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(sStats.getDatabase()).isEqualTo(testDatabase);
-        assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        assertThat(sStats.getTotalLatencyMillis()).isGreaterThan(0);
-        assertThat(sStats.getVisibilityScope()).isEqualTo(SearchStats.VISIBILITY_SCOPE_LOCAL);
-        assertThat(sStats.getTermCount()).isEqualTo(2);
-        assertThat(sStats.getQueryLength()).isEqualTo(queryStr.length());
-        assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(1);
-        assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(1);
-        assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(2);
-        assertThat(sStats.isFirstPage()).isTrue();
-        assertThat(sStats.getRankingStrategy())
-                .isEqualTo(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP);
-        assertThat(sStats.getScoredDocumentCount()).isEqualTo(2);
-        assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testLoggingStats_search_failure() throws Exception {
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        List<AppSearchSchema> schemas =
-                ImmutableList.of(
-                        new AppSearchSchema.Builder("Type1").build(),
-                        new AppSearchSchema.Builder("Type2").build());
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        SearchSpec searchSpec =
-                new SearchSpec.Builder()
-                        .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
-                        .setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
-                        .addFilterPackageNames("anotherPackage")
-                        .build();
-
-        mAppSearchImpl.query(
-                testPackageName,
-                testPackageName,
-                /* queryExpression= */ "",
-                searchSpec,
-                /*logger=*/ mLogger);
-
-        SearchStats sStats = mLogger.mSearchStats;
-        assertThat(sStats).isNotNull();
-        assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(sStats.getDatabase()).isEqualTo(testPackageName);
-        assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
-    }
-
-    @Test
-    public void testLoggingStats_remove_success() throws Exception {
-        // Insert schema
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        final String testNamespace = "testNameSpace";
-        final String testId = "id";
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        GenericDocument document =
-                new GenericDocument.Builder<>(testNamespace, testId, "type").build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
-
-        RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
-        mAppSearchImpl.remove(testPackageName, testDatabase, testNamespace, testId, rStatsBuilder);
-        RemoveStats rStats = rStatsBuilder.build();
-
-        assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
-        // delete by namespace + id
-        assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
-        assertThat(rStats.getDeletedDocumentCount()).isEqualTo(1);
-    }
-
-    @Test
-    public void testLoggingStats_remove_failure() throws Exception {
-        // Insert schema
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        final String testNamespace = "testNameSpace";
-        final String testId = "id";
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-
-        GenericDocument document =
-                new GenericDocument.Builder<>(testNamespace, testId, "type").build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
-
-        RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
-
-        AppSearchException exception =
-                Assert.assertThrows(
-                        AppSearchException.class,
-                        () ->
-                                mAppSearchImpl.remove(
-                                        testPackageName,
-                                        testDatabase,
-                                        testNamespace,
-                                        "invalidId",
-                                        rStatsBuilder));
-        assertThat(exception.getResultCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
-
-        RemoveStats rStats = rStatsBuilder.build();
-        assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
-        assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
-        // delete by namespace + id
-        assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
-        assertThat(rStats.getDeletedDocumentCount()).isEqualTo(0);
-    }
-
-    @Test
-    public void testLoggingStats_removeByQuery_success() throws Exception {
-        // Insert schema
-        final String testPackageName = "testPackage";
-        final String testDatabase = "testDatabase";
-        final String testNamespace = "testNameSpace";
-        List<AppSearchSchema> schemas =
-                Collections.singletonList(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema(
-                testPackageName,
-                testDatabase,
-                schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
-                /*forceOverride=*/ false,
-                /*version=*/ 0);
-        GenericDocument document1 =
-                new GenericDocument.Builder<>(testNamespace, "id1", "type").build();
-        GenericDocument document2 =
-                new GenericDocument.Builder<>(testNamespace, "id2", "type").build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
-        // No query filters specified. package2 should only get its own documents back.
-        SearchSpec searchSpec =
-                new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
-
-        RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
-        mAppSearchImpl.removeByQuery(
-                testPackageName, testDatabase, /*queryExpression=*/ "", searchSpec, rStatsBuilder);
-        RemoveStats rStats = rStatsBuilder.build();
-
-        assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
-        assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
-        assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        // delete by query
-        assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.QUERY_VALUE);
-        assertThat(rStats.getDeletedDocumentCount()).isEqualTo(2);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
deleted file mode 100644
index 204fc54..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
+++ /dev/null
@@ -1,256 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.GenericDocument;
-
-import com.android.server.appsearch.icing.proto.DocumentProto;
-import com.android.server.appsearch.icing.proto.PropertyConfigProto;
-import com.android.server.appsearch.icing.proto.PropertyProto;
-import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto;
-import com.android.server.appsearch.protobuf.ByteString;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class GenericDocumentToProtoConverterTest {
-    private static final byte[] BYTE_ARRAY_1 = new byte[] {(byte) 1, (byte) 2, (byte) 3};
-    private static final byte[] BYTE_ARRAY_2 = new byte[] {(byte) 4, (byte) 5, (byte) 6, (byte) 7};
-    private static final String SCHEMA_TYPE_1 = "sDocumentPropertiesSchemaType1";
-    private static final String SCHEMA_TYPE_2 = "sDocumentPropertiesSchemaType2";
-    private static final GenericDocument DOCUMENT_PROPERTIES_1 =
-            new GenericDocument.Builder<GenericDocument.Builder<?>>(
-                            "namespace", "sDocumentProperties1", SCHEMA_TYPE_1)
-                    .setCreationTimestampMillis(12345L)
-                    .build();
-    private static final GenericDocument DOCUMENT_PROPERTIES_2 =
-            new GenericDocument.Builder<GenericDocument.Builder<?>>(
-                            "namespace", "sDocumentProperties2", SCHEMA_TYPE_2)
-                    .setCreationTimestampMillis(6789L)
-                    .build();
-    private static final SchemaTypeConfigProto SCHEMA_PROTO_1 =
-            SchemaTypeConfigProto.newBuilder().setSchemaType(SCHEMA_TYPE_1).build();
-    private static final SchemaTypeConfigProto SCHEMA_PROTO_2 =
-            SchemaTypeConfigProto.newBuilder().setSchemaType(SCHEMA_TYPE_2).build();
-    private static final String PREFIX = "package$databaseName/";
-    private static final Map<String, SchemaTypeConfigProto> SCHEMA_MAP =
-            ImmutableMap.of(
-                    PREFIX + SCHEMA_TYPE_1, SCHEMA_PROTO_1, PREFIX + SCHEMA_TYPE_2, SCHEMA_PROTO_2);
-
-    @Test
-    public void testDocumentProtoConvert() {
-        GenericDocument document =
-                new GenericDocument.Builder<GenericDocument.Builder<?>>(
-                                "namespace", "id1", SCHEMA_TYPE_1)
-                        .setCreationTimestampMillis(5L)
-                        .setScore(1)
-                        .setTtlMillis(1L)
-                        .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.
-        DocumentProto.Builder documentProtoBuilder =
-                DocumentProto.newBuilder()
-                        .setUri("id1")
-                        .setSchema(SCHEMA_TYPE_1)
-                        .setCreationTimestampMs(5L)
-                        .setScore(1)
-                        .setTtlMs(1L)
-                        .setNamespace("namespace");
-        HashMap<String, PropertyProto.Builder> propertyProtoMap = new HashMap<>();
-        propertyProtoMap.put(
-                "longKey1", PropertyProto.newBuilder().setName("longKey1").addInt64Values(1L));
-        propertyProtoMap.put(
-                "doubleKey1",
-                PropertyProto.newBuilder().setName("doubleKey1").addDoubleValues(1.0));
-        propertyProtoMap.put(
-                "booleanKey1",
-                PropertyProto.newBuilder().setName("booleanKey1").addBooleanValues(true));
-        propertyProtoMap.put(
-                "stringKey1",
-                PropertyProto.newBuilder().setName("stringKey1").addStringValues("test-value1"));
-        propertyProtoMap.put(
-                "byteKey1",
-                PropertyProto.newBuilder()
-                        .setName("byteKey1")
-                        .addBytesValues(ByteString.copyFrom(BYTE_ARRAY_1))
-                        .addBytesValues(ByteString.copyFrom(BYTE_ARRAY_2)));
-        propertyProtoMap.put(
-                "documentKey1",
-                PropertyProto.newBuilder()
-                        .setName("documentKey1")
-                        .addDocumentValues(
-                                GenericDocumentToProtoConverter.toDocumentProto(
-                                        DOCUMENT_PROPERTIES_1)));
-        propertyProtoMap.put(
-                "documentKey2",
-                PropertyProto.newBuilder()
-                        .setName("documentKey2")
-                        .addDocumentValues(
-                                GenericDocumentToProtoConverter.toDocumentProto(
-                                        DOCUMENT_PROPERTIES_2)));
-        List<String> sortedKey = new ArrayList<>(propertyProtoMap.keySet());
-        Collections.sort(sortedKey);
-        for (String key : sortedKey) {
-            documentProtoBuilder.addProperties(propertyProtoMap.get(key));
-        }
-        DocumentProto documentProto = documentProtoBuilder.build();
-
-        GenericDocument convertedGenericDocument =
-                GenericDocumentToProtoConverter.toGenericDocument(
-                        documentProto, PREFIX, SCHEMA_MAP);
-        DocumentProto convertedDocumentProto =
-                GenericDocumentToProtoConverter.toDocumentProto(document);
-
-        assertThat(convertedDocumentProto).isEqualTo(documentProto);
-        assertThat(convertedGenericDocument).isEqualTo(document);
-    }
-
-    @Test
-    public void testConvertDocument_whenPropertyHasEmptyList() {
-        String emptyStringPropertyName = "emptyStringProperty";
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id1")
-                        .setSchema(SCHEMA_TYPE_1)
-                        .setCreationTimestampMs(5L)
-                        .setNamespace("namespace")
-                        .addProperties(
-                                PropertyProto.newBuilder().setName(emptyStringPropertyName).build())
-                        .build();
-
-        PropertyConfigProto emptyStringListProperty =
-                PropertyConfigProto.newBuilder()
-                        .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
-                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                        .setPropertyName(emptyStringPropertyName)
-                        .build();
-        SchemaTypeConfigProto schemaTypeConfigProto =
-                SchemaTypeConfigProto.newBuilder()
-                        .addProperties(emptyStringListProperty)
-                        .setSchemaType(SCHEMA_TYPE_1)
-                        .build();
-        Map<String, SchemaTypeConfigProto> schemaMap =
-                ImmutableMap.of(PREFIX + SCHEMA_TYPE_1, schemaTypeConfigProto);
-
-        GenericDocument convertedDocument =
-                GenericDocumentToProtoConverter.toGenericDocument(documentProto, PREFIX, schemaMap);
-
-        GenericDocument expectedDocument =
-                new GenericDocument.Builder<GenericDocument.Builder<?>>(
-                                "namespace", "id1", SCHEMA_TYPE_1)
-                        .setCreationTimestampMillis(5L)
-                        .setPropertyString(emptyStringPropertyName)
-                        .build();
-        assertThat(convertedDocument).isEqualTo(expectedDocument);
-        assertThat(expectedDocument.getPropertyStringArray(emptyStringPropertyName)).isEmpty();
-    }
-
-    @Test
-    public void testConvertDocument_whenNestedDocumentPropertyHasEmptyList() {
-        String emptyStringPropertyName = "emptyStringProperty";
-        String documentPropertyName = "documentProperty";
-        DocumentProto nestedDocumentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id2")
-                        .setSchema(SCHEMA_TYPE_2)
-                        .setCreationTimestampMs(5L)
-                        .setNamespace("namespace")
-                        .addProperties(
-                                PropertyProto.newBuilder().setName(emptyStringPropertyName).build())
-                        .build();
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id1")
-                        .setSchema(SCHEMA_TYPE_1)
-                        .setCreationTimestampMs(5L)
-                        .setNamespace("namespace")
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .addDocumentValues(nestedDocumentProto)
-                                        .setName(documentPropertyName)
-                                        .build())
-                        .build();
-
-        PropertyConfigProto documentProperty =
-                PropertyConfigProto.newBuilder()
-                        .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
-                        .setDataType(PropertyConfigProto.DataType.Code.DOCUMENT)
-                        .setPropertyName(documentPropertyName)
-                        .setSchemaType(SCHEMA_TYPE_2)
-                        .build();
-        SchemaTypeConfigProto schemaTypeConfigProto =
-                SchemaTypeConfigProto.newBuilder()
-                        .addProperties(documentProperty)
-                        .setSchemaType(SCHEMA_TYPE_1)
-                        .build();
-        PropertyConfigProto emptyStringListProperty =
-                PropertyConfigProto.newBuilder()
-                        .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
-                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                        .setPropertyName(emptyStringPropertyName)
-                        .build();
-        SchemaTypeConfigProto nestedSchemaTypeConfigProto =
-                SchemaTypeConfigProto.newBuilder()
-                        .addProperties(emptyStringListProperty)
-                        .setSchemaType(SCHEMA_TYPE_2)
-                        .build();
-        Map<String, SchemaTypeConfigProto> schemaMap =
-                ImmutableMap.of(
-                        PREFIX + SCHEMA_TYPE_1,
-                        schemaTypeConfigProto,
-                        PREFIX + SCHEMA_TYPE_2,
-                        nestedSchemaTypeConfigProto);
-
-        GenericDocument convertedDocument =
-                GenericDocumentToProtoConverter.toGenericDocument(documentProto, PREFIX, schemaMap);
-
-        GenericDocument expectedDocument =
-                new GenericDocument.Builder<GenericDocument.Builder<?>>(
-                                "namespace", "id1", SCHEMA_TYPE_1)
-                        .setCreationTimestampMillis(5L)
-                        .setPropertyDocument(
-                                documentPropertyName,
-                                new GenericDocument.Builder<GenericDocument.Builder<?>>(
-                                                "namespace", "id2", SCHEMA_TYPE_2)
-                                        .setCreationTimestampMillis(5L)
-                                        .setPropertyString(emptyStringPropertyName)
-                                        .build())
-                        .build();
-        assertThat(convertedDocument).isEqualTo(expectedDocument);
-        assertThat(
-                        expectedDocument
-                                .getPropertyDocument(documentPropertyName)
-                                .getPropertyStringArray(emptyStringPropertyName))
-                .isEmpty();
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
deleted file mode 100644
index ebceba4..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
+++ /dev/null
@@ -1,151 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.AppSearchSchema;
-
-import com.android.server.appsearch.icing.proto.PropertyConfigProto;
-import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto;
-import com.android.server.appsearch.icing.proto.StringIndexingConfig;
-import com.android.server.appsearch.icing.proto.TermMatchType;
-
-import org.junit.Test;
-
-public class SchemaToProtoConverterTest {
-    @Test
-    public void testGetProto_Email() {
-        AppSearchSchema emailSchema =
-                new AppSearchSchema.Builder("Email")
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("subject")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .build())
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("body")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .build())
-                        .build();
-
-        SchemaTypeConfigProto expectedEmailProto =
-                SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType("Email")
-                        .setVersion(12345)
-                        .addProperties(
-                                PropertyConfigProto.newBuilder()
-                                        .setPropertyName("subject")
-                                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                        .setCardinality(
-                                                PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                        .setStringIndexingConfig(
-                                                StringIndexingConfig.newBuilder()
-                                                        .setTokenizerType(
-                                                                StringIndexingConfig.TokenizerType
-                                                                        .Code.PLAIN)
-                                                        .setTermMatchType(
-                                                                TermMatchType.Code.PREFIX)))
-                        .addProperties(
-                                PropertyConfigProto.newBuilder()
-                                        .setPropertyName("body")
-                                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                        .setCardinality(
-                                                PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                        .setStringIndexingConfig(
-                                                StringIndexingConfig.newBuilder()
-                                                        .setTokenizerType(
-                                                                StringIndexingConfig.TokenizerType
-                                                                        .Code.PLAIN)
-                                                        .setTermMatchType(
-                                                                TermMatchType.Code.PREFIX)))
-                        .build();
-
-        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(emailSchema, /*version=*/ 12345))
-                .isEqualTo(expectedEmailProto);
-        assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedEmailProto))
-                .isEqualTo(emailSchema);
-    }
-
-    @Test
-    public void testGetProto_MusicRecording() {
-        AppSearchSchema musicRecordingSchema =
-                new AppSearchSchema.Builder("MusicRecording")
-                        .addProperty(
-                                new AppSearchSchema.StringPropertyConfig.Builder("artist")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
-                                        .setIndexingType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .INDEXING_TYPE_PREFIXES)
-                                        .setTokenizerType(
-                                                AppSearchSchema.StringPropertyConfig
-                                                        .TOKENIZER_TYPE_PLAIN)
-                                        .build())
-                        .addProperty(
-                                new AppSearchSchema.LongPropertyConfig.Builder("pubDate")
-                                        .setCardinality(
-                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
-                                        .build())
-                        .build();
-
-        SchemaTypeConfigProto expectedMusicRecordingProto =
-                SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType("MusicRecording")
-                        .setVersion(0)
-                        .addProperties(
-                                PropertyConfigProto.newBuilder()
-                                        .setPropertyName("artist")
-                                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                        .setCardinality(
-                                                PropertyConfigProto.Cardinality.Code.REPEATED)
-                                        .setStringIndexingConfig(
-                                                StringIndexingConfig.newBuilder()
-                                                        .setTokenizerType(
-                                                                StringIndexingConfig.TokenizerType
-                                                                        .Code.PLAIN)
-                                                        .setTermMatchType(
-                                                                TermMatchType.Code.PREFIX)))
-                        .addProperties(
-                                PropertyConfigProto.newBuilder()
-                                        .setPropertyName("pubDate")
-                                        .setDataType(PropertyConfigProto.DataType.Code.INT64)
-                                        .setCardinality(
-                                                PropertyConfigProto.Cardinality.Code.OPTIONAL))
-                        .build();
-
-        assertThat(
-                        SchemaToProtoConverter.toSchemaTypeConfigProto(
-                                musicRecordingSchema, /*version=*/ 0))
-                .isEqualTo(expectedMusicRecordingProto);
-        assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedMusicRecordingProto))
-                .isEqualTo(musicRecordingSchema);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
deleted file mode 100644
index 992961c..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
+++ /dev/null
@@ -1,322 +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 com.android.server.appsearch.external.localstorage.converter;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResultPage;
-
-import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.icing.proto.DocumentProto;
-import com.android.server.appsearch.icing.proto.PropertyProto;
-import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto;
-import com.android.server.appsearch.icing.proto.SearchResultProto;
-import com.android.server.appsearch.icing.proto.SnippetMatchProto;
-import com.android.server.appsearch.icing.proto.SnippetProto;
-
-import org.junit.Test;
-
-import java.util.Collections;
-import java.util.Map;
-
-public class SnippetTest {
-    private static final String SCHEMA_TYPE = "schema1";
-    private static final String PACKAGE_NAME = "packageName";
-    private static final String DATABASE_NAME = "databaseName";
-    private static final String PREFIX = PrefixUtil.createPrefix(PACKAGE_NAME, DATABASE_NAME);
-    private static final SchemaTypeConfigProto SCHEMA_TYPE_CONFIG_PROTO =
-            SchemaTypeConfigProto.newBuilder().setSchemaType(PREFIX + SCHEMA_TYPE).build();
-    private static final Map<String, Map<String, SchemaTypeConfigProto>> SCHEMA_MAP =
-            Collections.singletonMap(
-                    PREFIX,
-                    Collections.singletonMap(PREFIX + SCHEMA_TYPE, SCHEMA_TYPE_CONFIG_PROTO));
-
-    @Test
-    public void testSingleStringSnippet() {
-        final String propertyKeyString = "content";
-        final String propertyValueString =
-                "A commonly used fake word is foo.\n"
-                        + "   Another nonsense word that’s used a lot\n"
-                        + "   is bar.\n";
-        final String id = "id1";
-        final String exactMatch = "foo";
-        final String window = "is foo";
-
-        // Building the SearchResult received from query.
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri(id)
-                        .setSchema(SCHEMA_TYPE)
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .setName(propertyKeyString)
-                                        .addStringValues(propertyValueString))
-                        .build();
-        SnippetProto snippetProto =
-                SnippetProto.newBuilder()
-                        .addEntries(
-                                SnippetProto.EntryProto.newBuilder()
-                                        .setPropertyName(propertyKeyString)
-                                        .addSnippetMatches(
-                                                SnippetMatchProto.newBuilder()
-                                                        .setExactMatchBytePosition(29)
-                                                        .setExactMatchByteLength(3)
-                                                        .setExactMatchUtf16Position(29)
-                                                        .setExactMatchUtf16Length(3)
-                                                        .setWindowBytePosition(26)
-                                                        .setWindowByteLength(6)
-                                                        .setWindowUtf16Position(26)
-                                                        .setWindowUtf16Length(6)))
-                        .build();
-        SearchResultProto searchResultProto =
-                SearchResultProto.newBuilder()
-                        .addResults(
-                                SearchResultProto.ResultProto.newBuilder()
-                                        .setDocument(documentProto)
-                                        .setSnippet(snippetProto))
-                        .build();
-
-        // Making ResultReader and getting Snippet values.
-        SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.toSearchResultPage(
-                        searchResultProto,
-                        Collections.singletonList(PACKAGE_NAME),
-                        Collections.singletonList(DATABASE_NAME),
-                        SCHEMA_MAP);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        SearchResult.MatchInfo match = searchResultPage.getResults().get(0).getMatchInfos().get(0);
-        assertThat(match.getPropertyPath()).isEqualTo(propertyKeyString);
-        assertThat(match.getFullText()).isEqualTo(propertyValueString);
-        assertThat(match.getExactMatch()).isEqualTo(exactMatch);
-        assertThat(match.getExactMatchRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 29, /*upper=*/ 32));
-        assertThat(match.getFullText()).isEqualTo(propertyValueString);
-        assertThat(match.getSnippetRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 26, /*upper=*/ 32));
-        assertThat(match.getSnippet()).isEqualTo(window);
-    }
-
-    @Test
-    public void testNoSnippets() {
-        final String propertyKeyString = "content";
-        final String propertyValueString =
-                "A commonly used fake word is foo.\n"
-                        + "   Another nonsense word that’s used a lot\n"
-                        + "   is bar.\n";
-        final String id = "id1";
-
-        // Building the SearchResult received from query.
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri(id)
-                        .setSchema(SCHEMA_TYPE)
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .setName(propertyKeyString)
-                                        .addStringValues(propertyValueString))
-                        .build();
-        SearchResultProto searchResultProto =
-                SearchResultProto.newBuilder()
-                        .addResults(
-                                SearchResultProto.ResultProto.newBuilder()
-                                        .setDocument(documentProto))
-                        .build();
-
-        SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.toSearchResultPage(
-                        searchResultProto,
-                        Collections.singletonList(PACKAGE_NAME),
-                        Collections.singletonList(DATABASE_NAME),
-                        SCHEMA_MAP);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        assertThat(searchResultPage.getResults().get(0).getMatchInfos()).isEmpty();
-    }
-
-    @Test
-    public void testMultipleStringSnippet() {
-        // Building the SearchResult received from query.
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("uri1")
-                        .setSchema(SCHEMA_TYPE)
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .setName("senderName")
-                                        .addStringValues("Test Name Jr."))
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .setName("senderEmail")
-                                        .addStringValues("TestNameJr@gmail.com"))
-                        .build();
-        SnippetProto snippetProto =
-                SnippetProto.newBuilder()
-                        .addEntries(
-                                SnippetProto.EntryProto.newBuilder()
-                                        .setPropertyName("senderName")
-                                        .addSnippetMatches(
-                                                SnippetMatchProto.newBuilder()
-                                                        .setExactMatchBytePosition(0)
-                                                        .setExactMatchByteLength(4)
-                                                        .setExactMatchUtf16Position(0)
-                                                        .setExactMatchUtf16Length(4)
-                                                        .setWindowBytePosition(0)
-                                                        .setWindowByteLength(9)
-                                                        .setWindowUtf16Position(0)
-                                                        .setWindowUtf16Length(9)))
-                        .addEntries(
-                                SnippetProto.EntryProto.newBuilder()
-                                        .setPropertyName("senderEmail")
-                                        .addSnippetMatches(
-                                                SnippetMatchProto.newBuilder()
-                                                        .setExactMatchBytePosition(0)
-                                                        .setExactMatchByteLength(20)
-                                                        .setExactMatchUtf16Position(0)
-                                                        .setExactMatchUtf16Length(20)
-                                                        .setWindowBytePosition(0)
-                                                        .setWindowByteLength(20)
-                                                        .setWindowUtf16Position(0)
-                                                        .setWindowUtf16Length(20)))
-                        .build();
-        SearchResultProto searchResultProto =
-                SearchResultProto.newBuilder()
-                        .addResults(
-                                SearchResultProto.ResultProto.newBuilder()
-                                        .setDocument(documentProto)
-                                        .setSnippet(snippetProto))
-                        .build();
-
-        // Making ResultReader and getting Snippet values.
-        SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.toSearchResultPage(
-                        searchResultProto,
-                        Collections.singletonList(PACKAGE_NAME),
-                        Collections.singletonList(DATABASE_NAME),
-                        SCHEMA_MAP);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        SearchResult.MatchInfo match1 = searchResultPage.getResults().get(0).getMatchInfos().get(0);
-        assertThat(match1.getPropertyPath()).isEqualTo("senderName");
-        assertThat(match1.getFullText()).isEqualTo("Test Name Jr.");
-        assertThat(match1.getExactMatchRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 4));
-        assertThat(match1.getExactMatch()).isEqualTo("Test");
-        assertThat(match1.getSnippetRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 9));
-        assertThat(match1.getSnippet()).isEqualTo("Test Name");
-
-        SearchResult.MatchInfo match2 = searchResultPage.getResults().get(0).getMatchInfos().get(1);
-        assertThat(match2.getPropertyPath()).isEqualTo("senderEmail");
-        assertThat(match2.getFullText()).isEqualTo("TestNameJr@gmail.com");
-        assertThat(match2.getExactMatchRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
-        assertThat(match2.getExactMatch()).isEqualTo("TestNameJr@gmail.com");
-        assertThat(match2.getSnippetRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
-        assertThat(match2.getSnippet()).isEqualTo("TestNameJr@gmail.com");
-    }
-
-    @Test
-    public void testNestedDocumentSnippet() {
-        // Building the SearchResult received from query.
-        DocumentProto documentProto =
-                DocumentProto.newBuilder()
-                        .setUri("id1")
-                        .setSchema(SCHEMA_TYPE)
-                        .addProperties(
-                                PropertyProto.newBuilder()
-                                        .setName("sender")
-                                        .addDocumentValues(
-                                                DocumentProto.newBuilder()
-                                                        .addProperties(
-                                                                PropertyProto.newBuilder()
-                                                                        .setName("name")
-                                                                        .addStringValues(
-                                                                                "Test Name Jr."))
-                                                        .addProperties(
-                                                                PropertyProto.newBuilder()
-                                                                        .setName("email")
-                                                                        .addStringValues(
-                                                                                "TestNameJr@gmail.com")
-                                                                        .addStringValues(
-                                                                                "TestNameJr2@gmail.com"))))
-                        .build();
-        SnippetProto snippetProto =
-                SnippetProto.newBuilder()
-                        .addEntries(
-                                SnippetProto.EntryProto.newBuilder()
-                                        .setPropertyName("sender.name")
-                                        .addSnippetMatches(
-                                                SnippetMatchProto.newBuilder()
-                                                        .setExactMatchBytePosition(0)
-                                                        .setExactMatchByteLength(4)
-                                                        .setExactMatchUtf16Position(0)
-                                                        .setExactMatchUtf16Length(4)
-                                                        .setWindowBytePosition(0)
-                                                        .setWindowByteLength(9)
-                                                        .setWindowUtf16Position(0)
-                                                        .setWindowUtf16Length(9)))
-                        .addEntries(
-                                SnippetProto.EntryProto.newBuilder()
-                                        .setPropertyName("sender.email[1]")
-                                        .addSnippetMatches(
-                                                SnippetMatchProto.newBuilder()
-                                                        .setExactMatchBytePosition(0)
-                                                        .setExactMatchByteLength(21)
-                                                        .setExactMatchUtf16Position(0)
-                                                        .setExactMatchUtf16Length(21)
-                                                        .setWindowBytePosition(0)
-                                                        .setWindowByteLength(21)
-                                                        .setWindowUtf16Position(0)
-                                                        .setWindowUtf16Length(21)))
-                        .build();
-        SearchResultProto searchResultProto =
-                SearchResultProto.newBuilder()
-                        .addResults(
-                                SearchResultProto.ResultProto.newBuilder()
-                                        .setDocument(documentProto)
-                                        .setSnippet(snippetProto))
-                        .build();
-
-        // Making ResultReader and getting Snippet values.
-        SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.toSearchResultPage(
-                        searchResultProto,
-                        Collections.singletonList(PACKAGE_NAME),
-                        Collections.singletonList(DATABASE_NAME),
-                        SCHEMA_MAP);
-        assertThat(searchResultPage.getResults()).hasSize(1);
-        SearchResult.MatchInfo match1 = searchResultPage.getResults().get(0).getMatchInfos().get(0);
-        assertThat(match1.getPropertyPath()).isEqualTo("sender.name");
-        assertThat(match1.getFullText()).isEqualTo("Test Name Jr.");
-        assertThat(match1.getExactMatchRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 4));
-        assertThat(match1.getExactMatch()).isEqualTo("Test");
-        assertThat(match1.getSnippetRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 9));
-        assertThat(match1.getSnippet()).isEqualTo("Test Name");
-
-        SearchResult.MatchInfo match2 = searchResultPage.getResults().get(0).getMatchInfos().get(1);
-        assertThat(match2.getPropertyPath()).isEqualTo("sender.email[1]");
-        assertThat(match2.getFullText()).isEqualTo("TestNameJr2@gmail.com");
-        assertThat(match2.getExactMatchRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 21));
-        assertThat(match2.getExactMatch()).isEqualTo("TestNameJr2@gmail.com");
-        assertThat(match2.getSnippetRange())
-                .isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 21));
-        assertThat(match2.getSnippet()).isEqualTo("TestNameJr2@gmail.com");
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
deleted file mode 100644
index c1dc0e4..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.AppSearchResult;
-
-import org.junit.Test;
-
-public class AppSearchStatsTest {
-    static final String TEST_PACKAGE_NAME = "com.google.test";
-    static final String TEST_DATA_BASE = "testDataBase";
-    static final int TEST_STATUS_CODE = AppSearchResult.RESULT_INTERNAL_ERROR;
-    static final int TEST_TOTAL_LATENCY_MILLIS = 20;
-
-    @Test
-    public void testAppSearchStats_CallStats() {
-        final int estimatedBinderLatencyMillis = 1;
-        final int numOperationsSucceeded = 2;
-        final int numOperationsFailed = 3;
-        final @CallStats.CallType int callType = CallStats.CALL_TYPE_PUT_DOCUMENTS;
-
-        final CallStats cStats =
-                new CallStats.Builder()
-                        .setPackageName(TEST_PACKAGE_NAME)
-                        .setDatabase(TEST_DATA_BASE)
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setCallType(callType)
-                        .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
-                        .setNumOperationsSucceeded(numOperationsSucceeded)
-                        .setNumOperationsFailed(numOperationsFailed)
-                        .build();
-
-        assertThat(cStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(cStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
-        assertThat(cStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(cStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(cStats.getEstimatedBinderLatencyMillis())
-                .isEqualTo(estimatedBinderLatencyMillis);
-        assertThat(cStats.getCallType()).isEqualTo(callType);
-        assertThat(cStats.getNumOperationsSucceeded()).isEqualTo(numOperationsSucceeded);
-        assertThat(cStats.getNumOperationsFailed()).isEqualTo(numOperationsFailed);
-    }
-
-    @Test
-    public void testAppSearchCallStats_nullValues() {
-        final @CallStats.CallType int callType = CallStats.CALL_TYPE_PUT_DOCUMENTS;
-
-        final CallStats.Builder cStatsBuilder = new CallStats.Builder().setCallType(callType);
-
-        final CallStats cStats = cStatsBuilder.build();
-
-        assertThat(cStats.getPackageName()).isNull();
-        assertThat(cStats.getDatabase()).isNull();
-        assertThat(cStats.getCallType()).isEqualTo(callType);
-    }
-
-    @Test
-    public void testAppSearchStats_PutDocumentStats() {
-        final int generateDocumentProtoLatencyMillis = 1;
-        final int rewriteDocumentTypesLatencyMillis = 2;
-        final int nativeLatencyMillis = 3;
-        final int nativeDocumentStoreLatencyMillis = 4;
-        final int nativeIndexLatencyMillis = 5;
-        final int nativeIndexMergeLatencyMillis = 6;
-        final int nativeDocumentSize = 7;
-        final int nativeNumTokensIndexed = 8;
-        final boolean nativeExceededMaxNumTokens = true;
-        final PutDocumentStats.Builder pStatsBuilder =
-                new PutDocumentStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setGenerateDocumentProtoLatencyMillis(generateDocumentProtoLatencyMillis)
-                        .setRewriteDocumentTypesLatencyMillis(rewriteDocumentTypesLatencyMillis)
-                        .setNativeLatencyMillis(nativeLatencyMillis)
-                        .setNativeDocumentStoreLatencyMillis(nativeDocumentStoreLatencyMillis)
-                        .setNativeIndexLatencyMillis(nativeIndexLatencyMillis)
-                        .setNativeIndexMergeLatencyMillis(nativeIndexMergeLatencyMillis)
-                        .setNativeDocumentSizeBytes(nativeDocumentSize)
-                        .setNativeNumTokensIndexed(nativeNumTokensIndexed)
-                        .setNativeExceededMaxNumTokens(nativeExceededMaxNumTokens);
-
-        final PutDocumentStats pStats = pStatsBuilder.build();
-
-        assertThat(pStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(pStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
-        assertThat(pStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(pStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(pStats.getGenerateDocumentProtoLatencyMillis())
-                .isEqualTo(generateDocumentProtoLatencyMillis);
-        assertThat(pStats.getRewriteDocumentTypesLatencyMillis())
-                .isEqualTo(rewriteDocumentTypesLatencyMillis);
-        assertThat(pStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(pStats.getNativeDocumentStoreLatencyMillis())
-                .isEqualTo(nativeDocumentStoreLatencyMillis);
-        assertThat(pStats.getNativeIndexLatencyMillis()).isEqualTo(nativeIndexLatencyMillis);
-        assertThat(pStats.getNativeIndexMergeLatencyMillis())
-                .isEqualTo(nativeIndexMergeLatencyMillis);
-        assertThat(pStats.getNativeDocumentSizeBytes()).isEqualTo(nativeDocumentSize);
-        assertThat(pStats.getNativeNumTokensIndexed()).isEqualTo(nativeNumTokensIndexed);
-        assertThat(pStats.getNativeExceededMaxNumTokens()).isEqualTo(nativeExceededMaxNumTokens);
-    }
-
-    @Test
-    public void testAppSearchStats_InitializeStats() {
-        int prepareSchemaAndNamespacesLatencyMillis = 1;
-        int prepareVisibilityFileLatencyMillis = 2;
-        int nativeLatencyMillis = 3;
-        int nativeDocumentStoreRecoveryCause = 4;
-        int nativeIndexRestorationCause = 5;
-        int nativeSchemaStoreRecoveryCause = 6;
-        int nativeDocumentStoreRecoveryLatencyMillis = 7;
-        int nativeIndexRestorationLatencyMillis = 8;
-        int nativeSchemaStoreRecoveryLatencyMillis = 9;
-        int nativeDocumentStoreDataStatus = 10;
-        int nativeNumDocuments = 11;
-        int nativeNumSchemaTypes = 12;
-
-        final InitializeStats.Builder iStatsBuilder =
-                new InitializeStats.Builder()
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setHasDeSync(/* hasDeSyncs= */ true)
-                        .setPrepareSchemaAndNamespacesLatencyMillis(
-                                prepareSchemaAndNamespacesLatencyMillis)
-                        .setPrepareVisibilityStoreLatencyMillis(prepareVisibilityFileLatencyMillis)
-                        .setNativeLatencyMillis(nativeLatencyMillis)
-                        .setDocumentStoreRecoveryCause(nativeDocumentStoreRecoveryCause)
-                        .setIndexRestorationCause(nativeIndexRestorationCause)
-                        .setSchemaStoreRecoveryCause(nativeSchemaStoreRecoveryCause)
-                        .setDocumentStoreRecoveryLatencyMillis(
-                                nativeDocumentStoreRecoveryLatencyMillis)
-                        .setIndexRestorationLatencyMillis(nativeIndexRestorationLatencyMillis)
-                        .setSchemaStoreRecoveryLatencyMillis(nativeSchemaStoreRecoveryLatencyMillis)
-                        .setDocumentStoreDataStatus(nativeDocumentStoreDataStatus)
-                        .setDocumentCount(nativeNumDocuments)
-                        .setSchemaTypeCount(nativeNumSchemaTypes)
-                        .setHasReset(true)
-                        .setResetStatusCode(AppSearchResult.RESULT_INVALID_SCHEMA);
-        final InitializeStats iStats = iStatsBuilder.build();
-
-        assertThat(iStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(iStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(iStats.hasDeSync()).isTrue();
-        assertThat(iStats.getPrepareSchemaAndNamespacesLatencyMillis())
-                .isEqualTo(prepareSchemaAndNamespacesLatencyMillis);
-        assertThat(iStats.getPrepareVisibilityStoreLatencyMillis())
-                .isEqualTo(prepareVisibilityFileLatencyMillis);
-        assertThat(iStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(iStats.getDocumentStoreRecoveryCause())
-                .isEqualTo(nativeDocumentStoreRecoveryCause);
-        assertThat(iStats.getIndexRestorationCause()).isEqualTo(nativeIndexRestorationCause);
-        assertThat(iStats.getSchemaStoreRecoveryCause()).isEqualTo(nativeSchemaStoreRecoveryCause);
-        assertThat(iStats.getDocumentStoreRecoveryLatencyMillis())
-                .isEqualTo(nativeDocumentStoreRecoveryLatencyMillis);
-        assertThat(iStats.getIndexRestorationLatencyMillis())
-                .isEqualTo(nativeIndexRestorationLatencyMillis);
-        assertThat(iStats.getSchemaStoreRecoveryLatencyMillis())
-                .isEqualTo(nativeSchemaStoreRecoveryLatencyMillis);
-        assertThat(iStats.getDocumentStoreDataStatus()).isEqualTo(nativeDocumentStoreDataStatus);
-        assertThat(iStats.getDocumentCount()).isEqualTo(nativeNumDocuments);
-        assertThat(iStats.getSchemaTypeCount()).isEqualTo(nativeNumSchemaTypes);
-        assertThat(iStats.hasReset()).isTrue();
-        assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_INVALID_SCHEMA);
-    }
-
-    @Test
-    public void testAppSearchStats_SearchStats() {
-        int rewriteSearchSpecLatencyMillis = 1;
-        int rewriteSearchResultLatencyMillis = 2;
-        int visibilityScope = SearchStats.VISIBILITY_SCOPE_LOCAL;
-        int nativeLatencyMillis = 4;
-        int nativeNumTerms = 5;
-        int nativeQueryLength = 6;
-        int nativeNumNamespacesFiltered = 7;
-        int nativeNumSchemaTypesFiltered = 8;
-        int nativeRequestedPageSize = 9;
-        int nativeNumResultsReturnedCurrentPage = 10;
-        boolean nativeIsFirstPage = true;
-        int nativeParseQueryLatencyMillis = 11;
-        int nativeRankingStrategy = 12;
-        int nativeNumDocumentsScored = 13;
-        int nativeScoringLatencyMillis = 14;
-        int nativeRankingLatencyMillis = 15;
-        int nativeNumResultsSnippeted = 16;
-        int nativeDocumentRetrievingLatencyMillis = 17;
-        final SearchStats.Builder sStatsBuilder =
-                new SearchStats.Builder(visibilityScope, TEST_PACKAGE_NAME)
-                        .setDatabase(TEST_DATA_BASE)
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setRewriteSearchSpecLatencyMillis(rewriteSearchSpecLatencyMillis)
-                        .setRewriteSearchResultLatencyMillis(rewriteSearchResultLatencyMillis)
-                        .setNativeLatencyMillis(nativeLatencyMillis)
-                        .setTermCount(nativeNumTerms)
-                        .setQueryLength(nativeQueryLength)
-                        .setFilteredNamespaceCount(nativeNumNamespacesFiltered)
-                        .setFilteredSchemaTypeCount(nativeNumSchemaTypesFiltered)
-                        .setRequestedPageSize(nativeRequestedPageSize)
-                        .setCurrentPageReturnedResultCount(nativeNumResultsReturnedCurrentPage)
-                        .setIsFirstPage(nativeIsFirstPage)
-                        .setParseQueryLatencyMillis(nativeParseQueryLatencyMillis)
-                        .setRankingStrategy(nativeRankingStrategy)
-                        .setScoredDocumentCount(nativeNumDocumentsScored)
-                        .setScoringLatencyMillis(nativeScoringLatencyMillis)
-                        .setRankingLatencyMillis(nativeRankingLatencyMillis)
-                        .setResultWithSnippetsCount(nativeNumResultsSnippeted)
-                        .setDocumentRetrievingLatencyMillis(nativeDocumentRetrievingLatencyMillis);
-        final SearchStats sStats = sStatsBuilder.build();
-
-        assertThat(sStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(sStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
-        assertThat(sStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(sStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(sStats.getRewriteSearchSpecLatencyMillis())
-                .isEqualTo(rewriteSearchSpecLatencyMillis);
-        assertThat(sStats.getRewriteSearchResultLatencyMillis())
-                .isEqualTo(rewriteSearchResultLatencyMillis);
-        assertThat(sStats.getVisibilityScope()).isEqualTo(visibilityScope);
-        assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(sStats.getTermCount()).isEqualTo(nativeNumTerms);
-        assertThat(sStats.getQueryLength()).isEqualTo(nativeQueryLength);
-        assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(nativeNumNamespacesFiltered);
-        assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(nativeNumSchemaTypesFiltered);
-        assertThat(sStats.getRequestedPageSize()).isEqualTo(nativeRequestedPageSize);
-        assertThat(sStats.getCurrentPageReturnedResultCount())
-                .isEqualTo(nativeNumResultsReturnedCurrentPage);
-        assertThat(sStats.isFirstPage()).isTrue();
-        assertThat(sStats.getParseQueryLatencyMillis()).isEqualTo(nativeParseQueryLatencyMillis);
-        assertThat(sStats.getRankingStrategy()).isEqualTo(nativeRankingStrategy);
-        assertThat(sStats.getScoredDocumentCount()).isEqualTo(nativeNumDocumentsScored);
-        assertThat(sStats.getScoringLatencyMillis()).isEqualTo(nativeScoringLatencyMillis);
-        assertThat(sStats.getRankingLatencyMillis()).isEqualTo(nativeRankingLatencyMillis);
-        assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(nativeNumResultsSnippeted);
-        assertThat(sStats.getDocumentRetrievingLatencyMillis())
-                .isEqualTo(nativeDocumentRetrievingLatencyMillis);
-    }
-
-    @Test
-    public void testAppSearchStats_SetSchemaStats() {
-        SchemaMigrationStats schemaMigrationStats =
-                new SchemaMigrationStats.Builder()
-                        .setGetSchemaLatencyMillis(1)
-                        .setQueryAndTransformLatencyMillis(2)
-                        .setFirstSetSchemaLatencyMillis(3)
-                        .setSecondSetSchemaLatencyMillis(4)
-                        .setSaveDocumentLatencyMillis(5)
-                        .setMigratedDocumentCount(6)
-                        .setSavedDocumentCount(7)
-                        .build();
-        int nativeLatencyMillis = 1;
-        int newTypeCount = 2;
-        int compatibleTypeChangeCount = 3;
-        int indexIncompatibleTypeChangeCount = 4;
-        int backwardsIncompatibleTypeChangeCount = 5;
-        SetSchemaStats sStats =
-                new SetSchemaStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setSchemaMigrationStats(schemaMigrationStats)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setNativeLatencyMillis(nativeLatencyMillis)
-                        .setNewTypeCount(newTypeCount)
-                        .setCompatibleTypeChangeCount(compatibleTypeChangeCount)
-                        .setIndexIncompatibleTypeChangeCount(indexIncompatibleTypeChangeCount)
-                        .setBackwardsIncompatibleTypeChangeCount(
-                                backwardsIncompatibleTypeChangeCount)
-                        .build();
-
-        assertThat(sStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(sStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
-        assertThat(sStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(sStats.getSchemaMigrationStats()).isEqualTo(schemaMigrationStats);
-        assertThat(sStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(sStats.getNewTypeCount()).isEqualTo(newTypeCount);
-        assertThat(sStats.getCompatibleTypeChangeCount()).isEqualTo(compatibleTypeChangeCount);
-        assertThat(sStats.getIndexIncompatibleTypeChangeCount())
-                .isEqualTo(indexIncompatibleTypeChangeCount);
-        assertThat(sStats.getBackwardsIncompatibleTypeChangeCount())
-                .isEqualTo(backwardsIncompatibleTypeChangeCount);
-    }
-
-    @Test
-    public void testAppSearchStats_SchemaMigrationStats() {
-        int getSchemaLatency = 1;
-        int queryAndTransformLatency = 2;
-        int firstSetSchemaLatency = 3;
-        int secondSetSchemaLatency = 4;
-        int saveDocumentLatency = 5;
-        int migratedDocumentCount = 6;
-        int savedDocumentCount = 7;
-        SchemaMigrationStats sStats =
-                new SchemaMigrationStats.Builder()
-                        .setGetSchemaLatencyMillis(getSchemaLatency)
-                        .setQueryAndTransformLatencyMillis(queryAndTransformLatency)
-                        .setFirstSetSchemaLatencyMillis(firstSetSchemaLatency)
-                        .setSecondSetSchemaLatencyMillis(secondSetSchemaLatency)
-                        .setSaveDocumentLatencyMillis(saveDocumentLatency)
-                        .setMigratedDocumentCount(migratedDocumentCount)
-                        .setSavedDocumentCount(savedDocumentCount)
-                        .build();
-
-        assertThat(sStats.getGetSchemaLatencyMillis()).isEqualTo(getSchemaLatency);
-        assertThat(sStats.getQueryAndTransformLatencyMillis()).isEqualTo(queryAndTransformLatency);
-        assertThat(sStats.getFirstSetSchemaLatencyMillis()).isEqualTo(firstSetSchemaLatency);
-        assertThat(sStats.getSecondSetSchemaLatencyMillis()).isEqualTo(secondSetSchemaLatency);
-        assertThat(sStats.getSaveDocumentLatencyMillis()).isEqualTo(saveDocumentLatency);
-        assertThat(sStats.getMigratedDocumentCount()).isEqualTo(migratedDocumentCount);
-        assertThat(sStats.getSavedDocumentCount()).isEqualTo(savedDocumentCount);
-    }
-
-    @Test
-    public void testAppSearchStats_RemoveStats() {
-        int nativeLatencyMillis = 1;
-        @RemoveStats.DeleteType int deleteType = 2;
-        int documentDeletedCount = 3;
-
-        final RemoveStats rStats =
-                new RemoveStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setNativeLatencyMillis(nativeLatencyMillis)
-                        .setDeleteType(deleteType)
-                        .setDeletedDocumentCount(documentDeletedCount)
-                        .build();
-
-        assertThat(rStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(rStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
-        assertThat(rStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(rStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(rStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(rStats.getDeleteType()).isEqualTo(deleteType);
-        assertThat(rStats.getDeletedDocumentCount()).isEqualTo(documentDeletedCount);
-    }
-
-    @Test
-    public void testAppSearchStats_OptimizeStats() {
-        int nativeLatencyMillis = 1;
-        int nativeDocumentStoreOptimizeLatencyMillis = 2;
-        int nativeIndexRestorationLatencyMillis = 3;
-        int nativeNumOriginalDocuments = 4;
-        int nativeNumDeletedDocuments = 5;
-        int nativeNumExpiredDocuments = 6;
-        long nativeStorageSizeBeforeBytes = Integer.MAX_VALUE + 1;
-        long nativeStorageSizeAfterBytes = Integer.MAX_VALUE + 2;
-        long nativeTimeSinceLastOptimizeMillis = Integer.MAX_VALUE + 3;
-
-        final OptimizeStats oStats =
-                new OptimizeStats.Builder()
-                        .setStatusCode(TEST_STATUS_CODE)
-                        .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
-                        .setNativeLatencyMillis(nativeLatencyMillis)
-                        .setDocumentStoreOptimizeLatencyMillis(
-                                nativeDocumentStoreOptimizeLatencyMillis)
-                        .setIndexRestorationLatencyMillis(nativeIndexRestorationLatencyMillis)
-                        .setOriginalDocumentCount(nativeNumOriginalDocuments)
-                        .setDeletedDocumentCount(nativeNumDeletedDocuments)
-                        .setExpiredDocumentCount(nativeNumExpiredDocuments)
-                        .setStorageSizeBeforeBytes(nativeStorageSizeBeforeBytes)
-                        .setStorageSizeAfterBytes(nativeStorageSizeAfterBytes)
-                        .setTimeSinceLastOptimizeMillis(nativeTimeSinceLastOptimizeMillis)
-                        .build();
-
-        assertThat(oStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
-        assertThat(oStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
-        assertThat(oStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(oStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
-        assertThat(oStats.getDocumentStoreOptimizeLatencyMillis())
-                .isEqualTo(nativeDocumentStoreOptimizeLatencyMillis);
-        assertThat(oStats.getIndexRestorationLatencyMillis())
-                .isEqualTo(nativeIndexRestorationLatencyMillis);
-        assertThat(oStats.getOriginalDocumentCount()).isEqualTo(nativeNumOriginalDocuments);
-        assertThat(oStats.getDeletedDocumentCount()).isEqualTo(nativeNumDeletedDocuments);
-        assertThat(oStats.getExpiredDocumentCount()).isEqualTo(nativeNumExpiredDocuments);
-        assertThat(oStats.getStorageSizeBeforeBytes()).isEqualTo(nativeStorageSizeBeforeBytes);
-        assertThat(oStats.getStorageSizeAfterBytes()).isEqualTo(nativeStorageSizeAfterBytes);
-        assertThat(oStats.getTimeSinceLastOptimizeMillis())
-                .isEqualTo(nativeTimeSinceLastOptimizeMillis);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
deleted file mode 100644
index ec96d6a..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.stats;
-
-import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.PackageManager;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.appsearch.AppSearchConfig;
-import com.android.server.appsearch.external.localstorage.stats.CallStats;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Map;
-
-/**
- * Tests covering the functionalities in {@link PlatformLogger} NOT requiring overriding any flags
- * in {@link android.provider.DeviceConfig}.
- *
- * <p>To add tests rely on overriding the flags, please add them in the
- * tests for {@link PlatformLogger} in mockingservicestests.
- */
-public class PlatformLoggerTest {
-    private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
-    private Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = ApplicationProvider.getApplicationContext();
-        mContext = new ContextWrapper(context) {
-            @Override
-            public PackageManager getPackageManager() {
-                return getMockPackageManager(mContext.getUser());
-            }
-        };
-    }
-
-    @Test
-    public void testCalculateHashCode_MD5_int32_shortString()
-            throws NoSuchAlgorithmException, UnsupportedEncodingException {
-        final String str1 = "d1";
-        final String str2 = "d2";
-
-        int hashCodeForStr1 = PlatformLogger.calculateHashCodeMd5(str1);
-
-        // hashing should be stable
-        assertThat(hashCodeForStr1).isEqualTo(
-                PlatformLogger.calculateHashCodeMd5(str1));
-        assertThat(hashCodeForStr1).isNotEqualTo(
-                PlatformLogger.calculateHashCodeMd5(str2));
-    }
-
-    @Test
-    public void testGetCalculateCode_MD5_int32_mediumString()
-            throws NoSuchAlgorithmException, UnsupportedEncodingException {
-        final String str1 = "Siblings";
-        final String str2 = "Teheran";
-
-        int hashCodeForStr1 = PlatformLogger.calculateHashCodeMd5(str1);
-
-        // hashing should be stable
-        assertThat(hashCodeForStr1).isEqualTo(
-                PlatformLogger.calculateHashCodeMd5(str1));
-        assertThat(hashCodeForStr1).isNotEqualTo(
-                PlatformLogger.calculateHashCodeMd5(str2));
-    }
-
-    @Test
-    public void testCalculateHashCode_MD5_int32_longString() throws NoSuchAlgorithmException,
-            UnsupportedEncodingException {
-        final String str1 = "abcdefghijkl-mnopqrstuvwxyz";
-        final String str2 = "abcdefghijkl-mnopqrstuvwxy123";
-
-        int hashCodeForStr1 = PlatformLogger.calculateHashCodeMd5(str1);
-
-        // hashing should be stable
-        assertThat(hashCodeForStr1).isEqualTo(
-                PlatformLogger.calculateHashCodeMd5(str1));
-        assertThat(hashCodeForStr1).isNotEqualTo(
-                PlatformLogger.calculateHashCodeMd5(str2));
-    }
-
-    @Test
-    public void testCalculateHashCode_MD5_int32_sameAsBigInteger_intValue() throws
-            NoSuchAlgorithmException, UnsupportedEncodingException {
-        final String emptyStr = "";
-        final String shortStr = "a";
-        final String mediumStr = "Teheran";
-        final String longStr = "abcd-efgh-ijkl-mnop-qrst-uvwx-yz";
-
-        int emptyHashCode = PlatformLogger.calculateHashCodeMd5(emptyStr);
-        int shortHashCode = PlatformLogger.calculateHashCodeMd5(shortStr);
-        int mediumHashCode = PlatformLogger.calculateHashCodeMd5(mediumStr);
-        int longHashCode = PlatformLogger.calculateHashCodeMd5(longStr);
-
-        assertThat(emptyHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(emptyStr));
-        assertThat(shortHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(shortStr));
-        assertThat(mediumHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(mediumStr));
-        assertThat(longHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(longStr));
-    }
-
-    @Test
-    public void testCalculateHashCode_MD5_strIsNull() throws
-            NoSuchAlgorithmException, UnsupportedEncodingException {
-        assertThat(PlatformLogger.calculateHashCodeMd5(/*str=*/ null)).isEqualTo(-1);
-    }
-
-    /** Makes sure the caching works while getting the UID for calling package. */
-    @Test
-    public void testGetPackageUidAsUser() throws Exception {
-        final String testPackageName = "packageName";
-        final int testUid = 1234;
-        PlatformLogger logger = new PlatformLogger(
-                mContext,
-                AppSearchConfig.create(DIRECT_EXECUTOR));
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid);
-
-        // First time, no cache
-        PlatformLogger.ExtraStats extraStats = logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT);
-        verify(mockPackageManager, times(1))
-                .getPackageUid(eq(testPackageName), /*flags=*/ anyInt());
-        assertThat(extraStats.mPackageUid).isEqualTo(testUid);
-
-        // Second time, we have cache
-        extraStats = logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT);
-
-        // Count is still one since we will use the cache
-        verify(mockPackageManager, times(1))
-                .getPackageUid(eq(testPackageName), /*flags=*/ anyInt());
-        assertThat(extraStats.mPackageUid).isEqualTo(testUid);
-
-        // Remove the cache and try again
-        assertThat(logger.removeCachedUidForPackage(testPackageName)).isEqualTo(testUid);
-        extraStats = logger.createExtraStatsLocked(testPackageName,
-                CallStats.CALL_TYPE_PUT_DOCUMENT);
-
-        // count increased by 1 since cache is cleared
-        verify(mockPackageManager, times(2))
-                .getPackageUid(eq(testPackageName), /*flags=*/ anyInt());
-        assertThat(extraStats.mPackageUid).isEqualTo(testUid);
-    }
-
-    private static int calculateHashCodeMd5withBigInteger(@NonNull String str)
-            throws NoSuchAlgorithmException {
-        MessageDigest md = MessageDigest.getInstance("MD5");
-        md.update(str.getBytes(StandardCharsets.UTF_8));
-        byte[] digest = md.digest();
-        return new BigInteger(digest).intValue();
-    }
-
-    @NonNull
-    private PackageManager getMockPackageManager(@NonNull UserHandle user) {
-        PackageManager pm = mMockPackageManagers.get(user);
-        if (pm == null) {
-            pm = Mockito.mock(PackageManager.class);
-            mMockPackageManagers.put(user, pm);
-        }
-        return pm;
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java
deleted file mode 100644
index 374642b..0000000
--- a/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.visibilitystore;
-
-import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.appsearch.PackageIdentifier;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.PackageManager;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.external.localstorage.OptimizeStrategy;
-import com.android.server.appsearch.external.localstorage.UnlimitedLimitConfig;
-import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
-import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.Mockito;
-
-import java.util.Collections;
-import java.util.Map;
-
-public class VisibilityStoreImplTest {
-    /**
-     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
-     */
-    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
-
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-    private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
-    private Context mContext;
-    private VisibilityStoreImpl mVisibilityStore;
-    private int mUid;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = ApplicationProvider.getApplicationContext();
-        mContext = new ContextWrapper(context) {
-            @Override
-            public Context createContextAsUser(UserHandle user, int flags) {
-                return new ContextWrapper(super.createContextAsUser(user, flags)) {
-                    @Override
-                    public PackageManager getPackageManager() {
-                        return getMockPackageManager(user);
-                    }
-                };
-            }
-
-            @Override
-            public PackageManager getPackageManager() {
-                return createContextAsUser(getUser(), /*flags=*/ 0).getPackageManager();
-            }
-        };
-
-        // Give ourselves global query permissions
-        AppSearchImpl appSearchImpl = AppSearchImpl.create(
-                mTemporaryFolder.newFolder(),
-                new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
-        mVisibilityStore = VisibilityStoreImpl.create(appSearchImpl, mContext);
-        mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
-    }
-
-    /**
-     * Make sure that we don't conflict with any special characters that AppSearchImpl has reserved.
-     */
-    @Test
-    public void testValidPackageName() {
-        assertThat(VisibilityStore.PACKAGE_NAME)
-                .doesNotContain(String.valueOf(PrefixUtil.PACKAGE_DELIMITER));
-        assertThat(VisibilityStore.PACKAGE_NAME)
-                .doesNotContain(String.valueOf(PrefixUtil.DATABASE_DELIMITER));
-    }
-
-    /**
-     * Make sure that we don't conflict with any special characters that AppSearchImpl has reserved.
-     */
-    @Test
-    public void testValidDatabaseName() {
-        assertThat(VisibilityStore.DATABASE_NAME)
-                .doesNotContain(String.valueOf(PrefixUtil.PACKAGE_DELIMITER));
-        assertThat(VisibilityStore.DATABASE_NAME)
-                .doesNotContain(String.valueOf(PrefixUtil.DATABASE_DELIMITER));
-    }
-
-    @Test
-    public void testDoesCallerHaveSystemAccess() {
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager
-                .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-        assertThat(mVisibilityStore.doesCallerHaveSystemAccess(mContext.getPackageName())).isTrue();
-
-        when(mockPackageManager
-                .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_DENIED);
-        assertThat(mVisibilityStore.doesCallerHaveSystemAccess(mContext.getPackageName()))
-                .isFalse();
-    }
-
-    @Test
-    public void testSetVisibility_displayedBySystem() throws Exception {
-        // Make sure we have global query privileges
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager
-                .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-        assertThat(mVisibilityStore.doesCallerHaveSystemAccess(mContext.getPackageName())).isTrue();
-
-        mVisibilityStore.setVisibility(
-                "package",
-                "database",
-                /*schemasNotDisplayedBySystem=*/ ImmutableSet.of(
-                        "prefix/schema1", "prefix/schema2"),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap());
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema1",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema2",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-
-        // New .setVisibility() call completely overrides previous visibility settings.
-        // So "schema2" isn't preserved.
-        mVisibilityStore.setVisibility(
-                "package",
-                "database",
-                /*schemasNotDisplayedBySystem=*/ ImmutableSet.of(
-                        "prefix/schema1", "prefix/schema3"),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap());
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema1",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema2",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema3",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isFalse();
-
-        // Everything defaults to visible again.
-        mVisibilityStore.setVisibility(
-                "package",
-                "database",
-                /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap());
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema1",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema2",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                "package",
-                                "database",
-                                "prefix/schema3",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-    }
-
-    @Test
-    public void testSetVisibility_visibleToPackages() throws Exception {
-        // Values for a "foo" client
-        String packageNameFoo = "packageFoo";
-        byte[] sha256CertFoo = new byte[] {10};
-        int uidFoo = 1;
-
-        // Values for a "bar" client
-        String packageNameBar = "packageBar";
-        byte[] sha256CertBar = new byte[] {100};
-        int uidBar = 2;
-
-        // Can't be the same value as uidFoo nor uidBar
-        int uidNotFooOrBar = 3;
-
-        // Make sure none of them have global query privileges
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager
-                .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo))
-                .thenReturn(PERMISSION_DENIED);
-        when(mockPackageManager
-                .checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameBar))
-                .thenReturn(PERMISSION_DENIED);
-
-        // By default, a schema isn't package accessible.
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaFoo",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaBar",
-                uidBar,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-
-        // Grant package access
-        mVisibilityStore.setVisibility(
-                "package",
-                "database",
-                /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "prefix/schemaFoo",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo)),
-                        "prefix/schemaBar",
-                        ImmutableList.of(new PackageIdentifier(packageNameBar, sha256CertBar))));
-
-        // Should fail if PackageManager doesn't see that it has the proper certificate
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(false);
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaFoo",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-
-        // Should fail if PackageManager doesn't think the package belongs to the uid
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidNotFooOrBar);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaFoo",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-
-        // But if uid and certificate match, then we should have access
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaFoo",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-
-        when(mockPackageManager.getPackageUid(eq(packageNameBar), /*flags=*/ anyInt()))
-                .thenReturn(uidBar);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameBar, sha256CertBar, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaBar",
-                uidBar,
-                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-
-        // New .setVisibility() call completely overrides previous visibility settings. So
-        // "schemaBar" settings aren't preserved.
-        mVisibilityStore.setVisibility(
-                "package",
-                "database",
-                /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "prefix/schemaFoo",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
-
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaFoo",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-
-        when(mockPackageManager.getPackageUid(eq(packageNameBar), /*flags=*/ anyInt()))
-                .thenReturn(uidBar);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameBar, sha256CertBar, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaBar",
-                uidBar,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-    }
-
-    @Test
-    public void testIsSchemaSearchableByCaller_packageAccessibilityHandlesNameNotFoundException()
-            throws Exception {
-        // Values for a "foo" client
-        String packageNameFoo = "packageFoo";
-        byte[] sha256CertFoo = new byte[] {10};
-        int uidFoo = 1;
-
-        // Pretend we can't find the Foo package.
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenThrow(new PackageManager.NameNotFoundException());
-
-        // Make sure "foo" doesn't have global query privileges
-        when(mockPackageManager.checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo))
-                .thenReturn(PERMISSION_DENIED);
-
-        // Grant package access
-        mVisibilityStore.setVisibility(
-                "package",
-                "database",
-                /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "prefix/schemaFoo",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
-
-        // If we can't verify the Foo package that has access, assume it doesn't have access.
-        assertThat(mVisibilityStore.isSchemaSearchableByCaller(
-                "package",
-                "database",
-                "prefix/schemaFoo",
-                uidFoo,
-                /*callerHasSystemAccess=*/ false))
-                .isFalse();
-    }
-
-    @Test
-    public void testEmptyPrefix() throws Exception {
-        // Values for a "foo" client
-        String packageNameFoo = "packageFoo";
-        byte[] sha256CertFoo = new byte[] {10};
-        int uidFoo = 1;
-
-        // Set it up such that the test package has global query privileges, but "foo" doesn't.
-        PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
-        when(mockPackageManager.checkPermission(
-                READ_GLOBAL_APP_SEARCH_DATA, mContext.getPackageName()))
-                .thenReturn(PERMISSION_GRANTED);
-        when(mockPackageManager.checkPermission(READ_GLOBAL_APP_SEARCH_DATA, packageNameFoo))
-                .thenReturn(PERMISSION_DENIED);
-
-        mVisibilityStore.setVisibility(
-                /*packageName=*/ "",
-                /*databaseName=*/ "",
-                /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
-                /*schemasVisibleToPackages=*/ ImmutableMap.of(
-                        "schema",
-                        ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
-
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                /*packageName=*/ "",
-                                /*databaseName=*/ "",
-                                "schema",
-                                mUid,
-                                /*callerHasSystemAccess=*/ true))
-                .isTrue();
-
-        when(mockPackageManager.getPackageUid(eq(packageNameFoo), /*flags=*/ anyInt()))
-                .thenReturn(uidFoo);
-        when(mockPackageManager.hasSigningCertificate(
-                packageNameFoo, sha256CertFoo, PackageManager.CERT_INPUT_SHA256))
-                .thenReturn(true);
-        assertThat(
-                        mVisibilityStore.isSchemaSearchableByCaller(
-                                /*packageName=*/ "",
-                                /*databaseName=*/ "",
-                                "schema",
-                                uidFoo,
-                                /*callerHasSystemAccess=*/ false))
-                .isTrue();
-    }
-
-    @NonNull
-    private PackageManager getMockPackageManager(@NonNull UserHandle user) {
-        PackageManager pm = mMockPackageManagers.get(user);
-        if (pm == null) {
-            pm = Mockito.mock(PackageManager.class);
-            mMockPackageManagers.put(user, pm);
-        }
-        return pm;
-    }
-}