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

Commit 1ada60e5 authored by Helen Qin's avatar Helen Qin
Browse files

Similar to the create flow, make get request two staged.

Similar to the create flow, we will also split the get flow into the
candidate query stage (for displaying options) and the execution stage
(for getting a credential after a user makes the choice). This requires
the api to expose two request data getters: getCandidateQueryData for
the query stage and getRequestData for the execution stage.

Bug: 246564035
Bug: 253153445
CTS-Coverage-Bug: 246637346
Test: Local Build & Deployment
Change-Id: Ic63d8b257376beec039d8867e5b3ea1ab2d284e7
parent f5887cba
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -13096,9 +13096,10 @@ package android.credentials {
  }
  public final class GetCredentialOption implements android.os.Parcelable {
    ctor public GetCredentialOption(@NonNull String, @NonNull android.os.Bundle, boolean);
    ctor public GetCredentialOption(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean);
    method public int describeContents();
    method @NonNull public android.os.Bundle getData();
    method @NonNull public android.os.Bundle getCandidateQueryData();
    method @NonNull public android.os.Bundle getCredentialRetrievalData();
    method @NonNull public String getType();
    method public boolean requireSystemProvider();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ public final class CreateCredentialRequest implements Parcelable {
    private final Bundle mCandidateQueryData;

    /**
     * Determines whether or not the request must only be fulfilled by a system provider.
     * Determines whether the request must only be fulfilled by a system provider.
     */
    private final boolean mRequireSystemProvider;

+60 −27
Original line number Diff line number Diff line
@@ -38,13 +38,20 @@ public final class GetCredentialOption implements Parcelable {
    private final String mType;

    /**
     * The request data.
     * The full request data.
     */
    @NonNull
    private final Bundle mData;
    private final Bundle mCredentialRetrievalData;

    /**
     * Determines whether or not the request must only be fulfilled by a system provider.
     * The partial request data that will be sent to the provider during the initial credential
     * candidate query stage.
     */
    @NonNull
    private final Bundle mCandidateQueryData;

    /**
     * Determines whether the request must only be fulfilled by a system provider.
     */
    private final boolean mRequireSystemProvider;

@@ -57,11 +64,27 @@ public final class GetCredentialOption implements Parcelable {
    }

    /**
     * Returns the request data.
     * Returns the full request data.
     */
    @NonNull
    public Bundle getData() {
        return mData;
    public Bundle getCredentialRetrievalData() {
        return mCredentialRetrievalData;
    }

    /**
     * Returns the partial request data that will be sent to the provider during the initial
     * credential candidate query stage.
     *
     * For security reason, a provider will receive the request data in two stages. First it gets
     * this partial request that do not contain sensitive user information; it uses this
     * information to provide credential candidates that the [@code CredentialManager] will show to
     * the user. Next, the full request data, {@link #getCredentialRetrievalData()}, will be sent to
     * a provider only if the user further grants the consent by choosing a candidate from the
     * provider.
     */
    @NonNull
    public Bundle getCandidateQueryData() {
        return mCandidateQueryData;
    }

    /**
@@ -75,7 +98,8 @@ public final class GetCredentialOption implements Parcelable {
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString8(mType);
        dest.writeBundle(mData);
        dest.writeBundle(mCredentialRetrievalData);
        dest.writeBundle(mCandidateQueryData);
        dest.writeBoolean(mRequireSystemProvider);
    }

@@ -88,7 +112,8 @@ public final class GetCredentialOption implements Parcelable {
    public String toString() {
        return "GetCredentialOption {"
                + "type=" + mType
                + ", data=" + mData
                + ", requestData=" + mCredentialRetrievalData
                + ", candidateQueryData=" + mCandidateQueryData
                + ", requireSystemProvider=" + mRequireSystemProvider
                + "}";
    }
@@ -97,30 +122,38 @@ public final class GetCredentialOption implements Parcelable {
     * Constructs a {@link GetCredentialOption}.
     *
     * @param type                    the requested credential type
     * @param data the request data
     * @param requireSystemProvider whether or not the request must only be fulfilled by a system
     * @param credentialRetrievalData the request data
     * @param candidateQueryData      the partial request data that will be sent to the provider
     *                                during the initial credential candidate query stage
     * @param requireSystemProvider   whether the request must only be fulfilled by a system
     *                                provider
     *
     * @throws IllegalArgumentException If type is empty.
     */
    public GetCredentialOption(
            @NonNull String type,
            @NonNull Bundle data,
            @NonNull Bundle credentialRetrievalData,
            @NonNull Bundle candidateQueryData,
            boolean requireSystemProvider) {
        mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
        mData = requireNonNull(data, "data must not be null");
        mCredentialRetrievalData = requireNonNull(credentialRetrievalData,
                "requestData must not be null");
        mCandidateQueryData = requireNonNull(candidateQueryData,
                "candidateQueryData must not be null");
        mRequireSystemProvider = requireSystemProvider;
    }

    private GetCredentialOption(@NonNull Parcel in) {
        String type = in.readString8();
        Bundle data = in.readBundle();
        Bundle candidateQueryData = in.readBundle();
        boolean requireSystemProvider = in.readBoolean();

        mType = type;
        AnnotationValidations.validate(NonNull.class, null, mType);
        mData = data;
        AnnotationValidations.validate(NonNull.class, null, mData);
        mCredentialRetrievalData = data;
        AnnotationValidations.validate(NonNull.class, null, mCredentialRetrievalData);
        mCandidateQueryData = candidateQueryData;
        AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
        mRequireSystemProvider = requireSystemProvider;
    }

+1 −1
Original line number Diff line number Diff line
@@ -518,7 +518,7 @@ class CredentialManagerRepo(
      GetCredentialRequest.Builder()
        .addGetCredentialOption(
          GetCredentialOption(
            TYPE_PUBLIC_KEY_CREDENTIAL, Bundle(), /*requireSystemProvider=*/ false)
            TYPE_PUBLIC_KEY_CREDENTIAL, Bundle(), Bundle(), /*requireSystemProvider=*/ false)
        )
        .build(),
      /*isFirstUsage=*/false,
+13 −7
Original line number Diff line number Diff line
@@ -38,14 +38,20 @@ open class GetCredentialOption(
            return try {
                when (from.type) {
                    Credential.TYPE_PASSWORD_CREDENTIAL ->
                        GetPasswordOption.createFrom(from.data)
                        GetPasswordOption.createFrom(from.credentialRetrievalData)
                    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
                        GetPublicKeyCredentialBaseOption.createFrom(from.data)
                        GetPublicKeyCredentialBaseOption.createFrom(from.credentialRetrievalData)
                    else ->
                        GetCredentialOption(from.type, from.data, from.requireSystemProvider())
                        GetCredentialOption(
                            from.type, from.credentialRetrievalData, from.requireSystemProvider()
                        )
                }
            } catch (e: FrameworkClassParsingException) {
                GetCredentialOption(from.type, from.data, from.requireSystemProvider())
                GetCredentialOption(
                    from.type,
                    from.credentialRetrievalData,
                    from.requireSystemProvider()
                )
            }
        }
    }