OSDN Git Service

Report multiple FillContext-s onSave
authorPhilip P. Moltmann <moltmann@google.com>
Tue, 25 Apr 2017 18:57:37 +0000 (11:57 -0700)
committerPhilip P. Moltmann <moltmann@google.com>
Tue, 25 Apr 2017 22:22:08 +0000 (15:22 -0700)
To make life easier the reponseId is not part of the FillResponse.

Test: CtsAutofillServiceTestCases (added test for multiple Contexts)
Change-Id: If09e00b7267d293e4234a7a9837ad88d73af1b24
Fixes: 36481649

core/java/android/service/autofill/FillCallback.java
core/java/android/service/autofill/FillContext.java
core/java/android/service/autofill/FillRequest.java
core/java/android/service/autofill/FillResponse.java
core/java/android/service/autofill/IFillCallback.aidl
services/autofill/java/com/android/server/autofill/RemoteFillService.java
services/autofill/java/com/android/server/autofill/Session.java
services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java

index 7774bdd..105cd38 100644 (file)
@@ -47,8 +47,13 @@ public final class FillCallback {
     public void onSuccess(@Nullable FillResponse response) {
         assertNotCalled();
         mCalled = true;
+
+        if (response != null) {
+            response.setRequestId(mRequestId);
+        }
+
         try {
-            mCallback.onSuccess(response, mRequestId);
+            mCallback.onSuccess(response);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
index 2efa08c..8a28c45 100644 (file)
@@ -16,6 +16,8 @@
 
 package android.service.autofill;
 
+import static android.view.autofill.Helper.DEBUG;
+
 import android.annotation.NonNull;
 import android.app.assist.AssistStructure;
 import android.os.Bundle;
@@ -71,6 +73,15 @@ public final class FillContext implements Parcelable {
     }
 
     @Override
+    public String toString() {
+        if (!DEBUG) {
+            return super.toString();
+        } else {
+            return "FillContext [mRequestId=" + mRequestId + "]";
+        }
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
index 49f348c..5e43d36 100644 (file)
@@ -45,6 +45,9 @@ public final class FillRequest implements Parcelable {
     public static final int FLAG_MANUAL_REQUEST = 0x1;
 
     /** @hide */
+    public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE;
+
+    /** @hide */
     @IntDef(
         flag = true,
         value = {FLAG_MANUAL_REQUEST})
index 2afb1f4..5c8f3ce 100644 (file)
@@ -16,6 +16,7 @@
 
 package android.service.autofill;
 
+import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
 import static android.view.autofill.Helper.DEBUG;
 
 import android.annotation.NonNull;
@@ -138,6 +139,7 @@ public final class FillResponse implements Parcelable {
     private final @Nullable IntentSender mAuthentication;
     private final @Nullable AutofillId[] mAuthenticationIds;
     private final @Nullable AutofillId[] mIgnoredIds;
+    private int mRequestId;
 
     private FillResponse(@NonNull Builder builder) {
         mDatasets = builder.mDatasets;
@@ -147,6 +149,7 @@ public final class FillResponse implements Parcelable {
         mAuthentication = builder.mAuthentication;
         mAuthenticationIds = builder.mAuthenticationIds;
         mIgnoredIds = builder.mIgnoredIds;
+        mRequestId = INVALID_REQUEST_ID;
     }
 
     /** @hide */
@@ -185,6 +188,24 @@ public final class FillResponse implements Parcelable {
     }
 
     /**
+     * Associates a {@link FillResponse} to a request.
+     *
+     * <p>Set inside of the {@link FillCallback} code, not the {@link AutofillService}.
+     *
+     * @param requestId The id of the request to associate the response to.
+     *
+     * @hide
+     */
+    public void setRequestId(int requestId) {
+        mRequestId = requestId;
+    }
+
+    /** @hide */
+    public int getRequestId() {
+        return mRequestId;
+    }
+
+    /**
      * Builder for {@link FillResponse} objects. You must to provide at least
      * one dataset or set an authentication intent with a presentation view.
      */
@@ -376,7 +397,8 @@ public final class FillResponse implements Parcelable {
         if (!DEBUG) return super.toString();
 
         return new StringBuilder(
-                "FillResponse: [datasets=").append(mDatasets)
+                "FillResponse : [mRequestId=" + mRequestId)
+                .append(", datasets=").append(mDatasets)
                 .append(", saveInfo=").append(mSaveInfo)
                 .append(", clientState=").append(mClientState != null)
                 .append(", hasPresentation=").append(mPresentation != null)
@@ -385,6 +407,7 @@ public final class FillResponse implements Parcelable {
                         ? mAuthenticationIds.length : "N/A")
                 .append(", ignoredIdsSize=").append(mIgnoredIds != null
                     ? mIgnoredIds.length : "N/A")
+                .append("]")
                 .toString();
     }
 
@@ -406,6 +429,7 @@ public final class FillResponse implements Parcelable {
         parcel.writeParcelable(mAuthentication, flags);
         parcel.writeParcelable(mPresentation, flags);
         parcel.writeParcelableArray(mIgnoredIds, flags);
+        parcel.writeInt(mRequestId);
     }
 
     public static final Parcelable.Creator<FillResponse> CREATOR =
@@ -426,7 +450,11 @@ public final class FillResponse implements Parcelable {
             builder.setAuthentication(parcel.readParcelableArray(null, AutofillId.class),
                     parcel.readParcelable(null), parcel.readParcelable(null));
             builder.setIgnoredIds(parcel.readParcelableArray(null, AutofillId.class));
-            return builder.build();
+            final FillResponse response = builder.build();
+
+            response.setRequestId(parcel.readInt());
+
+            return response;
         }
 
         @Override
index 688ac84..2bb3e9a 100644 (file)
@@ -27,6 +27,6 @@ import android.service.autofill.FillResponse;
  */
 interface IFillCallback {
     void onCancellable(in ICancellationSignal cancellation);
-    void onSuccess(in FillResponse response, int requestId);
+    void onSuccess(in FillResponse response);
     void onFailure(CharSequence message);
 }
index 432a092..2aeb07e 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.server.autofill;
 
+import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
+
 import static com.android.server.autofill.Helper.DEBUG;
 
 import android.annotation.NonNull;
@@ -88,7 +90,7 @@ final class RemoteFillService implements DeathRecipient {
 
     public interface FillServiceCallbacks {
         void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
-                @NonNull String servicePackageName, int requestId);
+                @NonNull String servicePackageName);
         void onFillRequestFailure(@Nullable CharSequence message,
                 @NonNull String servicePackageName);
         void onSaveRequestSuccess(@NonNull String servicePackageName);
@@ -139,16 +141,26 @@ final class RemoteFillService implements DeathRecipient {
      *
      * <p>This can be used when the request is unnecessary or will be superceeded by a request that
      * will soon be queued.
+     *
+     * @return the id of the canceled request, or {@link FillRequest#INVALID_REQUEST_ID} if no
+     *         {@link PendingFillRequest} was canceled.
      */
-    public void cancelCurrentRequest() {
+    public int cancelCurrentRequest() {
         if (mDestroyed) {
-            return;
+            return INVALID_REQUEST_ID;
         }
 
+        int requestId = INVALID_REQUEST_ID;
         if (mPendingRequest != null) {
+            if (mPendingRequest instanceof PendingFillRequest) {
+                requestId = ((PendingFillRequest) mPendingRequest).mRequest.getId();
+            }
+
             mPendingRequest.cancel();
             mPendingRequest = null;
         }
+
+        return requestId;
     }
 
     public void onFillRequest(@NonNull FillRequest request) {
@@ -269,11 +281,11 @@ final class RemoteFillService implements DeathRecipient {
     }
 
     private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
-            int callingUid, FillResponse response, int requestId) {
+            int callingUid, FillResponse response) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
                 mCallbacks.onFillRequestSuccess(response, callingUid,
-                        mComponentName.getPackageName(), requestId);
+                        mComponentName.getPackageName());
             }
         });
     }
@@ -437,11 +449,11 @@ final class RemoteFillService implements DeathRecipient {
                 }
 
                 @Override
-                public void onSuccess(FillResponse response, int requestId) {
+                public void onSuccess(FillResponse response) {
                     RemoteFillService remoteService = mWeakService.get();
                     if (remoteService != null) {
                         remoteService.dispatchOnFillRequestSuccess(
-                                PendingFillRequest.this, getCallingUid(), response, requestId);
+                                PendingFillRequest.this, getCallingUid(), response);
                     }
                 }
 
index a00a397..5ef389f 100644 (file)
@@ -18,6 +18,7 @@
 package com.android.server.autofill;
 
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
+import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
 import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
 import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
 import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
@@ -152,11 +153,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     private Dataset mDatasetWaitingAuth;
 
     /**
-     * Assist structure sent by the app; it will be updated (sanitized, change values for save)
-     * before sent to {@link AutofillService}.
+     * Contexts read from the app; they will be updated (sanitized, change values for save) before
+     * sent to {@link AutofillService}. Ordered by the time they we read.
      */
     @GuardedBy("mLock")
-    private AssistStructure mStructure;
+    private ArrayList<FillContext> mContexts;
 
     /**
      * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}.
@@ -214,12 +215,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                 // Sanitize structure before it's sent to service.
                 structure.sanitizeForParceling(true);
 
-                mStructure = structure;
-            }
+                fillStructureWithAllowedValues(structure);
+
+                if (mContexts == null) {
+                    mContexts = new ArrayList<>(1);
+                }
+                mContexts.add(new FillContext(requestId, structure));
 
-            fillStructureWithAllowedValues(mStructure);
+                cancelCurrentRequestLocked();
+            }
 
-            FillRequest request = new FillRequest(requestId, mStructure, mClientState, mFlags);
+            FillRequest request = new FillRequest(requestId, structure, mClientState, mFlags);
             mRemoteFillService.onFillRequest(request);
         }
     };
@@ -259,10 +265,35 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     }
 
     /**
+     * Cancels the last request sent to the {@link #mRemoteFillService}.
+     */
+    private void cancelCurrentRequestLocked() {
+        int canceledRequest = mRemoteFillService.cancelCurrentRequest();
+
+        // Remove the FillContext as there will never be a response for the service
+        if (canceledRequest != INVALID_REQUEST_ID && mContexts != null) {
+            int numContexts = mContexts.size();
+
+            // It is most likely the last context, hence search backwards
+            for (int i = numContexts - 1; i >= 0; i--) {
+                if (mContexts.get(i).getRequestId() == canceledRequest) {
+                    mContexts.remove(i);
+                    break;
+                }
+            }
+        }
+
+    }
+
+    /**
      * Reads a new structure and then request a new fill response from the fill service.
      */
     private void requestNewFillResponseLocked() {
-        final int requestId = sIdCounter.getAndIncrement();
+        int requestId;
+
+        do {
+            requestId = sIdCounter.getAndIncrement();
+        } while (requestId == INVALID_REQUEST_ID);
 
         if (DEBUG) {
             Slog.d(TAG, "Requesting structure for requestId " + requestId);
@@ -273,7 +304,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         // enhanced as the focus change can be much faster than the taking of the assist structure.
         // Hence remove the currently queued request and replace it with the one queued after the
         // structure is taken. This causes only one fill request per bust of focus changes.
-        mRemoteFillService.cancelCurrentRequest();
+        cancelCurrentRequestLocked();
 
         try {
             final Bundle receiverExtras = new Bundle();
@@ -354,7 +385,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     // FillServiceCallbacks
     @Override
     public void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
-            @NonNull String servicePackageName, int requestId) {
+            @NonNull String servicePackageName) {
         if (response == null) {
             if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
                 getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
@@ -377,7 +408,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                 // TODO(b/37424539): proper implementation
                 mResponseWaitingAuth = response;
             }
-            processResponseLocked(response, requestId);
+            processResponseLocked(response);
         }
 
         final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
@@ -433,12 +464,37 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         removeSelf();
     }
 
+    /**
+     * Gets the {@link FillContext} for a request.
+     *
+     * @param requestId The id of the request
+     *
+     * @return The context or {@code null} if there is no context
+     */
+    @Nullable private FillContext getFillContextByRequestIdLocked(int requestId) {
+        if (mContexts == null) {
+            return null;
+        }
+
+        int numContexts = mContexts.size();
+        for (int i = 0; i < numContexts; i++) {
+            FillContext context = mContexts.get(i);
+
+            if (context.getRequestId() == requestId) {
+                return context;
+            }
+        }
+
+        return null;
+    }
+
     // FillServiceCallbacks
     @Override
-    public void authenticate(IntentSender intent, Bundle extras) {
+    public void authenticate(int requestId, IntentSender intent, Bundle extras) {
         final Intent fillInIntent;
         synchronized (mLock) {
-            fillInIntent = createAuthFillInIntent(mStructure, extras);
+            fillInIntent = createAuthFillInIntent(
+                    getFillContextByRequestIdLocked(requestId).getStructure(), extras);
         }
 
         mService.setAuthenticationSelected();
@@ -454,8 +510,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
 
     // AutoFillUiCallback
     @Override
-    public void fill(Dataset dataset) {
-        mHandlerCaller.getHandler().post(() -> autoFill(dataset));
+    public void fill(int requestId, Dataset dataset) {
+        mHandlerCaller.getHandler().post(() -> autoFill(requestId, dataset));
     }
 
     // AutoFillUiCallback
@@ -530,12 +586,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
             final Parcelable result = data.getParcelable(
                     AutofillManager.EXTRA_AUTHENTICATION_RESULT);
             if (result instanceof FillResponse) {
+                FillResponse response = (FillResponse) result;
+
                 mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
                 final int requestIndex = mResponses.indexOfValue(mResponseWaitingAuth);
                 mResponseWaitingAuth = null;
                 if (requestIndex >= 0) {
-                    final int requestId = mResponses.keyAt(requestIndex);
-                    processResponseLocked((FillResponse) result, requestId);
+                    response.setRequestId(mResponses.keyAt(requestIndex));
+                    processResponseLocked(response);
                 } else {
                     Slog.e(TAG, "Error cannot find id for auth response");
                 }
@@ -547,7 +605,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                     if (index >= 0) {
                         response.getDatasets().set(index, dataset);
                         mDatasetWaitingAuth = null;
-                        autoFill(dataset);
+                        autoFill(mResponses.keyAt(i), dataset);
                         resetViewStatesLocked(dataset, ViewState.STATE_WAITING_DATASET_AUTH);
                         return;
                     }
@@ -566,8 +624,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
      * @return {@code true} if session is done, or {@code false} if it's pending user action.
      */
     public boolean showSaveLocked() {
-        if (mStructure == null) {
-            Slog.d(TAG, "showSaveLocked(): no mStructure");
+        if (mContexts == null) {
+            Slog.d(TAG, "showSaveLocked(): no contexts");
             return true;
         }
         if (mResponses == null) {
@@ -589,7 +647,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         final FillResponse response = mResponses.valueAt(lastResponseIdx);
         final SaveInfo saveInfo = response.getSaveInfo();
         if (DEBUG) {
-            Slog.d(TAG, "showSaveLocked(): mResponses=" + mResponses
+            Slog.d(TAG, "showSaveLocked(): mResponses=" + mResponses + ", mContexts=" + mContexts
                     + ", mViewStates=" + mViewStates);
         }
 
@@ -689,43 +747,49 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
             Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
         }
 
-        for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
-            final AutofillValue value = entry.getValue().getCurrentValue();
-            if (value == null) {
-                if (VERBOSE) {
-                    Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
-                }
-                continue;
-            }
-            final AutofillId id = entry.getKey();
-            final ViewNode node = findViewNodeById(mStructure, id);
-            if (node == null) {
-                Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
-                continue;
-            }
+        int numContexts = mContexts.size();
+
+        for (int i = 0; i < numContexts; i++) {
+            FillContext context = mContexts.get(i);
+
             if (VERBOSE) {
-                Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
+                Slog.v(TAG, "callSaveLocked(): updating " + context);
             }
 
-            node.updateAutofillValue(value);
-        }
+            for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
+                final AutofillValue value = entry.getValue().getCurrentValue();
+                if (value == null) {
+                    if (VERBOSE) {
+                        Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
+                    }
+                    continue;
+                }
+                final AutofillId id = entry.getKey();
+                final ViewNode node = findViewNodeById(context.getStructure(), id);
+                if (node == null) {
+                    Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
+                    continue;
+                }
+                if (VERBOSE) {
+                    Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
+                }
+
+                node.updateAutofillValue(value);
+            }
 
-        // Sanitize structure before it's sent to service.
-        mStructure.sanitizeForParceling(false);
+            // Sanitize structure before it's sent to service.
+            context.getStructure().sanitizeForParceling(false);
 
-        if (VERBOSE) {
-            Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
-            mStructure.dump();
+            if (VERBOSE) {
+                Slog.v(TAG, "Dumping structure of " + context + " before calling service.save()");
+                context.getStructure().dump();
+            }
         }
 
-        // TODO(b/37426206): Implement partitioning properly
-        final int lastResponseIdx = getLastResponseIndex();
-        final int requestId = mResponses.keyAt(lastResponseIdx);
-        final FillContext fillContext = new FillContext(requestId, mStructure);
-        final ArrayList<FillContext> fillContexts = new ArrayList<>(1);
-        fillContexts.add(fillContext);
+        // Remove pending fill requests as the session is finished.
+        cancelCurrentRequestLocked();
 
-        final SaveRequest saveRequest = new SaveRequest(fillContexts, mClientState);
+        final SaveRequest saveRequest = new SaveRequest(mContexts, mClientState);
         mRemoteFillService.onSaveRequest(saveRequest);
     }
 
@@ -921,7 +985,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         }
     }
 
-    private void processResponseLocked(FillResponse response, int requestId) {
+    private void processResponseLocked(@NonNull FillResponse response) {
         if (DEBUG) {
             Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
         }
@@ -929,10 +993,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         if (mResponses == null) {
             mResponses = new SparseArray<>(4);
         }
-        mResponses.put(requestId, response);
-        if (response != null) {
-            mClientState = response.getClientState();
-        }
+        mResponses.put(response.getRequestId(), response);
+        mClientState = response.getClientState();
 
         setViewStatesLocked(response, ViewState.STATE_FILLABLE);
         updateTrackedIdsLocked();
@@ -944,7 +1006,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
                 && response.getDatasets().size() == 1) {
             Slog.d(TAG, "autofilling manual request directly");
-            autoFill(response.getDatasets().get(0));
+            autoFill(response.getRequestId(), response.getDatasets().get(0));
             return;
         }
 
@@ -1033,7 +1095,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
         }
     }
 
-    void autoFill(Dataset dataset) {
+    void autoFill(int requestId, Dataset dataset) {
         synchronized (mLock) {
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
@@ -1048,7 +1110,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
             mService.setDatasetAuthenticationSelected(dataset.getId());
             mDatasetWaitingAuth = dataset;
             setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
-            final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
+            final Intent fillInIntent = createAuthFillInIntent(
+                    getFillContextByRequestIdLocked(requestId).getStructure(), null);
             startAuthentication(dataset.getAuthentication(), fillInIntent);
         }
     }
@@ -1095,16 +1158,25 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
             pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
             entry.getValue().dump(prefix2, pw);
         }
-        if (VERBOSE) {
-            pw.print(prefix); pw.print("mStructure: " );
-            // TODO: add method on AssistStructure to dump on pw
-            if (mStructure != null) {
-                pw.println("look at logcat" );
-                mStructure.dump(); // dumps to logcat
-            } else {
-                pw.println("null");
+
+        pw.print(prefix); pw.print("mContexts: " );
+        if (mContexts != null) {
+            int numContexts = mContexts.size();
+            for (int i = 0; i < numContexts; i++) {
+                FillContext context = mContexts.get(i);
+
+                pw.print(prefix2); pw.print(context);
+                if (VERBOSE) {
+                    pw.println(context.getStructure() + " (look at logcat)");
+
+                    // TODO: add method on AssistStructure to dump on pw
+                    context.getStructure().dump();
+                }
             }
+        } else {
+            pw.println("null");
         }
+
         pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
         pw.print(prefix); pw.print("mClientState: "); pw.println(
                 Helper.bundleToString(mClientState));
index ab6a3a7..0556c67 100644 (file)
@@ -60,8 +60,8 @@ public final class AutoFillUI {
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public interface AutoFillUiCallback {
-        void authenticate(@NonNull IntentSender intent, @Nullable Bundle extras);
-        void fill(@NonNull Dataset dataset);
+        void authenticate(int requestId, @NonNull IntentSender intent, @Nullable Bundle extras);
+        void fill(int requestId, @NonNull Dataset dataset);
         void save();
         void cancelSave();
         void requestShowFillUi(AutofillId id, int width, int height,
@@ -161,8 +161,8 @@ public final class AutoFillUI {
                     log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
                     hideFillUiUiThread();
                     if (mCallback != null) {
-                        mCallback.authenticate(response.getAuthentication(),
-                                response.getClientState());
+                        mCallback.authenticate(response.getRequestId(),
+                                response.getAuthentication(), response.getClientState());
                     }
                 }
 
@@ -171,7 +171,7 @@ public final class AutoFillUI {
                     log.setType(MetricsProto.MetricsEvent.TYPE_ACTION);
                     hideFillUiUiThread();
                     if (mCallback != null) {
-                        mCallback.fill(dataset);
+                        mCallback.fill(response.getRequestId(), dataset);
                     }
                 }