Loading core/java/android/credentials/CredentialManager.java +65 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.credentials; import static java.util.Objects.requireNonNull; import android.annotation.CallbackExecutor; import android.annotation.Hide; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -116,6 +117,32 @@ public final class CredentialManager { mService = service; } /** * Returns a list of candidate credentials returned from credential manager providers * * @param request the request specifying type(s) of credentials to get from the * credential providers * @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 * * @hide */ @Hide public void getCandidateCredentials( @NonNull GetCredentialRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) { requireNonNull(request, "request 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"); } } /** * Launches the necessary flows to retrieve an app credential from the user. * Loading Loading @@ -641,6 +668,44 @@ public final class CredentialManager { } } private static class GetCandidateCredentialsTransport extends IGetCandidateCredentialsCallback.Stub { private final Executor mExecutor; private final OutcomeReceiver<GetCandidateCredentialsResponse, GetCandidateCredentialsException> mCallback; private GetCandidateCredentialsTransport( Executor executor, OutcomeReceiver<GetCandidateCredentialsResponse, GetCandidateCredentialsException> callback) { mExecutor = executor; mCallback = callback; } @Override public void onResponse(GetCandidateCredentialsResponse response) { final long identity = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> mCallback.onResult(response)); } finally { Binder.restoreCallingIdentity(identity); } } @Override public void onError(String errorType, String message) { final long identity = Binder.clearCallingIdentity(); try { mExecutor.execute( () -> mCallback.onError(new GetCandidateCredentialsException( errorType, message))); } finally { Binder.restoreCallingIdentity(identity); } } } private static class GetCredentialTransport extends IGetCredentialCallback.Stub { // TODO: listen for cancellation to release callback. Loading core/java/android/credentials/GetCandidateCredentialsException.java 0 → 100644 +95 −0 Original line number Diff line number Diff line /* * 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.credentials; import android.annotation.Hide; import android.annotation.NonNull; import android.annotation.Nullable; import com.android.internal.util.Preconditions; /** * Represents an error encountered during the * {@link CredentialManager#getCandidateCredentials} operation. * * @hide */ @Hide public class GetCandidateCredentialsException extends Exception { /** * The error type value for when the given operation failed due to an unknown reason. */ @NonNull public static final String TYPE_UNKNOWN = "android.credentials.GetCandidateCredentialsException.TYPE_UNKNOWN"; /** * The error type value for when no credential is found available for the given {@link * CredentialManager#getCandidateCredentials} request. */ @NonNull public static final String TYPE_NO_CREDENTIAL = "android.credentials.GetCandidateCredentialsException.TYPE_NO_CREDENTIAL"; @NonNull private final String mType; /** Returns the specific exception type. */ @NonNull public String getType() { return mType; } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException(@NonNull String type, @Nullable String message) { this(type, message, null); } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException( @NonNull String type, @Nullable String message, @Nullable Throwable cause) { super(message, cause); this.mType = Preconditions.checkStringNotEmpty(type, "type must not be empty"); } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException(@NonNull String type, @Nullable Throwable cause) { this(type, null, cause); } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException(@NonNull String type) { this(type, null, null); } } core/java/android/credentials/GetCandidateCredentialsRequest.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * 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.credentials; parcelable GetCandidateCredentialsRequest; No newline at end of file core/java/android/credentials/GetCandidateCredentialsRequest.java 0 → 100644 +147 −0 Original line number Diff line number Diff line /* * 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.credentials; import static java.util.Objects.requireNonNull; import android.annotation.Hide; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; 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; /** * A request to retrieve a list of candidate credentials against the list of credential * options * * @hide */ @Hide public final class GetCandidateCredentialsRequest implements Parcelable { /** * The list of credential requests. */ @NonNull private final List<CredentialOption> mCredentialOptions; /** * The top request level data. */ @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; /** * Returns the list of credential options to be requested. */ @NonNull public List<CredentialOption> getCredentialOptions() { return mCredentialOptions; } /** * Returns the top request level data. */ @NonNull public Bundle getData() { return mData; } /** * 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.writeTypedList(mCredentialOptions, flags); dest.writeBundle(mData); dest.writeString8(mOrigin); } @Override public int describeContents() { return 0; } @Override public String toString() { return "GetCandidateCredentialsRequest {credentialOption=" + mCredentialOptions + ", data=" + mData + ", origin=" + mOrigin + "}"; } private GetCandidateCredentialsRequest(@NonNull List<CredentialOption> credentialOptions, @NonNull Bundle data, String origin) { Preconditions.checkCollectionNotEmpty( credentialOptions, /*valueName=*/ "credentialOptions"); Preconditions.checkCollectionElementsNotNull( credentialOptions, /*valueName=*/ "credentialOptions"); mCredentialOptions = credentialOptions; mData = requireNonNull(data, "data must not be null"); mOrigin = origin; } private GetCandidateCredentialsRequest(@NonNull Parcel in) { List<CredentialOption> credentialOptions = new ArrayList<CredentialOption>(); in.readTypedList(credentialOptions, CredentialOption.CREATOR); mCredentialOptions = credentialOptions; AnnotationValidations.validate(NonNull.class, null, mCredentialOptions); Bundle data = in.readBundle(); mData = data; AnnotationValidations.validate(NonNull.class, null, mData); mOrigin = in.readString8(); } @NonNull public static final Creator<GetCandidateCredentialsRequest> CREATOR = new Creator<>() { @Override public GetCandidateCredentialsRequest[] newArray(int size) { return new GetCandidateCredentialsRequest[size]; } @Override public GetCandidateCredentialsRequest createFromParcel(@NonNull Parcel in) { return new GetCandidateCredentialsRequest(in); } }; } core/java/android/credentials/GetCandidateCredentialsResponse.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * 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.credentials; parcelable GetCandidateCredentialsResponse; No newline at end of file Loading
core/java/android/credentials/CredentialManager.java +65 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.credentials; import static java.util.Objects.requireNonNull; import android.annotation.CallbackExecutor; import android.annotation.Hide; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -116,6 +117,32 @@ public final class CredentialManager { mService = service; } /** * Returns a list of candidate credentials returned from credential manager providers * * @param request the request specifying type(s) of credentials to get from the * credential providers * @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 * * @hide */ @Hide public void getCandidateCredentials( @NonNull GetCredentialRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) { requireNonNull(request, "request 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"); } } /** * Launches the necessary flows to retrieve an app credential from the user. * Loading Loading @@ -641,6 +668,44 @@ public final class CredentialManager { } } private static class GetCandidateCredentialsTransport extends IGetCandidateCredentialsCallback.Stub { private final Executor mExecutor; private final OutcomeReceiver<GetCandidateCredentialsResponse, GetCandidateCredentialsException> mCallback; private GetCandidateCredentialsTransport( Executor executor, OutcomeReceiver<GetCandidateCredentialsResponse, GetCandidateCredentialsException> callback) { mExecutor = executor; mCallback = callback; } @Override public void onResponse(GetCandidateCredentialsResponse response) { final long identity = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> mCallback.onResult(response)); } finally { Binder.restoreCallingIdentity(identity); } } @Override public void onError(String errorType, String message) { final long identity = Binder.clearCallingIdentity(); try { mExecutor.execute( () -> mCallback.onError(new GetCandidateCredentialsException( errorType, message))); } finally { Binder.restoreCallingIdentity(identity); } } } private static class GetCredentialTransport extends IGetCredentialCallback.Stub { // TODO: listen for cancellation to release callback. Loading
core/java/android/credentials/GetCandidateCredentialsException.java 0 → 100644 +95 −0 Original line number Diff line number Diff line /* * 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.credentials; import android.annotation.Hide; import android.annotation.NonNull; import android.annotation.Nullable; import com.android.internal.util.Preconditions; /** * Represents an error encountered during the * {@link CredentialManager#getCandidateCredentials} operation. * * @hide */ @Hide public class GetCandidateCredentialsException extends Exception { /** * The error type value for when the given operation failed due to an unknown reason. */ @NonNull public static final String TYPE_UNKNOWN = "android.credentials.GetCandidateCredentialsException.TYPE_UNKNOWN"; /** * The error type value for when no credential is found available for the given {@link * CredentialManager#getCandidateCredentials} request. */ @NonNull public static final String TYPE_NO_CREDENTIAL = "android.credentials.GetCandidateCredentialsException.TYPE_NO_CREDENTIAL"; @NonNull private final String mType; /** Returns the specific exception type. */ @NonNull public String getType() { return mType; } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException(@NonNull String type, @Nullable String message) { this(type, message, null); } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException( @NonNull String type, @Nullable String message, @Nullable Throwable cause) { super(message, cause); this.mType = Preconditions.checkStringNotEmpty(type, "type must not be empty"); } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException(@NonNull String type, @Nullable Throwable cause) { this(type, null, cause); } /** * Constructs a {@link GetCandidateCredentialsException}. * * @throws IllegalArgumentException If type is empty. */ public GetCandidateCredentialsException(@NonNull String type) { this(type, null, null); } }
core/java/android/credentials/GetCandidateCredentialsRequest.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * 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.credentials; parcelable GetCandidateCredentialsRequest; No newline at end of file
core/java/android/credentials/GetCandidateCredentialsRequest.java 0 → 100644 +147 −0 Original line number Diff line number Diff line /* * 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.credentials; import static java.util.Objects.requireNonNull; import android.annotation.Hide; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; 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; /** * A request to retrieve a list of candidate credentials against the list of credential * options * * @hide */ @Hide public final class GetCandidateCredentialsRequest implements Parcelable { /** * The list of credential requests. */ @NonNull private final List<CredentialOption> mCredentialOptions; /** * The top request level data. */ @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; /** * Returns the list of credential options to be requested. */ @NonNull public List<CredentialOption> getCredentialOptions() { return mCredentialOptions; } /** * Returns the top request level data. */ @NonNull public Bundle getData() { return mData; } /** * 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.writeTypedList(mCredentialOptions, flags); dest.writeBundle(mData); dest.writeString8(mOrigin); } @Override public int describeContents() { return 0; } @Override public String toString() { return "GetCandidateCredentialsRequest {credentialOption=" + mCredentialOptions + ", data=" + mData + ", origin=" + mOrigin + "}"; } private GetCandidateCredentialsRequest(@NonNull List<CredentialOption> credentialOptions, @NonNull Bundle data, String origin) { Preconditions.checkCollectionNotEmpty( credentialOptions, /*valueName=*/ "credentialOptions"); Preconditions.checkCollectionElementsNotNull( credentialOptions, /*valueName=*/ "credentialOptions"); mCredentialOptions = credentialOptions; mData = requireNonNull(data, "data must not be null"); mOrigin = origin; } private GetCandidateCredentialsRequest(@NonNull Parcel in) { List<CredentialOption> credentialOptions = new ArrayList<CredentialOption>(); in.readTypedList(credentialOptions, CredentialOption.CREATOR); mCredentialOptions = credentialOptions; AnnotationValidations.validate(NonNull.class, null, mCredentialOptions); Bundle data = in.readBundle(); mData = data; AnnotationValidations.validate(NonNull.class, null, mData); mOrigin = in.readString8(); } @NonNull public static final Creator<GetCandidateCredentialsRequest> CREATOR = new Creator<>() { @Override public GetCandidateCredentialsRequest[] newArray(int size) { return new GetCandidateCredentialsRequest[size]; } @Override public GetCandidateCredentialsRequest createFromParcel(@NonNull Parcel in) { return new GetCandidateCredentialsRequest(in); } }; }
core/java/android/credentials/GetCandidateCredentialsResponse.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * 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.credentials; parcelable GetCandidateCredentialsResponse; No newline at end of file