diff options
| author | 2017-11-20 23:07:23 +0000 | |
|---|---|---|
| committer | 2017-11-20 23:07:23 +0000 | |
| commit | d39edd02e277267548162fd1ac8e2cad47085a3e (patch) | |
| tree | 6701b31bfc4373eef5bb9aedbc86ec3ab7bd66a1 | |
| parent | de3766e95d880ea6c9f3e9280a8ac921effe47a8 (diff) | |
| parent | f5059c39cbf72603c6a28ae9337041ddce5d4899 (diff) | |
Merge "Optimize Autofill Sanitizer to work as a Validator."
5 files changed, 55 insertions, 9 deletions
diff --git a/core/java/android/service/autofill/InternalSanitizer.java b/core/java/android/service/autofill/InternalSanitizer.java index 95d2f660b24b..d77e41e3f022 100644 --- a/core/java/android/service/autofill/InternalSanitizer.java +++ b/core/java/android/service/autofill/InternalSanitizer.java @@ -16,6 +16,7 @@ package android.service.autofill; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; import android.os.Parcelable; import android.view.autofill.AutofillValue; @@ -32,7 +33,11 @@ public abstract class InternalSanitizer implements Sanitizer, Parcelable { /** * Sanitizes an {@link AutofillValue}. * + * @return sanitized value or {@code null} if value could not be sanitized (for example: didn't + * match regex, it's an invalid type, regex failed, etc). + * * @hide */ + @Nullable public abstract AutofillValue sanitize(@NonNull AutofillValue value); } diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java index 9a1dcbb2785f..bc4b3fc3d5ea 100644 --- a/core/java/android/service/autofill/SaveInfo.java +++ b/core/java/android/service/autofill/SaveInfo.java @@ -613,6 +613,11 @@ public final class SaveInfo implements Parcelable { * usernameId, passwordId); * </pre> * + * <p>The sanitizer can also be used as an alternative for a + * {@link #setValidator(Validator) validator}&mdashif any of the {@code ids} is a + * {@link #SaveInfo.Builder(int, AutofillId[]) required id} and the {@code sanitizer} fail + * for it, then the save UI is not shown. + * * @param sanitizer an implementation provided by the Android System. * @param ids id of fields whose value will be sanitized. * @return this builder. diff --git a/core/java/android/service/autofill/TextValueSanitizer.java b/core/java/android/service/autofill/TextValueSanitizer.java index 12e85b1db490..a3a98d8e6390 100644 --- a/core/java/android/service/autofill/TextValueSanitizer.java +++ b/core/java/android/service/autofill/TextValueSanitizer.java @@ -19,6 +19,7 @@ package android.service.autofill; import static android.view.autofill.Helper.sDebug; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -62,24 +63,31 @@ public final class TextValueSanitizer extends InternalSanitizer implements /** @hide */ @Override @TestApi + @Nullable public AutofillValue sanitize(@NonNull AutofillValue value) { if (value == null) { Slog.w(TAG, "sanitize() called with null value"); return null; } - if (!value.isText()) return value; + if (!value.isText()) { + if (sDebug) Slog.d(TAG, "sanitize() called with non-text value: " + value); + return null; + } final CharSequence text = value.getTextValue(); try { final Matcher matcher = mRegex.matcher(text); - if (!matcher.matches()) return value; + if (!matcher.matches()) { + if (sDebug) Slog.d(TAG, "sanitize(): " + mRegex + " failed for " + value); + return null; + } final CharSequence sanitized = matcher.replaceAll(mSubst); return AutofillValue.forText(sanitized); } catch (Exception e) { Slog.w(TAG, "Exception evaluating " + mRegex + "/" + mSubst + ": " + e); - return value; + return null; } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index af4668a63c03..974148623b00 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -1167,7 +1167,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState break; } } + value = getSanitizedValue(sanitizers, id, value); + if (value == null) { + if (sDebug) { + Slog.d(TAG, "value of required field " + id + " failed sanitization"); + } + allRequiredAreNotEmpty = false; + break; + } + viewState.setSanitizedValue(value); currentValues.put(id, value); final AutofillValue filledValue = viewState.getAutofilledValue(); @@ -1337,7 +1346,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return sanitizers; } - @NonNull + @Nullable private AutofillValue getSanitizedValue( @Nullable ArrayMap<AutofillId, InternalSanitizer> sanitizers, @NonNull AutofillId id, @@ -1431,10 +1440,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (sVerbose) Slog.v(TAG, "callSaveLocked(): updating " + context); for (int viewStateNum = 0; viewStateNum < mViewStates.size(); viewStateNum++) { - final ViewState state = mViewStates.valueAt(viewStateNum); + final ViewState viewState = mViewStates.valueAt(viewStateNum); - final AutofillId id = state.id; - final AutofillValue value = state.getCurrentValue(); + final AutofillId id = viewState.id; + final AutofillValue value = viewState.getCurrentValue(); if (value == null) { if (sVerbose) Slog.v(TAG, "callSaveLocked(): skipping " + id); continue; @@ -1446,9 +1455,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (sVerbose) Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value); - final AutofillValue sanitizedValue = getSanitizedValue(sanitizers, id, value); + AutofillValue sanitizedValue = viewState.getSanitizedValue(); - node.updateAutofillValue(sanitizedValue); + if (sanitizedValue == null) { + // Field is optional and haven't been sanitized yet. + sanitizedValue = getSanitizedValue(sanitizers, id, value); + } + if (sanitizedValue != null) { + node.updateAutofillValue(sanitizedValue); + } else if (sDebug) { + Slog.d(TAG, "Not updating field " + id + " because it failed sanitization"); + } } // Sanitize structure before it's sent to service. diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index 832a66b26b12..0dbdc13e429b 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -76,6 +76,7 @@ final class ViewState { private FillResponse mResponse; private AutofillValue mCurrentValue; private AutofillValue mAutofilledValue; + private AutofillValue mSanitizedValue; private Rect mVirtualBounds; private int mState; private String mDatasetId; @@ -117,6 +118,15 @@ final class ViewState { } @Nullable + AutofillValue getSanitizedValue() { + return mSanitizedValue; + } + + void setSanitizedValue(@Nullable AutofillValue value) { + mSanitizedValue = value; + } + + @Nullable FillResponse getResponse() { return mResponse; } @@ -218,6 +228,7 @@ final class ViewState { } pw.print(prefix); pw.print("currentValue:" ); pw.println(mCurrentValue); pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue); + pw.print(prefix); pw.print("sanitizedValue:" ); pw.println(mSanitizedValue); pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds); } }
\ No newline at end of file |