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

Commit 9a2e6058 authored by Felipe Leme's avatar Felipe Leme
Browse files

Always start a manual request, even if view was already autofilled.

Fixes: 36034784
Test: CtsAutoFillServiceTestCases pass
Test: testAutofillManuallyAgainAfterAutomaticallyAutofilledBefore()
Test: testAutofillManuallyAgainAfterManuallyAutofilledBefore()

Change-Id: Ided8c42367b71766772bd364445510848db2adce
parent 395f0ec8
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import android.annotation.NonNull;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Bundle;
import android.util.DebugUtils;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;

import java.util.Arrays;
import java.util.Objects;
@@ -40,6 +42,10 @@ public final class Helper {
     */
    public static boolean sVerbose = false;

    private Helper() {
        throw new UnsupportedOperationException("contains static members only");
    }

    static void append(StringBuilder builder, Bundle bundle) {
        if (bundle == null || !sVerbose) {
            builder.append("null");
@@ -62,8 +68,8 @@ public final class Helper {
        return builder.toString();
    }

    private Helper() {
        throw new UnsupportedOperationException("contains static members only");
    static String getUpdateActionAsString(int action) {
        return DebugUtils.flagsToString(AutofillManager.class, "ACTION_", action);
    }

    static ViewNode findViewNodeById(@NonNull AssistStructure structure, @NonNull AutofillId id) {
+53 −12
Original line number Diff line number Diff line
@@ -25,9 +25,13 @@ import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;

import static com.android.server.autofill.Helper.findViewNodeById;
import static com.android.server.autofill.Helper.getUpdateActionAsString;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
import static com.android.server.autofill.Helper.findViewNodeById;
import static com.android.server.autofill.ViewState.STATE_AUTOFILLED;
import static com.android.server.autofill.ViewState.STATE_FILLABLE;
import static com.android.server.autofill.ViewState.STATE_RESTARTED_SESSION;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -251,16 +255,21 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                continue;
            }

            final AutofillValue initialValue = viewState.getInitialValue();
            final AutofillValue currentValue = viewState.getCurrentValue();
            final AutofillValue filledValue = viewState.getAutofilledValue();
            final AutofillOverlay overlay = new AutofillOverlay();
            if (filledValue != null && !filledValue.equals(initialValue)) {
                overlay.value = filledValue;

            // Sanitizes the value if the current value matches what the service sent.
            if (filledValue != null && filledValue.equals(currentValue)) {
                overlay.value = currentValue;
            }

            if (mCurrentViewId != null) {
                // Updates the focus value.
                overlay.focused = mCurrentViewId.equals(viewState.id);
                // Sanitizes the value of the focused field in a manual request.
                if (overlay.focused && (flags & FLAG_MANUAL_REQUEST) != 0) {
                    overlay.value = node.getAutofillValue();
                    overlay.value = currentValue;
                }
            }
            node.setAutofillOverlay(overlay);
@@ -886,6 +895,40 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        mRemoteFillService.onSaveRequest(saveRequest);
    }

    /**
     * Starts (if necessary) a new fill request upon entering a view.
     *
     * <p>A new request will be started in 2 scenarios:
     * <ol>
     *   <li>If the user manually requested autofill after the view was already filled.
     *   <li>If the view is part of a new partition.
     * </ol>
     *
     * @param id The id of the view that is entered.
     * @param viewState The view that is entered.
     * @param flags The flag that was passed by the AutofillManager.
     */
    private void requestNewFillResponseIfNecessaryLocked(@NonNull AutofillId id,
            @NonNull ViewState viewState, int flags) {
        // First check if this is a manual request after view was autofilled.
        final int state = viewState.getState();
        final boolean restart = (state & STATE_AUTOFILLED) != 0
                && (flags & FLAG_MANUAL_REQUEST) != 0;
        if (restart) {
            if (sDebug) Slog.d(TAG, "Re-starting session on view  " + id);
            viewState.setState(STATE_RESTARTED_SESSION);
            requestNewFillResponseLocked(flags);
            return;
        }

        // If it's not, then check if it it should start a partition.
        if (shouldStartNewPartitionLocked(id)) {
            if (sDebug) Slog.d(TAG, "Starting partition for view id " + id);
            viewState.setState(ViewState.STATE_STARTED_PARTITION);
            requestNewFillResponseLocked(flags);
        }
    }

    /**
     * Determines if a new partition should be started for an id.
     *
@@ -942,6 +985,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                    + id + " destroyed");
            return;
        }
        if (sVerbose) {
            Slog.v(TAG, "updateLocked(): id=" + id + ", action=" + getUpdateActionAsString(action)
                    + ", flags=" + flags);
        }
        ViewState viewState = mViewStates.get(id);

        if (viewState == null) {
@@ -996,13 +1043,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                }
                break;
            case ACTION_VIEW_ENTERED:
                if (shouldStartNewPartitionLocked(id)) {
                    if (sDebug) {
                        Slog.d(TAG, "Starting partition for view id " + viewState.id);
                    }
                    viewState.setState(ViewState.STATE_STARTED_PARTITION);
                    requestNewFillResponseLocked(flags);
                }
                requestNewFillResponseIfNecessaryLocked(id, viewState, flags);

                // Remove the UI if the ViewState has changed.
                if (mCurrentViewId != viewState.id) {
+11 −9
Original line number Diff line number Diff line
@@ -47,23 +47,25 @@ final class ViewState {
    private static final String TAG = "ViewState";

    // NOTE: state constants must be public because of flagstoString().
    public static final int STATE_UNKNOWN = 0x00;
    public static final int STATE_UNKNOWN = 0x000;
    /** Initial state. */
    public static final int STATE_INITIAL = 0x01;
    public static final int STATE_INITIAL = 0x001;
    /** View id is present in a dataset returned by the service. */
    public static final int STATE_FILLABLE = 0x02;
    public static final int STATE_FILLABLE = 0x002;
    /** View was autofilled after user selected a dataset. */
    public static final int STATE_AUTOFILLED = 0x04;
    public static final int STATE_AUTOFILLED = 0x004;
    /** View value was changed, but not by the service. */
    public static final int STATE_CHANGED = 0x08;
    public static final int STATE_CHANGED = 0x008;
    /** Set only in the View that started a session. */
    public static final int STATE_STARTED_SESSION = 0x10;
    public static final int STATE_STARTED_SESSION = 0x010;
    /** View that started a new partition when focused on. */
    public static final int STATE_STARTED_PARTITION = 0x20;
    public static final int STATE_STARTED_PARTITION = 0x020;
    /** User select a dataset in this view, but service must authenticate first. */
    public static final int STATE_WAITING_DATASET_AUTH = 0x40;
    public static final int STATE_WAITING_DATASET_AUTH = 0x040;
    /** Service does not care about this view. */
    public static final int STATE_IGNORED = 0x80;
    public static final int STATE_IGNORED = 0x080;
    /** User manually request autofill in this view, after it was already autofilled. */
    public static final int STATE_RESTARTED_SESSION = 0x100;

    public final AutofillId id;