Merge "Add support for app specific field classification."
diff --git a/api/current.txt b/api/current.txt
index 1b6229e..0e0c24e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -40467,6 +40467,7 @@
     method public android.service.autofill.FillResponse.Builder setHeader(android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
+    method public android.service.autofill.FillResponse.Builder setUserData(android.service.autofill.UserData);
   }
 
   public final class ImageTransformation implements android.os.Parcelable android.service.autofill.Transformation {
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 1cd76d2..bd3c3d3 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -175,7 +175,7 @@
     public float[][] onGetScores(@Nullable String algorithm,
             @Nullable Bundle algorithmOptions, @NonNull List<AutofillValue> actualValues,
             @NonNull List<String> userDataValues) {
-        Log.e(TAG, "service implementation (" + getClass() + " does not implement onGetScore()");
+        Log.e(TAG, "service implementation (" + getClass() + " does not implement onGetScores()");
         return null;
     }
 
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 7bf1f83..d408e9a 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -84,6 +84,7 @@
     private final @Nullable AutofillId[] mFieldClassificationIds;
     private final int mFlags;
     private int mRequestId;
+    private final @Nullable UserData mUserData;
 
     private FillResponse(@NonNull Builder builder) {
         mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
@@ -99,6 +100,7 @@
         mFieldClassificationIds = builder.mFieldClassificationIds;
         mFlags = builder.mFlags;
         mRequestId = INVALID_REQUEST_ID;
+        mUserData = builder.mUserData;
     }
 
     /** @hide */
@@ -157,6 +159,11 @@
     }
 
     /** @hide */
+    public @Nullable UserData getUserData() {
+        return mUserData;
+    }
+
+    /** @hide */
     @TestApi
     public int getFlags() {
         return mFlags;
@@ -198,6 +205,7 @@
         private AutofillId[] mFieldClassificationIds;
         private int mFlags;
         private boolean mDestroyed;
+        private UserData mUserData;
 
         /**
          * Triggers a custom UI before before autofilling the screen with any data set in this
@@ -506,6 +514,21 @@
         }
 
         /**
+         * Sets a specific {@link UserData} for field classification for this request only.
+         *
+         * @return this builder
+         * @throws IllegalStateException if the FillResponse
+         * {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews)
+         * requires authentication}.
+         */
+        public Builder setUserData(@NonNull UserData userData) {
+            throwIfDestroyed();
+            throwIfAuthenticationCalled();
+            mUserData = Preconditions.checkNotNull(userData);
+            return this;
+        }
+
+        /**
          * Builds a new {@link FillResponse} instance.
          *
          * @throws IllegalStateException if any of the following conditions occur:
@@ -599,6 +622,9 @@
         if (mFieldClassificationIds != null) {
             builder.append(Arrays.toString(mFieldClassificationIds));
         }
+        if (mUserData != null) {
+            builder.append(", userData=").append(mUserData);
+        }
         return builder.append("]").toString();
     }
 
@@ -621,6 +647,7 @@
         parcel.writeParcelable(mPresentation, flags);
         parcel.writeParcelable(mHeader, flags);
         parcel.writeParcelable(mFooter, flags);
+        parcel.writeParcelable(mUserData, flags);
         parcel.writeParcelableArray(mIgnoredIds, flags);
         parcel.writeLong(mDisableDuration);
         parcel.writeParcelableArray(mFieldClassificationIds, flags);
@@ -661,6 +688,10 @@
             if (footer != null) {
                 builder.setFooter(footer);
             }
+            final UserData userData = parcel.readParcelable(null);
+            if (userData != null) {
+                builder.setUserData(userData);
+            }
 
             builder.setIgnoredIds(parcel.readParcelableArray(null, AutofillId.class));
             final long disableDuration = parcel.readLong();
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index d76a5df..aef16b1 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1238,7 +1238,15 @@
             return;
         }
 
-        final UserData userData = mService.getUserData();
+        final UserData packageUserData = lastResponse.getUserData();
+
+        final UserData userData;
+        if (packageUserData != null) {
+            // Replace default userData
+            userData = packageUserData;
+        } else {
+            userData = mService.getUserData();
+        }
 
         for (int i = 0; i < mViewStates.size(); i++) {
             final ViewState viewState = mViewStates.valueAt(i);