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