• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.hardware.biometrics;
18 
19 import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED;
20 import static android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT;
21 
22 import android.annotation.CallbackExecutor;
23 import android.annotation.FlaggedApi;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.annotation.RequiresPermission;
27 import android.content.DialogInterface;
28 import android.hardware.biometrics.BiometricPrompt.ButtonInfo;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 
32 import com.android.internal.annotations.VisibleForTesting;
33 
34 import java.util.concurrent.Executor;
35 
36 /**
37  * Contains the information of the template of content view with a more options button for
38  * Biometric Prompt.
39  * <p>
40  * This button should be used to provide more options for sign in or other purposes, such as when a
41  * user needs to select between multiple app-specific accounts or profiles that are available for
42  * sign in.
43  * <p>
44  * Apps should avoid using this when possible because it will create additional steps that the user
45  * must navigate through - clicking the more options button will dismiss the prompt, provide the app
46  * an opportunity to ask the user for the correct option, and finally allow the app to decide how to
47  * proceed once selected.
48  *
49  * <p>
50  * Here's how you'd set a <code>PromptContentViewWithMoreOptionsButton</code> on a Biometric
51  * Prompt:
52  * <pre class="prettyprint">
53  * BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(...)
54  *     .setTitle(...)
55  *     .setSubTitle(...)
56  *     .setContentView(new PromptContentViewWithMoreOptionsButton.Builder()
57  *         .setDescription("test description")
58  *         .setMoreOptionsButtonListener(executor, listener)
59  *         .build())
60  *     .build();
61  * </pre>
62  */
63 @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
64 public final class PromptContentViewWithMoreOptionsButton implements PromptContentViewParcelable {
65     @VisibleForTesting
66     static final int MAX_DESCRIPTION_CHARACTER_NUMBER = 225;
67 
68     private final String mDescription;
69     private DialogInterface.OnClickListener mListener;
70     private ButtonInfo mButtonInfo;
71 
PromptContentViewWithMoreOptionsButton( @onNull String description, @NonNull @CallbackExecutor Executor executor, @NonNull DialogInterface.OnClickListener listener)72     private PromptContentViewWithMoreOptionsButton(
73             @NonNull String description, @NonNull @CallbackExecutor Executor executor,
74             @NonNull DialogInterface.OnClickListener listener) {
75         mDescription = description;
76         mListener = listener;
77         mButtonInfo = new ButtonInfo(executor, listener);
78     }
79 
PromptContentViewWithMoreOptionsButton(Parcel in)80     private PromptContentViewWithMoreOptionsButton(Parcel in) {
81         mDescription = in.readString();
82     }
83 
84     /**
85      * Gets the description for the content view, as set by
86      * {@link PromptContentViewWithMoreOptionsButton.Builder#setDescription(String)}.
87      *
88      * @return The description for the content view, or null if the content view has no description.
89      */
90     @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
91     @Nullable
getDescription()92     public String getDescription() {
93         return mDescription;
94     }
95 
96     /**
97      * Gets the click listener for the more options button on the content view, as set by
98      * {@link PromptContentViewWithMoreOptionsButton.Builder#setMoreOptionsButtonListener(Executor,
99      * DialogInterface.OnClickListener)}.
100      *
101      * @return The click listener for the more options button on the content view.
102      */
103     @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
104     @NonNull
getMoreOptionsButtonListener()105     public DialogInterface.OnClickListener getMoreOptionsButtonListener() {
106         return mListener;
107     }
108 
getButtonInfo()109     ButtonInfo getButtonInfo() {
110         return mButtonInfo;
111     }
112 
113     @Override
describeContents()114     public int describeContents() {
115         return 0;
116     }
117 
118     @Override
writeToParcel(@onNull Parcel dest, int flags)119     public void writeToParcel(@NonNull Parcel dest, int flags) {
120         dest.writeString(mDescription);
121     }
122 
123     /**
124      * @see Parcelable.Creator
125      */
126     @NonNull
127     public static final Creator<PromptContentViewWithMoreOptionsButton> CREATOR = new Creator<>() {
128         @Override
129         public PromptContentViewWithMoreOptionsButton createFromParcel(Parcel in) {
130             return new PromptContentViewWithMoreOptionsButton(in);
131         }
132 
133         @Override
134         public PromptContentViewWithMoreOptionsButton[] newArray(int size) {
135             return new PromptContentViewWithMoreOptionsButton[size];
136         }
137     };
138 
139     /**
140      * A builder that collects arguments to be shown on the content view with more options button.
141      */
142     public static final class Builder {
143         private String mDescription;
144         private Executor mExecutor;
145         private DialogInterface.OnClickListener mListener;
146 
147         /**
148          * Optional: Sets a description that will be shown on the content view.
149          *
150          * @param description The description to display.
151          * @return This builder.
152          * @throws IllegalArgumentException If description exceeds certain character limit.
153          */
154         @NonNull
155         @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
setDescription(@onNull String description)156         public Builder setDescription(@NonNull String description) {
157             if (description.length() > MAX_DESCRIPTION_CHARACTER_NUMBER) {
158                 throw new IllegalArgumentException("The character number of description exceeds "
159                         + MAX_DESCRIPTION_CHARACTER_NUMBER);
160             }
161             mDescription = description;
162             return this;
163         }
164 
165         /**
166          * Required: Sets the executor and click listener for the more options button on the
167          * prompt content.
168          *
169          * @param executor Executor that will be used to run the on click callback.
170          * @param listener Listener containing a callback to be run when the button is pressed.
171          * @return This builder.
172          */
173         @NonNull
174         @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
setMoreOptionsButtonListener(@onNull @allbackExecutor Executor executor, @NonNull DialogInterface.OnClickListener listener)175         public Builder setMoreOptionsButtonListener(@NonNull @CallbackExecutor Executor executor,
176                 @NonNull DialogInterface.OnClickListener listener) {
177             mExecutor = executor;
178             mListener = listener;
179             return this;
180         }
181 
182 
183         /**
184          * Creates a {@link PromptContentViewWithMoreOptionsButton}.
185          *
186          * @return An instance of {@link PromptContentViewWithMoreOptionsButton}.
187          * @throws IllegalArgumentException If the executor of more options button is null, or the
188          *                                  listener of more options button is null.
189          */
190         @NonNull
191         @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
build()192         public PromptContentViewWithMoreOptionsButton build() {
193             if (mExecutor == null) {
194                 throw new IllegalArgumentException(
195                         "The executor for the listener of more options button on prompt content "
196                                 + "must be set and non-null if "
197                                 + "PromptContentViewWithMoreOptionsButton is used.");
198             }
199             if (mListener == null) {
200                 throw new IllegalArgumentException(
201                         "The listener of more options button on prompt content must be set and "
202                                 + "non-null if PromptContentViewWithMoreOptionsButton is used.");
203             }
204             return new PromptContentViewWithMoreOptionsButton(mDescription, mExecutor, mListener);
205         }
206     }
207 }
208