Loading core/java/android/service/autofill/FillRequest.java +10 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,14 @@ public final class FillRequest implements Parcelable { */ public static final int FLAG_COMPATIBILITY_MODE_REQUEST = 0x2; // Private flags below start from the highest-significative bit (0x80000000) /** * Request was only triggered for augmented autofill. * * @hide */ public static final int FLAG_AUGMENTED_AUTOFILL_REQUEST = 0x80000000; /** @hide */ public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE; Loading Loading @@ -115,7 +123,8 @@ public final class FillRequest implements Parcelable { /** * Gets the flags associated with this request. * * @see #FLAG_MANUAL_REQUEST * @return any combination of {@link #FLAG_MANUAL_REQUEST} and * {@link #FLAG_COMPATIBILITY_MODE_REQUEST}. */ public @RequestFlags int getFlags() { return mFlags; Loading core/java/android/view/View.java +17 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.annotation.StyleRes; import android.annotation.TestApi; import android.annotation.UiThread; import android.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.ClipData; import android.content.Context; import android.content.ContextWrapper; Loading Loading @@ -9524,8 +9525,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private boolean isAutofillable() { return getAutofillType() != AUTOFILL_TYPE_NONE && isImportantForAutofill() && getAutofillViewId() > LAST_APP_AUTOFILL_ID; if (getAutofillType() == AUTOFILL_TYPE_NONE) return false; if (!isImportantForAutofill()) { // View is not important for "regular" autofill, so we must check if Augmented Autofill // is enabled for the activity final AutofillOptions options = mContext.getAutofillOptions(); if (options == null || !options.augmentedEnabled) { // TODO(b/123100824): should also check if activity is whitelisted return false; } final AutofillManager afm = getAutofillManager(); if (afm == null) return false; afm.notifyViewEnteredForAugmentedAutofill(this); } return getAutofillViewId() > LAST_APP_AUTOFILL_ID; } /** @hide */ core/java/android/view/autofill/AutofillManager.java +36 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view.autofill; import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; Loading Loading @@ -467,6 +468,13 @@ public final class AutofillManager { @GuardedBy("mLock") @Nullable private ArraySet<AutofillId> mEnteredIds; /** * Views that were otherwised not important for autofill but triggered a session because the * context is whitelisted for augmented autofill. */ @GuardedBy("mLock") @Nullable private Set<AutofillId> mEnteredForAugmentedAutofillIds; /** If set, session is commited when the field is clicked. */ @GuardedBy("mLock") @Nullable private AutofillId mSaveTriggerId; Loading Loading @@ -1626,6 +1634,11 @@ public final class AutofillManager { @GuardedBy("mLock") private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds, @NonNull AutofillValue value, int flags) { if (mEnteredForAugmentedAutofillIds != null && mEnteredForAugmentedAutofillIds.contains(id)) { if (sVerbose) Log.v(TAG, "Starting session for augmented autofill on " + id); flags |= FLAG_AUGMENTED_AUTOFILL_REQUEST; } if (sVerbose) { Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value + ", flags=" + flags + ", state=" + getStateAsStringLocked() Loading Loading @@ -1861,6 +1874,25 @@ public final class AutofillManager { return set == null ? null : new ArrayList<T>(set); } /** * Notifies that a non-autofillable view was entered because the activity is whitelisted for * augmented autofill. * * <p>This method is necessary to set the right flag on start, so the server-side session * doesn't trigger the standard autofill workflow, but the augmented's instead. * * @hide */ public void notifyViewEnteredForAugmentedAutofill(@NonNull View view) { final AutofillId id = view.getAutofillId(); synchronized (mLock) { if (mEnteredForAugmentedAutofillIds == null) { mEnteredForAugmentedAutofillIds = new ArraySet<>(1); } mEnteredForAugmentedAutofillIds.add(id); } } private void requestShowFillUi(int sessionId, AutofillId id, int width, int height, Rect anchorBounds, IAutofillWindowPresenter presenter) { final View anchor = findView(id); Loading Loading @@ -2360,6 +2392,10 @@ public final class AutofillManager { } pw.print(pfx); pw.print("fillable ids: "); pw.println(mFillableIds); pw.print(pfx); pw.print("entered ids: "); pw.println(mEnteredIds); if (mEnteredForAugmentedAutofillIds != null) { pw.print(pfx); pw.print("entered ids for augmented autofill: "); pw.println(mEnteredForAugmentedAutofillIds); } pw.print(pfx); pw.print("save trigger id: "); pw.println(mSaveTriggerId); pw.print(pfx); pw.print("save on finish(): "); pw.println(mSaveOnFinish); if (mOptions != null) { Loading services/autofill/java/com/android/server/autofill/Session.java +11 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.autofill; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.INVALID_REQUEST_ID; import static android.view.autofill.AutofillManager.ACTION_START_SESSION; Loading Loading @@ -527,6 +528,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState */ @GuardedBy("mLock") private void requestNewFillResponseLocked(int flags) { if ((flags & FLAG_AUGMENTED_AUTOFILL_REQUEST) != 0) { // TODO(b/122858578): log metrics if (sVerbose) { Slog.v(TAG, "requestNewFillResponse(): triggering augmented autofill instead"); } triggerAugmentedAutofillLocked(); return; } int requestId; do { Loading Loading
core/java/android/service/autofill/FillRequest.java +10 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,14 @@ public final class FillRequest implements Parcelable { */ public static final int FLAG_COMPATIBILITY_MODE_REQUEST = 0x2; // Private flags below start from the highest-significative bit (0x80000000) /** * Request was only triggered for augmented autofill. * * @hide */ public static final int FLAG_AUGMENTED_AUTOFILL_REQUEST = 0x80000000; /** @hide */ public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE; Loading Loading @@ -115,7 +123,8 @@ public final class FillRequest implements Parcelable { /** * Gets the flags associated with this request. * * @see #FLAG_MANUAL_REQUEST * @return any combination of {@link #FLAG_MANUAL_REQUEST} and * {@link #FLAG_COMPATIBILITY_MODE_REQUEST}. */ public @RequestFlags int getFlags() { return mFlags; Loading
core/java/android/view/View.java +17 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.annotation.StyleRes; import android.annotation.TestApi; import android.annotation.UiThread; import android.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.ClipData; import android.content.Context; import android.content.ContextWrapper; Loading Loading @@ -9524,8 +9525,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private boolean isAutofillable() { return getAutofillType() != AUTOFILL_TYPE_NONE && isImportantForAutofill() && getAutofillViewId() > LAST_APP_AUTOFILL_ID; if (getAutofillType() == AUTOFILL_TYPE_NONE) return false; if (!isImportantForAutofill()) { // View is not important for "regular" autofill, so we must check if Augmented Autofill // is enabled for the activity final AutofillOptions options = mContext.getAutofillOptions(); if (options == null || !options.augmentedEnabled) { // TODO(b/123100824): should also check if activity is whitelisted return false; } final AutofillManager afm = getAutofillManager(); if (afm == null) return false; afm.notifyViewEnteredForAugmentedAutofill(this); } return getAutofillViewId() > LAST_APP_AUTOFILL_ID; } /** @hide */
core/java/android/view/autofill/AutofillManager.java +36 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view.autofill; import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; Loading Loading @@ -467,6 +468,13 @@ public final class AutofillManager { @GuardedBy("mLock") @Nullable private ArraySet<AutofillId> mEnteredIds; /** * Views that were otherwised not important for autofill but triggered a session because the * context is whitelisted for augmented autofill. */ @GuardedBy("mLock") @Nullable private Set<AutofillId> mEnteredForAugmentedAutofillIds; /** If set, session is commited when the field is clicked. */ @GuardedBy("mLock") @Nullable private AutofillId mSaveTriggerId; Loading Loading @@ -1626,6 +1634,11 @@ public final class AutofillManager { @GuardedBy("mLock") private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds, @NonNull AutofillValue value, int flags) { if (mEnteredForAugmentedAutofillIds != null && mEnteredForAugmentedAutofillIds.contains(id)) { if (sVerbose) Log.v(TAG, "Starting session for augmented autofill on " + id); flags |= FLAG_AUGMENTED_AUTOFILL_REQUEST; } if (sVerbose) { Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value + ", flags=" + flags + ", state=" + getStateAsStringLocked() Loading Loading @@ -1861,6 +1874,25 @@ public final class AutofillManager { return set == null ? null : new ArrayList<T>(set); } /** * Notifies that a non-autofillable view was entered because the activity is whitelisted for * augmented autofill. * * <p>This method is necessary to set the right flag on start, so the server-side session * doesn't trigger the standard autofill workflow, but the augmented's instead. * * @hide */ public void notifyViewEnteredForAugmentedAutofill(@NonNull View view) { final AutofillId id = view.getAutofillId(); synchronized (mLock) { if (mEnteredForAugmentedAutofillIds == null) { mEnteredForAugmentedAutofillIds = new ArraySet<>(1); } mEnteredForAugmentedAutofillIds.add(id); } } private void requestShowFillUi(int sessionId, AutofillId id, int width, int height, Rect anchorBounds, IAutofillWindowPresenter presenter) { final View anchor = findView(id); Loading Loading @@ -2360,6 +2392,10 @@ public final class AutofillManager { } pw.print(pfx); pw.print("fillable ids: "); pw.println(mFillableIds); pw.print(pfx); pw.print("entered ids: "); pw.println(mEnteredIds); if (mEnteredForAugmentedAutofillIds != null) { pw.print(pfx); pw.print("entered ids for augmented autofill: "); pw.println(mEnteredForAugmentedAutofillIds); } pw.print(pfx); pw.print("save trigger id: "); pw.println(mSaveTriggerId); pw.print(pfx); pw.print("save on finish(): "); pw.println(mSaveOnFinish); if (mOptions != null) { Loading
services/autofill/java/com/android/server/autofill/Session.java +11 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.autofill; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.INVALID_REQUEST_ID; import static android.view.autofill.AutofillManager.ACTION_START_SESSION; Loading Loading @@ -527,6 +528,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState */ @GuardedBy("mLock") private void requestNewFillResponseLocked(int flags) { if ((flags & FLAG_AUGMENTED_AUTOFILL_REQUEST) != 0) { // TODO(b/122858578): log metrics if (sVerbose) { Slog.v(TAG, "requestNewFillResponse(): triggering augmented autofill instead"); } triggerAugmentedAutofillLocked(); return; } int requestId; do { Loading