Loading api/current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -37054,7 +37054,7 @@ package android.service.autofill { } public static class ImageTransformation.Builder { ctor public ImageTransformation.Builder(android.view.autofill.AutofillId); ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int); method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int); method public android.service.autofill.ImageTransformation build(); } api/system-current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -40135,7 +40135,7 @@ package android.service.autofill { } public static class ImageTransformation.Builder { ctor public ImageTransformation.Builder(android.view.autofill.AutofillId); ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int); method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int); method public android.service.autofill.ImageTransformation build(); } api/test-current.txt +2 −1 Original line number Diff line number Diff line Loading @@ -37222,13 +37222,14 @@ package android.service.autofill { } public final class ImageTransformation implements android.os.Parcelable { method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int); method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.service.autofill.ImageTransformation> CREATOR; } public static class ImageTransformation.Builder { ctor public ImageTransformation.Builder(android.view.autofill.AutofillId); ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int); method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int); method public android.service.autofill.ImageTransformation build(); } core/java/android/service/autofill/ImageTransformation.java +41 −39 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package android.service.autofill; import static android.view.autofill.Helper.sDebug; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; Loading @@ -29,6 +31,8 @@ import android.widget.RemoteViews; import com.android.internal.util.Preconditions; import java.util.regex.Pattern; /** * Replaces the content of a child {@link ImageView} of a * {@link RemoteViews presentation template} with the first image that matches a regular expression Loading @@ -37,26 +41,20 @@ import com.android.internal.util.Preconditions; * <p>Typically used to display credit card logos. Example: * * <pre class="prettyprint"> * new ImageTransformation.Builder(ccNumberId) * .addOption("^4815.*$", R.drawable.ic_credit_card_logo1) * new ImageTransformation.Builder(ccNumberId, "^4815.*$", R.drawable.ic_credit_card_logo1) * .addOption("^1623.*$", R.drawable.ic_credit_card_logo2) * .addOption("^42.*$", R.drawable.ic_credit_card_logo3) * .build(); * </pre> * * <p>There is no imposed limit in the number of options, but keep in mind that regexs are * expensive to evaluate, so try to: * <ul> * <li>Use the minimum number of regex per image. * <li>Add the most common images first. * </ul> * expensive to evaluate, so use the minimum number of regexs. */ //TODO(b/62534917): add unit tests public final class ImageTransformation extends InternalTransformation implements Parcelable { private static final String TAG = "ImageTransformation"; private final AutofillId mId; private final ArrayMap<String, Integer> mOptions; private final ArrayMap<Pattern, Integer> mOptions; private ImageTransformation(Builder builder) { mId = builder.mId; Loading @@ -64,6 +62,7 @@ public final class ImageTransformation extends InternalTransformation implements } /** @hide */ @TestApi @Override public void apply(@NonNull ValueFinder finder, @NonNull RemoteViews parentTemplate, int childViewId) { Loading @@ -79,8 +78,8 @@ public final class ImageTransformation extends InternalTransformation implements } for (int i = 0; i < size; i++) { final String regex = mOptions.keyAt(i); if (value.matches(regex)) { final Pattern regex = mOptions.keyAt(i); if (regex.matcher(value).matches()) { Log.d(TAG, "Found match at " + i + ": " + regex); parentTemplate.setImageViewResource(childViewId, mOptions.valueAt(i)); return; Loading @@ -94,19 +93,22 @@ public final class ImageTransformation extends InternalTransformation implements */ public static class Builder { private final AutofillId mId; private ArrayMap<String, Integer> mOptions; private final ArrayMap<Pattern, Integer> mOptions = new ArrayMap<>(); private boolean mDestroyed; /** * Default constructor. * Create a new builder for a autofill id and add a first option. * * @param id id of the screen field that will be used to evaluate whether the image should * be used. * @param regex regular expression defining what should be matched to use this image. * @param resId resource id of the image (in the autofill service's package). The * {@link RemoteViews presentation} must contain a {@link ImageView} child with that id. */ //TODO(b/62534917): add a regex/resid so we force it to have at least one // (and then remove the check for empty from build()) public Builder(@NonNull AutofillId id) { public Builder(@NonNull AutofillId id, @NonNull String regex, @DrawableRes int resId) { mId = Preconditions.checkNotNull(id); addOption(regex, resId); } /** Loading @@ -118,13 +120,15 @@ public final class ImageTransformation extends InternalTransformation implements * * @return this build */ public Builder addOption(String regex, int resId) { //TODO(b/62534917): throw exception if regex / resId are invalid public Builder addOption(@NonNull String regex, @DrawableRes int resId) { throwIfDestroyed(); if (mOptions == null) { mOptions = new ArrayMap<>(); } mOptions.put(regex, resId); Preconditions.checkArgument(resId != 0); // Check regex Pattern pattern = Pattern.compile(regex); mOptions.put(pattern, resId); return this; } Loading Loading @@ -163,19 +167,15 @@ public final class ImageTransformation extends InternalTransformation implements public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeParcelable(mId, flags); if (mOptions == null) { parcel.writeStringArray(null); return; } final int size = mOptions.size(); final String[] regexs = new String[size]; final int[] resIds = new int[size]; for (int i = 0; i < size; i++) { regexs[i] = mOptions.keyAt(i); regexs[i] = mOptions.keyAt(i).pattern(); resIds[i] = mOptions.valueAt(i); } parcel.writeStringArray(regexs); Loading @@ -186,19 +186,21 @@ public final class ImageTransformation extends InternalTransformation implements new Parcelable.Creator<ImageTransformation>() { @Override public ImageTransformation createFromParcel(Parcel parcel) { // Always go through the builder to ensure the data ingested by // the system obeys the contract of the builder to avoid attacks // using specially crafted parcels. final ImageTransformation.Builder builder = new ImageTransformation.Builder(parcel.readParcelable(null)); final AutofillId id = parcel.readParcelable(null); final String[] regexs = parcel.createStringArray(); if (regexs != null) { final int[] resIds = parcel.createIntArray(); // Always go through the builder to ensure the data ingested by the system obeys the // contract of the builder to avoid attacks using specially crafted parcels. final ImageTransformation.Builder builder = new ImageTransformation.Builder(id, regexs[0], resIds[0]); final int size = regexs.length; for (int i = 0; i < size; i++) { for (int i = 1; i < size; i++) { builder.addOption(regexs[i], resIds[i]); } } return builder.build(); } Loading Loading
api/current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -37054,7 +37054,7 @@ package android.service.autofill { } public static class ImageTransformation.Builder { ctor public ImageTransformation.Builder(android.view.autofill.AutofillId); ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int); method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int); method public android.service.autofill.ImageTransformation build(); }
api/system-current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -40135,7 +40135,7 @@ package android.service.autofill { } public static class ImageTransformation.Builder { ctor public ImageTransformation.Builder(android.view.autofill.AutofillId); ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int); method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int); method public android.service.autofill.ImageTransformation build(); }
api/test-current.txt +2 −1 Original line number Diff line number Diff line Loading @@ -37222,13 +37222,14 @@ package android.service.autofill { } public final class ImageTransformation implements android.os.Parcelable { method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int); method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.service.autofill.ImageTransformation> CREATOR; } public static class ImageTransformation.Builder { ctor public ImageTransformation.Builder(android.view.autofill.AutofillId); ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int); method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int); method public android.service.autofill.ImageTransformation build(); }
core/java/android/service/autofill/ImageTransformation.java +41 −39 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package android.service.autofill; import static android.view.autofill.Helper.sDebug; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; Loading @@ -29,6 +31,8 @@ import android.widget.RemoteViews; import com.android.internal.util.Preconditions; import java.util.regex.Pattern; /** * Replaces the content of a child {@link ImageView} of a * {@link RemoteViews presentation template} with the first image that matches a regular expression Loading @@ -37,26 +41,20 @@ import com.android.internal.util.Preconditions; * <p>Typically used to display credit card logos. Example: * * <pre class="prettyprint"> * new ImageTransformation.Builder(ccNumberId) * .addOption("^4815.*$", R.drawable.ic_credit_card_logo1) * new ImageTransformation.Builder(ccNumberId, "^4815.*$", R.drawable.ic_credit_card_logo1) * .addOption("^1623.*$", R.drawable.ic_credit_card_logo2) * .addOption("^42.*$", R.drawable.ic_credit_card_logo3) * .build(); * </pre> * * <p>There is no imposed limit in the number of options, but keep in mind that regexs are * expensive to evaluate, so try to: * <ul> * <li>Use the minimum number of regex per image. * <li>Add the most common images first. * </ul> * expensive to evaluate, so use the minimum number of regexs. */ //TODO(b/62534917): add unit tests public final class ImageTransformation extends InternalTransformation implements Parcelable { private static final String TAG = "ImageTransformation"; private final AutofillId mId; private final ArrayMap<String, Integer> mOptions; private final ArrayMap<Pattern, Integer> mOptions; private ImageTransformation(Builder builder) { mId = builder.mId; Loading @@ -64,6 +62,7 @@ public final class ImageTransformation extends InternalTransformation implements } /** @hide */ @TestApi @Override public void apply(@NonNull ValueFinder finder, @NonNull RemoteViews parentTemplate, int childViewId) { Loading @@ -79,8 +78,8 @@ public final class ImageTransformation extends InternalTransformation implements } for (int i = 0; i < size; i++) { final String regex = mOptions.keyAt(i); if (value.matches(regex)) { final Pattern regex = mOptions.keyAt(i); if (regex.matcher(value).matches()) { Log.d(TAG, "Found match at " + i + ": " + regex); parentTemplate.setImageViewResource(childViewId, mOptions.valueAt(i)); return; Loading @@ -94,19 +93,22 @@ public final class ImageTransformation extends InternalTransformation implements */ public static class Builder { private final AutofillId mId; private ArrayMap<String, Integer> mOptions; private final ArrayMap<Pattern, Integer> mOptions = new ArrayMap<>(); private boolean mDestroyed; /** * Default constructor. * Create a new builder for a autofill id and add a first option. * * @param id id of the screen field that will be used to evaluate whether the image should * be used. * @param regex regular expression defining what should be matched to use this image. * @param resId resource id of the image (in the autofill service's package). The * {@link RemoteViews presentation} must contain a {@link ImageView} child with that id. */ //TODO(b/62534917): add a regex/resid so we force it to have at least one // (and then remove the check for empty from build()) public Builder(@NonNull AutofillId id) { public Builder(@NonNull AutofillId id, @NonNull String regex, @DrawableRes int resId) { mId = Preconditions.checkNotNull(id); addOption(regex, resId); } /** Loading @@ -118,13 +120,15 @@ public final class ImageTransformation extends InternalTransformation implements * * @return this build */ public Builder addOption(String regex, int resId) { //TODO(b/62534917): throw exception if regex / resId are invalid public Builder addOption(@NonNull String regex, @DrawableRes int resId) { throwIfDestroyed(); if (mOptions == null) { mOptions = new ArrayMap<>(); } mOptions.put(regex, resId); Preconditions.checkArgument(resId != 0); // Check regex Pattern pattern = Pattern.compile(regex); mOptions.put(pattern, resId); return this; } Loading Loading @@ -163,19 +167,15 @@ public final class ImageTransformation extends InternalTransformation implements public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeParcelable(mId, flags); if (mOptions == null) { parcel.writeStringArray(null); return; } final int size = mOptions.size(); final String[] regexs = new String[size]; final int[] resIds = new int[size]; for (int i = 0; i < size; i++) { regexs[i] = mOptions.keyAt(i); regexs[i] = mOptions.keyAt(i).pattern(); resIds[i] = mOptions.valueAt(i); } parcel.writeStringArray(regexs); Loading @@ -186,19 +186,21 @@ public final class ImageTransformation extends InternalTransformation implements new Parcelable.Creator<ImageTransformation>() { @Override public ImageTransformation createFromParcel(Parcel parcel) { // Always go through the builder to ensure the data ingested by // the system obeys the contract of the builder to avoid attacks // using specially crafted parcels. final ImageTransformation.Builder builder = new ImageTransformation.Builder(parcel.readParcelable(null)); final AutofillId id = parcel.readParcelable(null); final String[] regexs = parcel.createStringArray(); if (regexs != null) { final int[] resIds = parcel.createIntArray(); // Always go through the builder to ensure the data ingested by the system obeys the // contract of the builder to avoid attacks using specially crafted parcels. final ImageTransformation.Builder builder = new ImageTransformation.Builder(id, regexs[0], resIds[0]); final int size = regexs.length; for (int i = 0; i < size; i++) { for (int i = 1; i < size; i++) { builder.addOption(regexs[i], resIds[i]); } } return builder.build(); } Loading