diff --git a/core/api/current.txt b/core/api/current.txt index bd0db889801c0..5bca9c5867d0f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -50924,6 +50924,7 @@ package android.view.autofill { field public static final String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT"; field public static final String EXTRA_AUTHENTICATION_RESULT_EPHEMERAL_DATASET = "android.view.autofill.extra.AUTHENTICATION_RESULT_EPHEMERAL_DATASET"; field public static final String EXTRA_CLIENT_STATE = "android.view.autofill.extra.CLIENT_STATE"; + field public static final String EXTRA_INLINE_SUGGESTIONS_REQUEST = "android.view.autofill.extra.INLINE_SUGGESTIONS_REQUEST"; } public abstract static class AutofillManager.AutofillCallback { diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 4f0c568989de3..208cd967dc997 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -249,6 +249,18 @@ public final class AutofillManager { public static final String EXTRA_CLIENT_STATE = "android.view.autofill.extra.CLIENT_STATE"; + /** + * Intent extra: the {@link android.view.inputmethod.InlineSuggestionsRequest} in the + * autofill request. + * + *

This is filled in the authentication intent so the + * {@link android.service.autofill.AutofillService} can use it to create the inline + * suggestion {@link android.service.autofill.Dataset} in the response, if the original autofill + * request contains the {@link android.view.inputmethod.InlineSuggestionsRequest}. + */ + public static final String EXTRA_INLINE_SUGGESTIONS_REQUEST = + "android.view.autofill.extra.INLINE_SUGGESTIONS_REQUEST"; + /** @hide */ public static final String EXTRA_RESTORE_SESSION_TOKEN = "android.view.autofill.extra.RESTORE_SESSION_TOKEN"; diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 6d72ca7bae259..2aa5d263e7714 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -91,6 +91,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.LocalLog; import android.util.Log; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.TimeUtils; @@ -221,6 +222,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private final ArrayMap mViewStates = new ArrayMap<>(); + /** + * Tracks the most recent IME inline request and the corresponding request id, for regular + * autofill. + */ + @GuardedBy("mLock") + @Nullable private Pair mLastInlineSuggestionsRequest; + /** * Id of the View currently being displayed. */ @@ -330,7 +338,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private ArrayList mAugmentedAutofillableIds; - @Nullable + @NonNull private final AutofillInlineSessionController mInlineSessionController; /** @@ -821,11 +829,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState /* isInlineRequest= */ true); if (inlineSuggestionsRequestConsumer != null) { final AutofillId focusedId = mCurrentViewId; + final int requestIdCopy = requestId; remoteRenderService.getInlineSuggestionsRendererInfo( new RemoteCallback((extras) -> { synchronized (mLock) { mInlineSessionController.onCreateInlineSuggestionsRequestLocked( - focusedId, inlineSuggestionsRequestConsumer, extras); + focusedId, inlineSuggestionsRequestCacheDecorator( + inlineSuggestionsRequestConsumer, requestIdCopy), + extras); } }, mHandler) ); @@ -3668,11 +3679,27 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState requestId, mContexts); return null; } + if (mLastInlineSuggestionsRequest != null + && mLastInlineSuggestionsRequest.first == requestId) { + fillInIntent.putExtra(AutofillManager.EXTRA_INLINE_SUGGESTIONS_REQUEST, + mLastInlineSuggestionsRequest.second); + } fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, context.getStructure()); fillInIntent.putExtra(AutofillManager.EXTRA_CLIENT_STATE, extras); return fillInIntent; } + @NonNull + private Consumer inlineSuggestionsRequestCacheDecorator( + @NonNull Consumer consumer, int requestId) { + return inlineSuggestionsRequest -> { + consumer.accept(inlineSuggestionsRequest); + synchronized (mLock) { + mLastInlineSuggestionsRequest = Pair.create(requestId, inlineSuggestionsRequest); + } + }; + } + private void startAuthentication(int authenticationId, IntentSender intent, Intent fillInIntent, boolean authenticateInline) { try {