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

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

Change-Id: Ib6119589bdd965a34a8c3f2e9a3b8c376be2d039
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2023-02-24 04:30:02 +00:00
committed by Automerger Merge Worker
9 changed files with 277 additions and 209 deletions

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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.
*

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -17,6 +17,7 @@
package android.service.credentials;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.SigningInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,8 @@ import java.util.Objects;
public final class CallingAppInfo implements Parcelable {
@NonNull private final String mPackageName;
@NonNull private final SigningInfo mSigningInfo;
@Nullable
private final String mOrigin;
/**
* Constructs a new instance.
@@ -41,14 +44,31 @@ public final class CallingAppInfo implements Parcelable {
*/
public CallingAppInfo(@NonNull String packageName,
@NonNull SigningInfo signingInfo) {
this(packageName, signingInfo, /*origin=*/ null);
}
/**
* Constructs a new instance.
*
* @param packageName - the package name of the calling app
* @param signingInfo - the signing info on the calling app
* @param origin - the origin that the calling app wants to use when making request on behalf of
* other
* @throws IllegalArgumentException If {@code packageName} is null or empty.
* @throws NullPointerException If {@code signingInfo} is null.
*/
public CallingAppInfo(@NonNull String packageName,
@NonNull SigningInfo signingInfo, @Nullable String origin) {
mPackageName = Preconditions.checkStringNotEmpty(packageName, "package name"
+ "must not be null or empty");
mSigningInfo = Objects.requireNonNull(signingInfo);
mOrigin = origin;
}
private CallingAppInfo(@NonNull Parcel in) {
mPackageName = in.readString8();
mSigningInfo = in.readTypedObject(SigningInfo.CREATOR);
mOrigin = in.readString8();
}
public static final @NonNull Creator<CallingAppInfo> CREATOR = new Creator<CallingAppInfo>() {
@@ -76,6 +96,22 @@ public final class CallingAppInfo implements Parcelable {
return mSigningInfo;
}
/**
* Returns the origin of the calling app if set otherwise returns null.
* This value is set only if the origin is different than that of the calling app,
* and should be expected from privileged callers(browsers) only when making request on behalf
* of other applications.
*
* Android system makes sure that only applications that poses the permission
* {@link android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN} can set the origin on
* the incoming {@link android.credentials.GetCredentialRequest} or
* {@link android.credentials.CreateCredentialRequest}.
*/
@Nullable
public String getOrigin() {
return mOrigin;
}
@Override
public int describeContents() {
return 0;
@@ -85,6 +121,7 @@ public final class CallingAppInfo implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mPackageName);
dest.writeTypedObject(mSigningInfo, flags);
dest.writeString8(mOrigin);
}
@Override
@@ -97,6 +134,7 @@ public final class CallingAppInfo implements Parcelable {
} else {
builder.append(", mSigningInfo: null");
}
builder.append(",mOrigin: " + mOrigin);
builder.append(" }");
return builder.toString();
}

View File

@@ -101,8 +101,11 @@ public class CredentialManagerTest {
mGetRequest = new GetCredentialRequest.Builder(Bundle.EMPTY).addCredentialOption(
new CredentialOption(Credential.TYPE_PASSWORD_CREDENTIAL, Bundle.EMPTY,
Bundle.EMPTY, false)).build();
mCreateRequest = new CreateCredentialRequest(Credential.TYPE_PASSWORD_CREDENTIAL,
Bundle.EMPTY, Bundle.EMPTY, false, false);
mCreateRequest = new CreateCredentialRequest.Builder(Bundle.EMPTY, Bundle.EMPTY)
.setType(Credential.TYPE_PASSWORD_CREDENTIAL)
.setIsSystemProviderRequired(false)
.setAlwaysSendAppInfoToProvider(false)
.build();
mClearRequest = new ClearCredentialStateRequest(Bundle.EMPTY);
final Slice slice = new Slice.Builder(Uri.parse("foo://bar"), null).addText("some text",

View File

@@ -402,30 +402,26 @@ class CredentialManagerRepo(
)
val credentialData = request.credentialData
return RequestInfo.newCreateRequestInfo(
Binder(),
CreateCredentialRequest(
"androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL",
credentialData,
/*candidateQueryData=*/ Bundle(),
/*isSystemProviderRequired=*/ false,
/*alwaysSendAppInfoToProvider=*/ true
),
"com.google.android.youtube"
Binder(),
CreateCredentialRequest.Builder(credentialData, Bundle())
.setType("androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL")
.setIsSystemProviderRequired(false)
.setAlwaysSendAppInfoToProvider(true)
.build(),
"com.google.android.youtube"
)
}
private fun testCreatePasswordRequestInfo(): RequestInfo {
val request = CreatePasswordRequest("beckett-bakert@gmail.com", "password123")
return RequestInfo.newCreateRequestInfo(
Binder(),
CreateCredentialRequest(
TYPE_PASSWORD_CREDENTIAL,
request.credentialData,
request.candidateQueryData,
/*isSystemProviderRequired=*/ false,
/*alwaysSendAppInfoToProvider=*/ true
),
"com.google.android.youtube"
Binder(),
CreateCredentialRequest.Builder(request.credentialData, request.candidateQueryData)
.setType(TYPE_PASSWORD_CREDENTIAL)
.setIsSystemProviderRequired(false)
.setAlwaysSendAppInfoToProvider(true)
.build(),
"com.google.android.youtube"
)
}
@@ -437,15 +433,13 @@ class CredentialManagerRepo(
displayInfo.toBundle()
)
return RequestInfo.newCreateRequestInfo(
Binder(),
CreateCredentialRequest(
"other-sign-ins",
data,
/*candidateQueryData=*/ Bundle(),
/*isSystemProviderRequired=*/ false,
/*alwaysSendAppInfoToProvider=*/ true
),
"com.google.android.youtube"
Binder(),
CreateCredentialRequest.Builder(data, Bundle())
.setType("other-sign-ins")
.setIsSystemProviderRequired(false)
.setAlwaysSendAppInfoToProvider(true)
.build(),
"com.google.android.youtube"
)
}

