summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Philip P. Moltmann <moltmann@google.com> 2017-04-21 16:33:52 -0700
committer Philip P. Moltmann <moltmann@google.com> 2017-04-24 16:50:14 -0700
commit2f517c26d23393d4f0d6b3352de6e4c92c9e107e (patch)
tree3d01fabb58b96e99eb53cda7a2a29bef8ca54fa2
parent85d1c2d2905362b984563d9b5e8332010c272fc5 (diff)
Take new autofill structure for each partition
Bug: 36481649 Test: CtsAutofillServiceTestCases (now with a test that has an autofill session over two full screen fragments) Change-Id: I55f2f6203f3bd5a7082b4ce90500d2c16a260c7d
-rw-r--r--core/java/android/service/autofill/AutofillService.java4
-rw-r--r--core/java/android/service/autofill/FillRequest.java11
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java73
-rw-r--r--services/autofill/java/com/android/server/autofill/Helper.java38
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteFillService.java17
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java305
6 files changed, 250 insertions, 198 deletions
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 503617803cf0..05404598e6a9 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -66,10 +66,6 @@ public abstract class AutofillService extends Service {
*/
public static final String SERVICE_META_DATA = "android.autofill";
- // Internal extras
- /** @hide */
- public static final String EXTRA_SESSION_ID = "android.service.autofill.extra.SESSION_ID";
-
// Handler messages.
private static final int MSG_CONNECT = 1;
private static final int MSG_DISCONNECT = 2;
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index aa6db4d092f2..49f348c79ef2 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -39,8 +39,6 @@ import java.util.concurrent.atomic.AtomicInteger;
* @see AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)
*/
public final class FillRequest implements Parcelable {
- private static AtomicInteger sIdCounter = new AtomicInteger();
-
/**
* Indicates autofill was explicitly requested by the user.
*/
@@ -58,12 +56,6 @@ public final class FillRequest implements Parcelable {
private final @NonNull AssistStructure mStructure;
private final @Nullable Bundle mClientState;
- /** @hide */
- public FillRequest(@NonNull AssistStructure structure,
- @Nullable Bundle clientState, @RequestFlags int flags) {
- this(sIdCounter.incrementAndGet(), structure, clientState, flags);
- }
-
private FillRequest(@NonNull Parcel parcel) {
mId = parcel.readInt();
mStructure = parcel.readParcelable(null);
@@ -71,7 +63,8 @@ public final class FillRequest implements Parcelable {
mFlags = parcel.readInt();
}
- private FillRequest(int id, @NonNull AssistStructure structure,
+ /** @hide */
+ public FillRequest(int id, @NonNull AssistStructure structure,
@Nullable Bundle clientState, @RequestFlags int flags) {
mId = id;
mFlags = Preconditions.checkFlagsArgument(flags, FLAG_MANUAL_REQUEST);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index c2799304bf7a..d7a6b06b5844 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -16,9 +16,6 @@
package com.android.server.autofill;
-import static android.service.autofill.AutofillService.EXTRA_SESSION_ID;
-import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
-import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
import static android.view.autofill.AutofillManager.NO_SESSION;
@@ -27,10 +24,7 @@ import static com.android.server.autofill.Helper.VERBOSE;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.ActivityManager;
import android.app.AppGlobals;
-import android.app.assist.AssistStructure;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -50,7 +44,6 @@ import android.service.autofill.AutofillService;
import android.service.autofill.AutofillServiceInfo;
import android.service.autofill.FillEventHistory;
import android.service.autofill.FillEventHistory.Event;
-import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
import android.text.TextUtils;
@@ -66,7 +59,6 @@ import android.view.autofill.IAutoFillManagerClient;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.IResultReceiver;
import com.android.server.autofill.ui.AutoFillUI;
import java.io.PrintWriter;
@@ -127,56 +119,6 @@ final class AutofillManagerServiceImpl {
@GuardedBy("mLock")
private FillEventHistory mEventHistory;
- /**
- * Receiver of assist data from the app's {@link Activity}.
- */
- private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
- @Override
- public void send(int resultCode, Bundle resultData) throws RemoteException {
- if (VERBOSE) {
- Slog.v(TAG, "resultCode on mAssistReceiver: " + resultCode);
- }
-
- final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
- if (structure == null) {
- Slog.wtf(TAG, "no assist structure for id " + resultCode);
- return;
- }
-
- final Bundle receiverExtras = resultData.getBundle(KEY_RECEIVER_EXTRAS);
- if (receiverExtras == null) {
- Slog.wtf(TAG, "No " + KEY_RECEIVER_EXTRAS + " on receiver");
- return;
- }
-
- final int sessionId = receiverExtras.getInt(EXTRA_SESSION_ID);
- final Session session;
- synchronized (mLock) {
- session = mSessions.get(sessionId);
- if (session == null) {
- Slog.w(TAG, "no server session for " + sessionId);
- return;
- }
- session.setStructureLocked(structure);
- }
-
-
- // TODO(b/35708678): Must fetch the data so it's available later on
- // handleSave(), even if if the activity is gone by then, but structure.ensureData()
- // gives a ONE_WAY warning because system_service could block on app calls.
- // We need to change AssistStructure so it provides a "one-way" writeToParcel()
- // method that sends all the data
- structure.ensureData();
-
- // Sanitize structure before it's sent to service.
- structure.sanitizeForParceling(true);
-
- // This is the first request, hence there is no Bundle to be sent as clientState
- final FillRequest request = new FillRequest(structure, null, session.mFlags);
- session.mRemoteFillService.onFillRequest(request);
- }
- };
-
AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
int userId, AutoFillUI ui, boolean disabled) {
mContext = context;
@@ -393,21 +335,6 @@ final class AutofillManagerServiceImpl {
mInfo.getServiceInfo().getComponentName(), packageName);
mSessions.put(newSession.id, newSession);
- try {
- final Bundle receiverExtras = new Bundle();
- receiverExtras.putInt(EXTRA_SESSION_ID, sessionId);
- final long identity = Binder.clearCallingIdentity();
- try {
- if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
- receiverExtras, activityToken)) {
- Slog.w(TAG, "failed to request autofill data for " + activityToken);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- } catch (RemoteException e) {
- // Should not happen, it's a local call.
- }
return newSession;
}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 17c30c561729..5964172e138a 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -16,7 +16,12 @@
package com.android.server.autofill;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
import android.os.Bundle;
+import android.view.autofill.AutofillId;
import java.util.Arrays;
import java.util.Objects;
@@ -53,4 +58,37 @@ final class Helper {
private Helper() {
throw new UnsupportedOperationException("contains static members only");
}
+
+ static ViewNode findViewNodeById(@NonNull AssistStructure structure, @NonNull AutofillId id) {
+ final int size = structure.getWindowNodeCount();
+ for (int i = 0; i < size; i++) {
+ final AssistStructure.WindowNode window = structure.getWindowNodeAt(i);
+ final ViewNode root = window.getRootViewNode();
+ if (id.equals(root.getAutofillId())) {
+ return root;
+ }
+ final ViewNode child = findViewNodeById(root, id);
+ if (child != null) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ static ViewNode findViewNodeById(@NonNull ViewNode parent, @NonNull AutofillId id) {
+ final int childrenSize = parent.getChildCount();
+ if (childrenSize > 0) {
+ for (int i = 0; i < childrenSize; i++) {
+ final ViewNode child = parent.getChildAt(i);
+ if (id.equals(child.getAutofillId())) {
+ return child;
+ }
+ final ViewNode grandChild = findViewNodeById(child, id);
+ if (grandChild != null && id.equals(grandChild.getAutofillId())) {
+ return grandChild;
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 4d0f38042276..432a092a9874 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -134,6 +134,23 @@ final class RemoteFillService implements DeathRecipient {
mCallbacks.onServiceDied(this);
}
+ /**
+ * Cancel the currently pending request.
+ *
+ * <p>This can be used when the request is unnecessary or will be superceeded by a request that
+ * will soon be queued.
+ */
+ public void cancelCurrentRequest() {
+ if (mDestroyed) {
+ return;
+ }
+
+ if (mPendingRequest != null) {
+ mPendingRequest.cancel();
+ mPendingRequest = null;
+ }
+ }
+
public void onFillRequest(@NonNull FillRequest request) {
cancelScheduledUnbind();
final PendingFillRequest pendingRequest = new PendingFillRequest(request, this);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 5e8a974614a9..a00a397ece08 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -18,6 +18,8 @@
package com.android.server.autofill;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
+import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
+import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
@@ -25,19 +27,22 @@ import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;
import static com.android.server.autofill.Helper.DEBUG;
import static com.android.server.autofill.Helper.VERBOSE;
+import static com.android.server.autofill.Helper.findViewNodeById;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.ActivityManager;
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;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.Rect;
import android.metrics.LogMaker;
+import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
@@ -64,14 +69,16 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.ArrayUtils;
import com.android.server.autofill.ui.AutoFillUI;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* A session for a given activity.
@@ -89,6 +96,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
AutoFillUI.AutoFillUiCallback {
private static final String TAG = "AutofillSession";
+ private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
+
private final AutofillManagerServiceImpl mService;
private final HandlerCaller mHandlerCaller;
private final Object mLock;
@@ -96,6 +105,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private final MetricsLogger mMetricsLogger = new MetricsLogger();
+ private static AtomicInteger sIdCounter = new AtomicInteger();
+
/** Id of the session */
public final int id;
@@ -123,8 +134,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@GuardedBy("mLock")
private IAutoFillManagerClient mClient;
- @GuardedBy("mLock")
- RemoteFillService mRemoteFillService;
+ private final RemoteFillService mRemoteFillService;
@GuardedBy("mLock")
private SparseArray<FillResponse> mResponses;
@@ -163,7 +173,124 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
/**
* Flags used to start the session.
*/
- int mFlags;
+ private final int mFlags;
+
+ /**
+ * Receiver of assist data from the app's {@link Activity}.
+ */
+ private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
+ @Override
+ public void send(int resultCode, Bundle resultData) throws RemoteException {
+ if (VERBOSE) {
+ Slog.v(TAG, "resultCode on mAssistReceiver: " + resultCode);
+ }
+
+ final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
+ if (structure == null) {
+ Slog.wtf(TAG, "no assist structure for id " + resultCode);
+ return;
+ }
+
+ final Bundle receiverExtras = resultData.getBundle(KEY_RECEIVER_EXTRAS);
+ if (receiverExtras == null) {
+ Slog.wtf(TAG, "No " + KEY_RECEIVER_EXTRAS + " on receiver");
+ return;
+ }
+
+ final int requestId = receiverExtras.getInt(EXTRA_REQUEST_ID);
+
+ if (DEBUG) {
+ Slog.d(TAG, "New structure for requestId " + requestId + ": " + structure);
+ }
+
+ synchronized (mLock) {
+ // TODO(b/35708678): Must fetch the data so it's available later on handleSave(),
+ // even if if the activity is gone by then, but structure .ensureData() gives a
+ // ONE_WAY warning because system_service could block on app calls. We need to
+ // change AssistStructure so it provides a "one-way" writeToParcel() method that
+ // sends all the data
+ structure.ensureData();
+
+ // Sanitize structure before it's sent to service.
+ structure.sanitizeForParceling(true);
+
+ mStructure = structure;
+ }
+
+ fillStructureWithAllowedValues(mStructure);
+
+ FillRequest request = new FillRequest(requestId, mStructure, mClientState, mFlags);
+ mRemoteFillService.onFillRequest(request);
+ }
+ };
+
+ /**
+ * Updates values of the nodes in the structure so that:
+ * - proper node is focused
+ * - autofillValue is sent back to service when it was previously autofilled
+ *
+ * @param structure The structure to be filled
+ */
+ private void fillStructureWithAllowedValues(@NonNull AssistStructure structure) {
+ final int numViewStates = mViewStates.size();
+ for (int i = 0; i < numViewStates; i++) {
+ final ViewState viewState = mViewStates.valueAt(i);
+
+ final ViewNode node = findViewNodeById(structure, viewState.id);
+ if (node == null) {
+ if (DEBUG) {
+ Slog.w(TAG, "fillStructureWithAllowedValues(): 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;
+ }
+ if (mCurrentViewId != null) {
+ overlay.focused = mCurrentViewId.equals(viewState.id);
+ }
+
+ node.setAutofillOverlay(overlay);
+ }
+ }
+
+ /**
+ * Reads a new structure and then request a new fill response from the fill service.
+ */
+ private void requestNewFillResponseLocked() {
+ final int requestId = sIdCounter.getAndIncrement();
+
+ if (DEBUG) {
+ Slog.d(TAG, "Requesting structure for requestId " + requestId);
+ }
+
+ // If the focus changes very quickly before the first request is returned each focus change
+ // triggers a new partition and we end up with many duplicate partitions. This is
+ // enhanced as the focus change can be much faster than the taking of the assist structure.
+ // Hence remove the currently queued request and replace it with the one queued after the
+ // structure is taken. This causes only one fill request per bust of focus changes.
+ mRemoteFillService.cancelCurrentRequest();
+
+ try {
+ final Bundle receiverExtras = new Bundle();
+ receiverExtras.putInt(EXTRA_REQUEST_ID, requestId);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
+ receiverExtras, mActivityToken)) {
+ Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ } catch (RemoteException e) {
+ // Should not happen, it's a local call.
+ }
+ }
Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
@NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
@@ -433,10 +560,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mHasCallback = hasIt;
}
- public void setStructureLocked(AssistStructure structure) {
- mStructure = structure;
- }
-
/**
* Shows the save UI, when session can be saved.
*
@@ -575,7 +698,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
continue;
}
final AutofillId id = entry.getKey();
- final ViewNode node = findViewNodeByIdLocked(id);
+ final ViewNode node = findViewNodeById(mStructure, id);
if (node == null) {
Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
continue;
@@ -606,24 +729,61 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mRemoteFillService.onSaveRequest(saveRequest);
}
+ /**
+ * Determines if a new partition should be started for an id.
+ *
+ * @param id The id of the view that is entered
+ *
+ * @return {@code true} iff a new partition should be started
+ */
+ private boolean shouldStartNewPartitionLocked(@NonNull AutofillId id) {
+ if (mResponses == null) {
+ return true;
+ }
+
+ final int numResponses = mResponses.size();
+ for (int responseNum = 0; responseNum < numResponses; responseNum++) {
+ final FillResponse response = mResponses.valueAt(responseNum);
+
+ if (ArrayUtils.contains(response.getIgnoredIds(), id)) {
+ return false;
+ }
+
+ final SaveInfo saveInfo = response.getSaveInfo();
+ if (saveInfo != null) {
+ if (ArrayUtils.contains(saveInfo.getOptionalIds(), id)
+ || ArrayUtils.contains(saveInfo.getRequiredIds(), id)) {
+ return false;
+ }
+ }
+
+ final ArrayList<Dataset> datasets = response.getDatasets();
+ if (datasets != null) {
+ final int numDatasets = datasets.size();
+
+ for (int dataSetNum = 0; dataSetNum < numDatasets; dataSetNum++) {
+ final ArrayList fields = datasets.get(dataSetNum).getFieldIds();
+
+ if (fields != null && fields.contains(id)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
ViewState viewState = mViewStates.get(id);
if (viewState == null) {
- if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED)) != 0) {
+ if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED | FLAG_VIEW_ENTERED)) != 0) {
if (DEBUG) {
Slog.d(TAG, "Creating viewState for " + id + " on " + getFlagAsString(flags));
}
viewState = new ViewState(this, id, value, this, ViewState.STATE_INITIAL);
mViewStates.put(id, viewState);
- } else if (mStructure != null && (flags & FLAG_VIEW_ENTERED) != 0) {
- if (isIgnoredLocked(id)) {
- if (DEBUG) {
- Slog.d(TAG, "Not starting partition for ignored view id " + id);
- }
- return;
- }
- viewState = startPartitionLocked(id, value);
} else {
if (VERBOSE) Slog.v(TAG, "Ignored " + getFlagAsString(flags) + " for " + id);
return;
@@ -635,6 +795,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mCurrentViewId = viewState.id;
viewState.update(value, virtualBounds);
viewState.setState(ViewState.STATE_STARTED_SESSION);
+ requestNewFillResponseLocked();
return;
}
@@ -664,6 +825,19 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
if ((flags & FLAG_VIEW_ENTERED) != 0) {
+ if (shouldStartNewPartitionLocked(id)) {
+ // TODO(b/37424539): proper implementation
+ if (mResponseWaitingAuth != null && ((flags & FLAG_START_SESSION) == 0)) {
+ viewState.setState(ViewState.STATE_WAITING_RESPONSE_AUTH);
+ } else if ((flags & FLAG_START_SESSION) == 0){
+ if (DEBUG) {
+ Slog.d(TAG, "Starting partition for view id " + viewState.id);
+ }
+ viewState.setState(ViewState.STATE_STARTED_PARTITION);
+ requestNewFillResponseLocked();
+ }
+ }
+
// Remove the UI if the ViewState has changed.
if (mCurrentViewId != viewState.id) {
mUi.hideFillUi(mCurrentViewId != null ? mCurrentViewId : null);
@@ -687,49 +861,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
Slog.w(TAG, "updateLocked(): unknown flags " + flags + ": " + getFlagAsString(flags));
}
- private ViewState startPartitionLocked(AutofillId id, AutofillValue value) {
- // TODO(b/37424539): proper implementation
- if (mResponseWaitingAuth != null) {
- final ViewState viewState =
- new ViewState(this, id, value, this, ViewState.STATE_WAITING_RESPONSE_AUTH);
- mViewStates.put(id, viewState);
- return viewState;
- }
- if (DEBUG) {
- Slog.d(TAG, "Starting partition for view id " + id);
- }
- final ViewState newViewState =
- new ViewState(this, id, value, this,ViewState.STATE_STARTED_PARTITION);
- mViewStates.put(id, newViewState);
-
- // 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);
- }
-
- FillRequest request = new FillRequest(mStructure, mClientState, 0);
- mRemoteFillService.onFillRequest(request);
-
- return newViewState;
- }
-
@Override
public void onFillReady(FillResponse response, AutofillId filledId,
@Nullable AutofillValue value) {
@@ -949,23 +1080,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
}
- private boolean isIgnoredLocked(@NonNull AutofillId id) {
- if (mResponses == null) return false;
-
- for (int i = mResponses.size() - 1; i >= 0; i--) {
- final FillResponse response = mResponses.valueAt(i);
- final AutofillId[] ignoredIds = response.getIgnoredIds();
- if (ignoredIds == null) continue;
- for (int j = 0; j < ignoredIds.length; j++) {
- final AutofillId ignoredId = ignoredIds[j];
- if (ignoredId != null && ignoredId.equals(id)) {
- return true;
- }
- }
- }
- return false;
- }
-
void dumpLocked(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("id: "); pw.println(id);
pw.print(prefix); pw.print("uid: "); pw.println(uid);
@@ -1018,39 +1132,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
}
- private ViewNode findViewNodeByIdLocked(AutofillId id) {
- final int size = mStructure.getWindowNodeCount();
- for (int i = 0; i < size; i++) {
- final WindowNode window = mStructure.getWindowNodeAt(i);
- final ViewNode root = window.getRootViewNode();
- if (id.equals(root.getAutofillId())) {
- return root;
- }
- final ViewNode child = findViewNodeByIdLocked(root, id);
- if (child != null) {
- return child;
- }
- }
- return null;
- }
-
- private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) {
- final int childrenSize = parent.getChildCount();
- if (childrenSize > 0) {
- for (int i = 0; i < childrenSize; i++) {
- final ViewNode child = parent.getChildAt(i);
- if (id.equals(child.getAutofillId())) {
- return child;
- }
- final ViewNode grandChild = findViewNodeByIdLocked(child, id);
- if (grandChild != null && id.equals(grandChild.getAutofillId())) {
- return grandChild;
- }
- }
- }
- return null;
- }
-
void destroyLocked() {
mRemoteFillService.destroy();
mUi.setCallback(null);