Always start a manual request, even if view was already autofilled.
Fixes: 36034784 Test: CtsAutoFillServiceTestCases pass Test: testAutofillManuallyAgainAfterAutomaticallyAutofilledBefore() Test: testAutofillManuallyAgainAfterManuallyAutofilledBefore() Change-Id: Ided8c42367b71766772bd364445510848db2adce
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user