summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt74
-rw-r--r--core/java/android/service/credentials/Action.java2
-rw-r--r--core/java/android/service/credentials/BeginCreateCredentialResponse.java2
-rw-r--r--core/java/android/service/credentials/BeginGetCredentialOption.java129
-rw-r--r--core/java/android/service/credentials/BeginGetCredentialsRequest.aidl (renamed from core/java/android/service/credentials/GetCredentialsRequest.aidl)2
-rw-r--r--core/java/android/service/credentials/BeginGetCredentialsRequest.java175
-rw-r--r--core/java/android/service/credentials/BeginGetCredentialsResponse.aidl3
-rw-r--r--core/java/android/service/credentials/BeginGetCredentialsResponse.java (renamed from core/java/android/service/credentials/GetCredentialsResponse.java)36
-rw-r--r--core/java/android/service/credentials/CredentialEntry.java64
-rw-r--r--core/java/android/service/credentials/CredentialProviderService.java91
-rw-r--r--core/java/android/service/credentials/CredentialsResponseContent.java6
-rw-r--r--core/java/android/service/credentials/GetCredentialRequest.java (renamed from core/java/android/service/credentials/GetCredentialsRequest.java)28
-rw-r--r--core/java/android/service/credentials/GetCredentialsResponse.aidl3
-rw-r--r--core/java/android/service/credentials/IBeginGetCredentialsCallback.aidl (renamed from core/java/android/service/credentials/IGetCredentialsCallback.aidl)6
-rw-r--r--core/java/android/service/credentials/ICredentialProviderService.aidl6
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerService.java6
-rw-r--r--services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java15
-rw-r--r--services/credentials/java/com/android/server/credentials/ProviderGetSession.java89
-rw-r--r--services/credentials/java/com/android/server/credentials/RemoteCredentialService.java27
19 files changed, 564 insertions, 200 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index c1c4c92237db..657bfef4c533 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -39472,6 +39472,40 @@ package android.service.credentials {
method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder setRemoteCreateEntry(@Nullable android.service.credentials.CreateEntry);
}
+ public final class BeginGetCredentialOption implements android.os.Parcelable {
+ ctor public BeginGetCredentialOption(@NonNull String, @NonNull android.os.Bundle);
+ method public int describeContents();
+ method @NonNull public android.os.Bundle getCandidateQueryData();
+ method @NonNull public String getType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginGetCredentialOption> CREATOR;
+ }
+
+ public final class BeginGetCredentialsRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.service.credentials.BeginGetCredentialOption> getBeginGetCredentialOptions();
+ method @NonNull public String getCallingPackage();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginGetCredentialsRequest> CREATOR;
+ }
+
+ public static final class BeginGetCredentialsRequest.Builder {
+ ctor public BeginGetCredentialsRequest.Builder(@NonNull String);
+ method @NonNull public android.service.credentials.BeginGetCredentialsRequest.Builder addBeginGetCredentialOption(@NonNull android.service.credentials.BeginGetCredentialOption);
+ method @NonNull public android.service.credentials.BeginGetCredentialsRequest build();
+ method @NonNull public android.service.credentials.BeginGetCredentialsRequest.Builder setBeginGetCredentialOptions(@NonNull java.util.List<android.service.credentials.BeginGetCredentialOption>);
+ }
+
+ public final class BeginGetCredentialsResponse implements android.os.Parcelable {
+ method @NonNull public static android.service.credentials.BeginGetCredentialsResponse createWithAuthentication(@NonNull android.service.credentials.Action);
+ method @NonNull public static android.service.credentials.BeginGetCredentialsResponse createWithResponseContent(@NonNull android.service.credentials.CredentialsResponseContent);
+ method public int describeContents();
+ method @Nullable public android.service.credentials.Action getAuthenticationAction();
+ method @Nullable public android.service.credentials.CredentialsResponseContent getCredentialsResponseContent();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginGetCredentialsResponse> CREATOR;
+ }
+
public final class CreateCredentialRequest implements android.os.Parcelable {
ctor public CreateCredentialRequest(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
method public int describeContents();
@@ -39493,8 +39527,7 @@ package android.service.credentials {
public final class CredentialEntry implements android.os.Parcelable {
method public int describeContents();
- method @Nullable public android.credentials.Credential getCredential();
- method @Nullable public android.app.PendingIntent getPendingIntent();
+ method @NonNull public android.app.PendingIntent getPendingIntent();
method @NonNull public android.app.slice.Slice getSlice();
method @NonNull public String getType();
method public boolean isAutoSelectAllowed();
@@ -39504,7 +39537,6 @@ package android.service.credentials {
public static final class CredentialEntry.Builder {
ctor public CredentialEntry.Builder(@NonNull String, @NonNull android.app.slice.Slice, @NonNull android.app.PendingIntent);
- ctor public CredentialEntry.Builder(@NonNull String, @NonNull android.app.slice.Slice, @NonNull android.credentials.Credential);
method @NonNull public android.service.credentials.CredentialEntry build();
method @NonNull public android.service.credentials.CredentialEntry.Builder setAutoSelectAllowed(@NonNull boolean);
}
@@ -39521,14 +39553,16 @@ package android.service.credentials {
public abstract class CredentialProviderService extends android.app.Service {
ctor public CredentialProviderService();
method public abstract void onBeginCreateCredential(@NonNull android.service.credentials.BeginCreateCredentialRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.credentials.BeginCreateCredentialResponse,android.service.credentials.CredentialProviderException>);
+ method public abstract void onBeginGetCredentials(@NonNull android.service.credentials.BeginGetCredentialsRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.credentials.BeginGetCredentialsResponse,android.service.credentials.CredentialProviderException>);
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method public abstract void onGetCredentials(@NonNull android.service.credentials.GetCredentialsRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.credentials.GetCredentialsResponse,android.service.credentials.CredentialProviderException>);
field public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
+ field public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION = "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";
field public static final String EXTRA_CREATE_CREDENTIAL_REQUEST = "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
- field public static final String EXTRA_CREATE_CREDENTIAL_RESULT = "android.service.credentials.extra.CREATE_CREDENTIAL_RESULT";
- field public static final String EXTRA_CREDENTIAL_RESULT = "android.service.credentials.extra.CREDENTIAL_RESULT";
- field public static final String EXTRA_ERROR = "android.service.credentials.extra.ERROR";
- field public static final String EXTRA_GET_CREDENTIALS_CONTENT_RESULT = "android.service.credentials.extra.GET_CREDENTIALS_CONTENT_RESULT";
+ field public static final String EXTRA_CREATE_CREDENTIAL_RESPONSE = "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE";
+ field public static final String EXTRA_CREDENTIALS_RESPONSE_CONTENT = "android.service.credentials.extra.CREDENTIALS_RESPONSE_CONTENT";
+ field public static final String EXTRA_GET_CREDENTIAL_EXCEPTION = "android.service.credentials.extra.GET_CREDENTIAL_EXCEPTION";
+ field public static final String EXTRA_GET_CREDENTIAL_REQUEST = "android.service.credentials.extra.GET_CREDENTIAL_REQUEST";
+ field public static final String EXTRA_GET_CREDENTIAL_RESPONSE = "android.service.credentials.extra.GET_CREDENTIAL_RESPONSE";
field public static final String SERVICE_INTERFACE = "android.service.credentials.CredentialProviderService";
}
@@ -39551,29 +39585,19 @@ package android.service.credentials {
method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setRemoteCredentialEntry(@Nullable android.service.credentials.CredentialEntry);
}
- public final class GetCredentialsRequest implements android.os.Parcelable {
+ public final class GetCredentialRequest implements android.os.Parcelable {
method public int describeContents();
method @NonNull public String getCallingPackage();
method @NonNull public java.util.List<android.credentials.GetCredentialOption> getGetCredentialOptions();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialsRequest> CREATOR;
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialRequest> CREATOR;
}
- public static final class GetCredentialsRequest.Builder {
- ctor public GetCredentialsRequest.Builder(@NonNull String);
- method @NonNull public android.service.credentials.GetCredentialsRequest.Builder addGetCredentialOption(@NonNull android.credentials.GetCredentialOption);
- method @NonNull public android.service.credentials.GetCredentialsRequest build();
- method @NonNull public android.service.credentials.GetCredentialsRequest.Builder setGetCredentialOptions(@NonNull java.util.List<android.credentials.GetCredentialOption>);
- }
-
- public final class GetCredentialsResponse implements android.os.Parcelable {
- method @NonNull public static android.service.credentials.GetCredentialsResponse createWithAuthentication(@NonNull android.service.credentials.Action);
- method @NonNull public static android.service.credentials.GetCredentialsResponse createWithResponseContent(@NonNull android.service.credentials.CredentialsResponseContent);
- method public int describeContents();
- method @Nullable public android.service.credentials.Action getAuthenticationAction();
- method @Nullable public android.service.credentials.CredentialsResponseContent getCredentialsResponseContent();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialsResponse> CREATOR;
+ public static final class GetCredentialRequest.Builder {
+ ctor public GetCredentialRequest.Builder(@NonNull String);
+ 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>);
}
}
diff --git a/core/java/android/service/credentials/Action.java b/core/java/android/service/credentials/Action.java
index 77570813e6c3..42dd52840575 100644
--- a/core/java/android/service/credentials/Action.java
+++ b/core/java/android/service/credentials/Action.java
@@ -42,7 +42,7 @@ public final class Action implements Parcelable {
* level authentication before displaying any content etc.
*
* <p> See details on usage of {@code Action} for various actionable entries in
- * {@link BeginCreateCredentialResponse} and {@link GetCredentialsResponse}.
+ * {@link BeginCreateCredentialResponse} and {@link BeginGetCredentialsResponse}.
*
* @param slice the display content to be displayed on the UI, along with this action
* @param pendingIntent the intent to be invoked when the user selects this action
diff --git a/core/java/android/service/credentials/BeginCreateCredentialResponse.java b/core/java/android/service/credentials/BeginCreateCredentialResponse.java
index 022678ea49bd..8ca3a1a2ec99 100644
--- a/core/java/android/service/credentials/BeginCreateCredentialResponse.java
+++ b/core/java/android/service/credentials/BeginCreateCredentialResponse.java
@@ -127,7 +127,7 @@ public final class BeginCreateCredentialResponse implements Parcelable {
*
* <p> Once the remote credential flow is complete, the {@link android.app.Activity}
* result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
- * {@link CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESULT} key should be populated
+ * {@link CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESPONSE} key should be populated
* with a {@link android.credentials.CreateCredentialResponse} object.
*/
public @NonNull Builder setRemoteCreateEntry(@Nullable CreateEntry remoteCreateEntry) {
diff --git a/core/java/android/service/credentials/BeginGetCredentialOption.java b/core/java/android/service/credentials/BeginGetCredentialOption.java
new file mode 100644
index 000000000000..c82b445d19e0
--- /dev/null
+++ b/core/java/android/service/credentials/BeginGetCredentialOption.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.credentials;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.AnnotationValidations;
+import com.android.internal.util.Preconditions;
+
+/**
+ * A specific type of credential request to be sent to the provider during the query phase of
+ * a get flow. This request contains limited parameters needed to populate a list of
+ * {@link CredentialEntry} on the {@link BeginGetCredentialsResponse}.
+ */
+public final class BeginGetCredentialOption implements Parcelable {
+
+ /**
+ * The requested credential type.
+ */
+ @NonNull
+ private final String mType;
+
+ /**
+ * The request candidateQueryData.
+ */
+ @NonNull
+ private final Bundle mCandidateQueryData;
+
+ /**
+ * Returns the requested credential type.
+ */
+ @NonNull
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * Returns the request candidate query data, denoting a set of parameters
+ * that can be used to populate a candidate list of credentials, as
+ * {@link CredentialEntry} on {@link BeginGetCredentialsResponse}. This list
+ * of entries is then presented to the user on a selector.
+ *
+ * <p>This data does not contain any sensitive parameters, and will be sent
+ * to all eligible providers.
+ * The complete set of parameters will only be set on the {@link android.app.PendingIntent}
+ * set on the {@link CredentialEntry} that is selected by the user.
+ */
+ @NonNull
+ public Bundle getCandidateQueryData() {
+ return mCandidateQueryData;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mType);
+ dest.writeBundle(mCandidateQueryData);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "GetCredentialOption {"
+ + "type=" + mType
+ + ", candidateQueryData=" + mCandidateQueryData
+ + "}";
+ }
+
+ /**
+ * Constructs a {@link BeginGetCredentialOption}.
+ *
+ * @param type the requested credential type
+ * @param candidateQueryData the request candidateQueryData
+ *
+ * @throws IllegalArgumentException If type is empty.
+ */
+ public BeginGetCredentialOption(
+ @NonNull String type,
+ @NonNull Bundle candidateQueryData) {
+ mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
+ mCandidateQueryData = requireNonNull(
+ candidateQueryData, "candidateQueryData must not be null");
+ }
+
+ private BeginGetCredentialOption(@NonNull Parcel in) {
+ String type = in.readString8();
+ Bundle candidateQueryData = in.readBundle();
+
+ mType = type;
+ AnnotationValidations.validate(NonNull.class, null, mType);
+ mCandidateQueryData = candidateQueryData;
+ AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
+ }
+
+ public static final @NonNull Creator<BeginGetCredentialOption> CREATOR =
+ new Creator<BeginGetCredentialOption>() {
+ @Override
+ public BeginGetCredentialOption[] newArray(int size) {
+ return new BeginGetCredentialOption[size];
+ }
+
+ @Override
+ public BeginGetCredentialOption createFromParcel(@NonNull Parcel in) {
+ return new BeginGetCredentialOption(in);
+ }
+ };
+}
diff --git a/core/java/android/service/credentials/GetCredentialsRequest.aidl b/core/java/android/service/credentials/BeginGetCredentialsRequest.aidl
index b309d698e7de..5e1fe8abc2aa 100644
--- a/core/java/android/service/credentials/GetCredentialsRequest.aidl
+++ b/core/java/android/service/credentials/BeginGetCredentialsRequest.aidl
@@ -1,3 +1,3 @@
package android.service.credentials;
-parcelable GetCredentialsRequest; \ No newline at end of file
+parcelable BeginGetCredentialsRequest; \ No newline at end of file
diff --git a/core/java/android/service/credentials/BeginGetCredentialsRequest.java b/core/java/android/service/credentials/BeginGetCredentialsRequest.java
new file mode 100644
index 000000000000..795840b42f2a
--- /dev/null
+++ b/core/java/android/service/credentials/BeginGetCredentialsRequest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.credentials;
+
+import android.annotation.NonNull;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.credentials.GetCredentialOption;
+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;
+
+/**
+ * Query stage request for getting user's credentials from a given credential provider.
+ *
+ * <p>This request contains a list of {@link GetCredentialOption} that have parameters
+ * to be used to query credentials, and return a list of {@link CredentialEntry} to be set
+ * on the {@link BeginGetCredentialsResponse}. This list is then shown to the user on a selector.
+ *
+ * If a {@link PendingIntent} is set on a {@link CredentialEntry}, and the user selects that
+ * entry, a {@link GetCredentialRequest} with all parameters needed to get the actual
+ * {@link android.credentials.Credential} will be sent as part of the {@link Intent} fired
+ * through the {@link PendingIntent}.
+ */
+public final class BeginGetCredentialsRequest implements Parcelable {
+ /** Calling package of the app requesting for credentials. */
+ @NonNull private final String mCallingPackage;
+
+ /**
+ * List of credential options. Each {@link BeginGetCredentialOption} object holds parameters to
+ * be used for populating a list of {@link CredentialEntry} for a specific type of credential.
+ *
+ * This request does not reveal sensitive parameters. Complete list of parameters
+ * is retrieved through the {@link PendingIntent} set on each {@link CredentialEntry}
+ * on {@link CredentialsResponseContent} set on {@link BeginGetCredentialsResponse},
+ * when the user selects one of these entries.
+ */
+ @NonNull private final List<BeginGetCredentialOption> mBeginGetCredentialOptions;
+
+ private BeginGetCredentialsRequest(@NonNull String callingPackage,
+ @NonNull List<BeginGetCredentialOption> getBeginCredentialOptions) {
+ this.mCallingPackage = callingPackage;
+ this.mBeginGetCredentialOptions = getBeginCredentialOptions;
+ }
+
+ private BeginGetCredentialsRequest(@NonNull Parcel in) {
+ mCallingPackage = in.readString8();
+ List<BeginGetCredentialOption> getBeginCredentialOptions = new ArrayList<>();
+ in.readTypedList(getBeginCredentialOptions, BeginGetCredentialOption.CREATOR);
+ mBeginGetCredentialOptions = getBeginCredentialOptions;
+ AnnotationValidations.validate(NonNull.class, null, mBeginGetCredentialOptions);
+ }
+
+ public static final @NonNull Creator<BeginGetCredentialsRequest> CREATOR =
+ new Creator<BeginGetCredentialsRequest>() {
+ @Override
+ public BeginGetCredentialsRequest createFromParcel(Parcel in) {
+ return new BeginGetCredentialsRequest(in);
+ }
+
+ @Override
+ public BeginGetCredentialsRequest[] newArray(int size) {
+ return new BeginGetCredentialsRequest[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mCallingPackage);
+ dest.writeTypedList(mBeginGetCredentialOptions);
+ }
+
+ /**
+ * Returns the calling package of the app requesting credentials.
+ */
+ public @NonNull String getCallingPackage() {
+ return mCallingPackage;
+ }
+
+ /**
+ * Returns the list of type specific credential options to list credentials for in
+ * {@link BeginGetCredentialsResponse}.
+ */
+ public @NonNull List<BeginGetCredentialOption> getBeginGetCredentialOptions() {
+ return mBeginGetCredentialOptions;
+ }
+
+ /**
+ * Builder for {@link BeginGetCredentialsRequest}.
+ */
+ public static final class Builder {
+ private String mCallingPackage;
+ private List<BeginGetCredentialOption> mBeginGetCredentialOptions = new ArrayList<>();
+
+ /**
+ * Creates a new builder.
+ * @param callingPackage the calling package of the app requesting credentials
+ *
+ * @throws IllegalArgumentException If {@code callingPackage} is null or empty.
+ */
+ public Builder(@NonNull String callingPackage) {
+ mCallingPackage = Preconditions.checkStringNotEmpty(callingPackage);
+ }
+
+ /**
+ * Sets the list of credential options.
+ *
+ * @throws NullPointerException If {@code getBeginCredentialOptions} itself or any of its
+ * elements is null.
+ * @throws IllegalArgumentException If {@code getBeginCredentialOptions} is empty.
+ */
+ public @NonNull Builder setBeginGetCredentialOptions(
+ @NonNull List<BeginGetCredentialOption> getBeginCredentialOptions) {
+ Preconditions.checkCollectionNotEmpty(getBeginCredentialOptions,
+ "getBeginCredentialOptions");
+ Preconditions.checkCollectionElementsNotNull(getBeginCredentialOptions,
+ "getBeginCredentialOptions");
+ mBeginGetCredentialOptions = getBeginCredentialOptions;
+ return this;
+ }
+
+ /**
+ * Adds a single {@link BeginGetCredentialOption} object to the list of credential options.
+ *
+ * @throws NullPointerException If {@code beginGetCredentialOption} is null.
+ */
+ public @NonNull Builder addBeginGetCredentialOption(
+ @NonNull BeginGetCredentialOption beginGetCredentialOption) {
+ Objects.requireNonNull(beginGetCredentialOption,
+ "beginGetCredentialOption must not be null");
+ mBeginGetCredentialOptions.add(beginGetCredentialOption);
+ return this;
+ }
+
+ /**
+ * Builds a new {@link BeginGetCredentialsRequest} instance.
+ *
+ * @throws NullPointerException If {@code beginGetCredentialOptions} is null.
+ * @throws IllegalArgumentException If {@code beginGetCredentialOptions} is empty, or if
+ * {@code callingPackage} is null or empty.
+ */
+ public @NonNull BeginGetCredentialsRequest build() {
+ Preconditions.checkStringNotEmpty(mCallingPackage,
+ "Must set the calling package");
+ Preconditions.checkCollectionNotEmpty(mBeginGetCredentialOptions,
+ "beginGetCredentialOptions");
+ return new BeginGetCredentialsRequest(mCallingPackage, mBeginGetCredentialOptions);
+ }
+ }
+}
diff --git a/core/java/android/service/credentials/BeginGetCredentialsResponse.aidl b/core/java/android/service/credentials/BeginGetCredentialsResponse.aidl
new file mode 100644
index 000000000000..ca69bcaa866b
--- /dev/null
+++ b/core/java/android/service/credentials/BeginGetCredentialsResponse.aidl
@@ -0,0 +1,3 @@
+package android.service.credentials;
+
+parcelable BeginGetCredentialsResponse; \ No newline at end of file
diff --git a/core/java/android/service/credentials/GetCredentialsResponse.java b/core/java/android/service/credentials/BeginGetCredentialsResponse.java
index 5263141f982a..2cda56067ba8 100644
--- a/core/java/android/service/credentials/GetCredentialsResponse.java
+++ b/core/java/android/service/credentials/BeginGetCredentialsResponse.java
@@ -27,7 +27,7 @@ import java.util.Objects;
* Response from a credential provider, containing credential entries and other associated
* data to be shown on the account selector UI.
*/
-public final class GetCredentialsResponse implements Parcelable {
+public final class BeginGetCredentialsResponse implements Parcelable {
/** Content to be used for the UI. */
private final @Nullable CredentialsResponseContent mCredentialsResponseContent;
@@ -38,14 +38,15 @@ public final class GetCredentialsResponse implements Parcelable {
private final @Nullable Action mAuthenticationAction;
/**
- * Creates a {@link GetCredentialsResponse} instance with an authentication {@link Action} set.
- * Providers must use this method when no content can be shown before authentication.
+ * Creates a {@link BeginGetCredentialsResponse} instance with an authentication
+ * {@link Action} set. Providers must use this method when no content can be shown
+ * before authentication.
*
* <p> When the user selects this {@code authenticationAction}, the system invokes the
* corresponding {@code pendingIntent}. Once the authentication flow is complete,
* the {@link android.app.Activity} result should be set
* to {@link android.app.Activity#RESULT_OK} and the
- * {@link CredentialProviderService#EXTRA_GET_CREDENTIALS_CONTENT_RESULT} extra should be set
+ * {@link CredentialProviderService#EXTRA_CREDENTIALS_RESPONSE_CONTENT} extra should be set
* with a fully populated {@link CredentialsResponseContent} object.
* the authentication action activity is launched, and the user is authenticated, providers
* should create another response with {@link CredentialsResponseContent} using
@@ -54,48 +55,49 @@ public final class GetCredentialsResponse implements Parcelable {
*
* @throws NullPointerException If {@code authenticationAction} is null.
*/
- public static @NonNull GetCredentialsResponse createWithAuthentication(
+ public static @NonNull BeginGetCredentialsResponse createWithAuthentication(
@NonNull Action authenticationAction) {
Objects.requireNonNull(authenticationAction,
"authenticationAction must not be null");
- return new GetCredentialsResponse(null, authenticationAction);
+ return new BeginGetCredentialsResponse(null, authenticationAction);
}
/**
- * Creates a {@link GetCredentialsRequest} instance with content to be shown on the UI.
+ * Creates a {@link BeginGetCredentialsRequest} instance with content to be shown on the UI.
* Providers must use this method when there is content to be shown without top level
* authentication required, including credential entries, action entries or a remote entry,
*
* @throws NullPointerException If {@code credentialsResponseContent} is null.
*/
- public static @NonNull GetCredentialsResponse createWithResponseContent(
+ public static @NonNull BeginGetCredentialsResponse createWithResponseContent(
@NonNull CredentialsResponseContent credentialsResponseContent) {
Objects.requireNonNull(credentialsResponseContent,
"credentialsResponseContent must not be null");
- return new GetCredentialsResponse(credentialsResponseContent, null);
+ return new BeginGetCredentialsResponse(credentialsResponseContent, null);
}
- private GetCredentialsResponse(@Nullable CredentialsResponseContent credentialsResponseContent,
+ private BeginGetCredentialsResponse(@Nullable CredentialsResponseContent
+ credentialsResponseContent,
@Nullable Action authenticationAction) {
mCredentialsResponseContent = credentialsResponseContent;
mAuthenticationAction = authenticationAction;
}
- private GetCredentialsResponse(@NonNull Parcel in) {
+ private BeginGetCredentialsResponse(@NonNull Parcel in) {
mCredentialsResponseContent = in.readTypedObject(CredentialsResponseContent.CREATOR);
mAuthenticationAction = in.readTypedObject(Action.CREATOR);
}
- public static final @NonNull Creator<GetCredentialsResponse> CREATOR =
- new Creator<GetCredentialsResponse>() {
+ public static final @NonNull Creator<BeginGetCredentialsResponse> CREATOR =
+ new Creator<BeginGetCredentialsResponse>() {
@Override
- public GetCredentialsResponse createFromParcel(Parcel in) {
- return new GetCredentialsResponse(in);
+ public BeginGetCredentialsResponse createFromParcel(Parcel in) {
+ return new BeginGetCredentialsResponse(in);
}
@Override
- public GetCredentialsResponse[] newArray(int size) {
- return new GetCredentialsResponse[size];
+ public BeginGetCredentialsResponse[] newArray(int size) {
+ return new BeginGetCredentialsResponse[size];
}
};
diff --git a/core/java/android/service/credentials/CredentialEntry.java b/core/java/android/service/credentials/CredentialEntry.java
index 941db02be8d1..3c399d26c2fb 100644
--- a/core/java/android/service/credentials/CredentialEntry.java
+++ b/core/java/android/service/credentials/CredentialEntry.java
@@ -17,10 +17,9 @@
package android.service.credentials;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.PendingIntent;
import android.app.slice.Slice;
-import android.credentials.Credential;
+import android.credentials.GetCredentialResponse;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,32 +40,23 @@ public final class CredentialEntry implements Parcelable {
private final @NonNull Slice mSlice;
/** The pending intent to be invoked when this credential entry is selected. */
- private final @Nullable PendingIntent mPendingIntent;
-
- /**
- * The underlying credential to be returned to the app when the user selects
- * this credential entry.
- */
- private final @Nullable Credential mCredential;
+ private final @NonNull PendingIntent mPendingIntent;
/** A flag denoting whether auto-select is enabled for this entry. */
private final @NonNull boolean mAutoSelectAllowed;
private CredentialEntry(@NonNull String type, @NonNull Slice slice,
- @Nullable PendingIntent pendingIntent, @Nullable Credential credential,
- @NonNull boolean autoSeletAllowed) {
+ @NonNull PendingIntent pendingIntent, @NonNull boolean autoSelectAllowed) {
mType = type;
mSlice = slice;
mPendingIntent = pendingIntent;
- mCredential = credential;
- mAutoSelectAllowed = autoSeletAllowed;
+ mAutoSelectAllowed = autoSelectAllowed;
}
private CredentialEntry(@NonNull Parcel in) {
mType = in.readString8();
mSlice = in.readTypedObject(Slice.CREATOR);
mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
- mCredential = in.readTypedObject(Credential.CREATOR);
mAutoSelectAllowed = in.readBoolean();
}
@@ -93,7 +83,6 @@ public final class CredentialEntry implements Parcelable {
dest.writeString8(mType);
dest.writeTypedObject(mSlice, flags);
dest.writeTypedObject(mPendingIntent, flags);
- dest.writeTypedObject(mCredential, flags);
dest.writeBoolean(mAutoSelectAllowed);
}
@@ -114,18 +103,11 @@ public final class CredentialEntry implements Parcelable {
/**
* Returns the pending intent to be invoked if the user selects this entry.
*/
- public @Nullable PendingIntent getPendingIntent() {
+ public @NonNull PendingIntent getPendingIntent() {
return mPendingIntent;
}
/**
- * Returns the credential associated with this entry.
- */
- public @Nullable Credential getCredential() {
- return mCredential;
- }
-
- /**
* Returns whether this entry can be auto selected if it is the only option for the user.
*/
public boolean isAutoSelectAllowed() {
@@ -138,8 +120,7 @@ public final class CredentialEntry implements Parcelable {
public static final class Builder {
private String mType;
private Slice mSlice;
- private PendingIntent mPendingIntent = null;
- private Credential mCredential = null;
+ private PendingIntent mPendingIntent;
private boolean mAutoSelectAllowed = false;
/**
@@ -152,8 +133,8 @@ public final class CredentialEntry implements Parcelable {
* Once the activity fulfills the required user engagement, the
* {@link android.app.Activity} result should be set to
* {@link android.app.Activity#RESULT_OK}, and the
- * {@link CredentialProviderService#EXTRA_CREDENTIAL_RESULT} must be set with a
- * {@link Credential} object.
+ * {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE} must be set with a
+ * {@link GetCredentialResponse} object.
*
* @param type the type of credential underlying this credential entry
* @param slice the content to be displayed with this entry on the UI
@@ -179,26 +160,6 @@ public final class CredentialEntry implements Parcelable {
}
/**
- * Creates a builder for a {@link CredentialEntry} that contains a {@link Credential},
- * and does not require further action.
- * @param type the type of credential underlying this credential entry
- * @param slice the content to be displayed with this entry on the UI
- * @param credential the credential to be returned to the client app, when this entry is
- * selected by the user
- *
- * @throws IllegalArgumentException If {@code type} is null or empty.
- * @throws NullPointerException If {@code slice}, or {@code credential} is null.
- */
- public Builder(@NonNull String type, @NonNull Slice slice, @NonNull Credential credential) {
- mType = Preconditions.checkStringNotEmpty(type, "type must not be "
- + "null, or empty");
- mSlice = Objects.requireNonNull(slice,
- "slice must not be null");
- mCredential = Objects.requireNonNull(credential,
- "credential must not be null");
- }
-
- /**
* Sets whether the entry is allowed to be auto selected by the framework.
* The default value is set to false.
*
@@ -219,12 +180,9 @@ public final class CredentialEntry implements Parcelable {
* is set, or if both are set.
*/
public @NonNull CredentialEntry build() {
- Preconditions.checkState(((mPendingIntent != null && mCredential == null)
- || (mPendingIntent == null && mCredential != null)),
- "Either pendingIntent or credential must be set, and both cannot"
- + "be set at the same time");
- return new CredentialEntry(mType, mSlice, mPendingIntent,
- mCredential, mAutoSelectAllowed);
+ Preconditions.checkState(mPendingIntent != null,
+ "pendingIntent must not be null");
+ return new CredentialEntry(mType, mSlice, mPendingIntent, mAutoSelectAllowed);
}
}
}
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index 32646e6fd289..416ddf172616 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -21,6 +21,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.SdkConstant;
+import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.CancellationSignal;
@@ -45,12 +46,23 @@ public abstract class CredentialProviderService extends Service {
* returned as part of the {@link BeginCreateCredentialResponse}
*
* <p>
- * Type: {@link android.credentials.CreateCredentialRequest}
+ * Type: {@link android.service.credentials.CreateCredentialRequest}
*/
public static final String EXTRA_CREATE_CREDENTIAL_REQUEST =
"android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
/**
+ * Intent extra: The {@link GetCredentialRequest} attached with
+ * the {@code pendingIntent} that is invoked when the user selects a {@link CredentialEntry}
+ * returned as part of the {@link BeginGetCredentialsResponse}
+ *
+ * <p>
+ * Type: {@link GetCredentialRequest}
+ */
+ public static final String EXTRA_GET_CREDENTIAL_REQUEST =
+ "android.service.credentials.extra.GET_CREDENTIAL_REQUEST";
+
+ /**
* Intent extra: The result of a create flow operation, to be set on finish of the
* {@link android.app.Activity} invoked through the {@code pendingIntent} set on
* a {@link CreateEntry}.
@@ -58,8 +70,8 @@ public abstract class CredentialProviderService extends Service {
* <p>
* Type: {@link android.credentials.CreateCredentialResponse}
*/
- public static final String EXTRA_CREATE_CREDENTIAL_RESULT =
- "android.service.credentials.extra.CREATE_CREDENTIAL_RESULT";
+ public static final String EXTRA_CREATE_CREDENTIAL_RESPONSE =
+ "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE";
/**
* Intent extra: The result of a get credential flow operation, to be set on finish of the
@@ -67,33 +79,48 @@ public abstract class CredentialProviderService extends Service {
* a {@link CredentialEntry}.
*
* <p>
- * Type: {@link android.credentials.Credential}
+ * Type: {@link android.credentials.GetCredentialResponse}
*/
- public static final String EXTRA_CREDENTIAL_RESULT =
- "android.service.credentials.extra.CREDENTIAL_RESULT";
+ public static final String EXTRA_GET_CREDENTIAL_RESPONSE =
+ "android.service.credentials.extra.GET_CREDENTIAL_RESPONSE";
/**
* Intent extra: The result of an authentication flow, to be set on finish of the
* {@link android.app.Activity} invoked through the {@link android.app.PendingIntent} set on
- * a {@link GetCredentialsResponse}. This result should contain the actual content, including
- * credential entries and action entries, to be shown on the selector.
+ * a {@link BeginGetCredentialsResponse}. This result should contain the actual content,
+ * including credential entries and action entries, to be shown on the selector.
*
* <p>
* Type: {@link CredentialsResponseContent}
*/
- public static final String EXTRA_GET_CREDENTIALS_CONTENT_RESULT =
- "android.service.credentials.extra.GET_CREDENTIALS_CONTENT_RESULT";
+ public static final String EXTRA_CREDENTIALS_RESPONSE_CONTENT =
+ "android.service.credentials.extra.CREDENTIALS_RESPONSE_CONTENT";
/**
- * Intent extra: The error result of any {@link android.app.PendingIntent} flow, to be set
- * on finish of the corresponding {@link android.app.Activity}. This result should contain an
- * error code, representing the error encountered by the provider.
+ * Intent extra: The failure exception set at the final stage of a get flow.
+ * This exception is set at the finishing result of the {@link android.app.Activity}
+ * invoked by the {@link PendingIntent} , when a user selects the {@link CredentialEntry}
+ * that contained the {@link PendingIntent} in question.
+ *
+ * <p>The result must be set through {@link android.app.Activity#setResult} as an intent extra
*
* <p>
- * Type: {@link String}
+ * Type: {@link android.credentials.GetCredentialException}
*/
- public static final String EXTRA_ERROR =
- "android.service.credentials.extra.ERROR";
+ public static final String EXTRA_GET_CREDENTIAL_EXCEPTION =
+ "android.service.credentials.extra.GET_CREDENTIAL_EXCEPTION";
+
+ /**
+ * Intent extra: The failure exception set at the final stage of a create flow.
+ * This exception is set at the finishing result of the {@link android.app.Activity}
+ * invoked by the {@link PendingIntent} , when a user selects the {@link CreateEntry}
+ * that contained the {@link PendingIntent} in question.
+ *
+ * <p>
+ * Type: {@link android.credentials.CreateCredentialException}
+ */
+ public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION =
+ "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";
private static final String TAG = "CredProviderService";
@@ -128,20 +155,21 @@ public abstract class CredentialProviderService extends Service {
private final ICredentialProviderService mInterface = new ICredentialProviderService.Stub() {
@Override
- public ICancellationSignal onGetCredentials(GetCredentialsRequest request,
- IGetCredentialsCallback callback) {
+ public ICancellationSignal onBeginGetCredentials(BeginGetCredentialsRequest request,
+ IBeginGetCredentialsCallback callback) {
Objects.requireNonNull(request);
Objects.requireNonNull(callback);
ICancellationSignal transport = CancellationSignal.createTransport();
mHandler.sendMessage(obtainMessage(
- CredentialProviderService::onGetCredentials,
+ CredentialProviderService::onBeginGetCredentials,
CredentialProviderService.this, request,
CancellationSignal.fromTransport(transport),
- new OutcomeReceiver<GetCredentialsResponse, CredentialProviderException>() {
+ new OutcomeReceiver<BeginGetCredentialsResponse,
+ CredentialProviderException>() {
@Override
- public void onResult(GetCredentialsResponse result) {
+ public void onResult(BeginGetCredentialsResponse result) {
try {
callback.onSuccess(result);
} catch (RemoteException e) {
@@ -200,14 +228,29 @@ public abstract class CredentialProviderService extends Service {
/**
* Called by the android system to retrieve user credentials from the connected provider
* service.
- * @param request the credential request for the provider to handle
+ *
+ *
+ *
+ * <p>This API denotes a query stage request for getting user's credentials from a given
+ * credential provider. The request contains a list of
+ * {@link android.credentials.GetCredentialOption} that have parameters to be used for
+ * populating candidate credentials, as a list of {@link CredentialEntry} to be set
+ * on the {@link BeginGetCredentialsResponse}. This list is then shown to the user on a
+ * selector.
+ *
+ * <p>If a {@link PendingIntent} is set on a {@link CredentialEntry}, and the user selects that
+ * entry, a {@link GetCredentialRequest} with all parameters needed to get the actual
+ * {@link android.credentials.Credential} will be sent as part of the {@link Intent} fired
+ * through the {@link PendingIntent}.
+ * @param request the request for the provider to handle
* @param cancellationSignal signal for providers to listen to any cancellation requests from
* the android system
* @param callback object used to relay the response of the credentials request
*/
- public abstract void onGetCredentials(@NonNull GetCredentialsRequest request,
+ public abstract void onBeginGetCredentials(@NonNull BeginGetCredentialsRequest request,
@NonNull CancellationSignal cancellationSignal,
- @NonNull OutcomeReceiver<GetCredentialsResponse, CredentialProviderException> callback);
+ @NonNull OutcomeReceiver<
+ BeginGetCredentialsResponse, CredentialProviderException> callback);
/**
* Called by the android system to create a credential.
diff --git a/core/java/android/service/credentials/CredentialsResponseContent.java b/core/java/android/service/credentials/CredentialsResponseContent.java
index 32cab5004ac0..c2f28cb1204c 100644
--- a/core/java/android/service/credentials/CredentialsResponseContent.java
+++ b/core/java/android/service/credentials/CredentialsResponseContent.java
@@ -29,7 +29,7 @@ import java.util.Objects;
/**
* The content to be displayed on the account selector UI, including credential entries,
- * actions etc. Returned as part of {@link GetCredentialsResponse}
+ * actions etc. Returned as part of {@link BeginGetCredentialsResponse}
*/
public final class CredentialsResponseContent implements Parcelable {
/** List of credential entries to be displayed on the UI. */
@@ -124,7 +124,7 @@ public final class CredentialsResponseContent implements Parcelable {
*
* <p> Once the remote credential flow is complete, the {@link android.app.Activity}
* result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
- * {@link CredentialProviderService#EXTRA_CREDENTIAL_RESULT} key should be populated
+ * {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE} key should be populated
* with a {@link android.credentials.Credential} object.
*/
public @NonNull Builder setRemoteCredentialEntry(@Nullable CredentialEntry
@@ -188,7 +188,7 @@ public final class CredentialsResponseContent implements Parcelable {
}
/**
- * Builds a {@link GetCredentialsResponse} instance.
+ * Builds a {@link CredentialsResponseContent} instance.
*
* @throws IllegalStateException if {@code credentialEntries}, {@code actions}
* and {@code remoteCredentialEntry} are all null or empty.
diff --git a/core/java/android/service/credentials/GetCredentialsRequest.java b/core/java/android/service/credentials/GetCredentialRequest.java
index 9052b54c8291..1d6c83be0db1 100644
--- a/core/java/android/service/credentials/GetCredentialsRequest.java
+++ b/core/java/android/service/credentials/GetCredentialRequest.java
@@ -21,6 +21,7 @@ import android.credentials.GetCredentialOption;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.AnnotationValidations;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
@@ -30,7 +31,7 @@ import java.util.Objects;
/**
* Request for getting user's credentials from a given credential provider.
*/
-public final class GetCredentialsRequest implements Parcelable {
+public final class GetCredentialRequest implements Parcelable {
/** Calling package of the app requesting for credentials. */
private final @NonNull String mCallingPackage;
@@ -40,29 +41,30 @@ public final class GetCredentialsRequest implements Parcelable {
*/
private final @NonNull List<GetCredentialOption> mGetCredentialOptions;
- private GetCredentialsRequest(@NonNull String callingPackage,
+ private GetCredentialRequest(@NonNull String callingPackage,
@NonNull List<GetCredentialOption> getCredentialOptions) {
this.mCallingPackage = callingPackage;
this.mGetCredentialOptions = getCredentialOptions;
}
- private GetCredentialsRequest(@NonNull Parcel in) {
+ private GetCredentialRequest(@NonNull Parcel in) {
mCallingPackage = in.readString8();
List<GetCredentialOption> getCredentialOptions = new ArrayList<>();
in.readTypedList(getCredentialOptions, GetCredentialOption.CREATOR);
mGetCredentialOptions = getCredentialOptions;
+ AnnotationValidations.validate(NonNull.class, null, mGetCredentialOptions);
}
- public static final @NonNull Creator<GetCredentialsRequest> CREATOR =
- new Creator<GetCredentialsRequest>() {
+ public static final @NonNull Creator<GetCredentialRequest> CREATOR =
+ new Creator<GetCredentialRequest>() {
@Override
- public GetCredentialsRequest createFromParcel(Parcel in) {
- return new GetCredentialsRequest(in);
+ public GetCredentialRequest createFromParcel(Parcel in) {
+ return new GetCredentialRequest(in);
}
@Override
- public GetCredentialsRequest[] newArray(int size) {
- return new GetCredentialsRequest[size];
+ public GetCredentialRequest[] newArray(int size) {
+ return new GetCredentialRequest[size];
}
};
@@ -92,7 +94,7 @@ public final class GetCredentialsRequest implements Parcelable {
}
/**
- * Builder for {@link GetCredentialsRequest}.
+ * Builder for {@link GetCredentialRequest}.
*/
public static final class Builder {
private String mCallingPackage;
@@ -139,18 +141,18 @@ public final class GetCredentialsRequest implements Parcelable {
}
/**
- * Builds a new {@link GetCredentialsRequest} instance.
+ * Builds a new {@link GetCredentialRequest} instance.
*
* @throws NullPointerException If {@code getCredentialOptions} is null.
* @throws IllegalArgumentException If {@code getCredentialOptions} is empty, or if
* {@code callingPackage} is null or empty.
*/
- public @NonNull GetCredentialsRequest build() {
+ public @NonNull GetCredentialRequest build() {
Preconditions.checkStringNotEmpty(mCallingPackage,
"Must set the calling package");
Preconditions.checkCollectionNotEmpty(mGetCredentialOptions,
"getCredentialOptions");
- return new GetCredentialsRequest(mCallingPackage, mGetCredentialOptions);
+ return new GetCredentialRequest(mCallingPackage, mGetCredentialOptions);
}
}
}
diff --git a/core/java/android/service/credentials/GetCredentialsResponse.aidl b/core/java/android/service/credentials/GetCredentialsResponse.aidl
deleted file mode 100644
index 0d8c6357a715..000000000000
--- a/core/java/android/service/credentials/GetCredentialsResponse.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.service.credentials;
-
-parcelable GetCredentialsResponse; \ No newline at end of file
diff --git a/core/java/android/service/credentials/IGetCredentialsCallback.aidl b/core/java/android/service/credentials/IBeginGetCredentialsCallback.aidl
index 6e20c555af60..9ac28f26059b 100644
--- a/core/java/android/service/credentials/IGetCredentialsCallback.aidl
+++ b/core/java/android/service/credentials/IBeginGetCredentialsCallback.aidl
@@ -1,13 +1,13 @@
package android.service.credentials;
-import android.service.credentials.GetCredentialsResponse;
+import android.service.credentials.BeginGetCredentialsResponse;
/**
* Interface from the system to a credential provider service.
*
* @hide
*/
-oneway interface IGetCredentialsCallback {
- void onSuccess(in GetCredentialsResponse response);
+oneway interface IBeginGetCredentialsCallback {
+ void onSuccess(in BeginGetCredentialsResponse response);
void onFailure(int errorCode, in CharSequence message);
} \ No newline at end of file
diff --git a/core/java/android/service/credentials/ICredentialProviderService.aidl b/core/java/android/service/credentials/ICredentialProviderService.aidl
index b9eb3ed9571a..130688291795 100644
--- a/core/java/android/service/credentials/ICredentialProviderService.aidl
+++ b/core/java/android/service/credentials/ICredentialProviderService.aidl
@@ -17,9 +17,9 @@
package android.service.credentials;
import android.os.ICancellationSignal;
-import android.service.credentials.GetCredentialsRequest;
+import android.service.credentials.BeginGetCredentialsRequest;
import android.service.credentials.BeginCreateCredentialRequest;
-import android.service.credentials.IGetCredentialsCallback;
+import android.service.credentials.IBeginGetCredentialsCallback;
import android.service.credentials.IBeginCreateCredentialCallback;
import android.os.ICancellationSignal;
@@ -29,6 +29,6 @@ import android.os.ICancellationSignal;
* @hide
*/
interface ICredentialProviderService {
- ICancellationSignal onGetCredentials(in GetCredentialsRequest request, in IGetCredentialsCallback callback);
+ ICancellationSignal onBeginGetCredentials(in BeginGetCredentialsRequest request, in IBeginGetCredentialsCallback callback);
ICancellationSignal onBeginCreateCredential(in BeginCreateCredentialRequest request, in IBeginCreateCredentialCallback callback);
}
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index d3b9e10a436a..2f951ed63bb9 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -36,7 +36,7 @@ import android.os.ICancellationSignal;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.credentials.BeginCreateCredentialRequest;
-import android.service.credentials.GetCredentialsRequest;
+import android.service.credentials.BeginGetCredentialsRequest;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -169,8 +169,8 @@ public final class CredentialManagerService extends
// Iterate over all provider sessions and invoke the request
providerSessions.forEach(providerGetSession -> {
- providerGetSession.getRemoteCredentialService().onGetCredentials(
- (GetCredentialsRequest) providerGetSession.getProviderRequest(),
+ providerGetSession.getRemoteCredentialService().onBeginGetCredentials(
+ (BeginGetCredentialsRequest) providerGetSession.getProviderRequest(),
/*callback=*/providerGetSession);
});
return cancelTransport;
diff --git a/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java b/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
index d0bc0744f8a5..7f9e57a5bdb6 100644
--- a/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
+++ b/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
@@ -19,7 +19,7 @@ package com.android.server.credentials;
import android.app.Activity;
import android.content.Intent;
import android.credentials.CreateCredentialResponse;
-import android.credentials.Credential;
+import android.credentials.GetCredentialResponse;
import android.credentials.ui.ProviderPendingIntentResponse;
import android.service.credentials.CredentialProviderService;
import android.service.credentials.CredentialsResponseContent;
@@ -43,8 +43,7 @@ public class PendingIntentResultHandler {
return null;
}
return resultData.getParcelableExtra(
- CredentialProviderService
- .EXTRA_GET_CREDENTIALS_CONTENT_RESULT,
+ CredentialProviderService.EXTRA_CREDENTIALS_RESPONSE_CONTENT,
CredentialsResponseContent.class);
}
@@ -54,17 +53,17 @@ public class PendingIntentResultHandler {
return null;
}
return resultData.getParcelableExtra(
- CredentialProviderService.EXTRA_CREATE_CREDENTIAL_RESULT,
+ CredentialProviderService.EXTRA_CREATE_CREDENTIAL_RESPONSE,
CreateCredentialResponse.class);
}
- /** Extracts the {@link Credential} object added to the result data. */
- public static Credential extractCredential(Intent resultData) {
+ /** Extracts the {@link GetCredentialResponse} object added to the result data. */
+ public static GetCredentialResponse extractGetCredentialResponse(Intent resultData) {
if (resultData == null) {
return null;
}
return resultData.getParcelableExtra(
- CredentialProviderService.EXTRA_CREDENTIAL_RESULT,
- Credential.class);
+ CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE,
+ GetCredentialResponse.class);
}
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index 6cd011b7a686..9888cc0a3732 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -19,19 +19,23 @@ package com.android.server.credentials;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.PendingIntent;
import android.content.Context;
-import android.credentials.Credential;
+import android.content.Intent;
import android.credentials.GetCredentialOption;
import android.credentials.GetCredentialResponse;
import android.credentials.ui.Entry;
import android.credentials.ui.GetCredentialProviderData;
import android.credentials.ui.ProviderPendingIntentResponse;
import android.service.credentials.Action;
+import android.service.credentials.BeginGetCredentialOption;
+import android.service.credentials.BeginGetCredentialsRequest;
+import android.service.credentials.BeginGetCredentialsResponse;
import android.service.credentials.CredentialEntry;
import android.service.credentials.CredentialProviderInfo;
+import android.service.credentials.CredentialProviderService;
import android.service.credentials.CredentialsResponseContent;
-import android.service.credentials.GetCredentialsRequest;
-import android.service.credentials.GetCredentialsResponse;
+import android.service.credentials.GetCredentialRequest;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -41,6 +45,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.stream.Collectors;
/**
* Central provider session that listens for provider callbacks, and maintains provider state.
@@ -48,10 +53,10 @@ import java.util.UUID;
*
* @hide
*/
-public final class ProviderGetSession extends ProviderSession<GetCredentialsRequest,
- GetCredentialsResponse>
+public final class ProviderGetSession extends ProviderSession<BeginGetCredentialsRequest,
+ BeginGetCredentialsResponse>
implements
- RemoteCredentialService.ProviderCallbacks<GetCredentialsResponse> {
+ RemoteCredentialService.ProviderCallbacks<BeginGetCredentialsResponse> {
private static final String TAG = "ProviderGetSession";
// Key to be used as an entry key for a credential entry
@@ -69,6 +74,9 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
@Nullable
private Pair<String, Action> mUiAuthenticationAction = null;
+ /** The complete request to be used in the second round. */
+ private final GetCredentialRequest mCompleteRequest;
+
/** Creates a new provider session to be used by the request session. */
@Nullable public static ProviderGetSession createNewSession(
Context context,
@@ -76,20 +84,34 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
CredentialProviderInfo providerInfo,
GetRequestSession getRequestSession,
RemoteCredentialService remoteCredentialService) {
- GetCredentialsRequest providerRequest =
+ GetCredentialRequest completeRequest =
createProviderRequest(providerInfo.getCapabilities(),
getRequestSession.mClientRequest,
getRequestSession.mClientCallingPackage);
- if (providerRequest != null) {
+ if (completeRequest != null) {
+ // TODO: Update to using query data when ready
+ BeginGetCredentialsRequest beginGetCredentialsRequest =
+ new BeginGetCredentialsRequest.Builder(
+ completeRequest.getCallingPackage())
+ .setBeginGetCredentialOptions(
+ completeRequest.getGetCredentialOptions().stream().map(
+ option -> {
+ //TODO : Replace with option.getCandidateQueryData
+ // when ready
+ return new BeginGetCredentialOption(
+ option.getType(),
+ option.getCandidateQueryData());
+ }).collect(Collectors.toList()))
+ .build();
return new ProviderGetSession(context, providerInfo, getRequestSession, userId,
- remoteCredentialService, providerRequest);
+ remoteCredentialService, beginGetCredentialsRequest, completeRequest);
}
Log.i(TAG, "Unable to create provider session");
return null;
}
@Nullable
- private static GetCredentialsRequest createProviderRequest(List<String> providerCapabilities,
+ private static GetCredentialRequest createProviderRequest(List<String> providerCapabilities,
android.credentials.GetCredentialRequest clientRequest,
String clientCallingPackage) {
List<GetCredentialOption> filteredOptions = new ArrayList<>();
@@ -104,7 +126,7 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
}
}
if (!filteredOptions.isEmpty()) {
- return new GetCredentialsRequest.Builder(clientCallingPackage).setGetCredentialOptions(
+ return new GetCredentialRequest.Builder(clientCallingPackage).setGetCredentialOptions(
filteredOptions).build();
}
Log.i(TAG, "In createProviderRequest - returning null");
@@ -115,8 +137,10 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
CredentialProviderInfo info,
ProviderInternalCallback callbacks,
int userId, RemoteCredentialService remoteCredentialService,
- GetCredentialsRequest request) {
- super(context, info, request, callbacks, userId, remoteCredentialService);
+ BeginGetCredentialsRequest beginGetRequest,
+ GetCredentialRequest completeGetRequest) {
+ super(context, info, beginGetRequest, callbacks, userId, remoteCredentialService);
+ mCompleteRequest = completeGetRequest;
setStatus(Status.PENDING);
}
@@ -128,7 +152,7 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
/** Called when the provider response has been updated by an external source. */
@Override // Callback from the remote provider
- public void onProviderResponseSuccess(@Nullable GetCredentialsResponse response) {
+ public void onProviderResponseSuccess(@Nullable BeginGetCredentialsResponse response) {
Log.i(TAG, "in onProviderResponseSuccess");
onUpdateResponse(response);
}
@@ -254,19 +278,26 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
mUiCredentialEntries.put(entryId, credentialEntry);
Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId);
if (credentialEntry.getPendingIntent() != null) {
+ setUpFillInIntent(credentialEntry.getPendingIntent());
credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId,
credentialEntry.getSlice(), credentialEntry.getPendingIntent(),
/*fillInIntent=*/null));
- } else if (credentialEntry.getCredential() != null) {
- credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId,
- credentialEntry.getSlice()));
} else {
- Log.i(TAG, "No credential or pending intent. Should not happen.");
+ Log.i(TAG, "No pending intent. Should not happen.");
}
}
return credentialUiEntries;
}
+ private Intent setUpFillInIntent(PendingIntent pendingIntent) {
+ Intent intent = pendingIntent.getIntent();
+ intent.putExtra(
+ CredentialProviderService
+ .EXTRA_GET_CREDENTIAL_REQUEST,
+ mCompleteRequest);
+ return intent;
+ }
+
private List<Entry> prepareUiActionEntries(@Nullable List<Action> actions) {
List<Entry> actionEntries = new ArrayList<>();
for (Action action : actions) {
@@ -292,17 +323,14 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
private void onCredentialEntrySelected(CredentialEntry credentialEntry,
ProviderPendingIntentResponse providerPendingIntentResponse) {
- if (credentialEntry.getCredential() != null) {
- mCallbacks.onFinalResponseReceived(mComponentName, new GetCredentialResponse(
- credentialEntry.getCredential()));
- return;
- } else if (providerPendingIntentResponse != null) {
+ if (providerPendingIntentResponse != null) {
if (PendingIntentResultHandler.isSuccessfulResponse(providerPendingIntentResponse)) {
- Credential credential = PendingIntentResultHandler.extractCredential(
- providerPendingIntentResponse.getResultData());
- if (credential != null) {
- mCallbacks.onFinalResponseReceived(mComponentName,
- new GetCredentialResponse(credential));
+ // TODO: Remove credential extraction when flow is fully transitioned
+ GetCredentialResponse getCredentialResponse = PendingIntentResultHandler
+ .extractGetCredentialResponse(
+ providerPendingIntentResponse.getResultData());
+ if (getCredentialResponse != null) {
+ mCallbacks.onFinalResponseReceived(mComponentName, getCredentialResponse);
return;
}
}
@@ -320,7 +348,8 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
.extractResponseContent(providerPendingIntentResponse
.getResultData());
if (content != null) {
- onUpdateResponse(GetCredentialsResponse.createWithResponseContent(content));
+ onUpdateResponse(
+ BeginGetCredentialsResponse.createWithResponseContent(content));
return;
}
}
@@ -337,7 +366,7 @@ public final class ProviderGetSession extends ProviderSession<GetCredentialsRequ
/** Updates the response being maintained in state by this provider session. */
- private void onUpdateResponse(GetCredentialsResponse response) {
+ private void onUpdateResponse(BeginGetCredentialsResponse response) {
mProviderResponse = response;
if (response.getAuthenticationAction() != null) {
Log.i(TAG , "updateResponse with authentication entry");
diff --git a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
index e385bcb32201..7a883b359d9f 100644
--- a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
+++ b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
@@ -26,14 +26,14 @@ import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.service.credentials.BeginCreateCredentialRequest;
import android.service.credentials.BeginCreateCredentialResponse;
+import android.service.credentials.BeginGetCredentialsRequest;
+import android.service.credentials.BeginGetCredentialsResponse;
import android.service.credentials.CredentialProviderException;
import android.service.credentials.CredentialProviderException.CredentialProviderError;
import android.service.credentials.CredentialProviderService;
-import android.service.credentials.GetCredentialsRequest;
-import android.service.credentials.GetCredentialsResponse;
import android.service.credentials.IBeginCreateCredentialCallback;
+import android.service.credentials.IBeginGetCredentialsCallback;
import android.service.credentials.ICredentialProviderService;
-import android.service.credentials.IGetCredentialsCallback;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.Slog;
@@ -106,19 +106,21 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
* @param callback the callback to be used to send back the provider response to the
* {@link ProviderGetSession} class that maintains provider state
*/
- public void onGetCredentials(@NonNull GetCredentialsRequest request,
- ProviderCallbacks<GetCredentialsResponse> callback) {
+ public void onBeginGetCredentials(@NonNull BeginGetCredentialsRequest request,
+ ProviderCallbacks<BeginGetCredentialsResponse> callback) {
Log.i(TAG, "In onGetCredentials in RemoteCredentialService");
AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
- AtomicReference<CompletableFuture<GetCredentialsResponse>> futureRef =
+ AtomicReference<CompletableFuture<BeginGetCredentialsResponse>> futureRef =
new AtomicReference<>();
- CompletableFuture<GetCredentialsResponse> connectThenExecute = postAsync(service -> {
- CompletableFuture<GetCredentialsResponse> getCredentials = new CompletableFuture<>();
+ CompletableFuture<BeginGetCredentialsResponse> connectThenExecute = postAsync(service -> {
+ CompletableFuture<BeginGetCredentialsResponse> getCredentials =
+ new CompletableFuture<>();
ICancellationSignal cancellationSignal =
- service.onGetCredentials(request, new IGetCredentialsCallback.Stub() {
+ service.onBeginGetCredentials(request,
+ new IBeginGetCredentialsCallback.Stub() {
@Override
- public void onSuccess(GetCredentialsResponse response) {
+ public void onSuccess(BeginGetCredentialsResponse response) {
Log.i(TAG, "In onSuccess in RemoteCredentialService");
getCredentials.complete(response);
}
@@ -132,7 +134,7 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
errorCode, errorMsg));
}
});
- CompletableFuture<GetCredentialsResponse> future = futureRef.get();
+ CompletableFuture<BeginGetCredentialsResponse> future = futureRef.get();
if (future != null && future.isCancelled()) {
dispatchCancellationSignal(cancellationSignal);
} else {
@@ -159,7 +161,8 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
AtomicReference<CompletableFuture<BeginCreateCredentialResponse>> futureRef =
new AtomicReference<>();
- CompletableFuture<BeginCreateCredentialResponse> connectThenExecute = postAsync(service -> {
+ CompletableFuture<BeginCreateCredentialResponse> connectThenExecute =
+ postAsync(service -> {
CompletableFuture<BeginCreateCredentialResponse> createCredentialFuture =
new CompletableFuture<>();
ICancellationSignal cancellationSignal = service.onBeginCreateCredential(