blob: 180a8ca8520b343607312c465d96fc4d83914032 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.biometric;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.biometric.BiometricManager.Authenticators;
/**
* Utilities related to {@link BiometricManager.Authenticators} constants.
*/
class AuthenticatorUtils {
/**
* A bitmask for the portion of an {@link BiometricManager.AuthenticatorTypes} value related to
* biometric sensor class.
*/
private static final int BIOMETRIC_CLASS_MASK = 0x7FFF;
// Prevent instantiation.
private AuthenticatorUtils() {}
/**
* Converts the given set of allowed authenticator types to a unique, developer-readable string.
*
* @param authenticators A bit field representing a set of allowed authenticator types.
* @return A string that uniquely identifies the set of authenticators and can be used in
* developer-facing contexts (e.g. error messages).
*/
static String convertToString(@BiometricManager.AuthenticatorTypes int authenticators) {
switch (authenticators) {
case Authenticators.BIOMETRIC_STRONG:
return "BIOMETRIC_STRONG";
case Authenticators.BIOMETRIC_WEAK:
return "BIOMETRIC_WEAK";
case Authenticators.DEVICE_CREDENTIAL:
return "DEVICE_CREDENTIAL";
case Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL:
return "BIOMETRIC_STRONG | DEVICE_CREDENTIAL";
case Authenticators.BIOMETRIC_WEAK | Authenticators.DEVICE_CREDENTIAL:
return "BIOMETRIC_WEAK | DEVICE_CREDENTIAL";
default:
return String.valueOf(authenticators);
}
}
/**
* Combines relevant information from the given {@link BiometricPrompt.PromptInfo} and
* {@link BiometricPrompt.CryptoObject} to determine which type(s) of authenticators should be
* allowed for a given authentication session.
*
* @param info The {@link BiometricPrompt.PromptInfo} for a given authentication session.
* @param crypto The {@link BiometricPrompt.CryptoObject} for a given crypto-based
* authentication session, or {@code null} for non-crypto authentication.
* @return A bit field representing all valid authenticator types that may be invoked.
*/
@SuppressWarnings("deprecation")
@BiometricManager.AuthenticatorTypes
static int getConsolidatedAuthenticators(
@NonNull BiometricPrompt.PromptInfo info,
@Nullable BiometricPrompt.CryptoObject crypto) {
@BiometricManager.AuthenticatorTypes int authenticators;
if (info.getAllowedAuthenticators() != 0) {
// Use explicitly allowed authenticators if set.
authenticators = info.getAllowedAuthenticators();
} else {
// Crypto auth requires a Class 3 (Strong) biometric.
authenticators = crypto != null
? Authenticators.BIOMETRIC_STRONG
: Authenticators.BIOMETRIC_WEAK;
if (info.isDeviceCredentialAllowed()) {
authenticators |= Authenticators.DEVICE_CREDENTIAL;
}
}
return authenticators;
}
/**
* Checks if the given set of allowed authenticator types is supported on this Android version.
*
* @param authenticators A bit field representing a set of allowed authenticator types.
* @return Whether user authentication with the given set of allowed authenticator types is
* supported on the current Android version.
*/
static boolean isSupportedCombination(@BiometricManager.AuthenticatorTypes int authenticators) {
switch (authenticators) {
case Authenticators.BIOMETRIC_STRONG:
case Authenticators.BIOMETRIC_WEAK:
case Authenticators.BIOMETRIC_WEAK | Authenticators.DEVICE_CREDENTIAL:
return true;
// A biometric can be used instead of device credential prior to API 30.
case Authenticators.DEVICE_CREDENTIAL:
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
// A Class 2 (Weak) biometric can be used instead of device credential on API 28-29.
case Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL:
return Build.VERSION.SDK_INT < Build.VERSION_CODES.P
|| Build.VERSION.SDK_INT > Build.VERSION_CODES.Q;
default:
// 0 means "no authenticator types" and is supported. Other values are not.
return authenticators == 0;
}
}
/**
* Checks if a device credential is included in the given set of allowed authenticator types.
*
* @param authenticators A bit field representing a set of allowed authenticator types.
* @return Whether {@link Authenticators#DEVICE_CREDENTIAL} is an allowed authenticator type.
*/
static boolean isDeviceCredentialAllowed(
@BiometricManager.AuthenticatorTypes int authenticators) {
return (authenticators & Authenticators.DEVICE_CREDENTIAL) != 0;
}
/**
* Checks if any biometric class is included in the given set of allowed authenticator types.
*
* @param authenticators A bit field representing a set of allowed authenticator types.
* @return Whether the allowed authenticator types include one or more biometric classes.
*/
static boolean isSomeBiometricAllowed(@BiometricManager.AuthenticatorTypes int authenticators) {
return (authenticators & BIOMETRIC_CLASS_MASK) != 0;
}
/**
* Checks if a <strong>Class 2</strong> (formerly <strong>Weak</strong>) biometric is included
* in the given set of allowed authenticator types.
*
* @param authenticators A bit field representing a set of allowed authenticator types.
* @return Whether {@link Authenticators#BIOMETRIC_WEAK} is an allowed authenticator type.
*/
static boolean isWeakBiometricAllowed(@BiometricManager.AuthenticatorTypes int authenticators) {
return (authenticators & Authenticators.BIOMETRIC_WEAK) == Authenticators.BIOMETRIC_WEAK;
}
}