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

Commit 5b446737 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "New Autofill APIs for UserData id."

parents bba3be6a f0baef74
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -11613,15 +11613,15 @@ package android.content.res {
  public final class AssetManager implements java.lang.AutoCloseable {
    method public void close();
    method public java.lang.String[] getLocales();
    method public java.lang.String[] list(java.lang.String) throws java.io.IOException;
    method public java.io.InputStream open(java.lang.String) throws java.io.IOException;
    method public java.io.InputStream open(java.lang.String, int) throws java.io.IOException;
    method public android.content.res.AssetFileDescriptor openFd(java.lang.String) throws java.io.IOException;
    method public android.content.res.AssetFileDescriptor openNonAssetFd(java.lang.String) throws java.io.IOException;
    method public android.content.res.AssetFileDescriptor openNonAssetFd(int, java.lang.String) throws java.io.IOException;
    method public android.content.res.XmlResourceParser openXmlResourceParser(java.lang.String) throws java.io.IOException;
    method public android.content.res.XmlResourceParser openXmlResourceParser(int, java.lang.String) throws java.io.IOException;
    method public final java.lang.String[] getLocales();
    method public final java.lang.String[] list(java.lang.String) throws java.io.IOException;
    method public final java.io.InputStream open(java.lang.String) throws java.io.IOException;
    method public final java.io.InputStream open(java.lang.String, int) throws java.io.IOException;
    method public final android.content.res.AssetFileDescriptor openFd(java.lang.String) throws java.io.IOException;
    method public final android.content.res.AssetFileDescriptor openNonAssetFd(java.lang.String) throws java.io.IOException;
    method public final android.content.res.AssetFileDescriptor openNonAssetFd(int, java.lang.String) throws java.io.IOException;
    method public final android.content.res.XmlResourceParser openXmlResourceParser(java.lang.String) throws java.io.IOException;
    method public final android.content.res.XmlResourceParser openXmlResourceParser(int, java.lang.String) throws java.io.IOException;
    field public static final int ACCESS_BUFFER = 3; // 0x3
    field public static final int ACCESS_RANDOM = 1; // 0x1
    field public static final int ACCESS_STREAMING = 2; // 0x2
@@ -38707,6 +38707,7 @@ package android.service.autofill {
  public final class UserData implements android.os.Parcelable {
    method public int describeContents();
    method public java.lang.String getFieldClassificationAlgorithm();
    method public java.lang.String getId();
    method public static int getMaxFieldClassificationIdsSize();
    method public static int getMaxUserDataSize();
    method public static int getMaxValueLength();
@@ -38716,7 +38717,7 @@ package android.service.autofill {
  }
  public static final class UserData.Builder {
    ctor public UserData.Builder(java.lang.String, java.lang.String);
    ctor public UserData.Builder(java.lang.String, java.lang.String, java.lang.String);
    method public android.service.autofill.UserData.Builder add(java.lang.String, java.lang.String);
    method public android.service.autofill.UserData build();
    method public android.service.autofill.UserData.Builder setFieldClassificationAlgorithm(java.lang.String, android.os.Bundle);
@@ -49568,6 +49569,7 @@ package android.view.autofill {
    method public java.util.List<java.lang.String> getAvailableFieldClassificationAlgorithms();
    method public java.lang.String getDefaultFieldClassificationAlgorithm();
    method public android.service.autofill.UserData getUserData();
    method public java.lang.String getUserDataId();
    method public boolean hasEnabledAutofillServices();
    method public boolean isAutofillSupported();
    method public boolean isEnabled();
+36 −8
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Settings;
import android.service.autofill.FieldClassification.Match;
import android.text.TextUtils;
import android.util.Log;
import android.view.autofill.AutofillManager;
import android.view.autofill.Helper;
@@ -52,12 +53,14 @@ public final class UserData implements Parcelable {
    private static final int DEFAULT_MIN_VALUE_LENGTH = 5;
    private static final int DEFAULT_MAX_VALUE_LENGTH = 100;

    private final String mId;
    private final String mAlgorithm;
    private final Bundle mAlgorithmArgs;
    private final String[] mRemoteIds;
    private final String[] mValues;

    private UserData(Builder builder) {
        mId = builder.mId;
        mAlgorithm = builder.mAlgorithm;
        mAlgorithmArgs = builder.mAlgorithmArgs;
        mRemoteIds = new String[builder.mRemoteIds.size()];
@@ -75,6 +78,13 @@ public final class UserData implements Parcelable {
        return mAlgorithm;
    }

    /**
     * Gets the id.
     */
    public String getId() {
        return mId;
    }

    /** @hide */
    public Bundle getAlgorithmArgs() {
        return mAlgorithmArgs;
@@ -92,6 +102,7 @@ public final class UserData implements Parcelable {

    /** @hide */
    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("id: "); pw.print(mId);
        pw.print(prefix); pw.print("Algorithm: "); pw.print(mAlgorithm);
        pw.print(" Args: "); pw.println(mAlgorithmArgs);

@@ -121,6 +132,7 @@ public final class UserData implements Parcelable {
     * A builder for {@link UserData} objects.
     */
    public static final class Builder {
        private final String mId;
        private final ArrayList<String> mRemoteIds;
        private final ArrayList<String> mValues;
        private String mAlgorithm;
@@ -131,16 +143,28 @@ public final class UserData implements Parcelable {
         * Creates a new builder for the user data used for <a href="#FieldClassification">field
         * classification</a>.
         *
         * <p>The user data must contain at least one pair of {@code remoteId} -> {@code value}, and
         * more pairs can be added through the {@link #add(String, String)} method.
         *
         * @param id id used to identify the whole {@link UserData} object. This id is also returned
         * by {@link AutofillManager#getUserDataId()}, which can be used to check if the
         * {@link UserData} is up-to-date without fetching the whole object (through
         * {@link AutofillManager#getUserData()}).
         * @param remoteId unique string used to identify a user data value.
         * @param value value of the user data.
         *
         * @throws IllegalArgumentException if any of the following occurs:
         * <ol>
         *   <li>{@code id} is empty
         *   <li>{@code remoteId} is empty
         *   <li>{@code value} is empty
         *   <li>the length of {@code value} is lower than {@link UserData#getMinValueLength()}
         *   <li>the length of {@code value} is higher than {@link UserData#getMaxValueLength()}
         * </ol>
         */
        public Builder(@NonNull String remoteId, @NonNull String value) {
            checkValidRemoteId(remoteId);
        public Builder(@NonNull String id, @NonNull String remoteId, @NonNull String value) {
            mId = checkNotEmpty("id", id);
            checkNotEmpty("remoteId", remoteId);
            checkValidValue(value);
            final int capacity = getMaxUserDataSize();
            mRemoteIds = new ArrayList<>(capacity);
@@ -188,7 +212,7 @@ public final class UserData implements Parcelable {
         */
        public Builder add(@NonNull String remoteId, @NonNull String value) {
            throwIfDestroyed();
            checkValidRemoteId(remoteId);
            checkNotEmpty("remoteId", remoteId);
            checkValidValue(value);

            Preconditions.checkState(!mRemoteIds.contains(remoteId),
@@ -205,9 +229,10 @@ public final class UserData implements Parcelable {
            return this;
        }

        private void checkValidRemoteId(@Nullable String remoteId) {
            Preconditions.checkNotNull(remoteId);
            Preconditions.checkArgument(!remoteId.isEmpty(), "remoteId cannot be empty");
        private String checkNotEmpty(@NonNull String name, @Nullable String value) {
            Preconditions.checkNotNull(value);
            Preconditions.checkArgument(!TextUtils.isEmpty(value), "%s cannot be empty", name);
            return value;
        }

        private void checkValidValue(@Nullable String value) {
@@ -246,7 +271,8 @@ public final class UserData implements Parcelable {
    public String toString() {
        if (!sDebug) return super.toString();

        final StringBuilder builder = new StringBuilder("UserData: [algorithm=").append(mAlgorithm);
        final StringBuilder builder = new StringBuilder("UserData: [id=").append(mId)
                .append(", algorithm=").append(mAlgorithm);
        // Cannot disclose remote ids or values because they could contain PII
        builder.append(", remoteIds=");
        Helper.appendRedacted(builder, mRemoteIds);
@@ -266,6 +292,7 @@ public final class UserData implements Parcelable {

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeString(mId);
        parcel.writeStringArray(mRemoteIds);
        parcel.writeStringArray(mValues);
        parcel.writeString(mAlgorithm);
@@ -279,9 +306,10 @@ public final class UserData implements Parcelable {
            // 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 String id = parcel.readString();
            final String[] remoteIds = parcel.readStringArray();
            final String[] values = parcel.readStringArray();
            final Builder builder = new Builder(remoteIds[0], values[0])
            final Builder builder = new Builder(id, remoteIds[0], values[0])
                    .setFieldClassificationAlgorithm(parcel.readString(), parcel.readBundle());
            for (int i = 1; i < remoteIds.length; i++) {
                builder.add(remoteIds[i], values[i]);
+25 −1
Original line number Diff line number Diff line
@@ -1098,6 +1098,30 @@ public final class AutofillManager {
        }
    }

    /**
     * Gets the id of the {@link UserData} used for
     * <a href="AutofillService.html#FieldClassification">field classification</a>.
     *
     * <p>This method is useful when the service must check the status of the {@link UserData} in
     * the device without fetching the whole object.
     *
     * <p><b>Note:</b> This method should only be called by an app providing an autofill service,
     * and it's ignored if the caller currently doesn't have an enabled autofill service for
     * the user.
     *
     * @return id of the {@link UserData} previously set by {@link #setUserData(UserData)}
     * or {@code null} if it was reset or if the caller currently does not have an enabled autofill
     * service for the user.
     */
    @Nullable public String getUserDataId() {
        try {
            return mService.getUserDataId();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
            return null;
        }
    }

    /**
     * Gets the user data used for
     * <a href="AutofillService.html#FieldClassification">field classification</a>.
@@ -1119,7 +1143,7 @@ public final class AutofillManager {
    }

    /**
     * Sets the user data used for
     * Sets the {@link UserData} used for
     * <a href="AutofillService.html#FieldClassification">field classification</a>
     *
     * <p><b>Note:</b> This method should only be called by an app providing an autofill service,
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ interface IAutoFillManager {
    boolean isServiceEnabled(int userId, String packageName);
    void onPendingSaveUi(int operation, IBinder token);
    UserData getUserData();
    String getUserDataId();
    void setUserData(in UserData userData);
    boolean isFieldClassificationEnabled();
    ComponentName getAutofillServiceComponentName();
+17 −0
Original line number Diff line number Diff line
@@ -616,6 +616,23 @@ public final class AutofillManagerService extends SystemService {
            return null;
        }

        @Override
        public String getUserDataId() throws RemoteException {
            final int userId = UserHandle.getCallingUserId();

            synchronized (mLock) {
                final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
                if (service != null) {
                    final UserData userData = service.getUserData(getCallingUid());
                    return userData == null ? null : userData.getId();
                } else if (sVerbose) {
                    Slog.v(TAG, "getUserDataId(): no service for " + userId);
                }
            }

            return null;
        }

        @Override
        public void setUserData(UserData userData) throws RemoteException {
            final int userId = UserHandle.getCallingUserId();