diff options
Diffstat (limited to 'services/autofill')
4 files changed, 61 insertions, 33 deletions
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java index 23bb9d63d6fa..0ec8654f2a20 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java +++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java @@ -75,9 +75,7 @@ final class AutofillInlineSessionController { @NonNull Consumer<InlineSuggestionsRequest> requestConsumer, @NonNull Bundle uiExtras) { // TODO(b/151123764): rename the method to better reflect what it does. if (mSession != null) { - // Send an empty response to IME and destroy the existing session. - mSession.onInlineSuggestionsResponseLocked( - InlineFillUi.emptyUi(mSession.getAutofillIdLocked())); + // Destroy the existing session. mSession.destroySessionLocked(); mInlineFillUi = null; } @@ -117,13 +115,14 @@ final class AutofillInlineSessionController { } /** - * Permanently delete the current inline fill UI. Notify the IME to hide the suggestions as - * well. + * Disables prefix/regex based filtering. Other filtering rules (see {@link + * android.service.autofill.Dataset}) still apply. */ @GuardedBy("mLock") - boolean deleteInlineFillUiLocked(@NonNull AutofillId autofillId) { - mInlineFillUi = null; - return hideInlineSuggestionsUiLocked(autofillId); + void disableFilterMatching(@NonNull AutofillId autofillId) { + if (mInlineFillUi != null && mInlineFillUi.getAutofillId().equals(autofillId)) { + mInlineFillUi.disableFilterMatching(); + } } /** diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java index 687b75a8b949..e7a43b75f9d5 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java +++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java @@ -40,7 +40,6 @@ import com.android.server.autofill.ui.InlineFillUi; import com.android.server.inputmethod.InputMethodManagerInternal; import java.lang.ref.WeakReference; -import java.util.Collections; import java.util.Optional; import java.util.function.Consumer; @@ -209,18 +208,9 @@ final class AutofillInlineSuggestionsRequestSession { if (mDestroyed || mResponseCallback == null) { return; } - if (!mImeInputStarted && mPreviousResponseIsNotEmpty) { - // 1. if previous response is not empty, and IME is just disconnected from the view, - // then send empty response to make sure existing responses don't stick around. - // Although the inline suggestions should disappear when IME hides which removes them - // from the view hierarchy, but we still send an empty response to indicate that the - // previous suggestions are invalid now. - if (sVerbose) Slog.v(TAG, "Send empty inline response"); - updateResponseToImeUncheckLocked(new InlineSuggestionsResponse(Collections.EMPTY_LIST)); - mPreviousResponseIsNotEmpty = false; - } else if (mImeInputViewStarted && mInlineFillUi != null && match(mAutofillId, + if (mImeInputViewStarted && mInlineFillUi != null && match(mAutofillId, mImeCurrentFieldId)) { - // 2. if IME is visible, and response is not null, send the response + // if IME is visible, and response is not null, send the response InlineSuggestionsResponse response = mInlineFillUi.getInlineSuggestionsResponse(); boolean isEmptyResponse = response.getInlineSuggestions().isEmpty(); if (isEmptyResponse && !mPreviousResponseIsNotEmpty) { diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 37ed6f790c19..642526d13aff 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2698,6 +2698,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // TODO(b/156099633): remove this once framework gets out of business of resending // inline suggestions when IME visibility changes. mInlineSessionController.hideInlineSuggestionsUiLocked(viewState.id); + try { + mClient.notifyFillUiHidden(this.id, viewState.id); + } catch (RemoteException e) { + Slog.e(TAG, "Error requesting to hide fill UI", e); + } viewState.resetState(ViewState.STATE_CHANGED); return; } else if ((viewState.id.equals(this.mCurrentViewId)) @@ -2713,20 +2718,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } else if (viewState.id.equals(this.mCurrentViewId) && (viewState.getState() & ViewState.STATE_INLINE_SHOWN) != 0) { if ((viewState.getState() & ViewState.STATE_INLINE_DISABLED) != 0) { - final FillResponse response = viewState.getResponse(); - if (response != null) { - response.getDatasets().clear(); - } - mInlineSessionController.deleteInlineFillUiLocked(viewState.id); - } else { - mInlineSessionController.filterInlineFillUiLocked(mCurrentViewId, filterText); + mInlineSessionController.disableFilterMatching(viewState.id); } + mInlineSessionController.filterInlineFillUiLocked(mCurrentViewId, filterText); } else if (viewState.id.equals(this.mCurrentViewId) && (viewState.getState() & ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL) != 0) { if (!TextUtils.isEmpty(filterText)) { // TODO: we should be able to replace this with controller#filterInlineFillUiLocked // to accomplish filtering for augmented autofill. mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId); + try { + mClient.notifyFillUiHidden(this.id, mCurrentViewId); + } catch (RemoteException e) { + Slog.e(TAG, "Error sending fill UI hidden notification", e); + } } } @@ -2812,6 +2817,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (requestShowInlineSuggestionsLocked(response, filterText)) { final ViewState currentView = mViewStates.get(mCurrentViewId); currentView.setState(ViewState.STATE_INLINE_SHOWN); + try { + mClient.notifyFillUiShown(this.id, mCurrentViewId); + } catch (RemoteException e) { + Slog.e(TAG, "Error sending fill UI shown notification", e); + } //TODO(b/137800469): Fix it to log showed only when IME asks for inflation, // rather than here where framework sends back the response. mService.logDatasetShown(id, mClientState); @@ -2882,6 +2892,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState synchronized (mLock) { mInlineSessionController.hideInlineSuggestionsUiLocked( focusedId); + try { + mClient.notifyFillUiHidden(this.id, focusedId); + } catch (RemoteException e) { + Slog.e(TAG, "Error sending fill UI hidden notification", e); + } } }, remoteRenderService); return mInlineSessionController.setInlineFillUiLocked(inlineFillUi); @@ -3393,6 +3408,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (mCurrentViewId != null) { mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId); + try { + mClient.notifyFillUiHidden(this.id, mCurrentViewId); + } catch (RemoteException e) { + Slog.e(TAG, "Error sending fill UI hidden notification", e); + } } autoFillApp(dataset); return; @@ -3832,6 +3852,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState for (int i = 0; i < responseCount; i++) { if (mResponses.keyAt(i) > lastResponseId) { lastResponseIdx = i; + lastResponseId = mResponses.keyAt(i); } } } diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java index 2713a01ff3d1..a3d0fb955da4 100644 --- a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java @@ -84,6 +84,11 @@ public final class InlineFillUi { private String mFilterText; /** + * Whether prefix/regex based filtering is disabled. + */ + private boolean mFilterMatchingDisabled; + + /** * Returns an empty inline autofill UI. */ @NonNull @@ -199,7 +204,7 @@ public final class InlineFillUi { continue; } if (!inlinePresentation.isPinned() // don't filter pinned suggestions - && !includeDataset(dataset, fieldIndex, mFilterText)) { + && !includeDataset(dataset, fieldIndex)) { continue; } inlineSuggestions.add(copy(i, mInlineSuggestions.get(i))); @@ -235,14 +240,13 @@ public final class InlineFillUi { } // TODO: Extract the shared filtering logic here and in FillUi to a common method. - private static boolean includeDataset(Dataset dataset, int fieldIndex, - @Nullable String filterText) { + private boolean includeDataset(Dataset dataset, int fieldIndex) { // Show everything when the user input is empty. - if (TextUtils.isEmpty(filterText)) { + if (TextUtils.isEmpty(mFilterText)) { return true; } - final String constraintLowerCase = filterText.toString().toLowerCase(); + final String constraintLowerCase = mFilterText.toString().toLowerCase(); // Use the filter provided by the service, if available. final Dataset.DatasetFieldFilter filter = dataset.getFilter(fieldIndex); @@ -252,7 +256,10 @@ public final class InlineFillUi { if (sVerbose) { Slog.v(TAG, "Explicitly disabling filter for dataset id" + dataset.getId()); } - return true; + return false; + } + if (mFilterMatchingDisabled) { + return false; } return filterPattern.matcher(constraintLowerCase).matches(); } @@ -261,11 +268,22 @@ public final class InlineFillUi { if (value == null || !value.isText()) { return dataset.getAuthentication() == null; } + if (mFilterMatchingDisabled) { + return false; + } final String valueText = value.getTextValue().toString().toLowerCase(); return valueText.toLowerCase().startsWith(constraintLowerCase); } /** + * Disables prefix/regex based filtering. Other filtering rules (see {@link + * android.service.autofill.Dataset}) still apply. + */ + public void disableFilterMatching() { + mFilterMatchingDisabled = true; + } + + /** * Callback from the inline suggestion Ui. */ public interface InlineSuggestionUiCallback { |