Response and Dataset authentication via inline autofill.
Bug: 148815880 Test: manual verification Change-Id: Ic72f6d828521737db5ce890c0e79cd6f8d16a6c6
This commit is contained in:
@@ -43048,6 +43048,7 @@ package android.service.autofill {
|
||||
method @NonNull public android.service.autofill.FillResponse build();
|
||||
method @NonNull public android.service.autofill.FillResponse.Builder disableAutofill(long);
|
||||
method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews);
|
||||
method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews, @Nullable android.service.autofill.InlinePresentation);
|
||||
method @NonNull public android.service.autofill.FillResponse.Builder setClientState(@Nullable android.os.Bundle);
|
||||
method @NonNull public android.service.autofill.FillResponse.Builder setFieldClassificationIds(@NonNull android.view.autofill.AutofillId...);
|
||||
method @NonNull public android.service.autofill.FillResponse.Builder setFlags(int);
|
||||
|
||||
@@ -1907,6 +1907,7 @@ public class Activity extends ContextThemeWrapper
|
||||
if (!mAutoFillIgnoreFirstResumePause) {
|
||||
View focus = getCurrentFocus();
|
||||
if (focus != null && focus.canNotifyAutofillEnterExitEvent()) {
|
||||
// TODO(b/148815880): Bring up keyboard if resumed from inline authentication.
|
||||
// TODO: in Activity killed/recreated case, i.e. SessionLifecycleTest#
|
||||
// testDatasetVisibleWhileAutofilledAppIsLifecycled: the View's initial
|
||||
// window visibility after recreation is INVISIBLE in onResume() and next frame
|
||||
@@ -8467,7 +8468,7 @@ public class Activity extends ContextThemeWrapper
|
||||
/** @hide */
|
||||
@Override
|
||||
public final void autofillClientAuthenticate(int authenticationId, IntentSender intent,
|
||||
Intent fillInIntent) {
|
||||
Intent fillInIntent, boolean authenticateInline) {
|
||||
try {
|
||||
startIntentSenderForResultInner(intent, AUTO_FILL_AUTH_WHO_PREFIX,
|
||||
authenticationId, fillInIntent, 0, 0, null);
|
||||
|
||||
@@ -75,6 +75,7 @@ public final class FillResponse implements Parcelable {
|
||||
private final @Nullable SaveInfo mSaveInfo;
|
||||
private final @Nullable Bundle mClientState;
|
||||
private final @Nullable RemoteViews mPresentation;
|
||||
private final @Nullable InlinePresentation mInlinePresentation;
|
||||
private final @Nullable RemoteViews mHeader;
|
||||
private final @Nullable RemoteViews mFooter;
|
||||
private final @Nullable IntentSender mAuthentication;
|
||||
@@ -95,6 +96,7 @@ public final class FillResponse implements Parcelable {
|
||||
mSaveInfo = builder.mSaveInfo;
|
||||
mClientState = builder.mClientState;
|
||||
mPresentation = builder.mPresentation;
|
||||
mInlinePresentation = builder.mInlinePresentation;
|
||||
mHeader = builder.mHeader;
|
||||
mFooter = builder.mFooter;
|
||||
mAuthentication = builder.mAuthentication;
|
||||
@@ -130,6 +132,11 @@ public final class FillResponse implements Parcelable {
|
||||
return mPresentation;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public @Nullable InlinePresentation getInlinePresentation() {
|
||||
return mInlinePresentation;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public @Nullable RemoteViews getHeader() {
|
||||
return mHeader;
|
||||
@@ -219,6 +226,7 @@ public final class FillResponse implements Parcelable {
|
||||
private SaveInfo mSaveInfo;
|
||||
private Bundle mClientState;
|
||||
private RemoteViews mPresentation;
|
||||
private InlinePresentation mInlinePresentation;
|
||||
private RemoteViews mHeader;
|
||||
private RemoteViews mFooter;
|
||||
private IntentSender mAuthentication;
|
||||
@@ -317,6 +325,67 @@ public final class FillResponse implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a custom UI before before autofilling the screen with any data set in this
|
||||
* response.
|
||||
*
|
||||
* <p><b>Note:</b> Although the name of this method suggests that it should be used just for
|
||||
* authentication flow, it can be used for other advanced flows; see {@link AutofillService}
|
||||
* for examples.
|
||||
*
|
||||
* <p>This method is similar to
|
||||
* {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews)}, but also accepts
|
||||
* an {@link InlinePresentation} presentation which is required for authenticating through
|
||||
* the inline autofill flow.
|
||||
*
|
||||
* <p><b>Note:</b> {@link #setHeader(RemoteViews)} or {@link #setFooter(RemoteViews)} does
|
||||
* not work with {@link InlinePresentation}.</p>
|
||||
*
|
||||
* @param authentication Intent to an activity with your authentication flow.
|
||||
* @param presentation The presentation to visualize the response.
|
||||
* @param inlinePresentation The inlinePresentation to visualize the response inline.
|
||||
* @param ids id of Views that when focused will display the authentication UI.
|
||||
*
|
||||
* @return This builder.
|
||||
*
|
||||
* @throws IllegalArgumentException if any of the following occurs:
|
||||
* <ul>
|
||||
* <li>{@code ids} is {@code null}</li>
|
||||
* <li>{@code ids} is empty</li>
|
||||
* <li>{@code ids} contains a {@code null} element</li>
|
||||
* <li>both {@code authentication} and {@code presentation} are {@code null}</li>
|
||||
* <li>both {@code authentication} and {@code presentation} are non-{@code null}</li>
|
||||
* <li>both {@code authentication} and {@code inlinePresentation} are {@code null}</li>
|
||||
* <li>both {@code authentication} and {@code inlinePresentation} are
|
||||
* non-{@code null}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @throws IllegalStateException if a {@link #setHeader(RemoteViews) header} or a
|
||||
* {@link #setFooter(RemoteViews) footer} are already set for this builder.
|
||||
*
|
||||
* @see android.app.PendingIntent#getIntentSender()
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAuthentication(@NonNull AutofillId[] ids,
|
||||
@Nullable IntentSender authentication, @Nullable RemoteViews presentation,
|
||||
@Nullable InlinePresentation inlinePresentation) {
|
||||
throwIfDestroyed();
|
||||
throwIfDisableAutofillCalled();
|
||||
if (mHeader != null || mFooter != null) {
|
||||
throw new IllegalStateException("Already called #setHeader() or #setFooter()");
|
||||
}
|
||||
|
||||
if (authentication == null ^ (presentation == null && inlinePresentation == null)) {
|
||||
throw new IllegalArgumentException("authentication and presentation "
|
||||
+ "(dropdown or inline), must be both non-null or null");
|
||||
}
|
||||
mAuthentication = authentication;
|
||||
mPresentation = presentation;
|
||||
mInlinePresentation = inlinePresentation;
|
||||
mAuthenticationIds = assertValid(ids);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies views that should not trigger new
|
||||
* {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
|
||||
@@ -644,6 +713,8 @@ public final class FillResponse implements Parcelable {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (mInlinePresentation != null) {
|
||||
mSupportsInlineSuggestions = true;
|
||||
}
|
||||
|
||||
mDestroyed = true;
|
||||
@@ -691,6 +762,9 @@ public final class FillResponse implements Parcelable {
|
||||
if (mPresentation != null) {
|
||||
builder.append(", hasPresentation");
|
||||
}
|
||||
if (mInlinePresentation != null) {
|
||||
builder.append(", hasInlinePresentation");
|
||||
}
|
||||
if (mHeader != null) {
|
||||
builder.append(", hasHeader");
|
||||
}
|
||||
@@ -740,6 +814,7 @@ public final class FillResponse implements Parcelable {
|
||||
parcel.writeParcelableArray(mAuthenticationIds, flags);
|
||||
parcel.writeParcelable(mAuthentication, flags);
|
||||
parcel.writeParcelable(mPresentation, flags);
|
||||
parcel.writeParcelable(mInlinePresentation, flags);
|
||||
parcel.writeParcelable(mHeader, flags);
|
||||
parcel.writeParcelable(mFooter, flags);
|
||||
parcel.writeParcelable(mUserData, flags);
|
||||
@@ -774,8 +849,10 @@ public final class FillResponse implements Parcelable {
|
||||
AutofillId.class);
|
||||
final IntentSender authentication = parcel.readParcelable(null);
|
||||
final RemoteViews presentation = parcel.readParcelable(null);
|
||||
final InlinePresentation inlinePresentation = parcel.readParcelable(null);
|
||||
if (authenticationIds != null) {
|
||||
builder.setAuthentication(authenticationIds, authentication, presentation);
|
||||
builder.setAuthentication(authenticationIds, authentication, presentation,
|
||||
inlinePresentation);
|
||||
}
|
||||
final RemoteViews header = parcel.readParcelable(null);
|
||||
if (header != null) {
|
||||
|
||||
@@ -86,9 +86,10 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
//TODO: use java.lang.ref.Cleaner once Android supports Java 9
|
||||
import sun.misc.Cleaner;
|
||||
|
||||
//TODO: use java.lang.ref.Cleaner once Android supports Java 9
|
||||
|
||||
/**
|
||||
* <p>The {@link AutofillManager} class provides ways for apps and custom views to
|
||||
* integrate with the Autofill Framework lifecycle.
|
||||
@@ -547,7 +548,7 @@ public final class AutofillManager {
|
||||
* @param fillInIntent The authentication fill-in intent.
|
||||
*/
|
||||
void autofillClientAuthenticate(int authenticationId, IntentSender intent,
|
||||
Intent fillInIntent);
|
||||
Intent fillInIntent, boolean authenticateInline);
|
||||
|
||||
/**
|
||||
* Tells the client this manager has state to be reset.
|
||||
@@ -2070,7 +2071,7 @@ public final class AutofillManager {
|
||||
}
|
||||
|
||||
private void authenticate(int sessionId, int authenticationId, IntentSender intent,
|
||||
Intent fillInIntent) {
|
||||
Intent fillInIntent, boolean authenticateInline) {
|
||||
synchronized (mLock) {
|
||||
if (sessionId == mSessionId) {
|
||||
final AutofillClient client = getClient();
|
||||
@@ -2078,7 +2079,8 @@ public final class AutofillManager {
|
||||
// clear mOnInvisibleCalled and we will see if receive onInvisibleForAutofill()
|
||||
// before onAuthenticationResult()
|
||||
mOnInvisibleCalled = false;
|
||||
client.autofillClientAuthenticate(authenticationId, intent, fillInIntent);
|
||||
client.autofillClientAuthenticate(authenticationId, intent, fillInIntent,
|
||||
authenticateInline);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3250,10 +3252,11 @@ public final class AutofillManager {
|
||||
|
||||
@Override
|
||||
public void authenticate(int sessionId, int authenticationId, IntentSender intent,
|
||||
Intent fillInIntent) {
|
||||
Intent fillInIntent, boolean authenticateInline) {
|
||||
final AutofillManager afm = mAfm.get();
|
||||
if (afm != null) {
|
||||
afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
|
||||
afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent,
|
||||
authenticateInline));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ oneway interface IAutoFillManagerClient {
|
||||
* Authenticates a fill response or a data set.
|
||||
*/
|
||||
void authenticate(int sessionId, int authenticationId, in IntentSender intent,
|
||||
in Intent fillInIntent);
|
||||
in Intent fillInIntent, boolean authenticateInline);
|
||||
|
||||
/**
|
||||
* Sets the views to track. If saveOnAllViewsInvisible is set and all these view are invisible
|
||||
|
||||
@@ -1018,7 +1018,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
|
||||
// FillServiceCallbacks
|
||||
@Override
|
||||
public void authenticate(int requestId, int datasetIndex, IntentSender intent, Bundle extras) {
|
||||
public void authenticate(int requestId, int datasetIndex, IntentSender intent, Bundle extras,
|
||||
boolean authenticateInline) {
|
||||
if (sDebug) {
|
||||
Slog.d(TAG, "authenticate(): requestId=" + requestId + "; datasetIdx=" + datasetIndex
|
||||
+ "; intentSender=" + intent);
|
||||
@@ -1042,7 +1043,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
final int authenticationId = AutofillManager.makeAuthenticationId(requestId, datasetIndex);
|
||||
mHandler.sendMessage(obtainMessage(
|
||||
Session::startAuthentication,
|
||||
this, authenticationId, intent, fillInIntent));
|
||||
this, authenticationId, intent, fillInIntent, authenticateInline));
|
||||
}
|
||||
|
||||
// VultureCallback
|
||||
@@ -2623,8 +2624,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
mService.getServicePackageName(), mComponentName,
|
||||
serviceLabel, serviceIcon, this, id, mCompatMode);
|
||||
|
||||
mService.logDatasetShown(id, mClientState);
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mUiShownTime == 0) {
|
||||
// Log first time UI is shown.
|
||||
@@ -2656,10 +2655,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
private boolean requestShowInlineSuggestionsLocked(@NonNull FillResponse response,
|
||||
@Nullable String filterText) {
|
||||
final List<Dataset> datasets = response.getDatasets();
|
||||
if (datasets == null) {
|
||||
Log.w(TAG, "response returned null datasets");
|
||||
return false;
|
||||
}
|
||||
|
||||
final InlineSuggestionSession.ImeResponse imeResponse =
|
||||
mInlineSuggestionSession.waitAndGetImeResponse();
|
||||
@@ -2671,9 +2666,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
final InlineSuggestionsRequest request = imeResponse.getRequest();
|
||||
InlineSuggestionsResponse inlineSuggestionsResponse =
|
||||
InlineSuggestionFactory.createInlineSuggestionsResponse(request,
|
||||
response.getRequestId(),
|
||||
datasets.toArray(new Dataset[]{}), filterText, response.getInlineActions(),
|
||||
mCurrentViewId, mContext, this, () -> {
|
||||
response, filterText, response.getInlineActions(), mCurrentViewId, mContext,
|
||||
this, () -> {
|
||||
synchronized (mLock) {
|
||||
requestHideFillUi(mCurrentViewId);
|
||||
}
|
||||
@@ -3160,7 +3154,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
final int authenticationId = AutofillManager.makeAuthenticationId(requestId,
|
||||
datasetIndex);
|
||||
startAuthentication(authenticationId, dataset.getAuthentication(), fillInIntent);
|
||||
startAuthentication(authenticationId, dataset.getAuthentication(), fillInIntent,
|
||||
/* authenticateInline= */false);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3184,10 +3179,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
private void startAuthentication(int authenticationId, IntentSender intent,
|
||||
Intent fillInIntent) {
|
||||
Intent fillInIntent, boolean authenticateInline) {
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
mClient.authenticate(id, authenticationId, intent, fillInIntent);
|
||||
mClient.authenticate(id, authenticationId, intent, fillInIntent,
|
||||
authenticateInline);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error launching auth intent", e);
|
||||
|
||||
@@ -79,7 +79,7 @@ public final class AutoFillUI {
|
||||
|
||||
public interface AutoFillUiCallback {
|
||||
void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent,
|
||||
@Nullable Bundle extras);
|
||||
@Nullable Bundle extras, boolean authenticateInline);
|
||||
void fill(int requestId, int datasetIndex, @NonNull Dataset dataset);
|
||||
void save();
|
||||
void cancelSave();
|
||||
@@ -217,7 +217,8 @@ public final class AutoFillUI {
|
||||
if (mCallback != null) {
|
||||
mCallback.authenticate(response.getRequestId(),
|
||||
AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED,
|
||||
response.getAuthentication(), response.getClientState());
|
||||
response.getAuthentication(), response.getClientState(),
|
||||
/* authenticateInline= */ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@ import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.service.autofill.Dataset;
|
||||
import android.service.autofill.FillResponse;
|
||||
import android.service.autofill.IInlineSuggestionUiCallback;
|
||||
import android.service.autofill.InlinePresentation;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillValue;
|
||||
import android.view.inline.InlinePresentationSpec;
|
||||
import android.view.inputmethod.InlineSuggestion;
|
||||
@@ -69,8 +71,7 @@ public final class InlineSuggestionFactory {
|
||||
* autofill service, potentially filtering the datasets.
|
||||
*/
|
||||
public static InlineSuggestionsResponse createInlineSuggestionsResponse(
|
||||
@NonNull InlineSuggestionsRequest request, int requestId,
|
||||
@NonNull Dataset[] datasets,
|
||||
@NonNull InlineSuggestionsRequest request, @NonNull FillResponse response,
|
||||
@Nullable String filterText,
|
||||
@Nullable List<InlinePresentation> inlineActions,
|
||||
@NonNull AutofillId autofillId,
|
||||
@@ -79,10 +80,24 @@ public final class InlineSuggestionFactory {
|
||||
@NonNull Runnable onErrorCallback,
|
||||
@Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
|
||||
if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called");
|
||||
return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request, datasets,
|
||||
filterText, inlineActions, autofillId, context, onErrorCallback,
|
||||
(dataset, datasetIndex) -> client.fill(requestId, datasetIndex, dataset),
|
||||
remoteRenderService);
|
||||
final BiConsumer<Dataset, Integer> onClickFactory;
|
||||
if (response.getAuthentication() != null) {
|
||||
onClickFactory = (dataset, datasetIndex) -> client.authenticate(response.getRequestId(),
|
||||
datasetIndex, response.getAuthentication(), response.getClientState(),
|
||||
/* authenticateInline= */ true);
|
||||
} else {
|
||||
onClickFactory = (dataset, datasetIndex) ->
|
||||
client.fill(response.getRequestId(), datasetIndex, dataset);
|
||||
}
|
||||
|
||||
final List<Dataset> datasetList = response.getDatasets();
|
||||
final Dataset[] datasets = datasetList == null
|
||||
? null
|
||||
: datasetList.toArray(new Dataset[]{});
|
||||
|
||||
return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request, response,
|
||||
datasets, filterText, inlineActions, autofillId, context, onErrorCallback,
|
||||
onClickFactory, remoteRenderService);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,22 +114,38 @@ public final class InlineSuggestionFactory {
|
||||
@Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
|
||||
if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
|
||||
return createInlineSuggestionsResponseInternal(/* isAugmented= */ true, request,
|
||||
datasets, /* filterText= */ null, /* inlineActions= */ null, autofillId, context,
|
||||
onErrorCallback,
|
||||
(dataset, fieldIndex) -> inlineSuggestionUiCallback.autofill(dataset),
|
||||
remoteRenderService);
|
||||
/* fillResponse= */ null, datasets, /* filterText= */ null,
|
||||
/* inlineActions= */ null, autofillId, context, onErrorCallback,
|
||||
(dataset, fieldIndex) ->
|
||||
inlineSuggestionUiCallback.autofill(dataset), remoteRenderService);
|
||||
}
|
||||
|
||||
private static InlineSuggestionsResponse createInlineSuggestionsResponseInternal(
|
||||
boolean isAugmented, @NonNull InlineSuggestionsRequest request,
|
||||
@NonNull Dataset[] datasets, @Nullable String filterText,
|
||||
@Nullable FillResponse response, @Nullable Dataset[] datasets,
|
||||
@Nullable String filterText,
|
||||
@Nullable List<InlinePresentation> inlineActions, @NonNull AutofillId autofillId,
|
||||
@NonNull Context context, @NonNull Runnable onErrorCallback,
|
||||
@NonNull BiConsumer<Dataset, Integer> onClickFactory,
|
||||
@Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
|
||||
|
||||
final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
|
||||
for (int i = 0; i < datasets.length; i++) {
|
||||
final Dataset dataset = datasets[i];
|
||||
if (response.getAuthentication() != null) {
|
||||
InlineSuggestion inlineAuthSuggestion = createInlineAuthSuggestion(response,
|
||||
remoteRenderService, onClickFactory, onErrorCallback,
|
||||
request.getHostInputToken());
|
||||
inlineSuggestions.add(inlineAuthSuggestion);
|
||||
|
||||
return new InlineSuggestionsResponse(inlineSuggestions);
|
||||
}
|
||||
|
||||
if (datasets == null) {
|
||||
Slog.w(TAG, "Datasets should not be null here");
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
final Dataset dataset = datasets[datasetIndex];
|
||||
final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
|
||||
if (fieldIndex < 0) {
|
||||
Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
|
||||
@@ -130,9 +161,10 @@ public final class InlineSuggestionFactory {
|
||||
continue;
|
||||
}
|
||||
InlineSuggestion inlineSuggestion = createInlineSuggestion(isAugmented, dataset,
|
||||
fieldIndex, mergedInlinePresentation(request, i, inlinePresentation),
|
||||
fieldIndex, mergedInlinePresentation(request, datasetIndex, inlinePresentation),
|
||||
onClickFactory, remoteRenderService, onErrorCallback,
|
||||
request.getHostInputToken());
|
||||
|
||||
inlineSuggestions.add(inlineSuggestion);
|
||||
}
|
||||
if (inlineActions != null) {
|
||||
@@ -198,7 +230,7 @@ public final class InlineSuggestionFactory {
|
||||
}
|
||||
|
||||
private static InlineSuggestion createInlineSuggestion(boolean isAugmented,
|
||||
@NonNull Dataset dataset, int fieldIndex,
|
||||
@NonNull Dataset dataset, int datasetIndex,
|
||||
@NonNull InlinePresentation inlinePresentation,
|
||||
@NonNull BiConsumer<Dataset, Integer> onClickFactory,
|
||||
@NonNull RemoteInlineSuggestionRenderService remoteRenderService,
|
||||
@@ -212,12 +244,28 @@ public final class InlineSuggestionFactory {
|
||||
|
||||
final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
|
||||
createInlineContentProvider(inlinePresentation,
|
||||
() -> onClickFactory.accept(dataset, fieldIndex), onErrorCallback,
|
||||
() -> onClickFactory.accept(dataset, datasetIndex), onErrorCallback,
|
||||
remoteRenderService, hostInputToken));
|
||||
|
||||
return inlineSuggestion;
|
||||
}
|
||||
|
||||
private static InlineSuggestion createInlineAuthSuggestion(@NonNull FillResponse response,
|
||||
@NonNull RemoteInlineSuggestionRenderService remoteRenderService,
|
||||
@NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull Runnable onErrorCallback,
|
||||
@Nullable IBinder hostInputToken) {
|
||||
final InlinePresentation inlinePresentation = response.getInlinePresentation();
|
||||
final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
|
||||
inlinePresentation.getInlinePresentationSpec(),
|
||||
InlineSuggestionInfo.SOURCE_AUTOFILL, null, InlineSuggestionInfo.TYPE_SUGGESTION);
|
||||
|
||||
return new InlineSuggestion(inlineSuggestionInfo,
|
||||
createInlineContentProvider(inlinePresentation,
|
||||
() -> onClickFactory.accept(null,
|
||||
AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED),
|
||||
onErrorCallback, remoteRenderService, hostInputToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link InlinePresentation} with the style spec from the request/host, and
|
||||
* everything else from the provided {@code inlinePresentation}.
|
||||
@@ -299,4 +347,4 @@ public final class InlineSuggestionFactory {
|
||||
|
||||
private InlineSuggestionFactory() {
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user