Loading core/java/android/view/View.java +11 −10 Original line number Diff line number Diff line Loading @@ -8206,24 +8206,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (canNotifyAutofillEnterExitEvent()) { AutofillManager afm = getAutofillManager(); if (afm != null) { if (enter && isFocused()) { if (enter) { // We have not been laid out yet, hence cannot evaluate // whether this view is visible to the user, we will do // the evaluation once layout is complete. if (!isLaidOut()) { mPrivateFlags3 |= PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; } else if (isVisibleToUser()) { // TODO This is a potential problem that View gets focus before it's visible // to User. Ideally View should handle the event when isVisibleToUser() // becomes true where it should issue notifyViewEntered(). if (isFocused()) { // TODO This is a potential problem that View gets focus before it's // visible to User. Ideally View should handle the event when // isVisibleToUser() becomes true where it should issue // notifyViewEntered(). afm.notifyViewEntered(this); } else { afm.enableFillRequestActivityStarted(this); afm.notifyViewEnteredForFillDialog(this); } } } else if (!enter && !isFocused()) { } else if (!isFocused()) { afm.notifyViewExited(this); } else if (enter) { afm.enableFillRequestActivityStarted(this); } } } core/java/android/view/ViewRootImpl.java +0 −14 Original line number Diff line number Diff line Loading @@ -590,7 +590,6 @@ public final class ViewRootImpl implements ViewParent, @Nullable int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED; boolean mPerformContentCapture; boolean mPerformAutoFill; boolean mReportNextDraw; Loading Loading @@ -912,7 +911,6 @@ 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); Loading Loading @@ -4331,18 +4329,6 @@ 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); } } /** Loading core/java/android/view/autofill/AutofillManager.java +20 −41 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import sun.misc.Cleaner; Loading Loading @@ -644,16 +645,6 @@ public final class AutofillManager { @GuardedBy("mLock") private boolean mEnabledForAugmentedAutofillOnly; /** * 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. Loading @@ -663,7 +654,7 @@ public final class AutofillManager { * triggered autofill, it is unnecessary to trigger again through * AutofillManager#notifyViewEnteredForActivityStarted. */ private boolean mIsFillRequested; private AtomicBoolean mIsFillRequested; @Nullable private List<AutofillId> mFillDialogTriggerIds; Loading Loading @@ -811,8 +802,7 @@ public final class AutofillManager { mContext = Objects.requireNonNull(context, "context cannot be null"); mService = service; mOptions = context.getAutofillOptions(); mIsFillRequested = false; mRequireAutofill = false; mIsFillRequested = new AtomicBoolean(false); mIsFillDialogEnabled = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_AUTOFILL, Loading Loading @@ -1113,46 +1103,36 @@ public final class AutofillManager { } /** * The view have the allowed autofill hints, marked to perform a fill request after layout if * the field does not trigger a fill request. * The {@link #DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED} is {@code true} or the view have * the allowed autofill hints, performs a fill request to know there is any field supported * fill dialog. * * @hide */ public void enableFillRequestActivityStarted(View v) { if (mRequireAutofill) { public void notifyViewEnteredForFillDialog(View v) { // Skip if the fill request has been performed for a view. if (mIsFillRequested.get()) { return; } if (mIsFillDialogEnabled || ArrayUtils.containsAny(v.getAutofillHints(), mFillDialogEnabledHints)) { if (sDebug) { Log.d(TAG, "Trigger fill request at starting"); } mRequireAutofill = true; } Log.d(TAG, "Trigger fill request at view entered"); } private boolean hasFillDialogUiFeature() { return mIsFillDialogEnabled || !ArrayUtils.isEmpty(mFillDialogEnabledHints); } // Note: No need for atomic getAndSet as this method is called on the UI thread. mIsFillRequested.set(true); /** * Notify autofill to do a fill request while the activity started. * * @hide */ public void notifyViewEnteredForActivityStarted(@NonNull View view) { if (!hasAutofillFeature() || !hasFillDialogUiFeature()) { return; int flags = FLAG_SUPPORTS_FILL_DIALOG; flags |= FLAG_VIEW_NOT_FOCUSED; // use root view, so autofill UI does not trigger immediately. notifyViewEntered(v.getRootView(), flags); } if (!mRequireAutofill || mIsFillRequested) { return; } int flags = FLAG_SUPPORTS_FILL_DIALOG; flags |= FLAG_VIEW_NOT_FOCUSED; notifyViewEntered(view, flags); private boolean hasFillDialogUiFeature() { return mIsFillDialogEnabled || !ArrayUtils.isEmpty(mFillDialogEnabledHints); } private int getImeStateFlag(View v) { Loading Loading @@ -1203,7 +1183,7 @@ public final class AutofillManager { } AutofillCallback callback; synchronized (mLock) { mIsFillRequested = true; mIsFillRequested.set(true); callback = notifyViewEnteredLocked(view, flags); } Loading Loading @@ -2119,8 +2099,7 @@ public final class AutofillManager { mFillableIds = null; mSaveTriggerId = null; mIdShownFillUi = null; mIsFillRequested = false; mRequireAutofill = false; mIsFillRequested.set(false); mShowAutofillDialogCalled = false; mFillDialogTriggerIds = null; if (resetEnteredIds) { Loading Loading
core/java/android/view/View.java +11 −10 Original line number Diff line number Diff line Loading @@ -8206,24 +8206,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (canNotifyAutofillEnterExitEvent()) { AutofillManager afm = getAutofillManager(); if (afm != null) { if (enter && isFocused()) { if (enter) { // We have not been laid out yet, hence cannot evaluate // whether this view is visible to the user, we will do // the evaluation once layout is complete. if (!isLaidOut()) { mPrivateFlags3 |= PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; } else if (isVisibleToUser()) { // TODO This is a potential problem that View gets focus before it's visible // to User. Ideally View should handle the event when isVisibleToUser() // becomes true where it should issue notifyViewEntered(). if (isFocused()) { // TODO This is a potential problem that View gets focus before it's // visible to User. Ideally View should handle the event when // isVisibleToUser() becomes true where it should issue // notifyViewEntered(). afm.notifyViewEntered(this); } else { afm.enableFillRequestActivityStarted(this); afm.notifyViewEnteredForFillDialog(this); } } } else if (!enter && !isFocused()) { } else if (!isFocused()) { afm.notifyViewExited(this); } else if (enter) { afm.enableFillRequestActivityStarted(this); } } }
core/java/android/view/ViewRootImpl.java +0 −14 Original line number Diff line number Diff line Loading @@ -590,7 +590,6 @@ public final class ViewRootImpl implements ViewParent, @Nullable int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED; boolean mPerformContentCapture; boolean mPerformAutoFill; boolean mReportNextDraw; Loading Loading @@ -912,7 +911,6 @@ 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); Loading Loading @@ -4331,18 +4329,6 @@ 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); } } /** Loading
core/java/android/view/autofill/AutofillManager.java +20 −41 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import sun.misc.Cleaner; Loading Loading @@ -644,16 +645,6 @@ public final class AutofillManager { @GuardedBy("mLock") private boolean mEnabledForAugmentedAutofillOnly; /** * 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. Loading @@ -663,7 +654,7 @@ public final class AutofillManager { * triggered autofill, it is unnecessary to trigger again through * AutofillManager#notifyViewEnteredForActivityStarted. */ private boolean mIsFillRequested; private AtomicBoolean mIsFillRequested; @Nullable private List<AutofillId> mFillDialogTriggerIds; Loading Loading @@ -811,8 +802,7 @@ public final class AutofillManager { mContext = Objects.requireNonNull(context, "context cannot be null"); mService = service; mOptions = context.getAutofillOptions(); mIsFillRequested = false; mRequireAutofill = false; mIsFillRequested = new AtomicBoolean(false); mIsFillDialogEnabled = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_AUTOFILL, Loading Loading @@ -1113,46 +1103,36 @@ public final class AutofillManager { } /** * The view have the allowed autofill hints, marked to perform a fill request after layout if * the field does not trigger a fill request. * The {@link #DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED} is {@code true} or the view have * the allowed autofill hints, performs a fill request to know there is any field supported * fill dialog. * * @hide */ public void enableFillRequestActivityStarted(View v) { if (mRequireAutofill) { public void notifyViewEnteredForFillDialog(View v) { // Skip if the fill request has been performed for a view. if (mIsFillRequested.get()) { return; } if (mIsFillDialogEnabled || ArrayUtils.containsAny(v.getAutofillHints(), mFillDialogEnabledHints)) { if (sDebug) { Log.d(TAG, "Trigger fill request at starting"); } mRequireAutofill = true; } Log.d(TAG, "Trigger fill request at view entered"); } private boolean hasFillDialogUiFeature() { return mIsFillDialogEnabled || !ArrayUtils.isEmpty(mFillDialogEnabledHints); } // Note: No need for atomic getAndSet as this method is called on the UI thread. mIsFillRequested.set(true); /** * Notify autofill to do a fill request while the activity started. * * @hide */ public void notifyViewEnteredForActivityStarted(@NonNull View view) { if (!hasAutofillFeature() || !hasFillDialogUiFeature()) { return; int flags = FLAG_SUPPORTS_FILL_DIALOG; flags |= FLAG_VIEW_NOT_FOCUSED; // use root view, so autofill UI does not trigger immediately. notifyViewEntered(v.getRootView(), flags); } if (!mRequireAutofill || mIsFillRequested) { return; } int flags = FLAG_SUPPORTS_FILL_DIALOG; flags |= FLAG_VIEW_NOT_FOCUSED; notifyViewEntered(view, flags); private boolean hasFillDialogUiFeature() { return mIsFillDialogEnabled || !ArrayUtils.isEmpty(mFillDialogEnabledHints); } private int getImeStateFlag(View v) { Loading Loading @@ -1203,7 +1183,7 @@ public final class AutofillManager { } AutofillCallback callback; synchronized (mLock) { mIsFillRequested = true; mIsFillRequested.set(true); callback = notifyViewEnteredLocked(view, flags); } Loading Loading @@ -2119,8 +2099,7 @@ public final class AutofillManager { mFillableIds = null; mSaveTriggerId = null; mIdShownFillUi = null; mIsFillRequested = false; mRequireAutofill = false; mIsFillRequested.set(false); mShowAutofillDialogCalled = false; mFillDialogTriggerIds = null; if (resetEnteredIds) { Loading