Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 575d7ad9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Response and Dataset authentication via inline autofill."

parents d8c867b1 5be0f158
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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);
+78 −1
Original line number Diff line number Diff line
@@ -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) {
+9 −6
Original line number Diff line number Diff line
@@ -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));
            }
        }

+1 −1
Original line number Diff line number Diff line
@@ -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
Loading