From 6fb52a5fca3d6030509aff08c22b6ffcd9fc1baf Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 17 Jan 2018 16:08:01 -0800 Subject: [PATCH] Use LinkedHashMap on CharSequenceTransformation to keep order of insertions. Test: atest CtsAppSecurityHostTestCases:CharSequenceTransformationTest#testFieldsAreAppliedInOrder Fixes: 72118060 Change-Id: Ic8f5120fb4b5d10503a3909528accd0ecf6076f4 --- .../autofill/CharSequenceTransformation.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/core/java/android/service/autofill/CharSequenceTransformation.java b/core/java/android/service/autofill/CharSequenceTransformation.java index 2413e97ba8376..f52ac85052898 100644 --- a/core/java/android/service/autofill/CharSequenceTransformation.java +++ b/core/java/android/service/autofill/CharSequenceTransformation.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; -import android.util.ArrayMap; import android.util.Log; import android.util.Pair; import android.view.autofill.AutofillId; @@ -31,6 +30,8 @@ import android.widget.TextView; import com.android.internal.util.Preconditions; +import java.util.LinkedHashMap; +import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -62,7 +63,9 @@ import java.util.regex.Pattern; public final class CharSequenceTransformation extends InternalTransformation implements Transformation, Parcelable { private static final String TAG = "CharSequenceTransformation"; - @NonNull private final ArrayMap> mFields; + + // Must use LinkedHashMap to preserve insertion order. + @NonNull private final LinkedHashMap> mFields; private CharSequenceTransformation(Builder builder) { mFields = builder.mFields; @@ -76,9 +79,9 @@ public final class CharSequenceTransformation extends InternalTransformation imp final StringBuilder converted = new StringBuilder(); final int size = mFields.size(); if (sDebug) Log.d(TAG, size + " multiple fields on id " + childViewId); - for (int i = 0; i < size; i++) { - final AutofillId id = mFields.keyAt(i); - final Pair field = mFields.valueAt(i); + for (Entry> entry : mFields.entrySet()) { + final AutofillId id = entry.getKey(); + final Pair field = entry.getValue(); final String value = finder.findByAutofillId(id); if (value == null) { Log.w(TAG, "No value for id " + id); @@ -107,8 +110,10 @@ public final class CharSequenceTransformation extends InternalTransformation imp * Builder for {@link CharSequenceTransformation} objects. */ public static class Builder { - @NonNull private final ArrayMap> mFields = - new ArrayMap<>(); + + // Must use LinkedHashMap to preserve insertion order. + @NonNull private final LinkedHashMap> mFields = + new LinkedHashMap<>(); private boolean mDestroyed; /** @@ -186,12 +191,15 @@ public final class CharSequenceTransformation extends InternalTransformation imp final Pattern[] regexs = new Pattern[size]; final String[] substs = new String[size]; Pair pair; - for (int i = 0; i < size; i++) { - ids[i] = mFields.keyAt(i); - pair = mFields.valueAt(i); + int i = 0; + for (Entry> entry : mFields.entrySet()) { + ids[i] = entry.getKey(); + pair = entry.getValue(); regexs[i] = pair.first; substs[i] = pair.second; + i++; } + parcel.writeParcelableArray(ids, flags); parcel.writeSerializable(regexs); parcel.writeStringArray(substs);