Loading core/java/android/credentials/CredentialDescription.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright 2023 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; /** * @hide */ parcelable CredentialDescription; No newline at end of file core/java/android/credentials/CredentialDescription.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.service.credentials.CredentialEntry; import com.android.internal.util.AnnotationValidations; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * Represents the type and contained data fields of a {@link Credential}. * @hide */ public final class CredentialDescription implements Parcelable { /** * The credential type. */ @NonNull private final String mType; /** * The flattened JSON string that will be matched with requests. */ @NonNull private final String mFlattenedRequestString; /** * The entry to be used in the UI. */ @NonNull private final List<CredentialEntry> mCredentialEntries; /** * Constructs a {@link CredentialDescription}. * * @param type the type of the credential returned. * @param flattenedRequestString flattened JSON string that will be matched with requests. * @param credentialEntries a list of {@link CredentialEntry}s that have been returned * to the developer upon credential creation. * * @throws IllegalArgumentException If type is empty. */ public CredentialDescription(@NonNull String type, @NonNull String flattenedRequestString, @NonNull List<CredentialEntry> credentialEntries) { mType = Preconditions.checkStringNotEmpty(type, "type must not be empty"); mFlattenedRequestString = Preconditions.checkStringNotEmpty(flattenedRequestString); mCredentialEntries = Objects.requireNonNull(credentialEntries); } private CredentialDescription(@NonNull Parcel in) { String type = in.readString8(); String flattenedRequestString = in.readString(); List<CredentialEntry> entries = new ArrayList<>(); in.readTypedList(entries, CredentialEntry.CREATOR); mType = type; AnnotationValidations.validate(android.annotation.NonNull.class, null, mType); mFlattenedRequestString = flattenedRequestString; AnnotationValidations.validate(android.annotation.NonNull.class, null, mFlattenedRequestString); mCredentialEntries = entries; AnnotationValidations.validate(android.annotation.NonNull.class, null, mCredentialEntries); } public static final @NonNull Parcelable.Creator<CredentialDescription> CREATOR = new Parcelable.Creator<CredentialDescription>() { @Override public CredentialDescription createFromParcel(Parcel in) { return new CredentialDescription(in); } @Override public CredentialDescription[] newArray(int size) { return new CredentialDescription[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mType); dest.writeString(mFlattenedRequestString); dest.writeTypedList(mCredentialEntries, flags); } @NonNull public String getType() { return mType; } @NonNull public String getFlattenedRequestString() { return mFlattenedRequestString; } @NonNull public List<CredentialEntry> getCredentialEntries() { return mCredentialEntries; } @Override public int hashCode() { return Objects.hash(mType, mFlattenedRequestString); } @Override public boolean equals(Object obj) { return Objects.equals(mType, ((CredentialDescription) obj).getType()) && Objects.equals(mFlattenedRequestString, ((CredentialDescription) obj).getType()); } } core/java/android/credentials/CredentialManager.java +164 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,14 @@ public final class CredentialManager { public static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER = "enable_credential_manager"; /** * Flag to enable and disable Credential Description api. * * @hide */ private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API = "enable_credential_description_api"; /** * @hide instantiated by ContextImpl. */ Loading Loading @@ -294,6 +302,112 @@ public final class CredentialManager { true); } /** * Returns whether the credential description api is enabled. * * @hide */ public static boolean isCredentialDescriptionApiEnabled() { return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API, false); } /** * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} * a CredentialProvider has. This registry will then be used by * {@link #executeGetCredential(GetCredentialRequest, Activity, * CancellationSignal, Executor, OutcomeReceiver)} to determine where to * fetch the requested {@link Credential} from. * * * @param request the request data * @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 * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * * @hide */ public void registerCredentialDescription( @NonNull RegisterCredentialDescriptionRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<Void, RegisterCredentialDescriptionException> callback) { if (!isCredentialDescriptionApiEnabled()) { throw new UnsupportedOperationException("This API is not currently supported."); } requireNonNull(executor, "executor must not be null"); requireNonNull(callback, "callback must not be null"); if (cancellationSignal != null && cancellationSignal.isCanceled()) { Log.w(TAG, "executeCreateCredential already canceled"); return; } ICancellationSignal cancelRemote = null; try { cancelRemote = mService.registerCredentialDescription(request, new RegisterCredentialDescriptionTransport(executor, callback), mContext.getOpPackageName()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } if (cancellationSignal != null && cancelRemote != null) { cancellationSignal.setRemote(cancelRemote); } } /** * Unregisters a {@link CredentialDescription} for an actively provisioned {@link Credential} * that has been registered previously. * * * @param request the request data * @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 * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * * @hide */ public void unRegisterCredentialDescription( @NonNull UnregisterCredentialDescriptionRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<Void, UnregisterCredentialDescriptionException> callback) { if (!isCredentialDescriptionApiEnabled()) { throw new UnsupportedOperationException("This API is not currently supported."); } requireNonNull(executor, "executor must not be null"); requireNonNull(callback, "callback must not be null"); if (cancellationSignal != null && cancellationSignal.isCanceled()) { Log.w(TAG, "executeCreateCredential already canceled"); return; } ICancellationSignal cancelRemote = null; try { cancelRemote = mService.unRegisterCredentialDescription(request, new UnregisterCredentialDescriptionTransport(executor, callback), mContext.getOpPackageName()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } if (cancellationSignal != null && cancelRemote != null) { cancellationSignal.setRemote(cancelRemote); } } private static class GetCredentialTransport extends IGetCredentialCallback.Stub { // TODO: listen for cancellation to release callback. Loading Loading @@ -455,4 +569,54 @@ public final class CredentialManager { () -> mCallback.onError(new SetEnabledProvidersException(errorType, message))); } } private static class RegisterCredentialDescriptionTransport extends IRegisterCredentialDescriptionCallback.Stub { private final Executor mExecutor; private final OutcomeReceiver<Void, RegisterCredentialDescriptionException> mCallback; private RegisterCredentialDescriptionTransport(Executor executor, OutcomeReceiver<Void, RegisterCredentialDescriptionException> callback) { mExecutor = executor; mCallback = callback; } @Override public void onResponse() { mCallback.onResult(null); } @Override public void onError(String errorCode, String message) { mExecutor.execute( () -> mCallback.onError(new RegisterCredentialDescriptionException(errorCode, message))); } } private static class UnregisterCredentialDescriptionTransport extends IUnregisterCredentialDescriptionCallback.Stub { private final Executor mExecutor; private final OutcomeReceiver<Void, UnregisterCredentialDescriptionException> mCallback; private UnregisterCredentialDescriptionTransport(Executor executor, OutcomeReceiver<Void, UnregisterCredentialDescriptionException> callback) { mExecutor = executor; mCallback = callback; } @Override public void onResponse() { mCallback.onResult(null); } @Override public void onError(String errorCode, String message) { mExecutor.execute( () -> mCallback.onError(new UnregisterCredentialDescriptionException(errorCode, message))); } } } core/java/android/credentials/ICredentialManager.aidl +9 −0 Original line number Diff line number Diff line Loading @@ -21,10 +21,14 @@ import java.util.List; import android.credentials.ClearCredentialStateRequest; import android.credentials.CreateCredentialRequest; import android.credentials.GetCredentialRequest; import android.credentials.RegisterCredentialDescriptionRequest; import android.credentials.UnregisterCredentialDescriptionRequest; import android.credentials.IClearCredentialStateCallback; import android.credentials.ICreateCredentialCallback; import android.credentials.IGetCredentialCallback; import android.credentials.IListEnabledProvidersCallback; import android.credentials.IRegisterCredentialDescriptionCallback; import android.credentials.IUnregisterCredentialDescriptionCallback; import android.credentials.ISetEnabledProvidersCallback; import android.os.ICancellationSignal; Loading @@ -44,4 +48,9 @@ interface ICredentialManager { @nullable ICancellationSignal listEnabledProviders(in IListEnabledProvidersCallback callback); void setEnabledProviders(in List<String> providers, in int userId, in ISetEnabledProvidersCallback callback); @nullable ICancellationSignal registerCredentialDescription(in RegisterCredentialDescriptionRequest request, in IRegisterCredentialDescriptionCallback callback, String callingPackage); @nullable ICancellationSignal unRegisterCredentialDescription(in UnregisterCredentialDescriptionRequest request, in IUnregisterCredentialDescriptionCallback callback, String callingPackage); } core/java/android/credentials/IRegisterCredentialDescriptionCallback.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright 2023 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; /** * Listener for an registerCredentialDescription request. * * @hide */ interface IRegisterCredentialDescriptionCallback { oneway void onResponse(); oneway void onError(String errorCode, String message); } No newline at end of file Loading
core/java/android/credentials/CredentialDescription.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright 2023 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; /** * @hide */ parcelable CredentialDescription; No newline at end of file
core/java/android/credentials/CredentialDescription.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.service.credentials.CredentialEntry; import com.android.internal.util.AnnotationValidations; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * Represents the type and contained data fields of a {@link Credential}. * @hide */ public final class CredentialDescription implements Parcelable { /** * The credential type. */ @NonNull private final String mType; /** * The flattened JSON string that will be matched with requests. */ @NonNull private final String mFlattenedRequestString; /** * The entry to be used in the UI. */ @NonNull private final List<CredentialEntry> mCredentialEntries; /** * Constructs a {@link CredentialDescription}. * * @param type the type of the credential returned. * @param flattenedRequestString flattened JSON string that will be matched with requests. * @param credentialEntries a list of {@link CredentialEntry}s that have been returned * to the developer upon credential creation. * * @throws IllegalArgumentException If type is empty. */ public CredentialDescription(@NonNull String type, @NonNull String flattenedRequestString, @NonNull List<CredentialEntry> credentialEntries) { mType = Preconditions.checkStringNotEmpty(type, "type must not be empty"); mFlattenedRequestString = Preconditions.checkStringNotEmpty(flattenedRequestString); mCredentialEntries = Objects.requireNonNull(credentialEntries); } private CredentialDescription(@NonNull Parcel in) { String type = in.readString8(); String flattenedRequestString = in.readString(); List<CredentialEntry> entries = new ArrayList<>(); in.readTypedList(entries, CredentialEntry.CREATOR); mType = type; AnnotationValidations.validate(android.annotation.NonNull.class, null, mType); mFlattenedRequestString = flattenedRequestString; AnnotationValidations.validate(android.annotation.NonNull.class, null, mFlattenedRequestString); mCredentialEntries = entries; AnnotationValidations.validate(android.annotation.NonNull.class, null, mCredentialEntries); } public static final @NonNull Parcelable.Creator<CredentialDescription> CREATOR = new Parcelable.Creator<CredentialDescription>() { @Override public CredentialDescription createFromParcel(Parcel in) { return new CredentialDescription(in); } @Override public CredentialDescription[] newArray(int size) { return new CredentialDescription[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mType); dest.writeString(mFlattenedRequestString); dest.writeTypedList(mCredentialEntries, flags); } @NonNull public String getType() { return mType; } @NonNull public String getFlattenedRequestString() { return mFlattenedRequestString; } @NonNull public List<CredentialEntry> getCredentialEntries() { return mCredentialEntries; } @Override public int hashCode() { return Objects.hash(mType, mFlattenedRequestString); } @Override public boolean equals(Object obj) { return Objects.equals(mType, ((CredentialDescription) obj).getType()) && Objects.equals(mFlattenedRequestString, ((CredentialDescription) obj).getType()); } }
core/java/android/credentials/CredentialManager.java +164 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,14 @@ public final class CredentialManager { public static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER = "enable_credential_manager"; /** * Flag to enable and disable Credential Description api. * * @hide */ private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API = "enable_credential_description_api"; /** * @hide instantiated by ContextImpl. */ Loading Loading @@ -294,6 +302,112 @@ public final class CredentialManager { true); } /** * Returns whether the credential description api is enabled. * * @hide */ public static boolean isCredentialDescriptionApiEnabled() { return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API, false); } /** * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} * a CredentialProvider has. This registry will then be used by * {@link #executeGetCredential(GetCredentialRequest, Activity, * CancellationSignal, Executor, OutcomeReceiver)} to determine where to * fetch the requested {@link Credential} from. * * * @param request the request data * @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 * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * * @hide */ public void registerCredentialDescription( @NonNull RegisterCredentialDescriptionRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<Void, RegisterCredentialDescriptionException> callback) { if (!isCredentialDescriptionApiEnabled()) { throw new UnsupportedOperationException("This API is not currently supported."); } requireNonNull(executor, "executor must not be null"); requireNonNull(callback, "callback must not be null"); if (cancellationSignal != null && cancellationSignal.isCanceled()) { Log.w(TAG, "executeCreateCredential already canceled"); return; } ICancellationSignal cancelRemote = null; try { cancelRemote = mService.registerCredentialDescription(request, new RegisterCredentialDescriptionTransport(executor, callback), mContext.getOpPackageName()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } if (cancellationSignal != null && cancelRemote != null) { cancellationSignal.setRemote(cancelRemote); } } /** * Unregisters a {@link CredentialDescription} for an actively provisioned {@link Credential} * that has been registered previously. * * * @param request the request data * @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 * * @throws {@link UnsupportedOperationException} if the feature has not been enabled. * * @hide */ public void unRegisterCredentialDescription( @NonNull UnregisterCredentialDescriptionRequest request, @Nullable CancellationSignal cancellationSignal, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<Void, UnregisterCredentialDescriptionException> callback) { if (!isCredentialDescriptionApiEnabled()) { throw new UnsupportedOperationException("This API is not currently supported."); } requireNonNull(executor, "executor must not be null"); requireNonNull(callback, "callback must not be null"); if (cancellationSignal != null && cancellationSignal.isCanceled()) { Log.w(TAG, "executeCreateCredential already canceled"); return; } ICancellationSignal cancelRemote = null; try { cancelRemote = mService.unRegisterCredentialDescription(request, new UnregisterCredentialDescriptionTransport(executor, callback), mContext.getOpPackageName()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } if (cancellationSignal != null && cancelRemote != null) { cancellationSignal.setRemote(cancelRemote); } } private static class GetCredentialTransport extends IGetCredentialCallback.Stub { // TODO: listen for cancellation to release callback. Loading Loading @@ -455,4 +569,54 @@ public final class CredentialManager { () -> mCallback.onError(new SetEnabledProvidersException(errorType, message))); } } private static class RegisterCredentialDescriptionTransport extends IRegisterCredentialDescriptionCallback.Stub { private final Executor mExecutor; private final OutcomeReceiver<Void, RegisterCredentialDescriptionException> mCallback; private RegisterCredentialDescriptionTransport(Executor executor, OutcomeReceiver<Void, RegisterCredentialDescriptionException> callback) { mExecutor = executor; mCallback = callback; } @Override public void onResponse() { mCallback.onResult(null); } @Override public void onError(String errorCode, String message) { mExecutor.execute( () -> mCallback.onError(new RegisterCredentialDescriptionException(errorCode, message))); } } private static class UnregisterCredentialDescriptionTransport extends IUnregisterCredentialDescriptionCallback.Stub { private final Executor mExecutor; private final OutcomeReceiver<Void, UnregisterCredentialDescriptionException> mCallback; private UnregisterCredentialDescriptionTransport(Executor executor, OutcomeReceiver<Void, UnregisterCredentialDescriptionException> callback) { mExecutor = executor; mCallback = callback; } @Override public void onResponse() { mCallback.onResult(null); } @Override public void onError(String errorCode, String message) { mExecutor.execute( () -> mCallback.onError(new UnregisterCredentialDescriptionException(errorCode, message))); } } }
core/java/android/credentials/ICredentialManager.aidl +9 −0 Original line number Diff line number Diff line Loading @@ -21,10 +21,14 @@ import java.util.List; import android.credentials.ClearCredentialStateRequest; import android.credentials.CreateCredentialRequest; import android.credentials.GetCredentialRequest; import android.credentials.RegisterCredentialDescriptionRequest; import android.credentials.UnregisterCredentialDescriptionRequest; import android.credentials.IClearCredentialStateCallback; import android.credentials.ICreateCredentialCallback; import android.credentials.IGetCredentialCallback; import android.credentials.IListEnabledProvidersCallback; import android.credentials.IRegisterCredentialDescriptionCallback; import android.credentials.IUnregisterCredentialDescriptionCallback; import android.credentials.ISetEnabledProvidersCallback; import android.os.ICancellationSignal; Loading @@ -44,4 +48,9 @@ interface ICredentialManager { @nullable ICancellationSignal listEnabledProviders(in IListEnabledProvidersCallback callback); void setEnabledProviders(in List<String> providers, in int userId, in ISetEnabledProvidersCallback callback); @nullable ICancellationSignal registerCredentialDescription(in RegisterCredentialDescriptionRequest request, in IRegisterCredentialDescriptionCallback callback, String callingPackage); @nullable ICancellationSignal unRegisterCredentialDescription(in UnregisterCredentialDescriptionRequest request, in IUnregisterCredentialDescriptionCallback callback, String callingPackage); }
core/java/android/credentials/IRegisterCredentialDescriptionCallback.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright 2023 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; /** * Listener for an registerCredentialDescription request. * * @hide */ interface IRegisterCredentialDescriptionCallback { oneway void onResponse(); oneway void onError(String errorCode, String message); } No newline at end of file