Made Autofill Field Classification API public and documented it.
Test: mmm frameworks/base/:doc-comment-check-docs
Test: atest FrameworksCoreTests:SettingsBackupTest
Test: m -j 100 update-api
Fixes: 67867469
Change-Id: Iedf56a2bbcde3826eb22f5ed7a96d6ed70b968f4
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index abc16ce..d0c1003 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5328,48 +5328,51 @@
public static final String AUTOFILL_SERVICE = "autofill_service";
/**
- * Experimental autofill feature.
+ * Boolean indicating if Autofill supports field classification.
*
- * <p>TODO(b/67867469): document (or remove) once feature is finished
+ * @see android.service.autofill.AutofillService
+ *
* @hide
*/
+ @SystemApi
@TestApi
public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION =
"autofill_field_classification";
/**
- * Experimental autofill feature.
+ * Defines value returned by {@link android.service.autofill.UserData#getMaxUserDataSize()}.
*
- * <p>TODO(b/67867469): document (or remove) once feature is finished
* @hide
*/
+ @SystemApi
public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE =
"autofill_user_data_max_user_data_size";
/**
- * Experimental autofill feature.
+ * Defines value returned by
+ * {@link android.service.autofill.UserData#getMaxFieldClassificationIdsSize()}.
*
- * <p>TODO(b/67867469): document (or remove) once feature is finished
* @hide
*/
+ @SystemApi
public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE =
"autofill_user_data_max_field_classification_size";
/**
- * Experimental autofill feature.
+ * Defines value returned by {@link android.service.autofill.UserData#getMaxValueLength()}.
*
- * <p>TODO(b/67867469): document (or remove) once feature is finished
* @hide
*/
+ @SystemApi
public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH =
"autofill_user_data_max_value_length";
/**
- * Experimental autofill feature.
+ * Defines value returned by {@link android.service.autofill.UserData#getMinValueLength()}.
*
- * <p>TODO(b/67867469): document (or remove) once feature is finished
* @hide
*/
+ @SystemApi
public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH =
"autofill_user_data_min_value_length";
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 97fdcef..2600f8a 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -453,13 +453,46 @@
* email address), the service should only use it locally (i.e., in the app's process) for
* heuristics purposes, but it should not be sent to external servers.
*
- * <a name="FieldsClassification"></a>
- * <h3>Metrics and fields classification</h3
+ * <a name="FieldClassification"></a>
+ * <h3>Metrics and field classification</h3
*
- * <p>TODO(b/67867469): document it or remove this section; in particular, document the relationship
- * between set/getUserData(), FillResponse.setFieldClassificationIds(), and
- * FillEventHistory.getFieldsClassification.
+ * <p>The service can call {@link #getFillEventHistory()} to get metrics representing the user
+ * actions, and then use these metrics to improve its heuristics.
+ *
+ * <p>Prior to Android {@link android.os.Build.VERSION_CODES#P}, the metrics covered just the
+ * scenarios where the service knew how to autofill an activity, but Android
+ * {@link android.os.Build.VERSION_CODES#P} introduced a new mechanism called field classification,
+ * which allows the service to dinamically classify the meaning of fields based on the existing user
+ * data known by the service.
+ *
+ * <p>Typically, field classification can be used to detect fields that can be autofilled with
+ * user data that is not associated with a specific app—such as email and physical
+ * address. Once the service identifies that a such field was manually filled by the user, the
+ * service could use this signal to improve its heuristics, either locally (i.e., in the same
+ * device) or globally (i.e., by crowdsourcing the results back to the service's server so it can
+ * be used by other users).
+ *
+ * <p>The field classification workflow involves 4 steps:
+ *
+ * <ol>
+ * <li>Set the user data through {@link AutofillManager#setUserData(UserData)}. This data is
+ * cached until the system restarts (or the service is disabled), so it doesn't need to be set for
+ * all requests.
+ * <li>Identify which fields should be analysed by calling
+ * {@link FillResponse.Builder#setFieldClassificationIds(AutofillId...)}.
+ * <li>Verify the results through {@link FillEventHistory.Event#getFieldsClassification()}.
+ * <li>Use the results to dynamically create {@link Dataset} or {@link SaveInfo} objects in future
+ * requests.
+ * </ol>
+ *
+ * <p>The field classification is an expensive operation and should be used carefully, otherwise it
+ * can reach its rate limit and get blocked by the Android System. Ideally, it should be used just
+ * in cases where the service could not determine how an activity can be autofilled, but it has a
+ * strong suspicious that it could. For example, if an activity has four or more fields and one of
+ * them is a list, chances are that these are address fields (like address, city, state, and
+ * zip code).
*/
+// TODO(b/70407264): add code snippets above???
public abstract class AutofillService extends Service {
private static final String TAG = "AutofillService";
diff --git a/core/java/android/service/autofill/EditDistanceScorer.java b/core/java/android/service/autofill/EditDistanceScorer.java
index e25cd04..0706b37 100644
--- a/core/java/android/service/autofill/EditDistanceScorer.java
+++ b/core/java/android/service/autofill/EditDistanceScorer.java
@@ -16,7 +16,6 @@
package android.service.autofill;
import android.annotation.NonNull;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.autofill.AutofillValue;
@@ -24,14 +23,8 @@
/**
* Helper used to calculate the classification score between an actual {@link AutofillValue} filled
* by the user and the expected value predicted by an autofill service.
- *
- * TODO(b/67867469):
- * - improve javadoc
- * - document algorithm / copy from InternalScorer
- * - unhide / remove testApi
- * @hide
*/
-@TestApi
+// TODO(b/70291841): explain algorithm once it's fully implemented
public final class EditDistanceScorer extends InternalScorer implements Scorer, Parcelable {
private static final EditDistanceScorer sInstance = new EditDistanceScorer();
@@ -46,10 +39,11 @@
private EditDistanceScorer() {
}
+ /** @hide */
@Override
public float getScore(@NonNull AutofillValue actualValue, @NonNull String userData) {
if (actualValue == null || !actualValue.isText() || userData == null) return 0;
- // TODO(b/67867469): implement edit distance - currently it's returning either 0, 100%, or
+ // TODO(b/70291841): implement edit distance - currently it's returning either 0, 100%, or
// partial match when number of chars match
final String textValue = actualValue.getTextValue().toString();
final int total = textValue.length();
diff --git a/core/java/android/service/autofill/FieldClassification.java b/core/java/android/service/autofill/FieldClassification.java
index 0a60208..b28c6f8 100644
--- a/core/java/android/service/autofill/FieldClassification.java
+++ b/core/java/android/service/autofill/FieldClassification.java
@@ -19,7 +19,6 @@
import static android.view.autofill.Helper.sDebug;
import android.annotation.NonNull;
-import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.autofill.Helper;
@@ -31,15 +30,10 @@
import java.util.List;
/**
- * Gets the <a href="#FieldsClassification">fields classification</a> results for a given field.
- *
- * TODO(b/67867469):
- * - improve javadoc
- * - unhide / remove testApi
- *
- * @hide
+ * Represents the <a href="AutofillService.html#FieldClassification">field classification</a>
+ * results for a given field.
*/
-@TestApi
+// TODO(b/70291841): let caller handle Parcelable...
public final class FieldClassification implements Parcelable {
private final Match mMatch;
@@ -79,7 +73,7 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeParcelable(mMatch, flags);
+ mMatch.writeToParcel(parcel);
}
public static final Parcelable.Creator<FieldClassification> CREATOR =
@@ -87,7 +81,7 @@
@Override
public FieldClassification createFromParcel(Parcel parcel) {
- return new FieldClassification(parcel.readParcelable(null));
+ return new FieldClassification(Match.readFromParcel(parcel));
}
@Override
@@ -97,16 +91,12 @@
};
/**
- * Gets the score of a {@link UserData} entry for the field.
+ * Represents the score of a {@link UserData} entry for the field.
*
- * TODO(b/67867469):
- * - improve javadoc
- * - unhide / remove testApi
- *
- * @hide
+ * <p>The score is defined by {@link #getScore()} and the entry is identified by
+ * {@link #getRemoteId()}.
*/
- @TestApi
- public static final class Match implements Parcelable {
+ public static final class Match {
private final String mRemoteId;
private final float mScore;
@@ -126,26 +116,19 @@
}
/**
- * Gets a score between the value of this field and the value of the {@link UserData} entry.
+ * Gets a classification score for the value of this field compared to the value of the
+ * {@link UserData} entry.
*
- * <p>The score is based in a case-insensitive comparisson of all characters from both the
- * field value and the user data entry, and it ranges from {@code 0} to {@code 1000000}:
+ * <p>The score is based in a comparison of the field value and the user data entry, and it
+ * ranges from {@code 0.0F} to {@code 1.0F}:
* <ul>
- * <li>{@code 1.0} represents a full match ({@code 100%}).
- * <li>{@code 0.0} represents a full mismatch ({@code 0%}).
+ * <li>{@code 1.0F} represents a full match ({@code 100%}).
+ * <li>{@code 0.0F} represents a full mismatch ({@code 0%}).
* <li>Any other value is a partial match.
* </ul>
*
- * <p>How the score is calculated depends on the algorithm used by the Android System.
- * For example, if the user data is {@code "abc"} and the field value us {@code " abc"},
- * the result could be:
- * <ul>
- * <li>{@code 1.0} if the algorithm trims the values.
- * <li>{@code 0.0} if the algorithm compares the values sequentially.
- * <li>{@code 0.75} if the algorithm consideres that 3/4 (75%) of the characters match.
- * </ul>
- *
- * <p>Currently, the autofill service cannot configure the algorithm.
+ * <p>How the score is calculated depends on the algorithm used by the {@link Scorer}
+ * implementation.
*/
public float getScore() {
return mScore;
@@ -160,33 +143,31 @@
return string.append(", score=").append(mScore).toString();
}
- /////////////////////////////////////
- // Parcelable "contract" methods. //
- /////////////////////////////////////
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int flags) {
+ private void writeToParcel(@NonNull Parcel parcel) {
parcel.writeString(mRemoteId);
parcel.writeFloat(mScore);
}
- @SuppressWarnings("hiding")
- public static final Parcelable.Creator<Match> CREATOR = new Parcelable.Creator<Match>() {
+ private static Match readFromParcel(@NonNull Parcel parcel) {
+ return new Match(parcel.readString(), parcel.readFloat());
+ }
- @Override
- public Match createFromParcel(Parcel parcel) {
- return new Match(parcel.readString(), parcel.readFloat());
+ /** @hide */
+ public static Match[] readArrayFromParcel(@NonNull Parcel parcel) {
+ final int length = parcel.readInt();
+ final Match[] matches = new Match[length];
+ for (int i = 0; i < length; i++) {
+ matches[i] = readFromParcel(parcel);
}
+ return matches;
+ }
- @Override
- public Match[] newArray(int size) {
- return new Match[size];
+ /** @hide */
+ public static void writeArrayToParcel(@NonNull Parcel parcel, @NonNull Match[] matches) {
+ parcel.writeInt(matches.length);
+ for (int i = 0; i < matches.length; i++) {
+ matches[i].writeToParcel(parcel);
}
- };
+ }
}
}
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index a527f16..07fab61 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -21,7 +21,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.content.IntentSender;
import android.os.Bundle;
import android.os.Parcel;
@@ -158,7 +157,7 @@
final AutofillId[] detectedFields = event.mDetectedFieldIds;
parcel.writeParcelableArray(detectedFields, flags);
if (detectedFields != null) {
- parcel.writeParcelableArray(event.mDetectedMatches, flags);
+ Match.writeArrayToParcel(parcel, event.mDetectedMatches);
}
}
}
@@ -208,6 +207,7 @@
* ({@link #getIgnoredDatasetIds()}).
* <li>Which fields in the selected datasets were changed by the user after the dataset
* was selected ({@link #getChangedFields()}.
+ * <li>Which fields match the {@link UserData} set by the service.
* </ul>
*
* <p><b>Note: </b>This event is only generated when:
@@ -222,7 +222,6 @@
* <p>See {@link android.view.autofill.AutofillManager} for more information about autofill
* contexts.
*/
- // TODO(b/67867469): update with field detection behavior
public static final int TYPE_CONTEXT_COMMITTED = 4;
/** @hide */
@@ -356,19 +355,13 @@
}
/**
- * Gets the <a href="#FieldsClassification">fields classification</a> results.
+ * Gets the <a href="AutofillService.html#FieldClassification">field classification</a>
+ * results.
*
* <p><b>Note: </b>Only set on events of type {@link #TYPE_CONTEXT_COMMITTED}, when the
* service requested {@link FillResponse.Builder#setFieldClassificationIds(AutofillId...)
- * fields classification}.
- *
- * TODO(b/67867469):
- * - improve javadoc
- * - unhide / remove testApi
- *
- * @hide
+ * field classification}.
*/
- @TestApi
@NonNull public Map<AutofillId, FieldClassification> getFieldsClassification() {
if (mDetectedFieldIds == null) {
return Collections.emptyMap();
@@ -462,6 +455,8 @@
* and belonged to datasets.
* @param manuallyFilledDatasetIds The ids of datasets that had values matching the
* respective entry on {@code manuallyFilledFieldIds}.
+ * @param detectedMatches the field classification matches.
+ *
* @throws IllegalArgumentException If the length of {@code changedFieldIds} and
* {@code changedDatasetIds} doesn't match.
* @throws IllegalArgumentException If the length of {@code manuallyFilledFieldIds} and
@@ -469,7 +464,6 @@
*
* @hide
*/
- // TODO(b/67867469): document field classification parameters once stable
public Event(int eventType, @Nullable String datasetId, @Nullable Bundle clientState,
@Nullable List<String> selectedDatasetIds,
@Nullable ArraySet<String> ignoredDatasetIds,
@@ -477,7 +471,7 @@
@Nullable ArrayList<String> changedDatasetIds,
@Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
@Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
- @Nullable AutofillId[] detectedFieldIds, @Nullable Match[] detectedMaches) {
+ @Nullable AutofillId[] detectedFieldIds, @Nullable Match[] detectedMatches) {
mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_CONTEXT_COMMITTED,
"eventType");
mDatasetId = datasetId;
@@ -502,7 +496,7 @@
mManuallyFilledDatasetIds = manuallyFilledDatasetIds;
mDetectedFieldIds = detectedFieldIds;
- mDetectedMatches = detectedMaches;
+ mDetectedMatches = detectedMatches;
}
@Override
@@ -555,7 +549,7 @@
final AutofillId[] detectedFieldIds = parcel.readParcelableArray(null,
AutofillId.class);
final Match[] detectedMatches = (detectedFieldIds != null)
- ? parcel.readParcelableArray(null, Match.class)
+ ? Match.readArrayFromParcel(parcel)
: null;
selection.addEvent(new Event(eventType, datasetId, clientState,
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 014d3e8..3a4b6bb 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -41,7 +41,7 @@
import java.util.List;
/**
- * Response for a {@link
+ * Response for an {@link
* AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}.
*
* <p>See the main {@link AutofillService} documentation for more details and examples.
@@ -156,6 +156,7 @@
}
/** @hide */
+ @TestApi
public int getFlags() {
return mFlags;
}
@@ -352,22 +353,18 @@
}
/**
- * Sets which fields are used for <a href="#FieldsClassification">fields classification</a>
+ * Sets which fields are used for
+ * <a href="AutofillService.html#FieldClassification">field classification</a>
*
+ * <p><b>Note:</b> This method automatically adds the
+ * {@link FillResponse#FLAG_TRACK_CONTEXT_COMMITED} to the {@link #setFlags(int) flags}.
+
* @throws IllegalArgumentException is length of {@code ids} args is more than
* {@link UserData#getMaxFieldClassificationIdsSize()}.
* @throws IllegalStateException if {@link #build()} or {@link #disableAutofill(long)} was
* already called.
* @throws NullPointerException if {@code ids} or any element on it is {@code null}.
- *
- * TODO(b/67867469):
- * - improve javadoc: explain relationship with UserData and how to check results
- * - unhide / remove testApi
- * - implement multiple ids
- *
- * @hide
*/
- @TestApi
public Builder setFieldClassificationIds(@NonNull AutofillId... ids) {
throwIfDestroyed();
throwIfDisableAutofillCalled();
@@ -375,6 +372,7 @@
Preconditions.checkArgumentInRange(ids.length, 1,
UserData.getMaxFieldClassificationIdsSize(), "ids length");
mFieldClassificationIds = ids;
+ mFlags |= FLAG_TRACK_CONTEXT_COMMITED;
return this;
}
@@ -423,9 +421,8 @@
* @throws IllegalStateException if either {@link #addDataset(Dataset)},
* {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews)},
* {@link #setSaveInfo(SaveInfo)}, {@link #setClientState(Bundle)}, or
- * {link #setFieldClassificationIds(AutofillId...)} was already called.
+ * {@link #setFieldClassificationIds(AutofillId...)} was already called.
*/
- // TODO(b/67867469): add @ to {link setFieldClassificationIds} once it's public
public Builder disableAutofill(long duration) {
throwIfDestroyed();
if (duration <= 0) {
@@ -506,14 +503,13 @@
* {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews)},
* {@link #setSaveInfo(SaveInfo)}, {@link #disableAutofill(long)},
* {@link #setClientState(Bundle)},
- * or {link #setFieldClassificationIds(AutofillId...)}.
+ * or {@link #setFieldClassificationIds(AutofillId...)}.
* <li>{@link #setHeader(RemoteViews)} or {@link #setFooter(RemoteViews)} is called
* without any previous calls to {@link #addDataset(Dataset)}.
* </ol>
*
* @return A built response.
*/
- // TODO(b/67867469): add @ to {link setFieldClassificationIds} once it's public
public FillResponse build() {
throwIfDestroyed();
if (mAuthentication == null && mDatasets == null && mSaveInfo == null
diff --git a/core/java/android/service/autofill/Scorer.java b/core/java/android/service/autofill/Scorer.java
index f6a802a..c401855 100644
--- a/core/java/android/service/autofill/Scorer.java
+++ b/core/java/android/service/autofill/Scorer.java
@@ -15,21 +15,14 @@
*/
package android.service.autofill;
-import android.annotation.TestApi;
-
/**
* Helper class used to calculate a score.
*
- * <p>Typically used to calculate the field classification score between an actual
- * {@link android.view.autofill.AutofillValue} filled by the user and the expected value predicted
- * by an autofill service.
- *
- * TODO(b/67867469):
- * - improve javadoc
- * - unhide / remove testApi
- * @hide
+ * <p>Typically used to calculate the
+ * <a href="AutofillService.html#FieldClassification">field classification</a> score between an
+ * actual {@link android.view.autofill.AutofillValue} filled by the user and the expected value
+ * predicted by an autofill service.
*/
-@TestApi
public interface Scorer {
}
diff --git a/core/java/android/service/autofill/UserData.java b/core/java/android/service/autofill/UserData.java
index 0d37815..f0cc360 100644
--- a/core/java/android/service/autofill/UserData.java
+++ b/core/java/android/service/autofill/UserData.java
@@ -23,7 +23,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.app.ActivityThread;
import android.content.ContentResolver;
import android.os.Parcel;
@@ -38,15 +37,9 @@
import java.util.ArrayList;
/**
- * Class used by service to improve autofillable fields detection by tracking the meaning of fields
- * manually edited by the user (when they match values provided by the service).
- *
- * TODO(b/67867469):
- * - improve javadoc / add link to section on AutofillService
- * - unhide / remove testApi
- * @hide
+ * Defines the user data used for
+ * <a href="AutofillService.html#FieldClassification">field classification</a>.
*/
-@TestApi
public final class UserData implements Parcelable {
private static final String TAG = "UserData";
@@ -110,12 +103,7 @@
/**
* A builder for {@link UserData} objects.
- *
- * TODO(b/67867469): unhide / remove testApi
- *
- * @hide
*/
- @TestApi
public static final class Builder {
private final InternalScorer mScorer;
private final ArrayList<String> mRemoteIds;
@@ -123,7 +111,7 @@
private boolean mDestroyed;
/**
- * Creates a new builder for the user data used for <a href="#FieldsClassification">fields
+ * Creates a new builder for the user data used for <a href="#FieldClassification">field
* classification</a>.
*
* @throws IllegalArgumentException if any of the following occurs:
@@ -288,14 +276,16 @@
}
/**
- * Gets the minimum length of values passed to {@link Builder#Builder(Scorer, String, String)}.
+ * Gets the minimum length of values passed to the builder's constructor or
+ * or {@link Builder#add(String, String)}.
*/
public static int getMinValueLength() {
return getInt(AUTOFILL_USER_DATA_MIN_VALUE_LENGTH, DEFAULT_MIN_VALUE_LENGTH);
}
/**
- * Gets the maximum length of values passed to {@link Builder#Builder(Scorer, String, String)}.
+ * Gets the maximum length of values passed to the builder's constructor or
+ * or {@link Builder#add(String, String)}.
*/
public static int getMaxValueLength() {
return getInt(AUTOFILL_USER_DATA_MAX_VALUE_LENGTH, DEFAULT_MAX_VALUE_LENGTH);
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 6d84aa0..d0dbff0e 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -24,7 +24,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
-import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -1010,20 +1009,14 @@
}
/**
- * Gets the user data used for <a href="#FieldsClassification">fields classification</a>.
+ * Gets the user data 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.
*
- * TODO(b/67867469):
- * - proper javadoc
- * - unhide / remove testApi
- *
* @return value 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.
- *
- * @hide
*/
- @TestApi
@Nullable public UserData getUserData() {
try {
return mService.getUserData();
@@ -1034,21 +1027,13 @@
}
/**
- * Sets the user data used for <a href="#FieldsClassification">fields classification</a>.
+ * Sets the user data 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,
* and it's ignored if the caller currently doesn't have an enabled autofill service for
* the user.
- *
- * TODO(b/67867469):
- * - proper javadoc
- * - unhide / remove testApi
- * - add unit tests:
- * - call set / get / verify
- *
- * @hide
*/
- @TestApi
public void setUserData(@Nullable UserData userData) {
try {
mService.setUserData(userData);
@@ -1058,13 +1043,17 @@
}
/**
- * TODO(b/67867469):
- * - proper javadoc
- * - mention this method in other places
- * - unhide / remove testApi
- * @hide
+ * Checks if <a href="AutofillService.html#FieldClassification">field classification</a> is
+ * enabled.
+ *
+ * <p>As field classification is an expensive operation, it could be disabled, either
+ * temporarily (for example, because the service exceeded a rate-limit threshold) or
+ * permanently (for example, because the device is a low-level device).
+ *
+ * <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.
*/
- @TestApi
public boolean isFieldClassificationEnabled() {
try {
return mService.isFieldClassificationEnabled();