summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/inputmethodservice/InlineSuggestionSession.java5
-rw-r--r--core/java/android/service/autofill/augmented/AugmentedAutofillService.java9
-rw-r--r--core/java/android/service/autofill/augmented/FillCallback.java4
-rw-r--r--core/java/android/service/autofill/augmented/IFillCallback.aidl6
-rw-r--r--core/java/com/android/internal/view/IInlineSuggestionsResponseCallback.aidl3
-rw-r--r--services/autofill/java/com/android/server/autofill/InlineSuggestionSession.java114
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java36
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java69
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java25
9 files changed, 153 insertions, 118 deletions
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSession.java b/core/java/android/inputmethodservice/InlineSuggestionSession.java
index edae06a0b9df..1f12d2a6b659 100644
--- a/core/java/android/inputmethodservice/InlineSuggestionSession.java
+++ b/core/java/android/inputmethodservice/InlineSuggestionSession.java
@@ -27,6 +27,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
+import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InlineSuggestionsResponse;
@@ -145,8 +146,8 @@ class InlineSuggestionSession {
}
@Override
- public void onInlineSuggestionsResponse(InlineSuggestionsResponse response)
- throws RemoteException {
+ public void onInlineSuggestionsResponse(AutofillId fieldId,
+ InlineSuggestionsResponse response) {
final InlineSuggestionSession session = mInlineSuggestionSession.get();
if (session != null) {
session.mHandler.sendMessage(obtainMessage(
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 672b501bbc41..fe792b1efd9f 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -40,6 +40,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.service.autofill.Dataset;
import android.service.autofill.FillEventHistory;
+import android.service.autofill.InlinePresentation;
import android.service.autofill.augmented.PresentationParams.SystemPopupPresentationParams;
import android.util.Log;
import android.util.Pair;
@@ -557,12 +558,10 @@ public abstract class AugmentedAutofillService extends Service {
}
}
- void reportResult(@Nullable List<Dataset> inlineSuggestionsData) {
+ void reportResult(@Nullable List<Dataset> inlineSuggestionsData,
+ @Nullable List<InlinePresentation> inlineActions) {
try {
- final Dataset[] inlineSuggestions = (inlineSuggestionsData != null)
- ? inlineSuggestionsData.toArray(new Dataset[inlineSuggestionsData.size()])
- : null;
- mCallback.onSuccess(inlineSuggestions);
+ mCallback.onSuccess(inlineSuggestionsData, inlineActions);
} catch (RemoteException e) {
Log.e(TAG, "Error calling back with the inline suggestions data: " + e);
}
diff --git a/core/java/android/service/autofill/augmented/FillCallback.java b/core/java/android/service/autofill/augmented/FillCallback.java
index 19eff57269ae..6b4e1185703c 100644
--- a/core/java/android/service/autofill/augmented/FillCallback.java
+++ b/core/java/android/service/autofill/augmented/FillCallback.java
@@ -55,14 +55,14 @@ public final class FillCallback {
if (response == null) {
mProxy.logEvent(AutofillProxy.REPORT_EVENT_NO_RESPONSE);
- mProxy.reportResult(null /*inlineSuggestions*/);
+ mProxy.reportResult(/* inlineSuggestionsData */ null, /* inlineActions */null);
return;
}
List<Dataset> inlineSuggestions = response.getInlineSuggestions();
if (inlineSuggestions != null && !inlineSuggestions.isEmpty()) {
mProxy.logEvent(AutofillProxy.REPORT_EVENT_INLINE_RESPONSE);
- mProxy.reportResult(inlineSuggestions);
+ mProxy.reportResult(inlineSuggestions, response.getInlineActions());
return;
}
diff --git a/core/java/android/service/autofill/augmented/IFillCallback.aidl b/core/java/android/service/autofill/augmented/IFillCallback.aidl
index d9837211be19..bf0adcd54ab1 100644
--- a/core/java/android/service/autofill/augmented/IFillCallback.aidl
+++ b/core/java/android/service/autofill/augmented/IFillCallback.aidl
@@ -20,6 +20,9 @@ import android.os.Bundle;
import android.os.ICancellationSignal;
import android.service.autofill.Dataset;
+import android.service.autofill.InlinePresentation;
+
+import java.util.List;
/**
* Interface to receive the result of an autofill request.
@@ -28,7 +31,8 @@ import android.service.autofill.Dataset;
*/
interface IFillCallback {
void onCancellable(in ICancellationSignal cancellation);
- void onSuccess(in @nullable Dataset[] inlineSuggestionsData);
+ void onSuccess(in @nullable List<Dataset> inlineSuggestionsData,
+ in @nullable List<InlinePresentation> inlineActions);
boolean isCompleted();
void cancel();
}
diff --git a/core/java/com/android/internal/view/IInlineSuggestionsResponseCallback.aidl b/core/java/com/android/internal/view/IInlineSuggestionsResponseCallback.aidl
index 0f93b8ebdb53..5a78e0d3082d 100644
--- a/core/java/com/android/internal/view/IInlineSuggestionsResponseCallback.aidl
+++ b/core/java/com/android/internal/view/IInlineSuggestionsResponseCallback.aidl
@@ -16,6 +16,7 @@
package com.android.internal.view;
+import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsResponse;
/**
@@ -23,5 +24,5 @@ import android.view.inputmethod.InlineSuggestionsResponse;
* {@hide}
*/
oneway interface IInlineSuggestionsResponseCallback {
- void onInlineSuggestionsResponse(in InlineSuggestionsResponse response);
+ void onInlineSuggestionsResponse(in AutofillId fieldId, in InlineSuggestionsResponse response);
}
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionSession.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionSession.java
index 6daa1064c89e..941244994dab 100644
--- a/services/autofill/java/com/android/server/autofill/InlineSuggestionSession.java
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionSession.java
@@ -24,8 +24,10 @@ import android.content.ComponentName;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
+import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsRequest;
+import android.view.inputmethod.InlineSuggestionsResponse;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
@@ -33,6 +35,8 @@ import com.android.internal.view.IInlineSuggestionsResponseCallback;
import com.android.internal.view.InlineSuggestionsRequestInfo;
import com.android.server.inputmethod.InputMethodManagerInternal;
+import java.util.Collections;
+import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -40,9 +44,16 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
- * Maintains an inline suggestion autofill session.
+ * Maintains an autofill inline suggestion session that communicates with the IME.
*
- * <p> This class is thread safe.
+ * <p>
+ * The same session may be reused for multiple input fields involved in the same autofill
+ * {@link Session}. Therefore, one {@link InlineSuggestionsRequest} and one
+ * {@link IInlineSuggestionsResponseCallback} may be used to generate and callback with inline
+ * suggestions for different input fields.
+ *
+ * <p>
+ * This class is thread safe.
*/
final class InlineSuggestionSession {
@@ -61,6 +72,9 @@ final class InlineSuggestionSession {
@Nullable
private CompletableFuture<ImeResponse> mPendingImeResponse;
+ @GuardedBy("mLock")
+ private boolean mIsLastResponseNonEmpty = false;
+
InlineSuggestionSession(InputMethodManagerInternal inputMethodManagerInternal,
int userId, ComponentName componentName) {
mInputMethodManagerInternal = inputMethodManagerInternal;
@@ -69,26 +83,28 @@ final class InlineSuggestionSession {
mLock = new Object();
}
- public void createRequest(@NonNull AutofillId currentViewId) {
+ public void onCreateInlineSuggestionsRequest(@NonNull AutofillId autofillId) {
+ if (sDebug) Log.d(TAG, "onCreateInlineSuggestionsRequest called for " + autofillId);
+
synchronized (mLock) {
cancelCurrentRequest();
mPendingImeResponse = new CompletableFuture<>();
// TODO(b/146454892): pipe the uiExtras from the ExtServices.
mInputMethodManagerInternal.onCreateInlineSuggestionsRequest(
mUserId,
- new InlineSuggestionsRequestInfo(mComponentName, currentViewId, new Bundle()),
+ new InlineSuggestionsRequestInfo(mComponentName, autofillId, new Bundle()),
new InlineSuggestionsRequestCallbackImpl(mPendingImeResponse));
}
}
- @Nullable
- public ImeResponse waitAndGetImeResponse() {
- CompletableFuture<ImeResponse> pendingImeResponse = getPendingImeResponse();
- if (pendingImeResponse == null || pendingImeResponse.isCancelled()) {
- return null;
+ public Optional<InlineSuggestionsRequest> waitAndGetInlineSuggestionsRequest() {
+ final CompletableFuture<ImeResponse> pendingImeResponse = getPendingImeResponse();
+ if (pendingImeResponse == null) {
+ return Optional.empty();
}
try {
- return pendingImeResponse.get(INLINE_REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ return Optional.ofNullable(pendingImeResponse.get(INLINE_REQUEST_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS)).map(ImeResponse::getRequest);
} catch (TimeoutException e) {
Log.w(TAG, "Exception getting inline suggestions request in time: " + e);
} catch (CancellationException e) {
@@ -96,13 +112,59 @@ final class InlineSuggestionSession {
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
- return null;
+ return Optional.empty();
+ }
+
+ public boolean hideInlineSuggestionsUi(@NonNull AutofillId autofillId) {
+ if (sDebug) Log.d(TAG, "Called hideInlineSuggestionsUi for " + autofillId);
+ synchronized (mLock) {
+ if (mIsLastResponseNonEmpty) {
+ if (sDebug) Log.d(TAG, "Send empty suggestion to IME");
+ return onInlineSuggestionsResponseLocked(autofillId,
+ new InlineSuggestionsResponse(Collections.EMPTY_LIST));
+ }
+ return false;
+ }
+ }
+
+ public boolean onInlineSuggestionsResponse(@NonNull AutofillId autofillId,
+ @NonNull InlineSuggestionsResponse inlineSuggestionsResponse) {
+ synchronized (mLock) {
+ return onInlineSuggestionsResponseLocked(autofillId, inlineSuggestionsResponse);
+ }
+ }
+
+ private boolean onInlineSuggestionsResponseLocked(@NonNull AutofillId autofillId,
+ @NonNull InlineSuggestionsResponse inlineSuggestionsResponse) {
+ final CompletableFuture<ImeResponse> completedImsResponse = getPendingImeResponse();
+ if (completedImsResponse == null || !completedImsResponse.isDone()) {
+ return false;
+ }
+ // There is no need to wait on the CompletableFuture since it should have been completed
+ // when {@link #waitAndGetInlineSuggestionsRequest()} was called.
+ ImeResponse imeResponse = completedImsResponse.getNow(null);
+ if (imeResponse == null) {
+ return false;
+ }
+ try {
+ imeResponse.mCallback.onInlineSuggestionsResponse(autofillId,
+ inlineSuggestionsResponse);
+ mIsLastResponseNonEmpty = !inlineSuggestionsResponse.getInlineSuggestions().isEmpty();
+ if (sDebug) {
+ Log.d(TAG, "Autofill sends inline response to IME: "
+ + inlineSuggestionsResponse.getInlineSuggestions().size());
+ }
+ return true;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException sending InlineSuggestionsResponse to IME");
+ return false;
+ }
}
private void cancelCurrentRequest() {
CompletableFuture<ImeResponse> pendingImeResponse = getPendingImeResponse();
- if (pendingImeResponse != null) {
- pendingImeResponse.cancel(true);
+ if (pendingImeResponse != null && !pendingImeResponse.isDone()) {
+ pendingImeResponse.complete(null);
}
}
@@ -125,22 +187,18 @@ final class InlineSuggestionSession {
@Override
public void onInlineSuggestionsUnsupported() throws RemoteException {
- if (sDebug) {
- Log.d(TAG, "onInlineSuggestionsUnsupported() called.");
- }
- mResponse.cancel(true);
+ if (sDebug) Log.d(TAG, "onInlineSuggestionsUnsupported() called.");
+ mResponse.complete(null);
}
@Override
public void onInlineSuggestionsRequest(InlineSuggestionsRequest request,
- IInlineSuggestionsResponseCallback callback) throws RemoteException {
- if (sDebug) {
- Log.d(TAG, "onInlineSuggestionsRequest() received: " + request);
- }
+ IInlineSuggestionsResponseCallback callback) {
+ if (sDebug) Log.d(TAG, "onInlineSuggestionsRequest() received: " + request);
if (request != null && callback != null) {
mResponse.complete(new ImeResponse(request, callback));
} else {
- mResponse.cancel(true);
+ mResponse.complete(null);
}
}
}
@@ -148,12 +206,12 @@ final class InlineSuggestionSession {
/**
* A data class wrapping IME responses for the inline suggestion request.
*/
- public static class ImeResponse {
+ private static class ImeResponse {
@NonNull
- private final InlineSuggestionsRequest mRequest;
+ final InlineSuggestionsRequest mRequest;
@NonNull
- private final IInlineSuggestionsResponseCallback mCallback;
+ final IInlineSuggestionsResponseCallback mCallback;
ImeResponse(@NonNull InlineSuggestionsRequest request,
@NonNull IInlineSuggestionsResponseCallback callback) {
@@ -161,12 +219,8 @@ final class InlineSuggestionSession {
mCallback = callback;
}
- public InlineSuggestionsRequest getRequest() {
+ InlineSuggestionsRequest getRequest() {
return mRequest;
}
-
- public IInlineSuggestionsResponseCallback getCallback() {
- return mCallback;
- }
}
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 228c6286a0f0..dcc91811905a 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -37,6 +37,7 @@ import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.os.SystemClock;
import android.service.autofill.Dataset;
+import android.service.autofill.InlinePresentation;
import android.service.autofill.augmented.AugmentedAutofillService;
import android.service.autofill.augmented.IAugmentedAutofillService;
import android.service.autofill.augmented.IFillCallback;
@@ -54,14 +55,14 @@ import com.android.internal.infra.AndroidFuture;
import com.android.internal.infra.ServiceConnector;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.IResultReceiver;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.view.IInlineSuggestionsResponseCallback;
import com.android.server.autofill.ui.InlineSuggestionFactory;
+import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
final class RemoteAugmentedAutofillService
extends ServiceConnector.Impl<IAugmentedAutofillService> {
@@ -146,7 +147,7 @@ final class RemoteAugmentedAutofillService
int taskId, @NonNull ComponentName activityComponent, @NonNull AutofillId focusedId,
@Nullable AutofillValue focusedValue,
@Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
- @Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
+ @Nullable Function<InlineSuggestionsResponse, Boolean> inlineSuggestionsCallback,
@NonNull Runnable onErrorCallback,
@NonNull RemoteInlineSuggestionRenderService remoteRenderService) {
long requestTime = SystemClock.elapsedRealtime();
@@ -165,12 +166,13 @@ final class RemoteAugmentedAutofillService
focusedId, focusedValue, requestTime, inlineSuggestionsRequest,
new IFillCallback.Stub() {
@Override
- public void onSuccess(@Nullable Dataset[] inlineSuggestionsData) {
+ public void onSuccess(@Nullable List<Dataset> inlineSuggestionsData,
+ @Nullable List<InlinePresentation> inlineActions) {
mCallbacks.resetLastResponse();
maybeRequestShowInlineSuggestions(sessionId,
inlineSuggestionsRequest, inlineSuggestionsData,
- focusedId, inlineSuggestionsCallback, client,
- onErrorCallback, remoteRenderService);
+ inlineActions, focusedId, inlineSuggestionsCallback,
+ client, onErrorCallback, remoteRenderService);
requestAutofill.complete(null);
}
@@ -233,20 +235,21 @@ final class RemoteAugmentedAutofillService
}
private void maybeRequestShowInlineSuggestions(int sessionId,
- @Nullable InlineSuggestionsRequest request, @Nullable Dataset[] inlineSuggestionsData,
- @NonNull AutofillId focusedId,
- @Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
+ @Nullable InlineSuggestionsRequest request,
+ @Nullable List<Dataset> inlineSuggestionsData,
+ @Nullable List<InlinePresentation> inlineActions, @NonNull AutofillId focusedId,
+ @Nullable Function<InlineSuggestionsResponse, Boolean> inlineSuggestionsCallback,
@NonNull IAutoFillManagerClient client, @NonNull Runnable onErrorCallback,
@NonNull RemoteInlineSuggestionRenderService remoteRenderService) {
- if (ArrayUtils.isEmpty(inlineSuggestionsData) || inlineSuggestionsCallback == null
- || request == null) {
+ if (inlineSuggestionsData == null || inlineSuggestionsData.isEmpty()
+ || inlineSuggestionsCallback == null || request == null) {
return;
}
mCallbacks.setLastResponse(sessionId);
final InlineSuggestionsResponse inlineSuggestionsResponse =
InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(
- request, inlineSuggestionsData, focusedId, mContext,
+ request, inlineSuggestionsData, inlineActions, focusedId, mContext,
dataset -> {
mCallbacks.logAugmentedAutofillSelected(sessionId,
dataset.getId());
@@ -262,14 +265,9 @@ final class RemoteAugmentedAutofillService
Slog.w(TAG, "InlineSuggestionFactory created null response");
return;
}
-
- try {
- inlineSuggestionsCallback.onInlineSuggestionsResponse(inlineSuggestionsResponse);
- } catch (RemoteException e) {
- Slog.w(TAG, "Exception sending inline suggestions response back to IME.");
+ if (inlineSuggestionsCallback.apply(inlineSuggestionsResponse)) {
+ mCallbacks.logAugmentedAutofillShown(sessionId);
}
-
- mCallbacks.logAugmentedAutofillShown(sessionId);
}
@Override
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 960997dd7df8..6fb65cae2482 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -100,7 +100,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.view.IInlineSuggestionsResponseCallback;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.autofill.ui.InlineSuggestionFactory;
import com.android.server.autofill.ui.PendingUi;
@@ -113,6 +112,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -403,11 +403,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final ArrayList<FillContext> contexts =
mergePreviousSessionLocked(/* forSave= */ false);
- final InlineSuggestionSession.ImeResponse imeResponse =
- mInlineSuggestionSession.waitAndGetImeResponse();
-
+ final Optional<InlineSuggestionsRequest> inlineSuggestionsRequest =
+ mInlineSuggestionSession.waitAndGetInlineSuggestionsRequest();
request = new FillRequest(requestId, contexts, mClientState, flags,
- imeResponse != null ? imeResponse.getRequest() : null);
+ inlineSuggestionsRequest.orElse(null));
}
if (mActivityToken != null) {
@@ -605,7 +604,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private void maybeRequestInlineSuggestionsRequestThenFillLocked(@NonNull ViewState viewState,
int newState, int flags) {
if (isInlineSuggestionsEnabled()) {
- mInlineSuggestionSession.createRequest(mCurrentViewId);
+ mInlineSuggestionSession.onCreateInlineSuggestionsRequest(mCurrentViewId);
}
requestNewFillResponseLocked(viewState, newState, flags);
@@ -1158,18 +1157,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
} catch (RemoteException e) {
Slog.e(TAG, "Error requesting to hide fill UI", e);
}
- try {
- final InlineSuggestionSession.ImeResponse imeResponse =
- mInlineSuggestionSession.waitAndGetImeResponse();
- if (imeResponse == null) {
- Log.w(TAG, "Session input method callback is not set yet");
- return;
- }
- imeResponse.getCallback().onInlineSuggestionsResponse(
- new InlineSuggestionsResponse(Collections.EMPTY_LIST));
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException hiding inline suggestions");
- }
}
}
@@ -2501,6 +2488,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (sVerbose) Slog.v(TAG, "Exiting view " + id);
mUi.hideFillUi(this);
hideAugmentedAutofillLocked(viewState);
+ mInlineSuggestionSession.hideInlineSuggestionsUi(mCurrentViewId);
mCurrentViewId = null;
}
break;
@@ -2668,38 +2656,27 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
*/
private boolean requestShowInlineSuggestionsLocked(@NonNull FillResponse response,
@Nullable String filterText) {
- final List<Dataset> datasets = response.getDatasets();
-
- final InlineSuggestionSession.ImeResponse imeResponse =
- mInlineSuggestionSession.waitAndGetImeResponse();
- if (imeResponse == null) {
- Log.w(TAG, "Session input method callback is not set yet");
+ final Optional<InlineSuggestionsRequest> inlineSuggestionsRequest =
+ mInlineSuggestionSession.waitAndGetInlineSuggestionsRequest();
+ if (!inlineSuggestionsRequest.isPresent()) {
+ Log.w(TAG, "InlineSuggestionsRequest unavailable");
return false;
}
-
- final InlineSuggestionsRequest request = imeResponse.getRequest();
InlineSuggestionsResponse inlineSuggestionsResponse =
- InlineSuggestionFactory.createInlineSuggestionsResponse(request,
+ InlineSuggestionFactory.createInlineSuggestionsResponse(
+ inlineSuggestionsRequest.get(),
response, filterText, response.getInlineActions(), mCurrentViewId, mContext,
this, () -> {
synchronized (mLock) {
requestHideFillUi(mCurrentViewId);
}
}, mService.getRemoteInlineSuggestionRenderServiceLocked());
-
if (inlineSuggestionsResponse == null) {
Slog.w(TAG, "InlineSuggestionFactory created null response");
return false;
}
-
- try {
- imeResponse.getCallback().onInlineSuggestionsResponse(inlineSuggestionsResponse);
- } catch (RemoteException e) {
- Log.w(TAG, "onFillReady() remote error calling onInlineSuggestionsResponse()");
- return false;
- }
-
- return true;
+ return mInlineSuggestionSession.onInlineSuggestionsResponse(mCurrentViewId,
+ inlineSuggestionsResponse);
}
boolean isDestroyed() {
@@ -2982,16 +2959,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// doesn't want autofill
if (mForAugmentedAutofillOnly || !isInlineSuggestionsEnabled()) {
if (sDebug) Slog.d(TAG, "Create inline request for augmented autofill");
- mInlineSuggestionSession.createRequest(mCurrentViewId);
- }
- InlineSuggestionSession.ImeResponse imeResponse =
- mInlineSuggestionSession.waitAndGetImeResponse();
- final InlineSuggestionsRequest inlineSuggestionsRequest =
- imeResponse != null ? imeResponse.getRequest() : null;
- final IInlineSuggestionsResponseCallback inlineSuggestionsResponseCallback =
- imeResponse != null ? imeResponse.getCallback() : null;
+ mInlineSuggestionSession.onCreateInlineSuggestionsRequest(mCurrentViewId);
+ }
+
+ Optional<InlineSuggestionsRequest> inlineSuggestionsRequest =
+ mInlineSuggestionSession.waitAndGetInlineSuggestionsRequest();
remoteService.onRequestAutofillLocked(id, mClient, taskId, mComponentName, focusedId,
- currentValue, inlineSuggestionsRequest, inlineSuggestionsResponseCallback, () -> {
+ currentValue, inlineSuggestionsRequest.orElse(null),
+ response -> mInlineSuggestionSession.onInlineSuggestionsResponse(
+ mCurrentViewId, response),
+ () -> {
synchronized (mLock) {
cancelAugmentedAutofillLocked();
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
index 0d1b6ddd2933..9bf369089e50 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
@@ -70,6 +70,7 @@ public final class InlineSuggestionFactory {
* Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by the
* autofill service, potentially filtering the datasets.
*/
+ @Nullable
public static InlineSuggestionsResponse createInlineSuggestionsResponse(
@NonNull InlineSuggestionsRequest request, @NonNull FillResponse response,
@Nullable String filterText, @Nullable List<InlinePresentation> inlineActions,
@@ -92,23 +93,21 @@ public final class InlineSuggestionFactory {
};
}
- final List<Dataset> datasetList = response.getDatasets();
- final Dataset[] datasets = datasetList == null
- ? null
- : datasetList.toArray(new Dataset[]{});
final InlinePresentation inlineAuthentication =
response.getAuthentication() == null ? null : response.getInlinePresentation();
return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request,
- datasets, filterText, inlineAuthentication, inlineActions, autofillId, context,
- onErrorCallback, onClickFactory, remoteRenderService);
+ response.getDatasets(), filterText, inlineAuthentication, inlineActions, autofillId,
+ context, onErrorCallback, onClickFactory, remoteRenderService);
}
/**
* Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by augmented
* autofill service.
*/
+ @Nullable
public static InlineSuggestionsResponse createAugmentedInlineSuggestionsResponse(
- @NonNull InlineSuggestionsRequest request, @NonNull Dataset[] datasets,
+ @NonNull InlineSuggestionsRequest request, @NonNull List<Dataset> datasets,
+ @Nullable List<InlinePresentation> inlineActions,
@NonNull AutofillId autofillId, @NonNull Context context,
@NonNull InlineSuggestionUiCallback inlineSuggestionUiCallback,
@NonNull Runnable onErrorCallback,
@@ -116,14 +115,15 @@ public final class InlineSuggestionFactory {
if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
return createInlineSuggestionsResponseInternal(/* isAugmented= */ true, request,
datasets, /* filterText= */ null, /* inlineAuthentication= */ null,
- /* inlineActions= */ null, autofillId, context, onErrorCallback,
+ inlineActions, autofillId, context, onErrorCallback,
(dataset, datasetIndex) ->
inlineSuggestionUiCallback.autofill(dataset), remoteRenderService);
}
+ @Nullable
private static InlineSuggestionsResponse createInlineSuggestionsResponseInternal(
boolean isAugmented, @NonNull InlineSuggestionsRequest request,
- @Nullable Dataset[] datasets, @Nullable String filterText,
+ @Nullable List<Dataset> datasets, @Nullable String filterText,
@Nullable InlinePresentation inlineAuthentication,
@Nullable List<InlinePresentation> inlineActions, @NonNull AutofillId autofillId,
@NonNull Context context, @NonNull Runnable onErrorCallback,
@@ -145,8 +145,8 @@ public final class InlineSuggestionFactory {
return null;
}
- for (int datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
- final Dataset dataset = datasets[datasetIndex];
+ for (int datasetIndex = 0; datasetIndex < datasets.size(); datasetIndex++) {
+ final Dataset dataset = datasets.get(datasetIndex);
final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
if (fieldIndex < 0) {
Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
@@ -169,7 +169,8 @@ public final class InlineSuggestionFactory {
inlineSuggestions.add(inlineSuggestion);
}
- if (inlineActions != null) {
+ // We should only add inline actions if there is at least one suggestion.
+ if (!inlineSuggestions.isEmpty() && inlineActions != null) {
for (InlinePresentation inlinePresentation : inlineActions) {
final InlineSuggestion inlineAction = createInlineAction(isAugmented, context,
mergedInlinePresentation(request, 0, inlinePresentation),