1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.credentials.selection; 18 19 import static android.credentials.flags.Flags.FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED; 20 21 import android.annotation.FlaggedApi; 22 import android.annotation.IntDef; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.SuppressLint; 26 import android.annotation.TestApi; 27 import android.os.Bundle; 28 import android.os.IBinder; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 35 /** 36 * Base dialog result data. 37 * 38 * Returned for simple use cases like cancellation. Can also be subclassed when more information 39 * is needed, e.g. {@link UserSelectionDialogResult}. 40 * 41 * @hide 42 */ 43 @TestApi 44 @FlaggedApi(FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED) 45 @SuppressLint("ParcelNotFinal") // Test API only. This is never intended to be officially exposed. 46 // Instead proper final wrapper classes are defined (e.g. {@code FailureDialogResult}). 47 public class BaseDialogResult implements Parcelable { 48 /** Parses and returns a BaseDialogResult from the given resultData. */ 49 @Nullable fromResultData(@onNull Bundle resultData)50 public static BaseDialogResult fromResultData(@NonNull Bundle resultData) { 51 return resultData.getParcelable(EXTRA_BASE_RESULT, BaseDialogResult.class); 52 } 53 54 /** 55 * Used for the UX to construct the {@code resultData Bundle} to send via the {@code 56 * ResultReceiver}. 57 */ addToBundle(@onNull BaseDialogResult result, @NonNull Bundle bundle)58 public static void addToBundle(@NonNull BaseDialogResult result, @NonNull Bundle bundle) { 59 bundle.putParcelable(EXTRA_BASE_RESULT, result); 60 } 61 62 /** 63 * The intent extra key for the {@code BaseDialogResult} object when the credential 64 * selector activity finishes. 65 */ 66 private static final String EXTRA_BASE_RESULT = 67 "android.credentials.selection.extra.BASE_RESULT"; 68 69 /** @hide **/ 70 @IntDef(prefix = {"RESULT_CODE_"}, value = { 71 RESULT_CODE_DIALOG_USER_CANCELED, 72 RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS, 73 RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION, 74 RESULT_CODE_DATA_PARSING_FAILURE, 75 }) 76 @Retention(RetentionPolicy.SOURCE) 77 public @interface ResultCode { 78 } 79 80 /** User intentionally canceled the dialog. */ 81 public static final int RESULT_CODE_DIALOG_USER_CANCELED = 0; 82 /** 83 * The UI was stopped since the user has chosen to navigate to the Settings UI to reconfigure 84 * their providers. 85 */ 86 public static final int RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS = 1; 87 /** 88 * User made a selection and the dialog finished. The user selection result is in the 89 * {@code resultData}. 90 */ 91 public static final int RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION = 2; 92 /** 93 * The UI was canceled because it failed to parse the incoming data. 94 */ 95 public static final int RESULT_CODE_DATA_PARSING_FAILURE = 3; 96 97 @Nullable 98 @Deprecated 99 private final IBinder mRequestToken; 100 BaseDialogResult(@ullable IBinder requestToken)101 public BaseDialogResult(@Nullable IBinder requestToken) { 102 mRequestToken = requestToken; 103 } 104 105 /** 106 * Returns the unique identifier for the request that launched the operation. 107 * 108 * @deprecated do not use 109 */ 110 @Nullable 111 @Deprecated getRequestToken()112 public IBinder getRequestToken() { 113 return mRequestToken; 114 } 115 116 @SuppressLint("ParcelConstructor") // Test API only. This is never intended to be officially 117 // exposed. Instead proper final wrapper classes are defined (e.g. {@code FailureDialogResult}). BaseDialogResult(@onNull Parcel in)118 protected BaseDialogResult(@NonNull Parcel in) { 119 IBinder requestToken = in.readStrongBinder(); 120 mRequestToken = requestToken; 121 } 122 123 @Override writeToParcel(@onNull Parcel dest, int flags)124 public void writeToParcel(@NonNull Parcel dest, int flags) { 125 dest.writeStrongBinder(mRequestToken); 126 } 127 128 @Override describeContents()129 public int describeContents() { 130 return 0; 131 } 132 133 public static final @NonNull Creator<BaseDialogResult> CREATOR = 134 new Creator<BaseDialogResult>() { 135 @Override 136 public BaseDialogResult createFromParcel(@NonNull Parcel in) { 137 return new BaseDialogResult(in); 138 } 139 140 @Override 141 public BaseDialogResult[] newArray(int size) { 142 return new BaseDialogResult[size]; 143 } 144 }; 145 } 146