From 8e815316dd47ac37dbe6ab34ea3f7f21d5671a5c Mon Sep 17 00:00:00 2001 From: lpeter Date: Fri, 8 May 2020 01:29:59 +0800 Subject: [PATCH] Fix cts fail for android.autofillservice.cts.augmented In the test we trigger the manual autofill request programmatically, because the focus isn't on the field, we will not get the callback from IME. It would be better not to ask IME for inline request if the request is manual and the view is not focused because it's a simpler/safer approach and manual request without focus should be rare. Bug: 154661868 Test: atest CtsAutoFillServiceTestCases Change-Id: I783b2542094cdea547ebd58ce89f30d9cd421708 --- .../android/service/autofill/FillRequest.java | 25 +++++++++++++++---- .../view/autofill/AutofillManager.java | 13 ++++++++-- .../com/android/server/autofill/Session.java | 21 +++++++++++----- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java index d94160c2b40ca..62becc5074042 100644 --- a/core/java/android/service/autofill/FillRequest.java +++ b/core/java/android/service/autofill/FillRequest.java @@ -86,6 +86,16 @@ public final class FillRequest implements Parcelable { */ public static final @RequestFlags int FLAG_PASSWORD_INPUT_TYPE = 0x4; + /** + * Indicates the view was not focused. + * + *

Note: Defines the flag value to 0x10, because the flag value 0x08 has been defined + * in {@link AutofillManager}.

+ * + * @hide + */ + public static final @RequestFlags int FLAG_VIEW_NOT_FOCUSED = 0x10; + /** @hide */ public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE; @@ -165,7 +175,8 @@ public final class FillRequest implements Parcelable { @IntDef(flag = true, prefix = "FLAG_", value = { FLAG_MANUAL_REQUEST, FLAG_COMPATIBILITY_MODE_REQUEST, - FLAG_PASSWORD_INPUT_TYPE + FLAG_PASSWORD_INPUT_TYPE, + FLAG_VIEW_NOT_FOCUSED }) @Retention(RetentionPolicy.SOURCE) @DataClass.Generated.Member @@ -187,6 +198,8 @@ public final class FillRequest implements Parcelable { return "FLAG_COMPATIBILITY_MODE_REQUEST"; case FLAG_PASSWORD_INPUT_TYPE: return "FLAG_PASSWORD_INPUT_TYPE"; + case FLAG_VIEW_NOT_FOCUSED: + return "FLAG_VIEW_NOT_FOCUSED"; default: return Integer.toHexString(value); } } @@ -248,7 +261,8 @@ public final class FillRequest implements Parcelable { mFlags, FLAG_MANUAL_REQUEST | FLAG_COMPATIBILITY_MODE_REQUEST - | FLAG_PASSWORD_INPUT_TYPE); + | FLAG_PASSWORD_INPUT_TYPE + | FLAG_VIEW_NOT_FOCUSED); this.mInlineSuggestionsRequest = inlineSuggestionsRequest; onConstructed(); @@ -384,7 +398,8 @@ public final class FillRequest implements Parcelable { mFlags, FLAG_MANUAL_REQUEST | FLAG_COMPATIBILITY_MODE_REQUEST - | FLAG_PASSWORD_INPUT_TYPE); + | FLAG_PASSWORD_INPUT_TYPE + | FLAG_VIEW_NOT_FOCUSED); this.mInlineSuggestionsRequest = inlineSuggestionsRequest; onConstructed(); @@ -405,10 +420,10 @@ public final class FillRequest implements Parcelable { }; @DataClass.Generated( - time = 1588119440090L, + time = 1589280816805L, codegenVersion = "1.0.15", 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 int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List 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 int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List 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/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 76fe6b5f666d9..553e3c8c2d1b5 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -18,6 +18,7 @@ package android.view.autofill; 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; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; import static android.view.autofill.Helper.toList; @@ -879,7 +880,11 @@ public final class AutofillManager { * @param view view requesting the new autofill context. */ public void requestAutofill(@NonNull View view) { - notifyViewEntered(view, FLAG_MANUAL_REQUEST); + int flags = FLAG_MANUAL_REQUEST; + if (!view.isFocused()) { + flags |= FLAG_VIEW_NOT_FOCUSED; + } + notifyViewEntered(view, flags); } /** @@ -926,7 +931,11 @@ public final class AutofillManager { * @param absBounds absolute boundaries of the virtual view in the screen. */ public void requestAutofill(@NonNull View view, int virtualId, @NonNull Rect absBounds) { - notifyViewEntered(view, virtualId, absBounds, FLAG_MANUAL_REQUEST); + int flags = FLAG_MANUAL_REQUEST; + if (!view.isFocused()) { + flags |= FLAG_VIEW_NOT_FOCUSED; + } + notifyViewEntered(view, virtualId, absBounds, flags); } /** diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 086a8be6d6cf2..ef17d1331a1e1 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -19,6 +19,7 @@ package com.android.server.autofill; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; 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; import static android.service.autofill.FillRequest.INVALID_REQUEST_ID; import static android.view.autofill.AutofillManager.ACTION_RESPONSE_EXPIRED; import static android.view.autofill.AutofillManager.ACTION_START_SESSION; @@ -653,6 +654,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return mService.isInlineSuggestionsEnabled(); } + private boolean isViewFocusedLocked(int flags) { + return (flags & FLAG_VIEW_NOT_FOCUSED) == 0; + } + /** * Clears the existing response for the partition, reads a new structure, and then requests a * new fill response from the fill service. @@ -711,10 +716,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState cancelCurrentRequestLocked(); // Only ask IME to create inline suggestions request if Autofill provider supports it and - // the render service is available. + // the render service is available except the autofill is triggered manually and the view + // is also not focused. final RemoteInlineSuggestionRenderService remoteRenderService = mService.getRemoteInlineSuggestionRenderServiceLocked(); - if (isInlineSuggestionsEnabledByAutofillProviderLocked() && remoteRenderService != null) { + if (isInlineSuggestionsEnabledByAutofillProviderLocked() + && remoteRenderService != null + && isViewFocusedLocked(flags)) { Consumer inlineSuggestionsRequestConsumer = mAssistReceiver.newAutofillRequestLocked(viewState, /*isInlineRequest=*/ true); @@ -3139,9 +3147,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } }; - // When the inline suggestion render service is available, there are 2 cases when - // augmented autofill should ask IME for inline suggestion request, because standard - // autofill flow didn't: + // When the inline suggestion render service is available and the view is focused, there + // are 2 cases when augmented autofill should ask IME for inline suggestion request, + // because standard autofill flow didn't: // 1. the field is augmented autofill only (when standard autofill provider is None or // when it returns null response) // 2. standard autofill provider doesn't support inline suggestion @@ -3149,7 +3157,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mService.getRemoteInlineSuggestionRenderServiceLocked(); if (remoteRenderService != null && (mForAugmentedAutofillOnly - || !isInlineSuggestionsEnabledByAutofillProviderLocked())) { + || !isInlineSuggestionsEnabledByAutofillProviderLocked()) + && isViewFocusedLocked(flags)) { if (sDebug) Slog.d(TAG, "Create inline request for augmented autofill"); remoteRenderService.getInlineSuggestionsRendererInfo(new RemoteCallback( (extras) -> {