diff options
| author | 2022-01-19 00:07:07 +0800 | |
|---|---|---|
| committer | 2022-01-27 14:42:34 -0800 | |
| commit | b482a249351661bcbdebd2fe61d13f35e8c3fe17 (patch) | |
| tree | 150682b7604678de9e6be8ba950f1a44b52dfea1 | |
| parent | 523f1f5f9edc1b1f0826495bec68c1b9f4725bdb (diff) | |
Notify Autofill while activity started
After activity started, if there is any field that is autofillable,
notify autofill to do a fill request to get ids that require a
special prompt UI.
Bug: 210926084
Test: Manual
Change-Id: Ia1058de63affc98065eeeb4808d4c3f8bae22d03
| -rw-r--r-- | core/java/android/service/autofill/FillRequest.java | 29 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 4 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 15 | ||||
| -rw-r--r-- | core/java/android/view/autofill/AutofillManager.java | 83 | 
4 files changed, 122 insertions, 9 deletions
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java index 43bd4102ffb5..f820f0389f0d 100644 --- a/core/java/android/service/autofill/FillRequest.java +++ b/core/java/android/service/autofill/FillRequest.java @@ -98,6 +98,12 @@ public final class FillRequest implements Parcelable {      // The flag value 0x20 has been defined in AutofillManager. +    /** +     * Indicates the request is coming from the activity just started. +     * @hide +     */ +    public static final @RequestFlags int FLAG_ACTIVITY_START = 0x40; +      /** @hide */      public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE; @@ -160,13 +166,13 @@ public final class FillRequest implements Parcelable { -    // Code below generated by codegen v1.0.15. +    // Code below generated by codegen v1.0.23.      //      // DO NOT MODIFY!      // CHECKSTYLE:OFF Generated code      //      // To regenerate run: -    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/autofill/FillRequest.java +    // $ codegen $ANDROID_BUILD_TOP/./frameworks/base/core/java/android/service/autofill/FillRequest.java      //      // To exclude the generated code from IntelliJ auto-formatting enable (one-time):      //   Settings > Editor > Code Style > Formatter Control @@ -178,7 +184,8 @@ public final class FillRequest implements Parcelable {          FLAG_MANUAL_REQUEST,          FLAG_COMPATIBILITY_MODE_REQUEST,          FLAG_PASSWORD_INPUT_TYPE, -        FLAG_VIEW_NOT_FOCUSED +        FLAG_VIEW_NOT_FOCUSED, +        FLAG_ACTIVITY_START      })      @Retention(RetentionPolicy.SOURCE)      @DataClass.Generated.Member @@ -202,6 +209,8 @@ public final class FillRequest implements Parcelable {                      return "FLAG_PASSWORD_INPUT_TYPE";              case FLAG_VIEW_NOT_FOCUSED:                      return "FLAG_VIEW_NOT_FOCUSED"; +            case FLAG_ACTIVITY_START: +                    return "FLAG_ACTIVITY_START";              default: return Integer.toHexString(value);          }      } @@ -264,7 +273,8 @@ public final class FillRequest implements Parcelable {                  FLAG_MANUAL_REQUEST                          | FLAG_COMPATIBILITY_MODE_REQUEST                          | FLAG_PASSWORD_INPUT_TYPE -                        | FLAG_VIEW_NOT_FOCUSED); +                        | FLAG_VIEW_NOT_FOCUSED +                        | FLAG_ACTIVITY_START);          this.mInlineSuggestionsRequest = inlineSuggestionsRequest;          onConstructed(); @@ -384,7 +394,7 @@ public final class FillRequest implements Parcelable {          byte flg = in.readByte();          int id = in.readInt();          List<FillContext> fillContexts = new ArrayList<>(); -        in.readParcelableList(fillContexts, FillContext.class.getClassLoader(), android.service.autofill.FillContext.class); +        in.readParcelableList(fillContexts, FillContext.class.getClassLoader());          Bundle clientState = (flg & 0x4) == 0 ? null : in.readBundle();          int flags = in.readInt();          InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x10) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR); @@ -401,7 +411,8 @@ public final class FillRequest implements Parcelable {                  FLAG_MANUAL_REQUEST                          | FLAG_COMPATIBILITY_MODE_REQUEST                          | FLAG_PASSWORD_INPUT_TYPE -                        | FLAG_VIEW_NOT_FOCUSED); +                        | FLAG_VIEW_NOT_FOCUSED +                        | FLAG_ACTIVITY_START);          this.mInlineSuggestionsRequest = inlineSuggestionsRequest;          onConstructed(); @@ -422,10 +433,10 @@ public final class FillRequest implements Parcelable {      };      @DataClass.Generated( -            time = 1589280816805L, -            codegenVersion = "1.0.15", +            time = 1643052544776L, +            codegenVersion = "1.0.23",              sourceFile = "frameworks/base/core/java/android/service/autofill/FillRequest.java", -            inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final  int INVALID_REQUEST_ID\nprivate final  int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate  void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)") +            inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_ACTIVITY_START\npublic static final  int INVALID_REQUEST_ID\nprivate final  int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate  void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")      @Deprecated      private void __metadata() {} diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 75592730067a..4ff7e2297ea0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8178,9 +8178,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                          // to User. Ideally View should handle the event when isVisibleToUser()                          // becomes true where it should issue notifyViewEntered().                          afm.notifyViewEntered(this); +                    } else { +                        afm.enableFillRequestActivityStarted();                      }                  } else if (!enter && !isFocused()) {                      afm.notifyViewExited(this); +                } else if (enter) { +                    afm.enableFillRequestActivityStarted();                  }              }          } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 1496a4a7c6b3..b1b1d0ca0daf 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -563,6 +563,8 @@ public final class ViewRootImpl implements ViewParent,      @Nullable      int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED;      boolean mPerformContentCapture; +    boolean mPerformAutoFill; +      boolean mReportNextDraw;      /** @@ -841,6 +843,7 @@ public final class ViewRootImpl implements ViewParent,          mPreviousTransparentRegion = new Region();          mFirst = true; // true for the first time the view is added          mPerformContentCapture = true; // also true for the first time the view is added +        mPerformAutoFill = true;          mAdded = false;          mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,                  context); @@ -4352,6 +4355,18 @@ public final class ViewRootImpl implements ViewParent,          if (mPerformContentCapture) {              performContentCaptureInitialReport();          } + +        if (mPerformAutoFill) { +            notifyEnterForAutoFillIfNeeded(); +        } +    } + +    private void notifyEnterForAutoFillIfNeeded() { +        mPerformAutoFill = false; +        final AutofillManager afm = getAutofillManager(); +        if (afm != null) { +            afm.notifyViewEnteredForActivityStarted(mView); +        }      }      /** diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index bb13c1e78964..ac984dacdef7 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -16,6 +16,7 @@  package android.view.autofill; +import static android.service.autofill.FillRequest.FLAG_ACTIVITY_START;  import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;  import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;  import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED; @@ -538,6 +539,8 @@ public final class AutofillManager {       */      public static final int NO_SESSION = Integer.MAX_VALUE; +    private static final boolean HAS_FILL_DIALOG_UI_FEATURE = false; +      private final IAutoFillManager mService;      private final Object mLock = new Object(); @@ -629,6 +632,29 @@ public final class AutofillManager {      @GuardedBy("mLock")      @Nullable private Executor mRequestCallbackExecutor; +    /** +     * Indicates whether there are any fields that need to do a fill request +     * after the activity starts. +     * +     * Note: This field will be set to true multiple times if there are many +     * autofillable views. So needs to check mIsFillRequested at the same time to +     * avoid re-trigger autofill. +     */ +    private boolean mRequireAutofill; + +    /** +     * Indicates whether there is already a field to do a fill request after +     * the activity started. +     * +     * Autofill will automatically trigger a fill request after activity +     * start if there is any field is autofillable. But if there is a field that +     * triggered autofill, it is unnecessary to trigger again through +     * AutofillManager#notifyViewEnteredForActivityStarted. +     */ +    private boolean mIsFillRequested; + +    @Nullable private List<AutofillId> mFillDialogTriggerIds; +      /** @hide */      public interface AutofillClient {          /** @@ -766,6 +792,8 @@ public final class AutofillManager {          mContext = Objects.requireNonNull(context, "context cannot be null");          mService = service;          mOptions = context.getAutofillOptions(); +        mIsFillRequested = false; +        mRequireAutofill = false;          if (mOptions != null) {              sDebug = (mOptions.loggingLevel & FLAG_ADD_CLIENT_DEBUG) != 0; @@ -1042,6 +1070,39 @@ public final class AutofillManager {          notifyViewEntered(view, 0);      } +    /** +     * The view is autofillable, marked to perform a fill request after layout if +     * the field does not trigger a fill request. +     * +     * @hide +     */ +    public void enableFillRequestActivityStarted() { +        mRequireAutofill = true; +    } + +    private boolean hasFillDialogUiFeature() { +        return HAS_FILL_DIALOG_UI_FEATURE; +    } + +    /** +     * Notify autofill to do a fill request while the activity started. +     * +     * @hide +     */ +    public void notifyViewEnteredForActivityStarted(@NonNull View view) { +        if (!hasAutofillFeature() || !hasFillDialogUiFeature()) { +            return; +        } + +        if (!mRequireAutofill || mIsFillRequested) { +            return; +        } + +        int flags = FLAG_ACTIVITY_START; +        flags |= FLAG_VIEW_NOT_FOCUSED; +        notifyViewEntered(view, flags); +    } +      @GuardedBy("mLock")      private boolean shouldIgnoreViewEnteredLocked(@NonNull AutofillId id, int flags) {          if (isDisabledByServiceLocked()) { @@ -1082,6 +1143,7 @@ public final class AutofillManager {          }          AutofillCallback callback;          synchronized (mLock) { +            mIsFillRequested = true;              callback = notifyViewEnteredLocked(view, flags);          } @@ -2026,6 +2088,8 @@ public final class AutofillManager {          mFillableIds = null;          mSaveTriggerId = null;          mIdShownFillUi = null; +        mIsFillRequested = false; +        mRequireAutofill = false;          if (resetEnteredIds) {              mEnteredIds = null;          } @@ -3032,6 +3096,25 @@ public final class AutofillManager {      }      /** +     * Checks the id of autofill whether supported the fill dialog. +     * +     * @hide +     */ +    public boolean isShowFillDialog(AutofillId id) { +        if (!hasFillDialogUiFeature() || mFillDialogTriggerIds == null) { +            return false; +        } +        final int size = mFillDialogTriggerIds.size(); +        for (int i = 0; i < size; i++) { +            AutofillId fillId = mFillDialogTriggerIds.get(i); +            if (fillId.equalsIgnoreSession(id)) { +                return true; +            } +        } +        return false; +    } + +    /**       * Implementation of the accessibility based compatibility.       */      private final class CompatibilityBridge implements AccessibilityManager.AccessibilityPolicy {  |