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