1 /*
2  * Copyright (C) 2020 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 android.annotation.DrawableRes;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.content.ComponentName;
23 import android.graphics.Bitmap;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 import java.util.ArrayList;
28 import java.util.List;
29 
30 /**
31  * Contains the information set/requested by the caller of the {@link BiometricPrompt}
32  * @hide
33  */
34 public class PromptInfo implements Parcelable {
35 
36     @DrawableRes private int mLogoRes;
37     @Nullable private Bitmap mLogoBitmap;
38     @Nullable private String mLogoDescription;
39     @NonNull private CharSequence mTitle;
40     private boolean mUseDefaultTitle;
41     @Nullable private CharSequence mSubtitle;
42     private boolean mUseDefaultSubtitle;
43     @Nullable private CharSequence mDescription;
44     @Nullable private PromptContentViewParcelable mContentView;
45     @Nullable private CharSequence mDeviceCredentialTitle;
46     @Nullable private CharSequence mDeviceCredentialSubtitle;
47     @Nullable private CharSequence mDeviceCredentialDescription;
48     @Nullable private CharSequence mNegativeButtonText;
49     private boolean mConfirmationRequested = true; // default to true
50     private boolean mDeviceCredentialAllowed;
51     private @BiometricManager.Authenticators.Types int mAuthenticators;
52     private boolean mDisallowBiometricsIfPolicyExists;
53     private boolean mReceiveSystemEvents;
54     @NonNull private List<Integer> mAllowedSensorIds = new ArrayList<>();
55     private boolean mAllowBackgroundAuthentication;
56     private boolean mIgnoreEnrollmentState;
57     private boolean mIsForLegacyFingerprintManager = false;
58     private boolean mShowEmergencyCallButton = false;
59     private boolean mUseParentProfileForDeviceCredential = false;
60     private ComponentName mComponentNameForConfirmDeviceCredentialActivity = null;
61 
PromptInfo()62     public PromptInfo() {
63 
64     }
65 
PromptInfo(Parcel in)66     PromptInfo(Parcel in) {
67         mLogoRes = in.readInt();
68         mLogoBitmap = in.readTypedObject(Bitmap.CREATOR);
69         mLogoDescription = in.readString();
70         mTitle = in.readCharSequence();
71         mUseDefaultTitle = in.readBoolean();
72         mSubtitle = in.readCharSequence();
73         mUseDefaultSubtitle = in.readBoolean();
74         mDescription = in.readCharSequence();
75         mContentView = in.readParcelable(PromptContentViewParcelable.class.getClassLoader(),
76                 PromptContentViewParcelable.class);
77         mDeviceCredentialTitle = in.readCharSequence();
78         mDeviceCredentialSubtitle = in.readCharSequence();
79         mDeviceCredentialDescription = in.readCharSequence();
80         mNegativeButtonText = in.readCharSequence();
81         mConfirmationRequested = in.readBoolean();
82         mDeviceCredentialAllowed = in.readBoolean();
83         mAuthenticators = in.readInt();
84         mDisallowBiometricsIfPolicyExists = in.readBoolean();
85         mReceiveSystemEvents = in.readBoolean();
86         mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class);
87         mAllowBackgroundAuthentication = in.readBoolean();
88         mIgnoreEnrollmentState = in.readBoolean();
89         mIsForLegacyFingerprintManager = in.readBoolean();
90         mShowEmergencyCallButton = in.readBoolean();
91         mUseParentProfileForDeviceCredential = in.readBoolean();
92         mComponentNameForConfirmDeviceCredentialActivity = in.readParcelable(
93                 ComponentName.class.getClassLoader(), ComponentName.class);
94     }
95 
96     public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() {
97         @Override
98         public PromptInfo createFromParcel(Parcel in) {
99             return new PromptInfo(in);
100         }
101 
102         @Override
103         public PromptInfo[] newArray(int size) {
104             return new PromptInfo[size];
105         }
106     };
107 
108     @Override
describeContents()109     public int describeContents() {
110         return 0;
111     }
112 
113     @Override
writeToParcel(Parcel dest, int flags)114     public void writeToParcel(Parcel dest, int flags) {
115         dest.writeInt(mLogoRes);
116         dest.writeTypedObject(mLogoBitmap, 0);
117         dest.writeString(mLogoDescription);
118         dest.writeCharSequence(mTitle);
119         dest.writeBoolean(mUseDefaultTitle);
120         dest.writeCharSequence(mSubtitle);
121         dest.writeBoolean(mUseDefaultSubtitle);
122         dest.writeCharSequence(mDescription);
123         dest.writeParcelable(mContentView, 0);
124         dest.writeCharSequence(mDeviceCredentialTitle);
125         dest.writeCharSequence(mDeviceCredentialSubtitle);
126         dest.writeCharSequence(mDeviceCredentialDescription);
127         dest.writeCharSequence(mNegativeButtonText);
128         dest.writeBoolean(mConfirmationRequested);
129         dest.writeBoolean(mDeviceCredentialAllowed);
130         dest.writeInt(mAuthenticators);
131         dest.writeBoolean(mDisallowBiometricsIfPolicyExists);
132         dest.writeBoolean(mReceiveSystemEvents);
133         dest.writeList(mAllowedSensorIds);
134         dest.writeBoolean(mAllowBackgroundAuthentication);
135         dest.writeBoolean(mIgnoreEnrollmentState);
136         dest.writeBoolean(mIsForLegacyFingerprintManager);
137         dest.writeBoolean(mShowEmergencyCallButton);
138         dest.writeBoolean(mUseParentProfileForDeviceCredential);
139         dest.writeParcelable(mComponentNameForConfirmDeviceCredentialActivity, 0);
140     }
141 
142     // LINT.IfChange
requiresTestOrInternalPermission()143     public boolean requiresTestOrInternalPermission() {
144         if (mIsForLegacyFingerprintManager
145                 && mAllowedSensorIds.size() == 1
146                 && !mAllowBackgroundAuthentication) {
147             return false;
148         } else if (!mAllowedSensorIds.isEmpty()) {
149             return true;
150         } else if (mAllowBackgroundAuthentication) {
151             return true;
152         } else if (mIsForLegacyFingerprintManager) {
153             return true;
154         } else if (mIgnoreEnrollmentState) {
155             return true;
156         } else if (mShowEmergencyCallButton) {
157             return true;
158         } else if (mComponentNameForConfirmDeviceCredentialActivity != null) {
159             return true;
160         }
161         return false;
162     }
163 
requiresInternalPermission()164     public boolean requiresInternalPermission() {
165         if (mDisallowBiometricsIfPolicyExists) {
166             return true;
167         } else if (mUseDefaultTitle) {
168             return true;
169         } else if (mUseDefaultSubtitle) {
170             return true;
171         } else if (mDeviceCredentialTitle != null) {
172             return true;
173         } else if (mDeviceCredentialSubtitle != null) {
174             return true;
175         } else if (mDeviceCredentialDescription != null) {
176             return true;
177         } else if (mReceiveSystemEvents) {
178             return true;
179         }
180         return false;
181     }
182 
183     /**
184      * Returns whether SET_BIOMETRIC_DIALOG_ADVANCED is contained.
185      *
186      * Currently, logo res, logo bitmap, logo description, PromptContentViewWithMoreOptions needs
187      * this permission.
188      */
requiresAdvancedPermission()189     public boolean requiresAdvancedPermission() {
190         if (mLogoRes != 0) {
191             return true;
192         } else if (mLogoBitmap != null) {
193             return true;
194         } else if (mLogoDescription != null) {
195             return true;
196         } else if (mContentView != null && isContentViewMoreOptionsButtonUsed()) {
197             return true;
198         }
199         return false;
200     }
201 
202     /**
203      * Returns if parent profile needs to be used for device credential.
204      */
shouldUseParentProfileForDeviceCredential()205     public boolean shouldUseParentProfileForDeviceCredential() {
206         return mUseParentProfileForDeviceCredential;
207     }
208 
209     /**
210      * Returns if the PromptContentViewWithMoreOptionsButton is set.
211      */
isContentViewMoreOptionsButtonUsed()212     public boolean isContentViewMoreOptionsButtonUsed() {
213         return Flags.customBiometricPrompt() && mContentView != null
214                 && mContentView instanceof PromptContentViewWithMoreOptionsButton;
215     }
216 
217     // LINT.ThenChange(frameworks/base/core/java/android/hardware/biometrics/BiometricPrompt.java)
218 
219     // Setters
220 
221     /**
222      * Sets logo res and bitmap
223      *
224      * @param logoRes    The logo res set by the app; Or 0 if the app sets bitmap directly.
225      * @param logoBitmap The bitmap from logoRes if the app sets logoRes; Or the bitmap set by the
226      *                   app directly.
227      */
setLogo(@rawableRes int logoRes, @NonNull Bitmap logoBitmap)228     public void setLogo(@DrawableRes int logoRes, @NonNull Bitmap logoBitmap) {
229         mLogoRes = logoRes;
230         mLogoBitmap = logoBitmap;
231     }
232 
setLogoDescription(@onNull String logoDescription)233     public void setLogoDescription(@NonNull String logoDescription) {
234         mLogoDescription = logoDescription;
235     }
236 
setTitle(CharSequence title)237     public void setTitle(CharSequence title) {
238         mTitle = title;
239     }
240 
setUseDefaultTitle(boolean useDefaultTitle)241     public void setUseDefaultTitle(boolean useDefaultTitle) {
242         mUseDefaultTitle = useDefaultTitle;
243     }
244 
setSubtitle(CharSequence subtitle)245     public void setSubtitle(CharSequence subtitle) {
246         mSubtitle = subtitle;
247     }
248 
setUseDefaultSubtitle(boolean useDefaultSubtitle)249     public void setUseDefaultSubtitle(boolean useDefaultSubtitle) {
250         mUseDefaultSubtitle = useDefaultSubtitle;
251     }
252 
setDescription(CharSequence description)253     public void setDescription(CharSequence description) {
254         mDescription = description;
255     }
256 
setContentView(PromptContentView view)257     public void setContentView(PromptContentView view) {
258         mContentView = (PromptContentViewParcelable) view;
259     }
260 
setDeviceCredentialTitle(CharSequence deviceCredentialTitle)261     public void setDeviceCredentialTitle(CharSequence deviceCredentialTitle) {
262         mDeviceCredentialTitle = deviceCredentialTitle;
263     }
264 
setDeviceCredentialSubtitle(CharSequence deviceCredentialSubtitle)265     public void setDeviceCredentialSubtitle(CharSequence deviceCredentialSubtitle) {
266         mDeviceCredentialSubtitle = deviceCredentialSubtitle;
267     }
268 
setDeviceCredentialDescription(CharSequence deviceCredentialDescription)269     public void setDeviceCredentialDescription(CharSequence deviceCredentialDescription) {
270         mDeviceCredentialDescription = deviceCredentialDescription;
271     }
272 
setNegativeButtonText(CharSequence negativeButtonText)273     public void setNegativeButtonText(CharSequence negativeButtonText) {
274         mNegativeButtonText = negativeButtonText;
275     }
276 
setConfirmationRequested(boolean confirmationRequested)277     public void setConfirmationRequested(boolean confirmationRequested) {
278         mConfirmationRequested = confirmationRequested;
279     }
280 
setDeviceCredentialAllowed(boolean deviceCredentialAllowed)281     public void setDeviceCredentialAllowed(boolean deviceCredentialAllowed) {
282         mDeviceCredentialAllowed = deviceCredentialAllowed;
283     }
284 
setAuthenticators(int authenticators)285     public void setAuthenticators(int authenticators) {
286         mAuthenticators = authenticators;
287     }
288 
setDisallowBiometricsIfPolicyExists(boolean disallowBiometricsIfPolicyExists)289     public void setDisallowBiometricsIfPolicyExists(boolean disallowBiometricsIfPolicyExists) {
290         mDisallowBiometricsIfPolicyExists = disallowBiometricsIfPolicyExists;
291     }
292 
setReceiveSystemEvents(boolean receiveSystemEvents)293     public void setReceiveSystemEvents(boolean receiveSystemEvents) {
294         mReceiveSystemEvents = receiveSystemEvents;
295     }
296 
setAllowedSensorIds(@onNull List<Integer> sensorIds)297     public void setAllowedSensorIds(@NonNull List<Integer> sensorIds) {
298         mAllowedSensorIds.clear();
299         mAllowedSensorIds.addAll(sensorIds);
300     }
301 
setAllowBackgroundAuthentication(boolean allow)302     public void setAllowBackgroundAuthentication(boolean allow) {
303         mAllowBackgroundAuthentication = allow;
304     }
305 
setIgnoreEnrollmentState(boolean ignoreEnrollmentState)306     public void setIgnoreEnrollmentState(boolean ignoreEnrollmentState) {
307         mIgnoreEnrollmentState = ignoreEnrollmentState;
308     }
309 
setIsForLegacyFingerprintManager(int sensorId)310     public void setIsForLegacyFingerprintManager(int sensorId) {
311         mIsForLegacyFingerprintManager = true;
312         mAllowedSensorIds.clear();
313         mAllowedSensorIds.add(sensorId);
314     }
315 
setShowEmergencyCallButton(boolean showEmergencyCallButton)316     public void setShowEmergencyCallButton(boolean showEmergencyCallButton) {
317         mShowEmergencyCallButton = showEmergencyCallButton;
318     }
319 
setComponentNameForConfirmDeviceCredentialActivity( ComponentName componentNameForConfirmDeviceCredentialActivity)320     public void setComponentNameForConfirmDeviceCredentialActivity(
321             ComponentName componentNameForConfirmDeviceCredentialActivity) {
322         mComponentNameForConfirmDeviceCredentialActivity =
323                 componentNameForConfirmDeviceCredentialActivity;
324     }
325 
setUseParentProfileForDeviceCredential( boolean useParentProfileForDeviceCredential)326     public void setUseParentProfileForDeviceCredential(
327             boolean useParentProfileForDeviceCredential) {
328         mUseParentProfileForDeviceCredential = useParentProfileForDeviceCredential;
329     }
330 
331     // Getters
332 
333     /**
334      * Returns the logo bitmap either from logo resource or bitmap passed in from the app.
335      */
getLogo()336     public Bitmap getLogo() {
337         return mLogoBitmap;
338     }
339 
340     /**
341      * Returns the logo res set by the app.
342      */
343     @DrawableRes
getLogoRes()344     public int getLogoRes() {
345         return mLogoRes;
346     }
347 
348     /**
349      * Returns the logo bitmap set by the app.
350      */
getLogoBitmap()351     public Bitmap getLogoBitmap() {
352         // If mLogoRes has been set, return null since mLogoBitmap is from the res, but not from
353         // the app directly.
354         return mLogoRes == 0 ? mLogoBitmap : null;
355     }
356 
getLogoDescription()357     public String getLogoDescription() {
358         return mLogoDescription;
359     }
360 
getTitle()361     public CharSequence getTitle() {
362         return mTitle;
363     }
364 
isUseDefaultTitle()365     public boolean isUseDefaultTitle() {
366         return mUseDefaultTitle;
367     }
368 
getSubtitle()369     public CharSequence getSubtitle() {
370         return mSubtitle;
371     }
372 
isUseDefaultSubtitle()373     public boolean isUseDefaultSubtitle() {
374         return mUseDefaultSubtitle;
375     }
376 
getDescription()377     public CharSequence getDescription() {
378         return mDescription;
379     }
380 
381     /**
382      * Gets the content view for the prompt.
383      *
384      * @return The content view for the prompt, or null if the prompt has no content view.
385      */
getContentView()386     public PromptContentView getContentView() {
387         return mContentView;
388     }
389 
getDeviceCredentialTitle()390     public CharSequence getDeviceCredentialTitle() {
391         return mDeviceCredentialTitle;
392     }
393 
getDeviceCredentialSubtitle()394     public CharSequence getDeviceCredentialSubtitle() {
395         return mDeviceCredentialSubtitle;
396     }
397 
getDeviceCredentialDescription()398     public CharSequence getDeviceCredentialDescription() {
399         return mDeviceCredentialDescription;
400     }
401 
getNegativeButtonText()402     public CharSequence getNegativeButtonText() {
403         return mNegativeButtonText;
404     }
405 
isConfirmationRequested()406     public boolean isConfirmationRequested() {
407         return mConfirmationRequested;
408     }
409 
410     /**
411      * This value is read once by {@link com.android.server.biometrics.BiometricService} and
412      * combined into {@link #getAuthenticators()}.
413      * @deprecated
414      * @return
415      */
416     @Deprecated
isDeviceCredentialAllowed()417     public boolean isDeviceCredentialAllowed() {
418         return mDeviceCredentialAllowed;
419     }
420 
getAuthenticators()421     public int getAuthenticators() {
422         return mAuthenticators;
423     }
424 
isDisallowBiometricsIfPolicyExists()425     public boolean isDisallowBiometricsIfPolicyExists() {
426         return mDisallowBiometricsIfPolicyExists;
427     }
428 
isReceiveSystemEvents()429     public boolean isReceiveSystemEvents() {
430         return mReceiveSystemEvents;
431     }
432 
433     @NonNull
getAllowedSensorIds()434     public List<Integer> getAllowedSensorIds() {
435         return mAllowedSensorIds;
436     }
437 
isAllowBackgroundAuthentication()438     public boolean isAllowBackgroundAuthentication() {
439         return mAllowBackgroundAuthentication;
440     }
441 
isIgnoreEnrollmentState()442     public boolean isIgnoreEnrollmentState() {
443         return mIgnoreEnrollmentState;
444     }
445 
isForLegacyFingerprintManager()446     public boolean isForLegacyFingerprintManager() {
447         return mIsForLegacyFingerprintManager;
448     }
449 
isShowEmergencyCallButton()450     public boolean isShowEmergencyCallButton() {
451         return mShowEmergencyCallButton;
452     }
453 
getComponentNameForConfirmDeviceCredentialActivity()454     public ComponentName getComponentNameForConfirmDeviceCredentialActivity() {
455         return mComponentNameForConfirmDeviceCredentialActivity;
456     }
457 
458 }
459