Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1715b69b authored by Ahaan Ugale's avatar Ahaan Ugale
Browse files

Don't allow the keyboard to probe Inline Suggestion content.

Test: manual
Test: atest android.autofillservice.cts.inline
Bug: 149243911
Change-Id: I1c1ddb46cef74b470aaebd8b0a6b79ea6a02f5c3
parent 68a4ab95
Loading
Loading
Loading
Loading
+58 −5
Original line number Diff line number Diff line
@@ -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,
+4 −0
Original line number Diff line number Diff line
@@ -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;