Merge "Change provider side GetCredRequest to contain single option"

This commit is contained in:
TreeHugger Robot
2022-12-29 19:30:07 +00:00
committed by Android (Google) Code Review
3 changed files with 69 additions and 126 deletions

View File

@@ -39865,20 +39865,14 @@ package android.service.credentials {
}
public final class GetCredentialRequest implements android.os.Parcelable {
ctor public GetCredentialRequest(@NonNull android.service.credentials.CallingAppInfo, @NonNull android.credentials.GetCredentialOption);
method public int describeContents();
method @NonNull public android.service.credentials.CallingAppInfo getCallingAppInfo();
method @NonNull public java.util.List<android.credentials.GetCredentialOption> getGetCredentialOptions();
method @NonNull public android.credentials.GetCredentialOption getGetCredentialOption();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialRequest> CREATOR;
}
public static final class GetCredentialRequest.Builder {
ctor public GetCredentialRequest.Builder(@NonNull android.service.credentials.CallingAppInfo);
method @NonNull public android.service.credentials.GetCredentialRequest.Builder addGetCredentialOption(@NonNull android.credentials.GetCredentialOption);
method @NonNull public android.service.credentials.GetCredentialRequest build();
method @NonNull public android.service.credentials.GetCredentialRequest.Builder setGetCredentialOptions(@NonNull java.util.List<android.credentials.GetCredentialOption>);
}
}
package android.service.dreams {

View File

@@ -22,37 +22,34 @@ import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.AnnotationValidations;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Request for getting user's credentials from a given credential provider.
* Request for getting user's credential from a given credential provider.
*
* <p>Provider will receive this request once the user selects a given {@link CredentialEntry}
* on the selector, that was sourced from provider's result to
* {@link CredentialProviderService#onBeginGetCredential}.
*/
public final class GetCredentialRequest implements Parcelable {
/** Calling package of the app requesting for credentials. */
private final @NonNull CallingAppInfo mCallingAppInfo;
/**
* List of credential options. Each {@link GetCredentialOption} object holds parameters to
* be used for retrieving specific type of credentials.
* Holds parameters to be used for retrieving a specific type of credential.
*/
private final @NonNull List<GetCredentialOption> mGetCredentialOptions;
private final @NonNull GetCredentialOption mGetCredentialOption;
private GetCredentialRequest(@NonNull CallingAppInfo callingAppInfo,
@NonNull List<GetCredentialOption> getCredentialOptions) {
public GetCredentialRequest(@NonNull CallingAppInfo callingAppInfo,
@NonNull GetCredentialOption getCredentialOption) {
this.mCallingAppInfo = callingAppInfo;
this.mGetCredentialOptions = getCredentialOptions;
this.mGetCredentialOption = getCredentialOption;
}
private GetCredentialRequest(@NonNull Parcel in) {
mCallingAppInfo = in.readTypedObject(CallingAppInfo.CREATOR);
List<GetCredentialOption> getCredentialOptions = new ArrayList<>();
in.readTypedList(getCredentialOptions, GetCredentialOption.CREATOR);
mGetCredentialOptions = getCredentialOptions;
AnnotationValidations.validate(NonNull.class, null, mGetCredentialOptions);
AnnotationValidations.validate(NonNull.class, null, mCallingAppInfo);
mGetCredentialOption = in.readTypedObject(GetCredentialOption.CREATOR);
AnnotationValidations.validate(NonNull.class, null, mGetCredentialOption);
}
public static final @NonNull Creator<GetCredentialRequest> CREATOR =
@@ -76,7 +73,7 @@ public final class GetCredentialRequest implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeTypedObject(mCallingAppInfo, flags);
dest.writeTypedList(mGetCredentialOptions);
dest.writeTypedObject(mGetCredentialOption, flags);
}
/**
@@ -87,72 +84,9 @@ public final class GetCredentialRequest implements Parcelable {
}
/**
* Returns the list of type specific credential options to return credentials for.
* Returns the parameters needed to return a given type of credential.
*/
public @NonNull List<GetCredentialOption> getGetCredentialOptions() {
return mGetCredentialOptions;
}
/**
* Builder for {@link GetCredentialRequest}.
*/
public static final class Builder {
private CallingAppInfo mCallingAppInfo;
private List<GetCredentialOption> mGetCredentialOptions = new ArrayList<>();
/**
* Creates a new builder.
* @param callingAppInfo info pertaining to the app requesting credentials
*
* @throws IllegalArgumentException If {@code callingPackag}e is null or empty.
*/
public Builder(@NonNull CallingAppInfo callingAppInfo) {
mCallingAppInfo = Objects.requireNonNull(callingAppInfo);
}
/**
* Sets the list of credential options.
*
* @throws NullPointerException If {@code getCredentialOptions} itself or any of its
* elements is null.
* @throws IllegalArgumentException If {@code getCredentialOptions} is empty.
*/
public @NonNull Builder setGetCredentialOptions(
@NonNull List<GetCredentialOption> getCredentialOptions) {
Preconditions.checkCollectionNotEmpty(getCredentialOptions,
"getCredentialOptions");
Preconditions.checkCollectionElementsNotNull(getCredentialOptions,
"getCredentialOptions");
mGetCredentialOptions = getCredentialOptions;
return this;
}
/**
* Adds a single {@link GetCredentialOption} object to the list of credential options.
*
* @throws NullPointerException If {@code getCredentialOption} is null.
*/
public @NonNull Builder addGetCredentialOption(
@NonNull GetCredentialOption getCredentialOption) {
Objects.requireNonNull(getCredentialOption,
"getCredentialOption must not be null");
mGetCredentialOptions.add(getCredentialOption);
return this;
}
/**
* Builds a new {@link GetCredentialRequest} instance.
*
* @throws NullPointerException If {@code getCredentialOptions} is null.
* @throws IllegalArgumentException If {@code getCredentialOptions} is empty, or if
* {@code callingAppInfo} is null or empty.
*/
public @NonNull GetCredentialRequest build() {
Objects.requireNonNull(mCallingAppInfo,
"mCallingAppInfo");
Preconditions.checkCollectionNotEmpty(mGetCredentialOptions,
"getCredentialOptions");
return new GetCredentialRequest(mCallingAppInfo, mGetCredentialOptions);
}
public @NonNull GetCredentialOption getGetCredentialOption() {
return mGetCredentialOption;
}
}

View File

@@ -22,6 +22,7 @@ import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.Signature;
import android.credentials.GetCredentialException;
import android.credentials.GetCredentialOption;
import android.credentials.GetCredentialResponse;
@@ -78,7 +79,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
private Pair<String, Action> mUiAuthenticationAction = null;
/** The complete request to be used in the second round. */
private final GetCredentialRequest mCompleteRequest;
private final android.credentials.GetCredentialRequest mCompleteRequest;
private final CallingAppInfo mCallingAppInfo;
private GetCredentialException mProviderException;
@@ -89,36 +91,42 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
CredentialProviderInfo providerInfo,
GetRequestSession getRequestSession,
RemoteCredentialService remoteCredentialService) {
GetCredentialRequest completeRequest =
createProviderRequest(providerInfo.getCapabilities(),
getRequestSession.mClientRequest,
getRequestSession.mClientCallingPackage);
if (completeRequest != null) {
// TODO: Update to using query data when ready
BeginGetCredentialRequest beginGetCredentialRequest =
new BeginGetCredentialRequest.Builder(
completeRequest.getCallingAppInfo())
.setBeginGetCredentialOptions(
completeRequest.getGetCredentialOptions().stream().map(
option -> {
//TODO : Replace with option.getCandidateQueryData
// when ready
return new BeginGetCredentialOption(
option.getType(),
option.getCandidateQueryData());
}).collect(Collectors.toList()))
.build();
android.credentials.GetCredentialRequest filteredRequest =
filterOptions(providerInfo.getCapabilities(),
getRequestSession.mClientRequest);
if (filteredRequest != null) {
BeginGetCredentialRequest beginGetCredentialRequest = constructQueryPhaseRequest(
filteredRequest, getRequestSession.mClientCallingPackage);
return new ProviderGetSession(context, providerInfo, getRequestSession, userId,
remoteCredentialService, beginGetCredentialRequest, completeRequest);
remoteCredentialService, beginGetCredentialRequest, filteredRequest);
}
Log.i(TAG, "Unable to create provider session");
return null;
}
private static BeginGetCredentialRequest constructQueryPhaseRequest(
android.credentials.GetCredentialRequest filteredRequest,
String clientCallingPackage
) {
return new BeginGetCredentialRequest.Builder(
new CallingAppInfo(clientCallingPackage,
new ArraySet<Signature>()))
.setBeginGetCredentialOptions(
filteredRequest.getGetCredentialOptions().stream().map(
option -> {
return new BeginGetCredentialOption(
option.getType(),
option.getCandidateQueryData());
}).collect(Collectors.toList()))
.build();
}
@Nullable
private static GetCredentialRequest createProviderRequest(List<String> providerCapabilities,
android.credentials.GetCredentialRequest clientRequest,
String clientCallingPackage) {
private static android.credentials.GetCredentialRequest filterOptions(
List<String> providerCapabilities,
android.credentials.GetCredentialRequest clientRequest
) {
List<GetCredentialOption> filteredOptions = new ArrayList<>();
for (GetCredentialOption option : clientRequest.getGetCredentialOptions()) {
if (providerCapabilities.contains(option.getType())) {
@@ -131,10 +139,10 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
}
}
if (!filteredOptions.isEmpty()) {
return new GetCredentialRequest.Builder(
new CallingAppInfo(clientCallingPackage,
new ArraySet<>())).setGetCredentialOptions(
filteredOptions).build();
return new android.credentials.GetCredentialRequest
.Builder(clientRequest.getData())
.setGetCredentialOptions(
filteredOptions).build();
}
Log.i(TAG, "In createProviderRequest - returning null");
return null;
@@ -145,9 +153,10 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
ProviderInternalCallback callbacks,
int userId, RemoteCredentialService remoteCredentialService,
BeginGetCredentialRequest beginGetRequest,
GetCredentialRequest completeGetRequest) {
android.credentials.GetCredentialRequest completeGetRequest) {
super(context, info, beginGetRequest, callbacks, userId, remoteCredentialService);
mCompleteRequest = completeGetRequest;
mCallingAppInfo = beginGetRequest.getCallingAppInfo();
setStatus(Status.PENDING);
}
@@ -303,7 +312,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
if (credentialEntry.getPendingIntent() != null) {
credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId,
credentialEntry.getSlice(), credentialEntry.getPendingIntent(),
/*fillInIntent=*/setUpFillInIntent(credentialEntry.getPendingIntent())));
setUpFillInIntent(credentialEntry.getPendingIntent(),
credentialEntry.getType())));
} else {
Log.i(TAG, "No pending intent. Should not happen.");
}
@@ -311,12 +321,17 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
return credentialUiEntries;
}
private Intent setUpFillInIntent(PendingIntent pendingIntent) {
private Intent setUpFillInIntent(PendingIntent pendingIntent, String type) {
Intent intent = pendingIntent.getIntent();
intent.putExtra(
CredentialProviderService
.EXTRA_GET_CREDENTIAL_REQUEST,
mCompleteRequest);
for (GetCredentialOption option : mCompleteRequest.getGetCredentialOptions()) {
if (option.getType().equals(type)) {
intent.putExtra(
CredentialProviderService
.EXTRA_GET_CREDENTIAL_REQUEST,
new GetCredentialRequest(mCallingAppInfo, option));
return intent;
}
}
return intent;
}