diff options
| -rw-r--r-- | core/java/android/credentials/ui/BaseDialogResult.java | 123 | ||||
| -rw-r--r-- | core/java/android/credentials/ui/ProviderDialogResult.java | 100 | ||||
| -rw-r--r-- | core/java/android/credentials/ui/UserSelectionDialogResult.java (renamed from core/java/android/credentials/ui/UserSelectionResult.java) | 66 | ||||
| -rw-r--r-- | packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt | 17 |
4 files changed, 266 insertions, 40 deletions
diff --git a/core/java/android/credentials/ui/BaseDialogResult.java b/core/java/android/credentials/ui/BaseDialogResult.java new file mode 100644 index 000000000000..cf5f0363208a --- /dev/null +++ b/core/java/android/credentials/ui/BaseDialogResult.java @@ -0,0 +1,123 @@ +/* + * 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.ui; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.AnnotationValidations; + +/** + * Base dialog result data. + * + * Returned for simple use cases like cancellation. Can also be subclassed when more information + * is needed, e.g. {@link UserSelectionDialogResult}. + * + * @hide + */ +public class BaseDialogResult implements Parcelable { + /** Parses and returns a BaseDialogResult from the given resultData. */ + @Nullable + public static BaseDialogResult fromResultData(@NonNull Bundle resultData) { + return resultData.getParcelable(EXTRA_BASE_RESULT, BaseDialogResult.class); + } + + /** + * Used for the UX to construct the {@code resultData Bundle} to send via the {@code + * ResultReceiver}. + */ + public static void addToBundle(@NonNull BaseDialogResult result, @NonNull Bundle bundle) { + bundle.putParcelable(EXTRA_BASE_RESULT, result); + } + + /** + * The intent extra key for the {@code BaseDialogResult} object when the credential + * selector activity finishes. + */ + private static final String EXTRA_BASE_RESULT = + "android.credentials.ui.extra.BASE_RESULT"; + + /** User intentionally canceled the dialog. */ + public static final int RESULT_CODE_DIALOG_CANCELED = 0; + /** + * User made a selection and the dialog finished. The user selection result is in the + * {@code resultData}. + */ + public static final int RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION = 1; + /** + * The user has acknowledged the consent page rendered for when they first used Credential + * Manager on this device. + */ + public static final int RESULT_CODE_CREDENTIAL_MANAGER_CONSENT_ACKNOWLEDGED = 2; + /** + * The user has acknowledged the consent page rendered for enabling a new provider. + * This should only happen during the first time use. The provider info is in the + * {@code resultData}. + */ + public static final int RESULT_CODE_PROVIDER_ENABLED = 3; + /** + * The user has consented to switching to a new default provider. The provider info is in the + * {@code resultData}. + */ + public static final int RESULT_CODE_DEFAULT_PROVIDER_CHANGED = 4; + + @NonNull + private final IBinder mRequestToken; + + public BaseDialogResult(@NonNull IBinder requestToken) { + mRequestToken = requestToken; + } + + /** Returns the unique identifier for the request that launched the operation. */ + @NonNull + public IBinder getRequestToken() { + return mRequestToken; + } + + protected BaseDialogResult(@NonNull Parcel in) { + IBinder requestToken = in.readStrongBinder(); + mRequestToken = requestToken; + AnnotationValidations.validate(NonNull.class, null, mRequestToken); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeStrongBinder(mRequestToken); + } + + @Override + public int describeContents() { + return 0; + } + + public static final @NonNull Creator<BaseDialogResult> CREATOR = + new Creator<BaseDialogResult>() { + @Override + public BaseDialogResult createFromParcel(@NonNull Parcel in) { + return new BaseDialogResult(in); + } + + @Override + public BaseDialogResult[] newArray(int size) { + return new BaseDialogResult[size]; + } + }; +} diff --git a/core/java/android/credentials/ui/ProviderDialogResult.java b/core/java/android/credentials/ui/ProviderDialogResult.java new file mode 100644 index 000000000000..9d1be2063423 --- /dev/null +++ b/core/java/android/credentials/ui/ProviderDialogResult.java @@ -0,0 +1,100 @@ +/* + * 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.ui; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.AnnotationValidations; + +/** + * Result data matching {@link BaseDialogResult#RESULT_CODE_PROVIDER_ENABLED}, or {@link + * BaseDialogResult#RESULT_CODE_DEFAULT_PROVIDER_CHANGED}. + * + * @hide + */ +public class ProviderDialogResult extends BaseDialogResult implements Parcelable { + /** Parses and returns a ProviderDialogResult from the given resultData. */ + @Nullable + public static ProviderDialogResult fromResultData(@NonNull Bundle resultData) { + return resultData.getParcelable(EXTRA_PROVIDER_RESULT, ProviderDialogResult.class); + } + + /** + * Used for the UX to construct the {@code resultData Bundle} to send via the {@code + * ResultReceiver}. + */ + public static void addToBundle( + @NonNull ProviderDialogResult result, @NonNull Bundle bundle) { + bundle.putParcelable(EXTRA_PROVIDER_RESULT, result); + } + + /** + * The intent extra key for the {@code ProviderDialogResult} object when the credential + * selector activity finishes. + */ + private static final String EXTRA_PROVIDER_RESULT = + "android.credentials.ui.extra.PROVIDER_RESULT"; + + @NonNull + private final String mProviderId; + + public ProviderDialogResult(@NonNull IBinder requestToken, @NonNull String providerId) { + super(requestToken); + mProviderId = providerId; + } + + @NonNull + public String getProviderId() { + return mProviderId; + } + + protected ProviderDialogResult(@NonNull Parcel in) { + super(in); + String providerId = in.readString8(); + mProviderId = providerId; + AnnotationValidations.validate(NonNull.class, null, mProviderId); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeString8(mProviderId); + } + + @Override + public int describeContents() { + return 0; + } + + public static final @NonNull Creator<ProviderDialogResult> CREATOR = + new Creator<ProviderDialogResult>() { + @Override + public ProviderDialogResult createFromParcel(@NonNull Parcel in) { + return new ProviderDialogResult(in); + } + + @Override + public ProviderDialogResult[] newArray(int size) { + return new ProviderDialogResult[size]; + } + }; +} diff --git a/core/java/android/credentials/ui/UserSelectionResult.java b/core/java/android/credentials/ui/UserSelectionDialogResult.java index 2ac559381c6e..eb3a4a8cfcbd 100644 --- a/core/java/android/credentials/ui/UserSelectionResult.java +++ b/core/java/android/credentials/ui/UserSelectionDialogResult.java @@ -17,6 +17,8 @@ package android.credentials.ui; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -24,24 +26,33 @@ import android.os.Parcelable; import com.android.internal.util.AnnotationValidations; /** - * User selection result information of a UX flow. - * - * Returned as part of the activity result intent data when the user dialog completes - * successfully. + * Result data matching {@link BaseDialogResult#RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION}. * * @hide */ -public class UserSelectionResult implements Parcelable { +public class UserSelectionDialogResult extends BaseDialogResult implements Parcelable { + /** Parses and returns a UserSelectionDialogResult from the given resultData. */ + @Nullable + public static UserSelectionDialogResult fromResultData(@NonNull Bundle resultData) { + return resultData.getParcelable( + EXTRA_USER_SELECTION_RESULT, UserSelectionDialogResult.class); + } /** - * The intent extra key for the {@code UserSelectionResult} object when the credential selector - * activity finishes. - */ - public static final String EXTRA_USER_SELECTION_RESULT = - "android.credentials.ui.extra.USER_SELECTION_RESULT"; + * Used for the UX to construct the {@code resultData Bundle} to send via the {@code + * ResultReceiver}. + */ + public static void addToBundle( + @NonNull UserSelectionDialogResult result, @NonNull Bundle bundle) { + bundle.putParcelable(EXTRA_USER_SELECTION_RESULT, result); + } - @NonNull - private final IBinder mRequestToken; + /** + * The intent extra key for the {@code UserSelectionDialogResult} object when the credential + * selector activity finishes. + */ + private static final String EXTRA_USER_SELECTION_RESULT = + "android.credentials.ui.extra.USER_SELECTION_RESULT"; @NonNull private final String mProviderId; @@ -49,19 +60,14 @@ public class UserSelectionResult implements Parcelable { // TODO: consider switching to string or other types, depending on the service implementation. private final int mEntryId; - public UserSelectionResult(@NonNull IBinder requestToken, @NonNull String providerId, + public UserSelectionDialogResult( + @NonNull IBinder requestToken, @NonNull String providerId, int entryId) { - mRequestToken = requestToken; + super(requestToken); mProviderId = providerId; mEntryId = entryId; } - /** Returns token of the app request that initiated this user dialog. */ - @NonNull - public IBinder getRequestToken() { - return mRequestToken; - } - /** Returns provider package name whose entry was selected by the user. */ @NonNull public String getProviderId() { @@ -73,13 +79,11 @@ public class UserSelectionResult implements Parcelable { return mEntryId; } - protected UserSelectionResult(@NonNull Parcel in) { - IBinder requestToken = in.readStrongBinder(); + protected UserSelectionDialogResult(@NonNull Parcel in) { + super(in); String providerId = in.readString8(); int entryId = in.readInt(); - mRequestToken = requestToken; - AnnotationValidations.validate(NonNull.class, null, mRequestToken); mProviderId = providerId; AnnotationValidations.validate(NonNull.class, null, mProviderId); mEntryId = entryId; @@ -87,7 +91,7 @@ public class UserSelectionResult implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeStrongBinder(mRequestToken); + super.writeToParcel(dest, flags); dest.writeString8(mProviderId); dest.writeInt(mEntryId); } @@ -97,16 +101,16 @@ public class UserSelectionResult implements Parcelable { return 0; } - public static final @NonNull Creator<UserSelectionResult> CREATOR = - new Creator<UserSelectionResult>() { + public static final @NonNull Creator<UserSelectionDialogResult> CREATOR = + new Creator<UserSelectionDialogResult>() { @Override - public UserSelectionResult createFromParcel(@NonNull Parcel in) { - return new UserSelectionResult(in); + public UserSelectionDialogResult createFromParcel(@NonNull Parcel in) { + return new UserSelectionDialogResult(in); } @Override - public UserSelectionResult[] newArray(int size) { - return new UserSelectionResult[size]; + public UserSelectionDialogResult[] newArray(int size) { + return new UserSelectionDialogResult[size]; } }; } diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt index 93eaeb315bfb..4b419e08263c 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt @@ -16,7 +16,6 @@ package com.android.credentialmanager -import android.app.Activity import android.app.slice.Slice import android.app.slice.SliceSpec import android.content.Context @@ -25,7 +24,8 @@ import android.credentials.ui.Constants import android.credentials.ui.Entry import android.credentials.ui.ProviderData import android.credentials.ui.RequestInfo -import android.credentials.ui.UserSelectionResult +import android.credentials.ui.BaseDialogResult +import android.credentials.ui.UserSelectionDialogResult import android.graphics.drawable.Icon import android.os.Binder import android.os.Bundle @@ -68,21 +68,20 @@ class CredentialManagerRepo( } fun onCancel() { - resultReceiver?.send(Activity.RESULT_CANCELED, null) + val resultData = Bundle() + BaseDialogResult.addToBundle(BaseDialogResult(requestInfo.token), resultData) + resultReceiver?.send(BaseDialogResult.RESULT_CODE_DIALOG_CANCELED, resultData) } fun onOptionSelected(providerPackageName: String, entryId: Int) { - val userSelectionResult = UserSelectionResult( + val userSelectionDialogResult = UserSelectionDialogResult( requestInfo.token, providerPackageName, entryId ) val resultData = Bundle() - resultData.putParcelable( - UserSelectionResult.EXTRA_USER_SELECTION_RESULT, - userSelectionResult - ) - resultReceiver?.send(Activity.RESULT_OK, resultData) + UserSelectionDialogResult.addToBundle(userSelectionDialogResult, resultData) + resultReceiver?.send(BaseDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION, resultData) } fun getCredentialInitialUiState(): GetCredentialUiState { |