From 1715b69bee086fedf383830151820c2b2d6297cc Mon Sep 17 00:00:00 2001 From: Ahaan Ugale Date: Tue, 11 Feb 2020 23:36:35 +0100 Subject: [PATCH] Don't allow the keyboard to probe Inline Suggestion content. Test: manual Test: atest android.autofillservice.cts.inline Bug: 149243911 Change-Id: I1c1ddb46cef74b470aaebd8b0a6b79ea6a02f5c3 --- .../com/android/server/autofill/Session.java | 63 +++++++++++++++++-- .../android/server/autofill/ViewState.java | 4 ++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 8032e9b70e0da..e942b274dc536 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2604,17 +2604,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private void updateViewStateAndUiOnValueChangedLocked(AutofillId id, AutofillValue value, ViewState viewState, int flags) { - viewState.setCurrentValue(value); - - final String filterText; + final String textValue; if (value == null || !value.isText()) { - filterText = null; + textValue = null; } else { final CharSequence text = value.getTextValue(); // Text should never be null, but it doesn't hurt to check to avoid a // system crash... - filterText = (text == null) ? null : text.toString(); + textValue = (text == null) ? null : text.toString(); } + updateFilteringStateOnValueChangedLocked(textValue, viewState); + + viewState.setCurrentValue(value); + + final String filterText = textValue; final AutofillValue filledValue = viewState.getAutofilledValue(); if (filledValue != null) { @@ -2645,6 +2648,52 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState getUiForShowing().filterFillUi(filterText, this); } + /** + * Disable filtering of inline suggestions for further text changes in this view if any + * character was removed earlier and now any character is being added. Such behaviour may + * indicate the IME attempting to probe the potentially sensitive content of inline suggestions. + */ + @GuardedBy("mLock") + private void updateFilteringStateOnValueChangedLocked(@Nullable String newTextValue, + ViewState viewState) { + if (newTextValue == null) { + // Don't just return here, otherwise the IME can circumvent this logic using non-text + // values. + newTextValue = ""; + } + final AutofillValue currentValue = viewState.getCurrentValue(); + final String currentTextValue; + if (currentValue == null || !currentValue.isText()) { + currentTextValue = ""; + } else { + currentTextValue = currentValue.getTextValue().toString(); + } + + if ((viewState.getState() & ViewState.STATE_CHAR_REMOVED) == 0) { + if (!containsCharsInOrder(newTextValue, currentTextValue)) { + viewState.setState(ViewState.STATE_CHAR_REMOVED); + } + } else if (!containsCharsInOrder(currentTextValue, newTextValue)) { + // Characters were added or replaced. + viewState.setState(ViewState.STATE_INLINE_DISABLED); + } + } + + /** + * Returns true if {@code s1} contains all characters of {@code s2}, in order. + */ + private static boolean containsCharsInOrder(String s1, String s2) { + int prevIndex = -1; + for (char ch : s2.toCharArray()) { + int index = TextUtils.indexOf(s1, ch, prevIndex + 1); + if (index == -1) { + return false; + } + prevIndex = index; + } + return true; + } + @Override public void onFillReady(@NonNull FillResponse response, @NonNull AutofillId filledId, @Nullable AutofillValue value) { @@ -2735,6 +2784,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return false; } + final ViewState currentView = mViewStates.get(mCurrentViewId); + if ((currentView.getState() & ViewState.STATE_INLINE_DISABLED) != 0) { + response.getDatasets().clear(); + } InlineSuggestionsResponse inlineSuggestionsResponse = InlineSuggestionFactory.createInlineSuggestionsResponse( inlineSuggestionsRequest.get(), response, filterText, mCurrentViewId, diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index f7c24f080fa45..9114576ad3b5d 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -76,6 +76,10 @@ final class ViewState { public static final int STATE_TRIGGERED_AUGMENTED_AUTOFILL = 0x1000; /** Inline suggestions were shown for this View. */ public static final int STATE_INLINE_SHOWN = 0x2000; + /** A character was removed from the View value (not by the service). */ + public static final int STATE_CHAR_REMOVED = 0x4000; + /** Showing inline suggestions is not allowed for this View. */ + public static final int STATE_INLINE_DISABLED = 0x8000; public final AutofillId id;