SafeParcelable Requests in AppSearch - Remove APIs.

Bug: 275629842
Test: atest CtsAppSearchTestCases CtsAppSearchHostTestCases AppSearchServicesTests AppSearchCoreTests ContactsIndexerTests
Change-Id: I2d520c5d62b439afb44d88c0c184451c806f85a7
diff --git a/framework/java/android/app/appsearch/AppSearchSession.java b/framework/java/android/app/appsearch/AppSearchSession.java
index c3dffde..a6551b5 100644
--- a/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/framework/java/android/app/appsearch/AppSearchSession.java
@@ -32,6 +32,9 @@
 import android.app.appsearch.aidl.IAppSearchResultCallback;
 import android.app.appsearch.aidl.InitializeAidlRequest;
 import android.app.appsearch.aidl.PersistToDiskAidlRequest;
+import android.app.appsearch.aidl.RemoveByDocumentIdAidlRequest;
+import android.app.appsearch.aidl.RemoveByDocumentIdAidlRequestCreator;
+import android.app.appsearch.aidl.RemoveByQueryAidlRequest;
 import android.app.appsearch.aidl.SetSchemaAidlRequest;
 import android.app.appsearch.exceptions.AppSearchException;
 import android.app.appsearch.safeparcel.GenericDocumentParcel;
