summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/autofill/AutofillManager.java207
-rw-r--r--core/java/android/view/autofill/IAutoFillManagerClient.aidl11
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java13
3 files changed, 126 insertions, 105 deletions
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 41c209cc016a..570f968587b1 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -760,8 +760,8 @@ public final class AutofillManager {
}
}
- private void requestShowFillUi(IBinder windowToken, AutofillId id, int width, int height,
- Rect anchorBounds, IAutofillWindowPresenter presenter) {
+ private void requestShowFillUi(int sessionId, IBinder windowToken, AutofillId id, int width,
+ int height, Rect anchorBounds, IAutofillWindowPresenter presenter) {
final View anchor = findAchorView(windowToken, id);
if (anchor == null) {
return;
@@ -769,9 +769,15 @@ public final class AutofillManager {
AutofillCallback callback = null;
synchronized (mLock) {
- if (getClientLocked().autofillCallbackRequestShowFillUi(anchor, width, height,
- anchorBounds, presenter) && mCallback != null) {
- callback = mCallback;
+ if (mSessionId == sessionId) {
+ AutofillClient client = getClientLocked();
+
+ if (client != null) {
+ if (client.autofillCallbackRequestShowFillUi(anchor, width, height,
+ anchorBounds, presenter) && mCallback != null) {
+ callback = mCallback;
+ }
+ }
}
}
@@ -785,6 +791,23 @@ public final class AutofillManager {
}
}
+ private void authenticate(int sessionId, IntentSender intent, Intent fillInIntent) {
+ synchronized (mLock) {
+ if (sessionId == mSessionId) {
+ AutofillClient client = getClientLocked();
+ if (client != null) {
+ client.autofillCallbackAuthenticate(intent, fillInIntent);
+ }
+ }
+ }
+ }
+
+ private void setState(boolean enabled) {
+ synchronized (mLock) {
+ mEnabled = enabled;
+ }
+ }
+
/**
* Sets a view as autofilled if the current value is the {code targetValue}.
*
@@ -804,80 +827,92 @@ public final class AutofillManager {
}
}
- private void handleAutofill(IBinder windowToken, List<AutofillId> ids,
+ private void autofill(int sessionId, IBinder windowToken, List<AutofillId> ids,
List<AutofillValue> values) {
- final View root = WindowManagerGlobal.getInstance().getWindowView(windowToken);
- if (root == null) {
- return;
- }
-
- final int itemCount = ids.size();
- int numApplied = 0;
- ArrayMap<View, SparseArray<AutofillValue>> virtualValues = null;
+ synchronized (mLock) {
+ if (sessionId != mSessionId) {
+ return;
+ }
- for (int i = 0; i < itemCount; i++) {
- final AutofillId id = ids.get(i);
- final AutofillValue value = values.get(i);
- final int viewId = id.getViewId();
- final View view = root.findViewByAccessibilityIdTraversal(viewId);
- if (view == null) {
- Log.w(TAG, "autofill(): no View with id " + viewId);
- continue;
+ final View root = WindowManagerGlobal.getInstance().getWindowView(windowToken);
+ if (root == null) {
+ return;
}
- if (id.isVirtual()) {
- if (virtualValues == null) {
- // Most likely there will be just one view with virtual children.
- virtualValues = new ArrayMap<>(1);
- }
- SparseArray<AutofillValue> valuesByParent = virtualValues.get(view);
- if (valuesByParent == null) {
- // We don't know the size yet, but usually it will be just a few fields...
- valuesByParent = new SparseArray<>(5);
- virtualValues.put(view, valuesByParent);
+
+ final int itemCount = ids.size();
+ int numApplied = 0;
+ ArrayMap<View, SparseArray<AutofillValue>> virtualValues = null;
+
+ for (int i = 0; i < itemCount; i++) {
+ final AutofillId id = ids.get(i);
+ final AutofillValue value = values.get(i);
+ final int viewId = id.getViewId();
+ final View view = root.findViewByAccessibilityIdTraversal(viewId);
+ if (view == null) {
+ Log.w(TAG, "autofill(): no View with id " + viewId);
+ continue;
}
- valuesByParent.put(id.getVirtualChildId(), value);
- } else {
- synchronized (mLock) {
+ if (id.isVirtual()) {
+ if (virtualValues == null) {
+ // Most likely there will be just one view with virtual children.
+ virtualValues = new ArrayMap<>(1);
+ }
+ SparseArray<AutofillValue> valuesByParent = virtualValues.get(view);
+ if (valuesByParent == null) {
+ // We don't know the size yet, but usually it will be just a few fields...
+ valuesByParent = new SparseArray<>(5);
+ virtualValues.put(view, valuesByParent);
+ }
+ valuesByParent.put(id.getVirtualChildId(), value);
+ } else {
// Mark the view as to be autofilled with 'value'
if (mLastAutofilledData == null) {
mLastAutofilledData = new ParcelableMap(itemCount - i);
}
mLastAutofilledData.put(id, value);
- }
- view.autofill(value);
+ view.autofill(value);
- // Set as autofilled if the values match now, e.g. when the value was updated
- // synchronously.
- // If autofill happens async, the view is set to autofilled in notifyValueChanged.
- setAutofilledIfValuesIs(view, value);
+ // Set as autofilled if the values match now, e.g. when the value was updated
+ // synchronously.
+ // If autofill happens async, the view is set to autofilled in
+ // notifyValueChanged.
+ setAutofilledIfValuesIs(view, value);
- numApplied++;
+ numApplied++;
+ }
}
- }
- if (virtualValues != null) {
- for (int i = 0; i < virtualValues.size(); i++) {
- final View parent = virtualValues.keyAt(i);
- final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
- parent.autofill(childrenValues);
- numApplied += childrenValues.size();
+ if (virtualValues != null) {
+ for (int i = 0; i < virtualValues.size(); i++) {
+ final View parent = virtualValues.keyAt(i);
+ final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
+ parent.autofill(childrenValues);
+ numApplied += childrenValues.size();
+ }
}
- }
- final LogMaker log = new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_DATASET_APPLIED);
- log.addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, itemCount);
- log.addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED, numApplied);
- mMetricsLogger.write(log);
+ final LogMaker log = new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_DATASET_APPLIED);
+ log.addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, itemCount);
+ log.addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED,
+ numApplied);
+ mMetricsLogger.write(log);
+ }
}
- private void requestHideFillUi(IBinder windowToken, AutofillId id) {
+ private void requestHideFillUi(int sessionId, IBinder windowToken, AutofillId id) {
final View anchor = findAchorView(windowToken, id);
AutofillCallback callback = null;
synchronized (mLock) {
- if (getClientLocked().autofillCallbackRequestHideFillUi() && mCallback != null) {
- callback = mCallback;
+ if (mSessionId == sessionId) {
+ AutofillClient client = getClientLocked();
+
+ if (client != null) {
+ if (client.autofillCallbackRequestHideFillUi() && mCallback != null) {
+ callback = mCallback;
+ }
+ }
}
}
@@ -891,12 +926,14 @@ public final class AutofillManager {
}
}
- private void notifyNoFillUi(IBinder windowToken, AutofillId id) {
+ private void notifyNoFillUi(int sessionId, IBinder windowToken, AutofillId id) {
final View anchor = findAchorView(windowToken, id);
- AutofillCallback callback;
+ AutofillCallback callback = null;
synchronized (mLock) {
- callback = mCallback;
+ if (mSessionId == sessionId && getClientLocked() != null) {
+ callback = mCallback;
+ }
}
if (callback != null) {
@@ -999,73 +1036,57 @@ public final class AutofillManager {
public void setState(boolean enabled) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> {
- synchronized (afm.mLock) {
- afm.mEnabled = enabled;
- }
- });
+ afm.mContext.getMainThreadHandler().post(() -> afm.setState(enabled));
}
}
@Override
- public void autofill(IBinder windowToken, List<AutofillId> ids,
+ public void autofill(int sessionId, IBinder windowToken, List<AutofillId> ids,
List<AutofillValue> values) {
// TODO(b/33197203): must keep the dataset so subsequent calls pass the same
// dataset.extras to service
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() ->
- afm.handleAutofill(windowToken, ids, values));
+ afm.mContext.getMainThreadHandler().post(
+ () -> afm.autofill(sessionId, windowToken, ids, values));
}
}
@Override
- public void authenticate(IntentSender intent, Intent fillInIntent) {
+ public void authenticate(int sessionId, IntentSender intent, Intent fillInIntent) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClientLocked() != null) {
- afm.getClientLocked().autofillCallbackAuthenticate(intent, fillInIntent);
- }
- });
+ afm.mContext.getMainThreadHandler().post(
+ () -> afm.authenticate(sessionId, intent, fillInIntent));
}
}
@Override
- public void requestShowFillUi(IBinder windowToken, AutofillId id,
+ public void requestShowFillUi(int sessionId, IBinder windowToken, AutofillId id,
int width, int height, Rect anchorBounds, IAutofillWindowPresenter presenter) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClientLocked() != null) {
- afm.requestShowFillUi(windowToken, id, width,
- height, anchorBounds, presenter);
- }
- });
+ afm.mContext.getMainThreadHandler().post(
+ () -> afm.requestShowFillUi(sessionId, windowToken, id, width, height,
+ anchorBounds, presenter));
}
}
@Override
- public void requestHideFillUi(IBinder windowToken, AutofillId id) {
+ public void requestHideFillUi(int sessionId, IBinder windowToken, AutofillId id) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClientLocked() != null) {
- afm.requestHideFillUi(windowToken, id);
- }
- });
+ afm.mContext.getMainThreadHandler().post(
+ () -> afm.requestHideFillUi(sessionId, windowToken, id));
}
}
@Override
- public void notifyNoFillUi(IBinder windowToken, AutofillId id) {
+ public void notifyNoFillUi(int sessionId, IBinder windowToken, AutofillId id) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClientLocked() != null) {
- afm.notifyNoFillUi(windowToken, id);
- }
- });
+ afm.mContext.getMainThreadHandler().post(
+ () -> afm.notifyNoFillUi(sessionId, windowToken, id));
}
}
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 176eaacb57ae..56f91ed6de9b 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -40,28 +40,29 @@ oneway interface IAutoFillManagerClient {
/**
* Autofills the activity with the contents of a dataset.
*/
- void autofill(in IBinder windowToken, in List<AutofillId> ids, in List<AutofillValue> values);
+ void autofill(int sessionId, in IBinder windowToken, in List<AutofillId> ids,
+ in List<AutofillValue> values);
/**
* Authenticates a fill response or a data set.
*/
- void authenticate(in IntentSender intent, in Intent fillInIntent);
+ void authenticate(int sessionId, in IntentSender intent, in Intent fillInIntent);
/**
* Requests showing the fill UI.
*/
- void requestShowFillUi(in IBinder windowToken, in AutofillId id, int width,
+ void requestShowFillUi(int sessionId, in IBinder windowToken, in AutofillId id, int width,
int height, in Rect anchorBounds, in IAutofillWindowPresenter presenter);
/**
* Requests hiding the fill UI.
*/
- void requestHideFillUi(in IBinder windowToken, in AutofillId id);
+ void requestHideFillUi(int sessionId, in IBinder windowToken, in AutofillId id);
/**
* Notifies no fill UI will be shown.
*/
- void notifyNoFillUi(in IBinder windowToken, in AutofillId id);
+ void notifyNoFillUi(int sessionId, in IBinder windowToken, in AutofillId id);
/**
* Starts the provided intent sender
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 0b1381ebec89..1a311614214e 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -343,9 +343,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (id.equals(mCurrentViewId)) {
try {
final ViewState view = mViewStates.get(id);
- mClient.requestShowFillUi(mWindowToken, id, width, height,
- view.getVirtualBounds(),
- presenter);
+ mClient.requestShowFillUi(this.id, mWindowToken, id, width, height,
+ view.getVirtualBounds(), presenter);
} catch (RemoteException e) {
Slog.e(TAG, "Error requesting to show fill UI", e);
}
@@ -363,7 +362,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
public void requestHideFillUi(AutofillId id) {
synchronized (mLock) {
try {
- mClient.requestHideFillUi(mWindowToken, id);
+ mClient.requestHideFillUi(this.id, mWindowToken, id);
} catch (RemoteException e) {
Slog.e(TAG, "Error requesting to hide fill UI", e);
}
@@ -716,7 +715,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
if (!mHasCallback) return;
try {
- mClient.notifyNoFillUi(mWindowToken, mCurrentViewId);
+ mClient.notifyNoFillUi(id, mWindowToken, mCurrentViewId);
} catch (RemoteException e) {
Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
+ " id=" + mCurrentViewId, e);
@@ -852,7 +851,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private void startAuthentication(IntentSender intent, Intent fillInIntent) {
try {
synchronized (mLock) {
- mClient.authenticate(intent, fillInIntent);
+ mClient.authenticate(id, intent, fillInIntent);
}
} catch (RemoteException e) {
Slog.e(TAG, "Error launching auth intent", e);
@@ -895,7 +894,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (DEBUG) {
Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
}
- mClient.autofill(mWindowToken, dataset.getFieldIds(), dataset.getFieldValues());
+ mClient.autofill(id, mWindowToken, dataset.getFieldIds(), dataset.getFieldValues());
setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED);
} catch (RemoteException e) {
Slog.w(TAG, "Error autofilling activity: " + e);