summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/service/autofill/FillRequest.java29
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/ViewRootImpl.java15
-rw-r--r--core/java/android/view/autofill/AutofillManager.java83
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 {