@@ -700,12 +703,13 @@
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
         try {
             mService.removeByDocumentId(
-                    mCallerAttributionSource,
-                    mDatabaseName,
-                    request.getNamespace(),
-                    new ArrayList<>(request.getIds()),
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
+                    new RemoveByDocumentIdAidlRequest(
+                            mCallerAttributionSource,
+                            mDatabaseName,
+                            request.getNamespace(),
+                            new ArrayList<>(request.getIds()),
+                            mUserHandle,
+                            /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()),
                     new IAppSearchBatchResultCallback.Stub() {
                         @Override
                         public void onResult(AppSearchBatchResultParcel resultParcel) {
@@ -765,12 +769,13 @@
         }
         try {
             mService.removeByQuery(
-                    mCallerAttributionSource,
-                    mDatabaseName,
-                    queryExpression,
-                    searchSpec,
-                    mUserHandle,
-                    /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
+                    new RemoveByQueryAidlRequest(
+                            mCallerAttributionSource,
+                            mDatabaseName,
+                            queryExpression,
+                            searchSpec,
+                            mUserHandle,
+                            /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()),
                     new IAppSearchResultCallback.Stub() {
                         @Override
                         public void onResult(AppSearchResultParcel resultParcel) {
diff --git a/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl b/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
index 5e14a69..4510411 100644
--- a/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
+++ b/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
@@ -29,6 +29,8 @@
 import android.app.appsearch.aidl.InitializeAidlRequest;
 import android.app.appsearch.aidl.PersistToDiskAidlRequest;
 import android.app.appsearch.aidl.RegisterObserverCallbackAidlRequest;
+import android.app.appsearch.aidl.RemoveByQueryAidlRequest;
+import android.app.appsearch.aidl.RemoveByDocumentIdAidlRequest;
 import android.app.appsearch.aidl.SetSchemaAidlRequest;
 import android.app.appsearch.aidl.UnregisterObserverCallbackAidlRequest;
 import android.app.appsearch.observer.ObserverSpec;
@@ -351,12 +353,8 @@
     /**
      * Removes documents by ID.
      *
-     * @param callerAttributionSource The permission identity 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 request {@link RemoveByDocumentIdAidlRequest} contains the input parameters for remove
+     *     by id operation.
      * @param callback
      *     If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
      *     will be called with the cause throwable. Otherwise,
@@ -366,33 +364,19 @@
      *     failure where the {@code throwable} is {@code null}.
      */
     void removeByDocumentId(
-        in AppSearchAttributionSource callerAttributionSource,
-        in String databaseName,
-        in String namespace,
-        in List<String> ids,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
+        in RemoveByDocumentIdAidlRequest request,
         in IAppSearchBatchResultCallback callback) = 14;
 
     /**
      * Removes documents by given query.
      *
-     * @param callerAttributionSource The permission identity of the package to query over.
-     * @param databaseName The databaseName this query for.
-     * @param queryExpression String to search for
-     * @param searchSpec SearchSpec
-     * @param userHandle Handle of the calling user
-     * @param binderCallStartTimeMillis start timestamp of binder call in Millis
+     * @param request {@link RemoveByQueryAidlRequest} contains the input parameters for remove by
+     *     query operation.
      * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
      *     {@link AppSearchResult}&lt;{@link Void}&gt;.
      */
     void removeByQuery(
-        in AppSearchAttributionSource callerAttributionSource,
-        in String databaseName,
-        in String queryExpression,
-        in SearchSpec searchSpec,
-        in UserHandle userHandle,
-        in long binderCallStartTimeMillis,
+        in RemoveByQueryAidlRequest request,
         in IAppSearchResultCallback callback) = 15;
 
     /**
diff --git a/framework/java/android/app/appsearch/aidl/RemoveByDocumentIdAidlRequest.aidl b/framework/java/android/app/appsearch/aidl/RemoveByDocumentIdAidlRequest.aidl
new file mode 100644
index 0000000..cbe73d8
--- /dev/null
+++ b/framework/java/android/app/appsearch/aidl/RemoveByDocumentIdAidlRequest.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2024, 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 RemoveByDocumentIdAidlRequest;
\ No newline at end of file
diff --git a/framework/java/android/app/appsearch/aidl/RemoveByDocumentIdAidlRequest.java b/framework/java/android/app/appsearch/aidl/RemoveByDocumentIdAidlRequest.java
new file mode 100644
index 0000000..d885628
--- /dev/null
+++ b/framework/java/android/app/appsearch/aidl/RemoveByDocumentIdAidlRequest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024 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.ElapsedRealtimeLong;
+import android.annotation.NonNull;
+import android.app.appsearch.safeparcel.AbstractSafeParcelable;
+import android.app.appsearch.safeparcel.SafeParcelable;
+import android.os.Parcel;
+import android.os.UserHandle;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Encapsulates a request to make a binder call to remove documents by id.
+ * @hide
+ */
+@SafeParcelable.Class(creator = "RemoveByDocumentIdAidlRequestCreator")
+public class RemoveByDocumentIdAidlRequest extends AbstractSafeParcelable {
+    @NonNull
+    public static final RemoveByDocumentIdAidlRequestCreator CREATOR =
+            new RemoveByDocumentIdAidlRequestCreator();
+
+    @NonNull
+    @Field(id = 1, getter = "getCallerAttributionSource")
+    private final AppSearchAttributionSource mCallerAttributionSource;
+    @NonNull
+    @Field(id = 2, getter = "getDatabaseName")
+    private final String mDatabaseName;
+    @NonNull
+    @Field(id = 3, getter = "getNamespace")
+    private final String mNamespace;
+    @NonNull
+    @Field(id = 4, getter = "getIds")
+    private final List<String> mIds;
+    @NonNull
+    @Field(id = 5, getter = "getUserHandle")
+    private final UserHandle mUserHandle;
+    @Field(id = 6, getter = "getBinderCallStartTimeMillis")
+    private final @ElapsedRealtimeLong long mBinderCallStartTimeMillis;
+
+    @Constructor
+    public RemoveByDocumentIdAidlRequest(
+            @Param(id = 1) @NonNull AppSearchAttributionSource callerAttributionSource,
+            @Param(id = 2) @NonNull String databaseName,
+            @Param(id = 3) @NonNull String namespace,
+            @Param(id = 4) @NonNull List<String> ids,
+            @Param(id = 5) @NonNull UserHandle userHandle,
+            @Param(id = 6) @ElapsedRealtimeLong long binderCallStartTimeMillis) {
+        mCallerAttributionSource = Objects.requireNonNull(callerAttributionSource);
+        mDatabaseName = Objects.requireNonNull(databaseName);
+        mNamespace = Objects.requireNonNull(namespace);
+        mIds = Objects.requireNonNull(ids);
+        mUserHandle = Objects.requireNonNull(userHandle);
+        mBinderCallStartTimeMillis = binderCallStartTimeMillis;
+    }
+
+    @NonNull
+    public AppSearchAttributionSource getCallerAttributionSource() {
+        return mCallerAttributionSource;
+    }
+
+    @NonNull
+    public String getDatabaseName() {
+        return mDatabaseName;
+    }
+
+    @NonNull
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    @NonNull
+    public List<String> getIds() {
+        return mIds;
+    }
+
+    @NonNull
+    public UserHandle getUserHandle() {
+        return mUserHandle;
+    }
+
+    @ElapsedRealtimeLong
+    public long getBinderCallStartTimeMillis() {
+        return mBinderCallStartTimeMillis;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        RemoveByDocumentIdAidlRequestCreator.writeToParcel(this, dest, flags);
+    }
+}
diff --git a/framework/java/android/app/appsearch/aidl/RemoveByQueryAidlRequest.aidl b/framework/java/android/app/appsearch/aidl/RemoveByQueryAidlRequest.aidl
new file mode 100644
index 0000000..7508206
--- /dev/null
+++ b/framework/java/android/app/appsearch/aidl/RemoveByQueryAidlRequest.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2024, 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 RemoveByQueryAidlRequest;
\ No newline at end of file
diff --git a/framework/java/android/app/appsearch/aidl/RemoveByQueryAidlRequest.java b/framework/java/android/app/appsearch/aidl/RemoveByQueryAidlRequest.java
new file mode 100644
index 0000000..69aa04c
--- /dev/null
+++ b/framework/java/android/app/appsearch/aidl/RemoveByQueryAidlRequest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2024 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.ElapsedRealtimeLong;
+import android.annotation.NonNull;
+import android.app.appsearch.SearchSpec;
+import android.app.appsearch.safeparcel.AbstractSafeParcelable;
+import android.app.appsearch.safeparcel.SafeParcelable;
+import android.os.Parcel;
+import android.os.UserHandle;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Encapsulates a request to make a binder call to remove documents by query.
+ * @hide
+ */
+@SafeParcelable.Class(creator = "RemoveByQueryAidlRequestCreator")
+public class RemoveByQueryAidlRequest extends AbstractSafeParcelable {
+    @NonNull
+    public static final RemoveByQueryAidlRequestCreator CREATOR =
+            new RemoveByQueryAidlRequestCreator();
+
+    @NonNull
+    @Field(id = 1, getter = "getCallerAttributionSource")
+    private final AppSearchAttributionSource mCallerAttributionSource;
+    @NonNull
+    @Field(id = 2, getter = "getDatabaseName")
+    private final String mDatabaseName;
+    @NonNull
+    @Field(id = 3, getter = "getQueryExpression")
+    private final String mQueryExpression;
+    @NonNull
+    @Field(id = 4, getter = "getSearchSpec")
+    private final SearchSpec mSearchSpec;
+    @NonNull
+    @Field(id = 5, getter = "getUserHandle")
+    private final UserHandle mUserHandle;
+    @Field(id = 6, getter = "getBinderCallStartTimeMillis")
+    private final @ElapsedRealtimeLong long mBinderCallStartTimeMillis;
+
+    @Constructor
+    public RemoveByQueryAidlRequest(
+            @Param(id = 1) @NonNull AppSearchAttributionSource callerAttributionSource,
+            @Param(id = 2) @NonNull String databaseName,
+            @Param(id = 3) @NonNull String queryExpression,
+            @Param(id = 4) @NonNull SearchSpec searchSpec,
+            @Param(id = 5) @NonNull UserHandle userHandle,
+            @Param(id = 6) @ElapsedRealtimeLong long binderCallStartTimeMillis) {
+        mCallerAttributionSource = Objects.requireNonNull(callerAttributionSource);
+        mDatabaseName = Objects.requireNonNull(databaseName);
+        mQueryExpression = Objects.requireNonNull(queryExpression);
+        mSearchSpec = Objects.requireNonNull(searchSpec);
+        mUserHandle = Objects.requireNonNull(userHandle);
+        mBinderCallStartTimeMillis = binderCallStartTimeMillis;
+    }
+
+    @NonNull
+    public AppSearchAttributionSource getCallerAttributionSource() {
+        return mCallerAttributionSource;
+    }
+
+    @NonNull
+    public String getDatabaseName() {
+        return mDatabaseName;
+    }
+
+    @NonNull
+    public String getQueryExpression() {
+        return mQueryExpression;
+    }
+
+    @NonNull
+    public SearchSpec getSearchSpec() {
+        return mSearchSpec;
+    }
+
+    @NonNull
+    public UserHandle getUserHandle() {
+        return mUserHandle;
+    }
+
+    @ElapsedRealtimeLong
+    public long getBinderCallStartTimeMillis() {
+        return mBinderCallStartTimeMillis;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        RemoveByQueryAidlRequestCreator.writeToParcel(this, dest, flags);
+    }
+}
diff --git a/service/java/com/android/server/appsearch/AppSearchManagerService.java b/service/java/com/android/server/appsearch/AppSearchManagerService.java
index e70653f..8d7fce5 100644
--- a/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -59,6 +59,8 @@
 import android.app.appsearch.aidl.InitializeAidlRequest;
 import android.app.appsearch.aidl.PersistToDiskAidlRequest;
 import android.app.appsearch.aidl.RegisterObserverCallbackAidlRequest;
+import android.app.appsearch.aidl.RemoveByDocumentIdAidlRequest;
+import android.app.appsearch.aidl.RemoveByQueryAidlRequest;
 import android.app.appsearch.aidl.SetSchemaAidlRequest;
 import android.app.appsearch.aidl.UnregisterObserverCallbackAidlRequest;
 import android.app.appsearch.exceptions.AppSearchException;
@@ -1724,32 +1726,23 @@
 
         @Override
         public void removeByDocumentId(
-                @NonNull AppSearchAttributionSource callerAttributionSource,
-                @NonNull String databaseName,
-                @NonNull String namespace,
-                @NonNull List<String> ids,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
+                @NonNull RemoveByDocumentIdAidlRequest request,
                 @NonNull IAppSearchBatchResultCallback callback) {
-            Objects.requireNonNull(callerAttributionSource);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(namespace);
-            Objects.requireNonNull(ids);
-            Objects.requireNonNull(userHandle);
+            Objects.requireNonNull(request);
             Objects.requireNonNull(callback);
 
             long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
             UserHandle targetUser = mServiceImplHelper.verifyIncomingCallWithCallback(
-                    callerAttributionSource, userHandle, callback);
+                    request.getCallerAttributionSource(), request.getUserHandle(), callback);
             String callingPackageName =
-                    Objects.requireNonNull(callerAttributionSource.getPackageName());
+                    Objects.requireNonNull(request.getCallerAttributionSource().getPackageName());
             if (targetUser == null) {
                 return;  // Verification failed; verifyIncomingCall triggered callback.
             }
-            if (checkCallDenied(callingPackageName, databaseName,
+            if (checkCallDenied(callingPackageName, request.getDatabaseName(),
                     CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID, callback, targetUser,
-                    binderCallStartTimeMillis, totalLatencyStartTimeMillis,
-                    /* numOperations= */ ids.size())) {
+                    request.getBinderCallStartTimeMillis(), totalLatencyStartTimeMillis,
+                    /* numOperations= */ request.getIds().size())) {
                 return;
             }
             boolean callAccepted = mServiceImplHelper.executeLambdaForUserAsync(targetUser,
@@ -1763,13 +1756,13 @@
                     AppSearchBatchResult.Builder<String, Void> resultBuilder =
                             new AppSearchBatchResult.Builder<>();
                     instance = mAppSearchUserInstanceManager.getUserInstance(targetUser);
-                    for (int i = 0; i < ids.size(); i++) {
-                        String id = ids.get(i);
+                    for (int i = 0; i < request.getIds().size(); i++) {
+                        String id = request.getIds().get(i);
                         try {
                             instance.getAppSearchImpl().remove(
                                     callingPackageName,
-                                    databaseName,
-                                    namespace,
+                                    request.getDatabaseName(),
+                                    request.getNamespace(),
                                     id,
                                     /* removeStatsBuilder= */ null);
                             ++operationSuccessCount;
@@ -1793,7 +1786,7 @@
                     // the method is called documented in the method description.
                     dispatchChangeNotifications(instance);
 
-                    checkForOptimize(targetUser, instance, ids.size());
+                    checkForOptimize(targetUser, instance, request.getIds().size());
                 } catch (AppSearchException | RuntimeException e) {
                     ++operationFailureCount;
                     AppSearchResult<Void> failedResult = throwableToFailedResult(e);
@@ -1803,12 +1796,13 @@
                     // TODO(b/261959320) add outstanding latency fields in AppSearch stats
                     if (instance != null) {
                         int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
+                                2 * (int) (totalLatencyStartTimeMillis
+                                        - request.getBinderCallStartTimeMillis());
                         int totalLatencyMillis =
                                 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
                         instance.getLogger().logStats(new CallStats.Builder()
                                 .setPackageName(callingPackageName)
-                                .setDatabase(databaseName)
+                                .setDatabase(request.getDatabaseName())
                                 .setStatusCode(statusCode)
                                 .setTotalLatencyMillis(totalLatencyMillis)
                                 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
@@ -1823,40 +1817,31 @@
                 }
             });
             if (!callAccepted) {
-                logRateLimitedOrCallDeniedCallStats(callingPackageName, databaseName,
+                logRateLimitedOrCallDeniedCallStats(callingPackageName, request.getDatabaseName(),
                         CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID, targetUser,
-                        binderCallStartTimeMillis, totalLatencyStartTimeMillis,
-                        /* numOperations= */ ids.size(), RESULT_RATE_LIMITED);
+                        request.getBinderCallStartTimeMillis(), totalLatencyStartTimeMillis,
+                        /* numOperations= */ request.getIds().size(), RESULT_RATE_LIMITED);
             }
         }
 
         @Override
         public void removeByQuery(
-                @NonNull AppSearchAttributionSource callerAttributionSource,
-                @NonNull String databaseName,
-                @NonNull String queryExpression,
-                @NonNull SearchSpec searchSpec,
-                @NonNull UserHandle userHandle,
-                @ElapsedRealtimeLong long binderCallStartTimeMillis,
+                @NonNull RemoveByQueryAidlRequest request,
                 @NonNull IAppSearchResultCallback callback) {
-            Objects.requireNonNull(callerAttributionSource);
-            Objects.requireNonNull(databaseName);
-            Objects.requireNonNull(queryExpression);
-            Objects.requireNonNull(searchSpec);
-            Objects.requireNonNull(userHandle);
+            Objects.requireNonNull(request);
             Objects.requireNonNull(callback);
 
             long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
             UserHandle targetUser = mServiceImplHelper.verifyIncomingCallWithCallback(
-                    callerAttributionSource, userHandle, callback);
+                    request.getCallerAttributionSource(), request.getUserHandle(), callback);
             String callingPackageName =
-                    Objects.requireNonNull(callerAttributionSource.getPackageName());
+                    Objects.requireNonNull(request.getCallerAttributionSource().getPackageName());
             if (targetUser == null) {
                 return;  // Verification failed; verifyIncomingCall triggered callback.
             }
-            if (checkCallDenied(callingPackageName, databaseName,
+            if (checkCallDenied(callingPackageName, request.getDatabaseName(),
                     CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH, callback, targetUser,
-                    binderCallStartTimeMillis, totalLatencyStartTimeMillis,
+                    request.getBinderCallStartTimeMillis(), totalLatencyStartTimeMillis,
                     /* numOperations= */ 1)) {
                 return;
             }
@@ -1871,9 +1856,9 @@
                     instance = mAppSearchUserInstanceManager.getUserInstance(targetUser);
                     instance.getAppSearchImpl().removeByQuery(
                             callingPackageName,
-                            databaseName,
-                            queryExpression,
-                            searchSpec,
+                            request.getDatabaseName(),
+                            request.getQueryExpression(),
+                            request.getSearchSpec(),
                             /* removeStatsBuilder= */ null);
                     // Now that the batch has been written. Persist the newly written data.
                     instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
@@ -1894,12 +1879,13 @@
                     // TODO(b/261959320) add outstanding latency fields in AppSearch stats
                     if (instance != null) {
                         int estimatedBinderLatencyMillis =
-                                2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
+                                2 * (int) (totalLatencyStartTimeMillis
+                                        - request.getBinderCallStartTimeMillis());
                         int totalLatencyMillis =
                                 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
                         instance.getLogger().logStats(new CallStats.Builder()
                                 .setPackageName(callingPackageName)
-                                .setDatabase(databaseName)
+                                .setDatabase(request.getDatabaseName())
                                 .setStatusCode(statusCode)
                                 .setTotalLatencyMillis(totalLatencyMillis)
                                 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
@@ -1914,9 +1900,9 @@
                 }
             });
             if (!callAccepted) {
-                logRateLimitedOrCallDeniedCallStats(callingPackageName, databaseName,
+                logRateLimitedOrCallDeniedCallStats(callingPackageName, request.getDatabaseName(),
                         CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH, targetUser,
-                        binderCallStartTimeMillis, totalLatencyStartTimeMillis,
+                        request.getBinderCallStartTimeMillis(), totalLatencyStartTimeMillis,
                         /* numOperations= */ 1, RESULT_RATE_LIMITED);
             }
         }
diff --git a/testing/mockingservicestests/src/com/android/server/appsearch/AppSearchManagerServiceTest.java b/testing/mockingservicestests/src/com/android/server/appsearch/AppSearchManagerServiceTest.java
index 63fd986..314da25 100644
--- a/testing/mockingservicestests/src/com/android/server/appsearch/AppSearchManagerServiceTest.java
+++ b/testing/mockingservicestests/src/com/android/server/appsearch/AppSearchManagerServiceTest.java
@@ -68,6 +68,8 @@
 import android.app.appsearch.aidl.InitializeAidlRequest;
 import android.app.appsearch.aidl.PersistToDiskAidlRequest;
 import android.app.appsearch.aidl.RegisterObserverCallbackAidlRequest;
+import android.app.appsearch.aidl.RemoveByDocumentIdAidlRequest;
+import android.app.appsearch.aidl.RemoveByQueryAidlRequest;
 import android.app.appsearch.aidl.SetSchemaAidlRequest;
 import android.app.appsearch.aidl.UnregisterObserverCallbackAidlRequest;
 import android.app.appsearch.observer.ObserverSpec;
@@ -527,9 +529,11 @@
     public void testRemoveByDocumentIdStatsLogging() throws Exception {
         TestBatchResultErrorCallback callback = new TestBatchResultErrorCallback();
         mAppSearchManagerServiceStub.removeByDocumentId(
-                AppSearchAttributionSource.createAttributionSource(mContext),
-                DATABASE_NAME, NAMESPACE, /* ids= */ Collections.emptyList(), mUserHandle,
-                BINDER_CALL_START_TIME, callback);
+                new RemoveByDocumentIdAidlRequest(
+                        AppSearchAttributionSource.createAttributionSource(mContext),
+                        DATABASE_NAME, NAMESPACE, /* ids= */ Collections.emptyList(), mUserHandle,
+                        BINDER_CALL_START_TIME),
+                callback);
         assertThat(callback.get()).isNull(); // null means there wasn't an error
         verifyCallStats(mContext.getPackageName(), DATABASE_NAME,
                 CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID);
@@ -539,9 +543,11 @@
     public void testRemoveByQueryStatsLogging() throws Exception {
         TestResultCallback callback = new TestResultCallback();
         mAppSearchManagerServiceStub.removeByQuery(
-                AppSearchAttributionSource.createAttributionSource(mContext), DATABASE_NAME,
-                /* queryExpression= */ "", EMPTY_SEARCH_SPEC, mUserHandle,
-                BINDER_CALL_START_TIME, callback);
+                new RemoveByQueryAidlRequest(
+                        AppSearchAttributionSource.createAttributionSource(mContext), DATABASE_NAME,
+                        /* queryExpression= */ "", EMPTY_SEARCH_SPEC, mUserHandle,
+                        BINDER_CALL_START_TIME),
+                callback);
         assertThat(callback.get().getResultCode()).isEqualTo(AppSearchResult.RESULT_OK);
         verifyCallStats(mContext.getPackageName(), DATABASE_NAME,
                 CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH);
@@ -1408,17 +1414,21 @@
     private void verifyRemoveByDocumentIdResult(int resultCode) throws Exception {
         TestBatchResultErrorCallback callback = new TestBatchResultErrorCallback();
         mAppSearchManagerServiceStub.removeByDocumentId(
-                AppSearchAttributionSource.createAttributionSource(mContext),
-                DATABASE_NAME, NAMESPACE, /* ids= */ Collections.emptyList(), mUserHandle,
-                BINDER_CALL_START_TIME, callback);
+                new RemoveByDocumentIdAidlRequest(
+                        AppSearchAttributionSource.createAttributionSource(mContext),
+                        DATABASE_NAME, NAMESPACE, /* ids= */ Collections.emptyList(), mUserHandle,
+                        BINDER_CALL_START_TIME),
+                callback);
         verifyCallResult(resultCode, CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID, callback.get());
     }
 
     private void verifyRemoveByQueryResult(int resultCode) throws Exception {
         TestResultCallback callback = new TestResultCallback();
         mAppSearchManagerServiceStub.removeByQuery(
-                AppSearchAttributionSource.createAttributionSource(mContext), DATABASE_NAME,
-                /* queryExpression= */ "", EMPTY_SEARCH_SPEC, mUserHandle, BINDER_CALL_START_TIME,
+                new RemoveByQueryAidlRequest(
+                        AppSearchAttributionSource.createAttributionSource(mContext), DATABASE_NAME,
+                        /* queryExpression= */ "", EMPTY_SEARCH_SPEC, mUserHandle,
+                        BINDER_CALL_START_TIME),
                 callback);
         verifyCallResult(resultCode, CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH,
                 callback.get());