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

Commit e04f9a06 authored by Haoran Zhang's avatar Haoran Zhang Committed by Android (Google) Code Review
Browse files

Merge "[Autofill Framework] Add a cache to store the last non-empty value when...

Merge "[Autofill Framework] Add a cache to store the last non-empty value when field is cleared" into main
parents b14d1bd6 8f71c728
Loading
Loading
Loading
Loading
+65 −15
Original line number Diff line number Diff line
@@ -1168,6 +1168,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        return null;
    }

    @GuardedBy("mLock")
    @Nullable
    private AutofillValue findValueFromThisSessionOnlyLocked(@NonNull AutofillId autofillId) {
        final ViewState state = mViewStates.get(autofillId);
@@ -1176,10 +1177,26 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
            return null;
        }
        AutofillValue value = state.getCurrentValue();

        // Some app clears the form before navigating to another activities. In this case, use the
        // cached value instead.
        if (value == null || value.isEmpty()) {
            AutofillValue candidateSaveValue = state.getCandidateSaveValue();
            if (candidateSaveValue != null && !candidateSaveValue.isEmpty()) {
                if (sDebug) {
                    Slog.d(TAG, "findValueLocked(): current value for " + autofillId
                            + " is empty, using candidateSaveValue instead.");
                }
                return candidateSaveValue;
            }
        }
        if (value == null) {
            if (sDebug) Slog.d(TAG, "findValueLocked(): no current value for " + autofillId);
            if (sDebug) {
                Slog.d(TAG, "findValueLocked(): no current value for " + autofillId
                        + ", checking value from previous fill contexts");
                value = getValueFromContextsLocked(autofillId);
            }
        }
        return value;
    }

@@ -3717,6 +3734,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState

                AutofillValue value = viewState.getCurrentValue();
                if (value == null || value.isEmpty()) {
                    // Some apps clear the form before navigating to other activities.
                    // If current value is empty, consider fall back to last cached
                    // non-empty result first.
                    final AutofillValue candidateSaveValue =
                            viewState.getCandidateSaveValue();
                    if (candidateSaveValue != null && !candidateSaveValue.isEmpty()) {
                        if (sVerbose) {
                            Slog.v(TAG, "current value is empty, using cached last non-empty "
                                    + "value instead");
                        }
                        value = candidateSaveValue;
                    } else {
                        // If candidate save value is also empty, consider falling back to initial
                        // value in context.
                        final AutofillValue initialValue = getValueFromContextsLocked(id);
                        if (initialValue != null) {
                            if (sDebug) {
@@ -3732,6 +3763,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                            break;
                        }
                    }
                }

                value = getSanitizedValue(sanitizers, id, value);
                if (value == null) {
@@ -3801,7 +3833,21 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                        continue;
                    }
                    if ((viewState.getState() & ViewState.STATE_CHANGED) != 0) {
                        final AutofillValue currentValue = viewState.getCurrentValue();
                        AutofillValue currentValue = viewState.getCurrentValue();
                        if (currentValue == null || currentValue.isEmpty()) {
                            // Some apps clear the form before navigating to other activities.
                            // If current value is empty, consider fall back to last cached
                            // non-empty result instead.
                            final AutofillValue candidateSaveValue =
                                    viewState.getCandidateSaveValue();
                            if (candidateSaveValue != null && !candidateSaveValue.isEmpty()) {
                                if (sVerbose) {
                                    Slog.v(TAG, "current value is empty, using cached last "
                                            + "non-empty value instead");
                                }
                                currentValue = candidateSaveValue;
                            }
                        }
                        final AutofillValue value = getSanitizedValue(sanitizers, id, currentValue);
                        if (value == null) {
                            if (sDebug) {
@@ -4714,14 +4760,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
    @GuardedBy("mLock")
    private void updateViewStateAndUiOnValueChangedLocked(AutofillId id, AutofillValue value,
            ViewState viewState, int flags) {
        // Cache the last non-empty value for save purpose. Some apps clear the form before
        // navigating to other activities.
        if (mIgnoreViewStateResetToEmpty && (value == null || value.isEmpty())
                && viewState.getCurrentValue() != null && viewState.getCurrentValue().isText()
                && viewState.getCurrentValue().getTextValue() != null
                && viewState.getCurrentValue().getTextValue().length() > 1) {
            if (sVerbose) {
                Slog.v(TAG, "Ignoring view state reset to empty on id " + id);
                Slog.v(TAG, "value is resetting to empty, caching the last non-empty value");
            }
            return;
            viewState.setCandidateSaveValue(viewState.getCurrentValue());
        } else {
            viewState.setCandidateSaveValue(null);
        }
        final String textValue;
        if (value == null || !value.isText()) {
+27 −0
Original line number Diff line number Diff line
@@ -106,6 +106,15 @@ final class ViewState {
     */
    private FillResponse mSecondaryFillResponse;
    private AutofillValue mCurrentValue;

    /**
     * Some apps clear the form before navigating to another activity. The mCandidateSaveValue
     * caches the value when a field with string longer than 2 characters are cleared.
     *
     * When showing save UI, if mCurrentValue of view state is empty, session would use
     * mCandidateSaveValue to prompt save instead.
     */
    private AutofillValue mCandidateSaveValue;
    private AutofillValue mAutofilledValue;
    private AutofillValue mSanitizedValue;
    private Rect mVirtualBounds;
@@ -139,6 +148,18 @@ final class ViewState {
        mCurrentValue = value;
    }

    /**
     * Gets the candidate save value of the view.
     */
    @Nullable
    AutofillValue getCandidateSaveValue() {
        return mCandidateSaveValue;
    }

    void setCandidateSaveValue(AutofillValue value) {
        mCandidateSaveValue = value;
    }

    @Nullable
    AutofillValue getAutofilledValue() {
        return mAutofilledValue;
@@ -268,6 +289,9 @@ final class ViewState {
        if (mCurrentValue != null) {
            builder.append(", currentValue:" ).append(mCurrentValue);
        }
        if (mCandidateSaveValue != null) {
            builder.append(", candidateSaveValue:").append(mCandidateSaveValue);
        }
        if (mAutofilledValue != null) {
            builder.append(", autofilledValue:" ).append(mAutofilledValue);
        }
@@ -302,6 +326,9 @@ final class ViewState {
        if (mAutofilledValue != null) {
            pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue);
        }
        if (mCandidateSaveValue != null) {
            pw.print(prefix); pw.print("candidateSaveValue:"); pw.println(mCandidateSaveValue);
        }
        if (mSanitizedValue != null) {
            pw.print(prefix); pw.print("sanitizedValue:" ); pw.println(mSanitizedValue);
        }