summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/assist/AssistStructure.java36
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java43
-rw-r--r--services/autofill/java/com/android/server/autofill/ViewState.java15
3 files changed, 79 insertions, 15 deletions
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index fe51633b50eb..545aef5224b7 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -599,6 +599,10 @@ public class AssistStructure implements Parcelable {
boolean mSanitized;
HtmlInfo mHtmlInfo;
+ // POJO used to override some autofill-related values when the node is parcelized.
+ // Not written to parcel.
+ AutofillOverlay mAutofillOverlay;
+
int mX;
int mY;
int mScrollX;
@@ -756,6 +760,7 @@ public class AssistStructure implements Parcelable {
boolean writeSensitive = true;
int flags = mFlags & ~FLAGS_ALL_CONTROL;
+
if (mId != View.NO_ID) {
flags |= FLAGS_HAS_ID;
}
@@ -810,6 +815,13 @@ public class AssistStructure implements Parcelable {
// Remove 'checked' from sanitized autofill request.
writtenFlags = flags & ~FLAGS_CHECKED;
}
+ if (mAutofillOverlay != null) {
+ if (mAutofillOverlay.focused) {
+ writtenFlags |= ViewNode.FLAGS_FOCUSED;
+ } else {
+ writtenFlags &= ~ViewNode.FLAGS_FOCUSED;
+ }
+ }
out.writeInt(writtenFlags);
if ((flags&FLAGS_HAS_ID) != 0) {
@@ -829,7 +841,14 @@ public class AssistStructure implements Parcelable {
out.writeParcelable(mAutofillId, 0);
out.writeInt(mAutofillType);
out.writeStringArray(mAutofillHints);
- final AutofillValue sanitizedValue = writeSensitive ? mAutofillValue : null;
+ final AutofillValue sanitizedValue;
+ if (mAutofillOverlay != null && mAutofillOverlay.value != null) {
+ sanitizedValue = mAutofillOverlay.value;
+ } else if (writeSensitive) {
+ sanitizedValue = mAutofillValue;
+ } else {
+ sanitizedValue = null;
+ }
out.writeParcelable(sanitizedValue, 0);
out.writeStringArray(mAutofillOptions);
if (mHtmlInfo instanceof Parcelable) {
@@ -959,6 +978,11 @@ public class AssistStructure implements Parcelable {
return mAutofillValue;
}
+ /** @hide **/
+ public void setAutofillOverlay(AutofillOverlay overlay) {
+ mAutofillOverlay = overlay;
+ }
+
/**
* Gets the options that can be used to autofill this structure.
*
@@ -1340,6 +1364,16 @@ public class AssistStructure implements Parcelable {
}
}
+ /**
+ * POJO used to override some autofill-related values when the node is parcelized.
+ *
+ * @hide
+ */
+ static public class AutofillOverlay {
+ public boolean focused;
+ public AutofillValue value;
+ }
+
static class ViewNodeBuilder extends ViewStructure {
final AssistStructure mAssist;
final ViewNode mNode;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 801769cc42e1..1ffc82fb438f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -29,6 +29,7 @@ import static com.android.server.autofill.Helper.VERBOSE;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.AutofillOverlay;
import android.app.assist.AssistStructure.ViewNode;
import android.app.assist.AssistStructure.WindowNode;
import android.content.ComponentName;
@@ -100,7 +101,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@NonNull private final String mPackageName;
@GuardedBy("mLock")
- private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>();
+ private final ArrayMap<AutofillId, ViewState> mViewStates = new ArrayMap<>();
/**
* Id of the View currently being displayed.
@@ -517,10 +518,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (DEBUG) {
Slog.d(TAG, "Creating viewState for " + id + " on " + getFlagAsString(flags));
}
- viewState = new ViewState(this, id, this, ViewState.STATE_INITIAL);
+ viewState = new ViewState(this, id, value, this, ViewState.STATE_INITIAL);
mViewStates.put(id, viewState);
} else if ((flags & FLAG_VIEW_ENTERED) != 0) {
- viewState = startPartitionLocked(id);
+ viewState = startPartitionLocked(id, value);
} else {
if (VERBOSE) Slog.v(TAG, "Ignored " + getFlagAsString(flags) + " for " + id);
return;
@@ -584,25 +585,45 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
Slog.w(TAG, "updateLocked(): unknown flags " + flags + ": " + getFlagAsString(flags));
}
- private ViewState startPartitionLocked(AutofillId id) {
+ private ViewState startPartitionLocked(AutofillId id, AutofillValue value) {
if (DEBUG) {
Slog.d(TAG, "Starting partition for view id " + id);
}
- final ViewState viewState =
- new ViewState(this, id, this,ViewState.STATE_STARTED_PARTITION);
- mViewStates.put(id, viewState);
+ final ViewState newViewState =
+ new ViewState(this, id, value, this,ViewState.STATE_STARTED_PARTITION);
+ mViewStates.put(id, newViewState);
/*
* TODO(b/33197203 , b/35707731): when start a new partition, it should
*
- * - add autofilled fields as sanitized
- * - set focus on ViewStructure that triggered it
* - pass the first onFillRequest() bundle
* - optional: perhaps add a new flag onFilLRequest() to indicate it's a new partition?
*/
+
+ // Must update value of nodes so:
+ // - proper node is focused
+ // - autofillValue is sent back to service when it was previously autofilled
+ for (int i = 0; i < mViewStates.size(); i++) {
+ final ViewState viewState = mViewStates.valueAt(i);
+
+ final ViewNode node = findViewNodeByIdLocked(viewState.id);
+ if (node == null) {
+ Slog.w(TAG, "startPartitionLocked(): no node for " + viewState.id);
+ continue;
+ }
+
+ final AutofillValue initialValue = viewState.getInitialValue();
+ final AutofillValue filledValue = viewState.getAutofilledValue();
+ final AutofillOverlay overlay = new AutofillOverlay();
+ if (filledValue != null && !filledValue.equals(initialValue)) {
+ overlay.value = filledValue;
+ }
+ overlay.focused = id.equals(viewState.id);
+ node.setAutofillOverlay(overlay);
+ }
mRemoteFillService.onFillRequest(mStructure, null, 0);
- return viewState;
+ return newViewState;
}
@Override
@@ -695,7 +716,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (viewState != null) {
viewState.setState(state);
} else {
- viewState = new ViewState(this, id, this, state);
+ viewState = new ViewState(this, id, null, this, state);
if (DEBUG) { // TODO(b/33197203): change to VERBOSE once stable
Slog.d(TAG, "Adding autofillable view with id " + id + " and state " + state);
}
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 549f231367c6..f8919eeb060b 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -67,15 +67,17 @@ final class ViewState {
private final Session mSession;
private FillResponse mResponse;
+ private AutofillValue mInitialValue;
private AutofillValue mCurrentValue;
private AutofillValue mAutofilledValue;
private Rect mVirtualBounds;
private int mState;
- ViewState(Session session, AutofillId id, Listener listener, int state) {
+ ViewState(Session session, AutofillId id, AutofillValue value, Listener listener, int state) {
mSession = session;
this.id = id;
+ mInitialValue = value;
mListener = listener;
mState = state;
}
@@ -110,6 +112,11 @@ final class ViewState {
}
@Nullable
+ AutofillValue getInitialValue() {
+ return mInitialValue;
+ }
+
+ @Nullable
FillResponse getResponse() {
return mResponse;
}
@@ -184,14 +191,16 @@ final class ViewState {
@Override
public String toString() {
- return "ViewState: [id=" + id + ", currentValue=" + mCurrentValue
- + ", bounds=" + mVirtualBounds + ", state=" + getStateAsString() +"]";
+ return "ViewState: [id=" + id + ", initialValue=" + mInitialValue
+ + ", currentValue=" + mCurrentValue + ", autofilledValue=" + mAutofilledValue
+ + ", bounds=" + mVirtualBounds + ", state=" + getStateAsString() + "]";
}
void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("id:" ); pw.println(this.id);
pw.print(prefix); pw.print("state:" ); pw.println(getStateAsString());
pw.print(prefix); pw.print("has response:" ); pw.println(mResponse != null);
+ pw.print(prefix); pw.print("initialValue:" ); pw.println(mInitialValue);
pw.print(prefix); pw.print("currentValue:" ); pw.println(mCurrentValue);
pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue);
pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds);