From 6f0c9ce894c56394910a25c9de85fff757381d2f Mon Sep 17 00:00:00 2001 From: Reema Bajwa Date: Fri, 3 Mar 2023 01:16:49 +0000 Subject: [PATCH] Exposes a new CredentialEntry constructor that takes in raw Id Based on DP1 feedback, if a provider adds > 20 entries we are seeing a size limit exception. While we are investigating different issues, one of the potential reasons for more data being passed than is needed is passing the entire option to the entry, which could contain a no. of strings. Hence, changing the framework constructor to take in an id only. In jetpack, we will still take in an option and internally extract the id and type and pass those to the framework. Test: CTS tests Bug: 269501289 Bug: 271298276 Change-Id: Icd6fe6b9a19d137b38785b1ef17c1c13a254e5a6 --- core/api/current.txt | 3 +- .../service/credentials/CredentialEntry.java | 59 +++++++++++++++---- .../credentials/ProviderGetSession.java | 3 +- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 259f1e9d4c538..f9d755ad377f6 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -40640,9 +40640,10 @@ package android.service.credentials { } public class CredentialEntry implements android.os.Parcelable { + ctor public CredentialEntry(@NonNull String, @NonNull String, @NonNull android.app.slice.Slice); ctor public CredentialEntry(@NonNull android.service.credentials.BeginGetCredentialOption, @NonNull android.app.slice.Slice); method public int describeContents(); - method @NonNull public android.service.credentials.BeginGetCredentialOption getBeginGetCredentialOption(); + method @NonNull public String getBeginGetCredentialOptionId(); method @NonNull public android.app.slice.Slice getSlice(); method @NonNull public String getType(); method public void writeToParcel(@NonNull android.os.Parcel, int); diff --git a/core/java/android/service/credentials/CredentialEntry.java b/core/java/android/service/credentials/CredentialEntry.java index 7e98bc7eb9752..85eac6edb6d27 100644 --- a/core/java/android/service/credentials/CredentialEntry.java +++ b/core/java/android/service/credentials/CredentialEntry.java @@ -27,6 +27,8 @@ import android.credentials.GetCredentialResponse; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.util.Preconditions; + /** * A credential entry that is to be displayed on the account selector that is presented to the * user. @@ -56,7 +58,7 @@ import android.os.Parcelable; @SuppressLint("ParcelNotFinal") public class CredentialEntry implements Parcelable { /** The request option that corresponds to this entry. **/ - private final @Nullable BeginGetCredentialOption mBeginGetCredentialOption; + private final @Nullable String mBeginGetCredentialOptionId; /** The type of the credential entry to be shown on the UI. */ private final @NonNull String mType; @@ -66,6 +68,35 @@ public class CredentialEntry implements Parcelable { * on the UI. */ private final @NonNull Slice mSlice; + /** + * Creates an entry that is associated with a {@link BeginGetCredentialOption} request. + * Providers must use this constructor when they extend from {@link CredentialProviderService} + * to respond to query phase {@link CredentialProviderService#onBeginGetCredential} + * credential retrieval requests. + * + * @param beginGetCredentialOptionId the beginGetCredentialOptionId to be retrieved from + * {@link BeginGetCredentialOption#getId()} - the request option for which this CredentialEntry + * is being constructed This helps maintain an association + * such that when the user selects this entry, providers can + * receive the complete corresponding + * {@link GetCredentialRequest}. + * @param type the type of the credential for which this credential entry is being created + * @param slice the slice containing the metadata to be shown on the UI. Must be + * constructed through the androidx.credentials jetpack library. + * + * @throws IllegalArgumentException If {@code beginGetCredentialOptionId} or {@code type} + * is null, or empty + */ + public CredentialEntry(@NonNull String beginGetCredentialOptionId, @NonNull String type, + @NonNull Slice slice) { + mBeginGetCredentialOptionId = Preconditions.checkStringNotEmpty( + beginGetCredentialOptionId, "beginGetCredentialOptionId must not be " + + "null, or empty"); + mType = Preconditions.checkStringNotEmpty(type, "type must not be null, or " + + "empty"); + mSlice = requireNonNull(slice, "slice must not be null"); + } + /** * Creates an entry that is associated with a {@link BeginGetCredentialOption} request. * Providers must use this constructor when they extend from {@link CredentialProviderService} @@ -75,16 +106,19 @@ public class CredentialEntry implements Parcelable { * @param beginGetCredentialOption the request option for which this credential entry is * being constructed This helps maintain an association, * such that when the user selects this entry, providers - * can receive the conmplete corresponding request. + * can receive the complete corresponding request. * @param slice the slice containing the metadata to be shown on the UI. Must be * constructed through the androidx.credentials jetpack library. */ public CredentialEntry(@NonNull BeginGetCredentialOption beginGetCredentialOption, @NonNull Slice slice) { - mBeginGetCredentialOption = requireNonNull(beginGetCredentialOption, - "beginGetCredentialOption must not be null"); - mType = requireNonNull(mBeginGetCredentialOption.getType(), - "type must not be null"); + requireNonNull(beginGetCredentialOption, "beginGetCredentialOption must not" + + " be null"); + mBeginGetCredentialOptionId = Preconditions.checkStringNotEmpty( + beginGetCredentialOption.getId(), "Id in beginGetCredentialOption " + + "must not be null"); + mType = Preconditions.checkStringNotEmpty(beginGetCredentialOption.getType(), + "type in beginGetCredentialOption must not be null"); mSlice = requireNonNull(slice, "slice must not be null"); } @@ -101,7 +135,7 @@ public class CredentialEntry implements Parcelable { */ // TODO: Unhide this constructor when the registry APIs are stable public CredentialEntry(@NonNull String type, @NonNull Slice slice) { - mBeginGetCredentialOption = null; + mBeginGetCredentialOptionId = null; mType = requireNonNull(type, "type must not be null"); mSlice = requireNonNull(slice, "slice must not be null"); } @@ -110,7 +144,7 @@ public class CredentialEntry implements Parcelable { requireNonNull(in, "parcel must not be null"); mType = in.readString8(); mSlice = in.readTypedObject(Slice.CREATOR); - mBeginGetCredentialOption = in.readTypedObject(BeginGetCredentialOption.CREATOR); + mBeginGetCredentialOptionId = in.readString8(); } @NonNull @@ -136,15 +170,16 @@ public class CredentialEntry implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString8(mType); dest.writeTypedObject(mSlice, flags); - dest.writeTypedObject(mBeginGetCredentialOption, flags); + dest.writeString8(mBeginGetCredentialOptionId); } /** - * Returns the request option for which this credential entry has been constructed. + * Returns the id of the {@link BeginGetCredentialOption} for which this credential + * entry has been constructed. */ @NonNull - public BeginGetCredentialOption getBeginGetCredentialOption() { - return mBeginGetCredentialOption; + public String getBeginGetCredentialOptionId() { + return mBeginGetCredentialOptionId; } /** diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java index ee813e90ddfed..cd36b91b9c0d4 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java @@ -493,8 +493,7 @@ public final class ProviderGetSession extends ProviderSession(credentialEntry, entry)); }