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

Commit d08d361d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Refactor origin to request object for the credential manager privilege...

Merge "Refactor origin to request object for the credential manager privilege APIs" into udc-dev am: eda0bf7f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21487335



Change-Id: Ib6119589bdd965a34a8c3f2e9a3b8c376be2d039
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 473ef0af eda0bf7f
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -13577,17 +13577,26 @@ package android.credentials {
  }
  public final class CreateCredentialRequest implements android.os.Parcelable {
    ctor public CreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean, boolean);
    method public boolean alwaysSendAppInfoToProvider();
    method public int describeContents();
    method @NonNull public android.os.Bundle getCandidateQueryData();
    method @NonNull public android.os.Bundle getCredentialData();
    method @Nullable public String getOrigin();
    method @NonNull public String getType();
    method public boolean isSystemProviderRequired();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.credentials.CreateCredentialRequest> CREATOR;
  }
  public static final class CreateCredentialRequest.Builder {
    ctor public CreateCredentialRequest.Builder(@NonNull android.os.Bundle, @NonNull android.os.Bundle);
    method @NonNull public android.credentials.CreateCredentialRequest build();
    method @NonNull public android.credentials.CreateCredentialRequest.Builder setAlwaysSendAppInfoToProvider(boolean);
    method @NonNull public android.credentials.CreateCredentialRequest.Builder setIsSystemProviderRequired(boolean);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN) public android.credentials.CreateCredentialRequest.Builder setOrigin(@NonNull String);
    method @NonNull public android.credentials.CreateCredentialRequest.Builder setType(@NonNull String);
  }
  public final class CreateCredentialResponse implements android.os.Parcelable {
    ctor public CreateCredentialResponse(@NonNull android.os.Bundle);
    method public int describeContents();
@@ -13619,9 +13628,7 @@ package android.credentials {
  public final class CredentialManager {
    method public void clearCredentialState(@NonNull android.credentials.ClearCredentialStateRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException>);
    method public void createCredential(@NonNull android.credentials.CreateCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CreateCredentialException>);
    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN) public void createCredentialWithOrigin(@NonNull android.credentials.CreateCredentialRequest, @Nullable String, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CreateCredentialException>);
    method public void getCredential(@NonNull android.credentials.GetCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>);
    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN) public void getCredentialWithOrigin(@NonNull android.credentials.GetCredentialRequest, @Nullable String, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>);
    method public boolean isEnabledCredentialProviderService(@NonNull android.content.ComponentName);
    method public void registerCredentialDescription(@NonNull android.credentials.RegisterCredentialDescriptionRequest);
    method public void unregisterCredentialDescription(@NonNull android.credentials.UnregisterCredentialDescriptionRequest);
@@ -13656,6 +13663,7 @@ package android.credentials {
    method public int describeContents();
    method @NonNull public java.util.List<android.credentials.CredentialOption> getCredentialOptions();
    method @NonNull public android.os.Bundle getData();
    method @Nullable public String getOrigin();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.credentials.GetCredentialRequest> CREATOR;
  }
@@ -13666,6 +13674,7 @@ package android.credentials {
    method @NonNull public android.credentials.GetCredentialRequest build();
    method @NonNull public android.credentials.GetCredentialRequest.Builder setAlwaysSendAppInfoToProvider(boolean);
    method @NonNull public android.credentials.GetCredentialRequest.Builder setCredentialOptions(@NonNull java.util.List<android.credentials.CredentialOption>);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN) public android.credentials.GetCredentialRequest.Builder setOrigin(@NonNull String);
  }
  public final class GetCredentialResponse implements android.os.Parcelable {
@@ -40564,7 +40573,9 @@ package android.service.credentials {
  public final class CallingAppInfo implements android.os.Parcelable {
    ctor public CallingAppInfo(@NonNull String, @NonNull android.content.pm.SigningInfo);
    ctor public CallingAppInfo(@NonNull String, @NonNull android.content.pm.SigningInfo, @Nullable String);
    method public int describeContents();
    method @Nullable public String getOrigin();
    method @NonNull public String getPackageName();
    method @NonNull public android.content.pm.SigningInfo getSigningInfo();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
+131 −2
Original line number Diff line number Diff line
@@ -16,9 +16,14 @@

package android.credentials;

import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;

import static java.util.Objects.requireNonNull;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -68,6 +73,14 @@ public final class CreateCredentialRequest implements Parcelable {
     */
    private final boolean mIsSystemProviderRequired;

    /**
     * The origin of the calling app. Callers of this special API (e.g. browsers)
     * can set this origin for an app different from their own, to be able to get credentials
     * on behalf of that app.
     */
    @Nullable
    private final String mOrigin;

    /**
     * Returns the requested credential type.
     */
@@ -123,6 +136,14 @@ public final class CreateCredentialRequest implements Parcelable {
        return mAlwaysSendAppInfoToProvider;
    }

    /**
     * Returns the origin of the calling app if set otherwise returns null.
     */
    @Nullable
    public String getOrigin() {
        return mOrigin;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString8(mType);
@@ -130,6 +151,7 @@ public final class CreateCredentialRequest implements Parcelable {
        dest.writeBundle(mCandidateQueryData);
        dest.writeBoolean(mIsSystemProviderRequired);
        dest.writeBoolean(mAlwaysSendAppInfoToProvider);
        dest.writeString8(mOrigin);
    }

    @Override
@@ -146,6 +168,7 @@ public final class CreateCredentialRequest implements Parcelable {
                + ", isSystemProviderRequired=" + mIsSystemProviderRequired
                + ", alwaysSendAppInfoToProvider="
                + mAlwaysSendAppInfoToProvider
                + ", origin=" + mOrigin
                + "}";
    }

@@ -165,21 +188,26 @@ public final class CreateCredentialRequest implements Parcelable {
     *                                    the query phase, and will only be sent along
     *                                    with the final request, after the user has selected
     *                                    an entry on the UI.
     * @param origin the origin of the calling app. Callers of this special setter (e.g. browsers)
     *               can set this origin for an app different from their own, to be able to get
     *               credentials on behalf of that app.
     *
     * @throws IllegalArgumentException If type is empty.
     */
    public CreateCredentialRequest(
    private CreateCredentialRequest(
            @NonNull String type,
            @NonNull Bundle credentialData,
            @NonNull Bundle candidateQueryData,
            boolean isSystemProviderRequired,
            boolean alwaysSendAppInfoToProvider) {
            boolean alwaysSendAppInfoToProvider,
            @NonNull String origin) {
        mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
        mCredentialData = requireNonNull(credentialData, "credentialData must not be null");
        mCandidateQueryData = requireNonNull(candidateQueryData,
                "candidateQueryData must not be null");
        mIsSystemProviderRequired = isSystemProviderRequired;
        mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
        mOrigin = origin;
    }

    private CreateCredentialRequest(@NonNull Parcel in) {
@@ -188,6 +216,7 @@ public final class CreateCredentialRequest implements Parcelable {
        Bundle candidateQueryData = in.readBundle();
        boolean isSystemProviderRequired = in.readBoolean();
        boolean alwaysSendAppInfoToProvider = in.readBoolean();
        mOrigin = in.readString8();

        mType = type;
        AnnotationValidations.validate(NonNull.class, null, mType);
@@ -211,4 +240,104 @@ public final class CreateCredentialRequest implements Parcelable {
            return new CreateCredentialRequest(in);
        }
    };

    /** A builder for {@link CreateCredentialRequest}. */
    public static final class Builder {

        private boolean mAlwaysSendAppInfoToProvider;

        @NonNull
        private String mType;

        @NonNull
        private final Bundle mCredentialData;

        @NonNull
        private final Bundle mCandidateQueryData;

        private boolean mIsSystemProviderRequired;

        private String mOrigin;

        /**
         * @param credentialData the full credential creation request data
         * @param candidateQueryData the partial request data that will be sent to the provider
         *                           during the initial creation candidate query stage
         */
        public Builder(@NonNull Bundle credentialData, @NonNull Bundle candidateQueryData) {
            mCredentialData = requireNonNull(credentialData,
                    "credentialData must not be null");
            mCandidateQueryData = requireNonNull(candidateQueryData,
                    "candidateQueryData must not be null");
        }

        /**
         * Sets a true/false value to determine if the calling app info should be
         * removed from the request that is sent to the providers.
         *
         * Developers must set this to false if they wish to remove the
         * {@link android.service.credentials.CallingAppInfo} from the query phases requests that
         * providers receive. Note that the calling app info will still be sent in the
         * final phase after the user has made a selection on the UI.
         *
         * If not set, the default value will be true and the calling app info will be
         * propagated to the providers in every phase.
         */
        @SuppressLint("MissingGetterMatchingBuilder")
        @NonNull
        public CreateCredentialRequest.Builder setAlwaysSendAppInfoToProvider(boolean value) {
            mAlwaysSendAppInfoToProvider = value;
            return this;
        }

        /**
         * Sets the requested credential type.
         */
        @SuppressLint("MissingGetterMatchingBuilder")
        @NonNull
        public CreateCredentialRequest.Builder setType(@NonNull String type) {
            mType = type;
            return this;
        }

        /**
         * Sets whether the request must only be fulfilled by a system provider.
         * This defaults to false
         */
        @SuppressLint("MissingGetterMatchingBuilder")
        @NonNull
        public CreateCredentialRequest.Builder setIsSystemProviderRequired(boolean value) {
            mIsSystemProviderRequired = value;
            return this;
        }

        /**
         * Sets the origin of the calling app. Callers of this special setter (e.g. browsers)
         * can set this origin for an app different from their own, to be able to get
         * credentials on behalf of that app. The permission check only happens later when this
         * instance is passed and processed by the Credential Manager.
         */
        @SuppressLint({"MissingGetterMatchingBuilder", "AndroidFrameworkRequiresPermission"})
        @RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
        @NonNull
        public CreateCredentialRequest.Builder setOrigin(@NonNull String origin) {
            mOrigin = origin;
            return this;
        }

        /**
         * Builds a {@link GetCredentialRequest}.
         *
         * @throws IllegalArgumentException If credentialOptions is empty.
         */
        @NonNull
        public CreateCredentialRequest build() {
            Preconditions.checkStringNotEmpty(
                    mType,
                    "type must not be empty");

            return new CreateCredentialRequest(mType, mCredentialData, mCandidateQueryData,
                    mIsSystemProviderRequired, mAlwaysSendAppInfoToProvider, mOrigin);
        }
    }
}
+8 −103
Original line number Diff line number Diff line
@@ -123,6 +123,10 @@ public final class CredentialManager {
     *
     * <p>The execution can potentially launch UI flows to collect user consent to using a
     * credential, display a picker when multiple credentials exist, etc.
     * Callers (e.g. browsers) may optionally set origin in {@link GetCredentialRequest} for an
     * app different from their own, to be able to get credentials on behalf of that app. They would
     * need additional permission {@link CREDENTIAL_MANAGER_SET_ORIGIN}
     * to use this functionality
     *
     * @param request the request specifying type(s) of credentials to get from the user
     * @param activity the activity used to launch any UI needed
@@ -162,62 +166,15 @@ public final class CredentialManager {
        }
    }

    /**
     * Launches the necessary flows to retrieve an app credential from the user, for the given
     * origin.
     *
     * <p>The execution can potentially launch UI flows to collect user consent to using a
     * credential, display a picker when multiple credentials exist, etc.
     *
     * @param request the request specifying type(s) of credentials to get from the user
     * @param origin the origin of the calling app. Callers of this special API (e.g. browsers)
     * can set this origin for an app different from their own, to be able to get credentials
     * on behalf of that app.
     * @param activity the activity used to launch any UI needed
     * @param cancellationSignal an optional signal that allows for cancelling this call
     * @param executor the callback will take place on this {@link Executor}
     * @param callback the callback invoked when the request succeeds or fails
     */
    @RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
    public void getCredentialWithOrigin(
            @NonNull GetCredentialRequest request,
            @Nullable String origin,
            @NonNull Activity activity,
            @Nullable CancellationSignal cancellationSignal,
            @CallbackExecutor @NonNull Executor executor,
            @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
        requireNonNull(request, "request must not be null");
        requireNonNull(activity, "activity must not be null");
        requireNonNull(executor, "executor must not be null");
        requireNonNull(callback, "callback must not be null");

        if (cancellationSignal != null && cancellationSignal.isCanceled()) {
            Log.w(TAG, "getCredential already canceled");
            return;
        }

        ICancellationSignal cancelRemote = null;
        try {
            cancelRemote =
                mService.executeGetCredentialWithOrigin(
                    request,
                    new GetCredentialTransport(activity, executor, callback),
                    mContext.getOpPackageName(),
                    origin);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }

        if (cancellationSignal != null && cancelRemote != null) {
            cancellationSignal.setRemote(cancelRemote);
        }
    }

    /**
     * Launches the necessary flows to register an app credential for the user.
     *
     * <p>The execution can potentially launch UI flows to collect user consent to creating or
     * storing the new credential, etc.
     * Callers (e.g. browsers) may optionally set origin in {@link CreateCredentialRequest} for an
     * app different from their own, to be able to get credentials on behalf of that app. They would
     * need additional permission {@link CREDENTIAL_MANAGER_SET_ORIGIN}
     * to use this functionality
     *
     * @param request the request specifying type(s) of credentials to get from the user
     * @param activity the activity used to launch any UI needed
@@ -258,58 +215,6 @@ public final class CredentialManager {
        }
    }

    /**
     * Launches the necessary flows to register an app credential for the user.
     *
     * <p>The execution can potentially launch UI flows to collect user consent to creating or
     * storing the new credential, etc.
     *
     * @param request the request specifying type(s) of credentials to get from the user, for the
     * given origin
     * @param origin the origin of the calling app. Callers of this special API (e.g. browsers)
     * can set this origin for an app different from their own, to be able to get credentials
     * on behalf of that app.
     * @param activity the activity used to launch any UI needed
     * @param cancellationSignal an optional signal that allows for cancelling this call
     * @param executor the callback will take place on this {@link Executor}
     * @param callback the callback invoked when the request succeeds or fails
     */
    @RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
    public void createCredentialWithOrigin(
            @NonNull CreateCredentialRequest request,
            @Nullable String origin,
            @NonNull Activity activity,
            @Nullable CancellationSignal cancellationSignal,
            @CallbackExecutor @NonNull Executor executor,
            @NonNull
            OutcomeReceiver<CreateCredentialResponse, CreateCredentialException> callback) {
        requireNonNull(request, "request must not be null");
        requireNonNull(activity, "activity must not be null");
        requireNonNull(executor, "executor must not be null");
        requireNonNull(callback, "callback must not be null");

        if (cancellationSignal != null && cancellationSignal.isCanceled()) {
            Log.w(TAG, "createCredential already canceled");
            return;
        }

        ICancellationSignal cancelRemote = null;
        try {
            cancelRemote =
                mService.executeCreateCredentialWithOrigin(
                    request,
                    new CreateCredentialTransport(activity, executor, callback),
                    mContext.getOpPackageName(),
                    origin);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }

        if (cancellationSignal != null && cancelRemote != null) {
            cancellationSignal.setRemote(cancelRemote);
        }
    }

    /**
     * Clears the current user credential state from all credential providers.
     *
+42 −2
Original line number Diff line number Diff line
@@ -16,9 +16,13 @@

package android.credentials;

import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;

import static java.util.Objects.requireNonNull;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Parcel;
@@ -48,6 +52,14 @@ public final class GetCredentialRequest implements Parcelable {
    @NonNull
    private final Bundle mData;

    /**
     * The origin of the calling app. Callers of this special API (e.g. browsers)
     * can set this origin for an app different from their own, to be able to get credentials
     * on behalf of that app.
     */
    @Nullable
    private String mOrigin;

    /**
     * True/False value to determine if the calling app info should be
     * removed from the request that is sent to the providers.
@@ -75,6 +87,14 @@ public final class GetCredentialRequest implements Parcelable {
        return mData;
    }

    /**
     * Returns the origin of the calling app if set otherwise returns null.
     */
    @Nullable
    public String getOrigin() {
        return mOrigin;
    }

    /**
     * Returns a value to determine if the calling app info should be always
     * sent to the provider in every phase (if true), or should be removed
@@ -90,6 +110,7 @@ public final class GetCredentialRequest implements Parcelable {
        dest.writeTypedList(mCredentialOptions, flags);
        dest.writeBundle(mData);
        dest.writeBoolean(mAlwaysSendAppInfoToProvider);
        dest.writeString8(mOrigin);
    }

    @Override
@@ -103,11 +124,12 @@ public final class GetCredentialRequest implements Parcelable {
                + ", data=" + mData
                + ", alwaysSendAppInfoToProvider="
                + mAlwaysSendAppInfoToProvider
                + ", origin=" + mOrigin
                + "}";
    }

    private GetCredentialRequest(@NonNull List<CredentialOption> credentialOptions,
            @NonNull Bundle data, @NonNull boolean alwaysSendAppInfoToProvider) {
            @NonNull Bundle data, @NonNull boolean alwaysSendAppInfoToProvider, String origin) {
        Preconditions.checkCollectionNotEmpty(
                credentialOptions,
                /*valueName=*/ "credentialOptions");
@@ -118,6 +140,7 @@ public final class GetCredentialRequest implements Parcelable {
        mData = requireNonNull(data,
                "data must not be null");
        mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
        mOrigin = origin;
    }

    private GetCredentialRequest(@NonNull Parcel in) {
@@ -132,6 +155,7 @@ public final class GetCredentialRequest implements Parcelable {
        AnnotationValidations.validate(NonNull.class, null, mData);

        mAlwaysSendAppInfoToProvider = in.readBoolean();
        mOrigin = in.readString8();
    }

    @NonNull public static final Parcelable.Creator<GetCredentialRequest> CREATOR =
@@ -159,6 +183,8 @@ public final class GetCredentialRequest implements Parcelable {
        @NonNull
        private boolean mAlwaysSendAppInfoToProvider = true;

        private String mOrigin;

        /**
         * @param data the top request level data
         */
@@ -208,6 +234,20 @@ public final class GetCredentialRequest implements Parcelable {
            return this;
        }

        /**
         * Sets the origin of the calling app. Callers of this special setter (e.g. browsers)
         * can set this origin for an app different from their own, to be able to get
         * credentials on behalf of that app. The permission check only happens later when this
         * instance is passed and processed by the Credential Manager.
         */
        @SuppressLint({"MissingGetterMatchingBuilder", "AndroidFrameworkRequiresPermission"})
        @RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
        @NonNull
        public Builder setOrigin(@NonNull String origin) {
            mOrigin = origin;
            return this;
        }

        /**
         * Builds a {@link GetCredentialRequest}.
         *
@@ -222,7 +262,7 @@ public final class GetCredentialRequest implements Parcelable {
                    mCredentialOptions,
                    /*valueName=*/ "credentialOptions");
            return new GetCredentialRequest(mCredentialOptions, mData,
                    mAlwaysSendAppInfoToProvider);
                    mAlwaysSendAppInfoToProvider, mOrigin);
        }
    }
}
+0 −4
Original line number Diff line number Diff line
@@ -41,12 +41,8 @@ interface ICredentialManager {

    @nullable ICancellationSignal executeGetCredential(in GetCredentialRequest request, in IGetCredentialCallback callback, String callingPackage);

    @nullable ICancellationSignal executeGetCredentialWithOrigin(in GetCredentialRequest request, in IGetCredentialCallback callback, String callingPackage, String origin);

    @nullable ICancellationSignal executeCreateCredential(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage);

    @nullable ICancellationSignal executeCreateCredentialWithOrigin(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage, String origin);

    @nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage);

    @nullable ICancellationSignal listEnabledProviders(in IListEnabledProvidersCallback callback);
Loading