View File

@@ -360,21 +360,22 @@ public final class CredentialManagerService
int userId,
@Nullable String origin) {
final PackageInfo packageInfo;
String actualPackageName = origin == null ? realPackageName : origin;
CallingAppInfo callingAppInfo;
try {
packageInfo =
getContext()
.getPackageManager()
.getPackageInfoAsUser(
actualPackageName,
realPackageName,
PackageManager.PackageInfoFlags.of(
PackageManager.GET_SIGNING_CERTIFICATES),
userId);
callingAppInfo = new CallingAppInfo(realPackageName, packageInfo.signingInfo, origin);
} catch (PackageManager.NameNotFoundException e) {
Log.i(TAG, "Issue while retrieving signatureInfo : " + e.getMessage());
return new CallingAppInfo(actualPackageName, null);
callingAppInfo = new CallingAppInfo(realPackageName, null, origin);
}
return new CallingAppInfo(actualPackageName, packageInfo.signingInfo);
return callingAppInfo;
}
final class CredentialManagerServiceStub extends ICredentialManager.Stub {
@@ -386,9 +387,15 @@ public final class CredentialManagerService
Log.i(TAG, "starting executeGetCredential with callingPackage: " + callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
if (request.getOrigin() != null) {
// Check privileged permissions
mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
}
final int userId = UserHandle.getCallingUserId();
final int callingUid = Binder.getCallingUid();
enforceCallingPackage(callingPackage, callingUid);
// New request session, scoped for this request only.
final GetRequestSession session =
new GetRequestSession(
@@ -397,43 +404,13 @@ public final class CredentialManagerService
callingUid,
callback,
request,
constructCallingAppInfo(callingPackage, userId, null),
constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
CancellationSignal.fromTransport(cancelTransport));
processGetCredential(request, callback, session);
return cancelTransport;
}
public ICancellationSignal executeGetCredentialWithOrigin(
GetCredentialRequest request,
IGetCredentialCallback callback,
final String callingPackage,
final String origin) {
Log.i(TAG, "starting executeGetCredential with callingPackage: " + callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
// Check privileged permissions
mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
final int userId = UserHandle.getCallingUserId();
final int callingUid = Binder.getCallingUid();
enforceCallingPackage(callingPackage, callingUid);
// New request session, scoped for this request only.
final GetRequestSession session =
new GetRequestSession(
getContext(),
userId,
callingUid,
callback,
request,
constructCallingAppInfo(callingPackage, userId, origin),
CancellationSignal.fromTransport(cancelTransport));
processGetCredential(request, callback, session);
return cancelTransport;
}
private void processGetCredential(
GetCredentialRequest request,
IGetCredentialCallback callback,
@@ -519,6 +496,11 @@ public final class CredentialManagerService
+ callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
if (request.getOrigin() != null) {
// Check privileged permissions
mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
}
final int userId = UserHandle.getCallingUserId();
final int callingUid = Binder.getCallingUid();
enforceCallingPackage(callingPackage, callingUid);
@@ -531,43 +513,13 @@ public final class CredentialManagerService
callingUid,
request,
callback,
constructCallingAppInfo(callingPackage, userId, null),
constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
CancellationSignal.fromTransport(cancelTransport));
processCreateCredential(request, callback, session);
return cancelTransport;
}
public ICancellationSignal executeCreateCredentialWithOrigin(
CreateCredentialRequest request,
ICreateCredentialCallback callback,
String callingPackage,
String origin) {
Log.i(TAG, "starting executeCreateCredential with callingPackage: " + callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
// Check privileged permissions
mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
final int userId = UserHandle.getCallingUserId();
final int callingUid = Binder.getCallingUid();
enforceCallingPackage(callingPackage, callingUid);
// New request session, scoped for this request only.
final CreateRequestSession session =
new CreateRequestSession(
getContext(),
userId,
callingUid,
request,
callback,
constructCallingAppInfo(callingPackage, userId, origin),
CancellationSignal.fromTransport(cancelTransport));
processCreateCredential(request, callback, session);
return cancelTransport;
}
private void processCreateCredential(
CreateCredentialRequest request,
ICreateCredentialCallback callback,