Merge "Add authenticator-aware string methods to BiometricManager" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
02a13d14d5
@@ -17536,6 +17536,9 @@ package android.hardware.biometrics {
|
||||
public class BiometricManager {
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate();
|
||||
method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate(int);
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public CharSequence getButtonLabel(int);
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public CharSequence getPromptMessage(int);
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public CharSequence getSettingName(int);
|
||||
field public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1; // 0x1
|
||||
field public static final int BIOMETRIC_ERROR_NONE_ENROLLED = 11; // 0xb
|
||||
field public static final int BIOMETRIC_ERROR_NO_HARDWARE = 12; // 0xc
|
||||
|
||||
@@ -62,10 +62,13 @@ public interface BiometricAuthenticator {
|
||||
* @hide
|
||||
*/
|
||||
int TYPE_FACE = 1 << 3;
|
||||
@IntDef({TYPE_NONE,
|
||||
|
||||
@IntDef(flag = true, value = {
|
||||
TYPE_NONE,
|
||||
TYPE_CREDENTIAL,
|
||||
TYPE_FINGERPRINT,
|
||||
TYPE_IRIS})
|
||||
TYPE_IRIS
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface Modality {}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
@@ -193,15 +194,15 @@ public class BiometricManager {
|
||||
int DEVICE_CREDENTIAL = 1 << 15;
|
||||
}
|
||||
|
||||
private final Context mContext;
|
||||
private final IAuthService mService;
|
||||
@NonNull private final Context mContext;
|
||||
@NonNull private final IAuthService mService;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param context
|
||||
* @param service
|
||||
*/
|
||||
public BiometricManager(Context context, IAuthService service) {
|
||||
public BiometricManager(@NonNull Context context, @NonNull IAuthService service) {
|
||||
mContext = context;
|
||||
mService = service;
|
||||
}
|
||||
@@ -274,7 +275,8 @@ public class BiometricManager {
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresPermission(USE_BIOMETRIC)
|
||||
public @BiometricError int canAuthenticate() {
|
||||
@BiometricError
|
||||
public int canAuthenticate() {
|
||||
return canAuthenticate(Authenticators.BIOMETRIC_WEAK);
|
||||
}
|
||||
|
||||
@@ -304,7 +306,8 @@ public class BiometricManager {
|
||||
* authenticators can currently be used (enrolled and available).
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC)
|
||||
public @BiometricError int canAuthenticate(@Authenticators.Types int authenticators) {
|
||||
@BiometricError
|
||||
public int canAuthenticate(@Authenticators.Types int authenticators) {
|
||||
return canAuthenticate(mContext.getUserId(), authenticators);
|
||||
}
|
||||
|
||||
@@ -312,8 +315,10 @@ public class BiometricManager {
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public @BiometricError int canAuthenticate(int userId,
|
||||
@Authenticators.Types int authenticators) {
|
||||
@BiometricError
|
||||
public int canAuthenticate(
|
||||
int userId, @Authenticators.Types int authenticators) {
|
||||
|
||||
if (mService != null) {
|
||||
try {
|
||||
final String opPackageName = mContext.getOpPackageName();
|
||||
@@ -322,7 +327,7 @@ public class BiometricManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
} else {
|
||||
Slog.w(TAG, "hasEnrolledBiometrics(): Service not connected");
|
||||
Slog.w(TAG, "canAuthenticate(): Service not connected");
|
||||
return BIOMETRIC_ERROR_HW_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
@@ -404,5 +409,115 @@ public class BiometricManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a localized string that may be used as the label for a button that invokes
|
||||
* {@link BiometricPrompt}.
|
||||
*
|
||||
* <p>When possible, this method should use the given authenticator requirements to more
|
||||
* precisely specify the authentication type that will be used. For example, if
|
||||
* <strong>Class 3</strong> biometric authentication is requested on a device with a
|
||||
* <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor, the
|
||||
* returned string should indicate that fingerprint authentication will be used.
|
||||
*
|
||||
* <p>This method should also try to specify which authentication method(s) will be used in
|
||||
* practice when multiple authenticators meet the given requirements. For example, if biometric
|
||||
* authentication is requested on a device with both face and fingerprint sensors but the user
|
||||
* has selected face as their preferred method, the returned string should indicate that face
|
||||
* authentication will be used.
|
||||
*
|
||||
* @param authenticators A bit field representing the types of {@link Authenticators} that may
|
||||
* be used for authentication.
|
||||
* @return The label for a button that invokes {@link BiometricPrompt} for authentication.
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC)
|
||||
@Nullable
|
||||
public CharSequence getButtonLabel(@Authenticators.Types int authenticators) {
|
||||
if (mService != null) {
|
||||
final int userId = mContext.getUserId();
|
||||
final String opPackageName = mContext.getOpPackageName();
|
||||
try {
|
||||
return mService.getButtonLabel(userId, opPackageName, authenticators);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
} else {
|
||||
Slog.w(TAG, "getButtonLabel(): Service not connected");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a localized string that may be shown while the user is authenticating with
|
||||
* {@link BiometricPrompt}.
|
||||
*
|
||||
* <p>When possible, this method should use the given authenticator requirements to more
|
||||
* precisely specify the authentication type that will be used. For example, if
|
||||
* <strong>Class 3</strong> biometric authentication is requested on a device with a
|
||||
* <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor, the
|
||||
* returned string should indicate that fingerprint authentication will be used.
|
||||
*
|
||||
* <p>This method should also try to specify which authentication method(s) will be used in
|
||||
* practice when multiple authenticators meet the given requirements. For example, if biometric
|
||||
* authentication is requested on a device with both face and fingerprint sensors but the user
|
||||
* has selected face as their preferred method, the returned string should indicate that face
|
||||
* authentication will be used.
|
||||
*
|
||||
* @param authenticators A bit field representing the types of {@link Authenticators} that may
|
||||
* be used for authentication.
|
||||
* @return The label for a button that invokes {@link BiometricPrompt} for authentication.
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC)
|
||||
@Nullable
|
||||
public CharSequence getPromptMessage(@Authenticators.Types int authenticators) {
|
||||
if (mService != null) {
|
||||
final int userId = mContext.getUserId();
|
||||
final String opPackageName = mContext.getOpPackageName();
|
||||
try {
|
||||
return mService.getPromptMessage(userId, opPackageName, authenticators);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
} else {
|
||||
Slog.w(TAG, "getPromptMessage(): Service not connected");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a localized string that may be shown as the title for an app setting that enables
|
||||
* biometric authentication.
|
||||
*
|
||||
* <p>When possible, this method should use the given authenticator requirements to more
|
||||
* precisely specify the authentication type that will be used. For example, if
|
||||
* <strong>Class 3</strong> biometric authentication is requested on a device with a
|
||||
* <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor, the
|
||||
* returned string should indicate that fingerprint authentication will be used.
|
||||
*
|
||||
* <p>This method should <em>not</em> try to specify which authentication method(s) will be used
|
||||
* in practice when multiple authenticators meet the given requirements. For example, if
|
||||
* biometric authentication is requested on a device with both face and fingerprint sensors, the
|
||||
* returned string should indicate that either face or fingerprint authentication may be used,
|
||||
* regardless of whether the user has enrolled or selected either as their preferred method.
|
||||
*
|
||||
* @param authenticators A bit field representing the types of {@link Authenticators} that may
|
||||
* be used for authentication.
|
||||
* @return The label for a button that invokes {@link BiometricPrompt} for authentication.
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC)
|
||||
@Nullable
|
||||
public CharSequence getSettingName(@Authenticators.Types int authenticators) {
|
||||
if (mService != null) {
|
||||
final int userId = mContext.getUserId();
|
||||
final String opPackageName = mContext.getOpPackageName();
|
||||
try {
|
||||
return mService.getSettingName(userId, opPackageName, authenticators);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
} else {
|
||||
Slog.w(TAG, "getSettingName(): Service not connected");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,4 +68,16 @@ interface IAuthService {
|
||||
// the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
|
||||
// land as SIDs, and are used during key generation.
|
||||
long[] getAuthenticatorIds();
|
||||
|
||||
// Provides a localized string that may be used as the label for a button that invokes
|
||||
// BiometricPrompt.
|
||||
CharSequence getButtonLabel(int userId, String opPackageName, int authenticators);
|
||||
|
||||
// Provides a localized string that may be shown while the user is authenticating with
|
||||
// BiometricPrompt.
|
||||
CharSequence getPromptMessage(int userId, String opPackageName, int authenticators);
|
||||
|
||||
// Provides a localized string that may be shown as the title for an app setting that enables
|
||||
// biometric authentication.
|
||||
CharSequence getSettingName(int userId, String opPackageName, int authenticators);
|
||||
}
|
||||
|
||||
@@ -75,4 +75,10 @@ interface IBiometricService {
|
||||
long[] getAuthenticatorIds(int callingUserId);
|
||||
|
||||
int getCurrentStrength(int sensorId);
|
||||
|
||||
// Returns a bit field of the modality (or modalities) that are will be used for authentication.
|
||||
int getCurrentModality(String opPackageName, int userId, int callingUserId, int authenticators);
|
||||
|
||||
// Returns a bit field of the authentication modalities that are supported by this device.
|
||||
int getSupportedModalities(int authenticators);
|
||||
}
|
||||
|
||||
@@ -1524,8 +1524,15 @@
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_mediaLocation">Allows the app to read locations from your media collection.</string>
|
||||
|
||||
<!-- Name for an app setting that lets the user authenticate for that app using biometrics (e.g. fingerprint or face). [CHAR LIMIT=30] -->
|
||||
<string name="biometric_app_setting_name">Use biometrics</string>
|
||||
<!-- Name for an app setting that lets the user authenticate for that app using biometrics (e.g. fingerprint or face) or their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=70] -->
|
||||
<string name="biometric_or_screen_lock_app_setting_name">Use biometrics or screen lock</string>
|
||||
<!-- Title shown when the system-provided biometric dialog is shown, asking the user to authenticate. [CHAR LIMIT=40] -->
|
||||
<string name="biometric_dialog_default_title">Verify it\u2019s you</string>
|
||||
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face). [CHAR LIMIT=70] -->
|
||||
<string name="biometric_dialog_default_subtitle">Use your biometric to continue</string>
|
||||
|
||||
<!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] -->
|
||||
<string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
|
||||
<!-- Message shown when biometric authentication was canceled by the user [CHAR LIMIT=50] -->
|
||||
@@ -1539,6 +1546,11 @@
|
||||
<!-- Message returned to applications when an unexpected/unknown error occurs. [CHAR LIMIT=50]-->
|
||||
<string name="biometric_error_generic">Error authenticating</string>
|
||||
|
||||
<!-- Name for an app setting that lets the user authenticate for that app with their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=30] -->
|
||||
<string name="screen_lock_app_setting_name">Use screen lock</string>
|
||||
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=70] -->
|
||||
<string name="screen_lock_dialog_default_subtitle">Enter your device credential to continue</string>
|
||||
|
||||
<!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized -->
|
||||
<string name="fingerprint_acquired_partial">Partial fingerprint detected. Please try again.</string>
|
||||
<!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized -->
|
||||
@@ -1585,6 +1597,11 @@
|
||||
|
||||
<!-- Template to be used to name enrolled fingerprints by default. -->
|
||||
<string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string>
|
||||
|
||||
<!-- Name for an app setting that lets the user authenticate for that app with their fingerprint. [CHAR LIMIT=30] -->
|
||||
<string name="fingerprint_app_setting_name">Use fingerprint</string>
|
||||
<!-- Name for an app setting that lets the user authenticate for that app with their fingerprint or screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=70] -->
|
||||
<string name="fingerprint_or_screen_lock_app_setting_name">Use fingerprint or screen lock</string>
|
||||
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their fingerprint. [CHAR LIMIT=70] -->
|
||||
<string name="fingerprint_dialog_default_subtitle">Use your fingerprint to continue</string>
|
||||
|
||||
@@ -1681,6 +1698,13 @@
|
||||
<!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] -->
|
||||
<string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string>
|
||||
|
||||
<!-- Name for an app setting that lets the user authenticate for that app with their face. [CHAR LIMIT=30] -->
|
||||
<string name="face_app_setting_name">Use face unlock</string>
|
||||
<!-- Name for an app setting that lets the user authenticate for that app with their face or screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=70] -->
|
||||
<string name="face_or_screen_lock_app_setting_name">Use face or screen lock</string>
|
||||
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their face. [CHAR LIMIT=70] -->
|
||||
<string name="face_dialog_default_subtitle">Use face unlock to continue</string>
|
||||
|
||||
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
|
||||
<string-array name="face_error_vendor">
|
||||
</string-array>
|
||||
|
||||
@@ -2472,7 +2472,10 @@
|
||||
<java-symbol type="string" name="config_keyguardComponent" />
|
||||
|
||||
<!-- Biometric messages -->
|
||||
<java-symbol type="string" name="biometric_app_setting_name" />
|
||||
<java-symbol type="string" name="biometric_or_screen_lock_app_setting_name" />
|
||||
<java-symbol type="string" name="biometric_dialog_default_title" />
|
||||
<java-symbol type="string" name="biometric_dialog_default_subtitle" />
|
||||
<java-symbol type="string" name="biometric_error_hw_unavailable" />
|
||||
<java-symbol type="string" name="biometric_error_user_canceled" />
|
||||
<java-symbol type="string" name="biometric_not_recognized" />
|
||||
@@ -2480,6 +2483,10 @@
|
||||
<java-symbol type="string" name="biometric_error_device_not_secured" />
|
||||
<java-symbol type="string" name="biometric_error_generic" />
|
||||
|
||||
<!-- Device credential strings for BiometricManager -->
|
||||
<java-symbol type="string" name="screen_lock_app_setting_name" />
|
||||
<java-symbol type="string" name="screen_lock_dialog_default_subtitle" />
|
||||
|
||||
<!-- Fingerprint messages -->
|
||||
<java-symbol type="string" name="fingerprint_error_unable_to_process" />
|
||||
<java-symbol type="string" name="fingerprint_error_hw_not_available" />
|
||||
@@ -2497,6 +2504,8 @@
|
||||
<java-symbol type="string" name="fingerprint_error_lockout" />
|
||||
<java-symbol type="string" name="fingerprint_error_lockout_permanent" />
|
||||
<java-symbol type="string" name="fingerprint_name_template" />
|
||||
<java-symbol type="string" name="fingerprint_app_setting_name" />
|
||||
<java-symbol type="string" name="fingerprint_or_screen_lock_app_setting_name" />
|
||||
<java-symbol type="string" name="fingerprint_dialog_default_subtitle" />
|
||||
<java-symbol type="string" name="fingerprint_authenticated" />
|
||||
<java-symbol type="string" name="fingerprint_error_no_fingerprints" />
|
||||
@@ -2544,6 +2553,9 @@
|
||||
<java-symbol type="string" name="face_acquired_sensor_dirty" />
|
||||
<java-symbol type="array" name="face_acquired_vendor" />
|
||||
<java-symbol type="string" name="face_name_template" />
|
||||
<java-symbol type="string" name="face_app_setting_name" />
|
||||
<java-symbol type="string" name="face_or_screen_lock_app_setting_name" />
|
||||
<java-symbol type="string" name="face_dialog_default_subtitle" />
|
||||
<java-symbol type="string" name="face_authenticated_no_confirmation_required" />
|
||||
<java-symbol type="string" name="face_authenticated_confirmation_required" />
|
||||
<java-symbol type="string" name="face_error_security_update_required" />
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.annotation.NonNull;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.IAuthService;
|
||||
import android.hardware.biometrics.IBiometricAuthenticator;
|
||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
||||
@@ -337,6 +338,168 @@ public class AuthService extends SystemService {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getButtonLabel(
|
||||
int userId,
|
||||
String opPackageName,
|
||||
@Authenticators.Types int authenticators) throws RemoteException {
|
||||
|
||||
// Only allow internal clients to call getButtonLabel with a different userId.
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
|
||||
if (userId != callingUserId) {
|
||||
checkInternalPermission();
|
||||
} else {
|
||||
checkPermission();
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@BiometricAuthenticator.Modality final int modality =
|
||||
mBiometricService.getCurrentModality(
|
||||
opPackageName, userId, callingUserId, authenticators);
|
||||
|
||||
final String result;
|
||||
switch (getCredentialBackupModality(modality)) {
|
||||
case BiometricAuthenticator.TYPE_NONE:
|
||||
result = null;
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_CREDENTIAL:
|
||||
result = getContext().getString(R.string.screen_lock_app_setting_name);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_FINGERPRINT:
|
||||
result = getContext().getString(R.string.fingerprint_app_setting_name);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_FACE:
|
||||
result = getContext().getString(R.string.face_app_setting_name);
|
||||
break;
|
||||
default:
|
||||
result = getContext().getString(R.string.biometric_app_setting_name);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPromptMessage(
|
||||
int userId,
|
||||
String opPackageName,
|
||||
@Authenticators.Types int authenticators) throws RemoteException {
|
||||
|
||||
// Only allow internal clients to call getButtonLabel with a different userId.
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
|
||||
if (userId != callingUserId) {
|
||||
checkInternalPermission();
|
||||
} else {
|
||||
checkPermission();
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@BiometricAuthenticator.Modality final int modality =
|
||||
mBiometricService.getCurrentModality(
|
||||
opPackageName, userId, callingUserId, authenticators);
|
||||
|
||||
final String result;
|
||||
switch (getCredentialBackupModality(modality)) {
|
||||
case BiometricAuthenticator.TYPE_NONE:
|
||||
result = null;
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_CREDENTIAL:
|
||||
result = getContext().getString(
|
||||
R.string.screen_lock_dialog_default_subtitle);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_FINGERPRINT:
|
||||
result = getContext().getString(
|
||||
R.string.fingerprint_dialog_default_subtitle);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_FACE:
|
||||
result = getContext().getString(R.string.face_dialog_default_subtitle);
|
||||
break;
|
||||
default:
|
||||
result = getContext().getString(R.string.biometric_dialog_default_subtitle);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSettingName(
|
||||
int userId,
|
||||
String opPackageName,
|
||||
@Authenticators.Types int authenticators) throws RemoteException {
|
||||
|
||||
// Only allow internal clients to call getButtonLabel with a different userId.
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
|
||||
if (userId != callingUserId) {
|
||||
checkInternalPermission();
|
||||
} else {
|
||||
checkPermission();
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@BiometricAuthenticator.Modality final int modality =
|
||||
mBiometricService.getSupportedModalities(authenticators);
|
||||
|
||||
final String result;
|
||||
switch (modality) {
|
||||
// Handle the case of a single supported modality.
|
||||
case BiometricAuthenticator.TYPE_NONE:
|
||||
result = null;
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_CREDENTIAL:
|
||||
result = getContext().getString(R.string.screen_lock_app_setting_name);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_IRIS:
|
||||
result = getContext().getString(R.string.biometric_app_setting_name);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_FINGERPRINT:
|
||||
result = getContext().getString(R.string.fingerprint_app_setting_name);
|
||||
break;
|
||||
case BiometricAuthenticator.TYPE_FACE:
|
||||
result = getContext().getString(R.string.face_app_setting_name);
|
||||
break;
|
||||
|
||||
// Handle other possible modality combinations.
|
||||
default:
|
||||
if ((modality & BiometricAuthenticator.TYPE_CREDENTIAL) == 0) {
|
||||
// 2+ biometric modalities are supported (but not device credential).
|
||||
result = getContext().getString(R.string.biometric_app_setting_name);
|
||||
} else {
|
||||
@BiometricAuthenticator.Modality final int biometricModality =
|
||||
modality & ~BiometricAuthenticator.TYPE_CREDENTIAL;
|
||||
if (biometricModality == BiometricAuthenticator.TYPE_FINGERPRINT) {
|
||||
// Only device credential and fingerprint are supported.
|
||||
result = getContext().getString(
|
||||
R.string.fingerprint_or_screen_lock_app_setting_name);
|
||||
} else if (biometricModality == BiometricAuthenticator.TYPE_FACE) {
|
||||
// Only device credential and face are supported.
|
||||
result = getContext().getString(
|
||||
R.string.face_or_screen_lock_app_setting_name);
|
||||
} else {
|
||||
// Device credential and 1+ other biometric(s) are supported.
|
||||
result = getContext().getString(
|
||||
R.string.biometric_or_screen_lock_app_setting_name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AuthService(Context context) {
|
||||
@@ -442,4 +605,10 @@ public class AuthService extends SystemService {
|
||||
return mInjector.getAppOps(getContext()).noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid,
|
||||
opPackageName, null /* attributionTag */, reason) == AppOpsManager.MODE_ALLOWED;
|
||||
}
|
||||
|
||||
@BiometricAuthenticator.Modality
|
||||
private static int getCredentialBackupModality(@BiometricAuthenticator.Modality int modality) {
|
||||
return modality == BiometricAuthenticator.TYPE_CREDENTIAL
|
||||
? modality : (modality & ~BiometricAuthenticator.TYPE_CREDENTIAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,14 +666,9 @@ public class BiometricService extends SystemService {
|
||||
throw new SecurityException("Invalid authenticator configuration");
|
||||
}
|
||||
|
||||
final PromptInfo promptInfo = new PromptInfo();
|
||||
promptInfo.setAuthenticators(authenticators);
|
||||
|
||||
try {
|
||||
PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager,
|
||||
mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo,
|
||||
opPackageName,
|
||||
false /* checkDevicePolicyManager */);
|
||||
final PreAuthInfo preAuthInfo =
|
||||
createPreAuthInfo(opPackageName, userId, authenticators);
|
||||
return preAuthInfo.getCanAuthenticateResult();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
@@ -807,6 +802,64 @@ public class BiometricService extends SystemService {
|
||||
return Authenticators.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public int getCurrentModality(
|
||||
String opPackageName,
|
||||
int userId,
|
||||
int callingUserId,
|
||||
@Authenticators.Types int authenticators) {
|
||||
|
||||
checkInternalPermission();
|
||||
|
||||
Slog.d(TAG, "getCurrentModality: User=" + userId
|
||||
+ ", Caller=" + callingUserId
|
||||
+ ", Authenticators=" + authenticators);
|
||||
|
||||
if (!Utils.isValidAuthenticatorConfig(authenticators)) {
|
||||
throw new SecurityException("Invalid authenticator configuration");
|
||||
}
|
||||
|
||||
try {
|
||||
final PreAuthInfo preAuthInfo =
|
||||
createPreAuthInfo(opPackageName, userId, authenticators);
|
||||
return preAuthInfo.getPreAuthenticateStatus().first;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
return BiometricAuthenticator.TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public int getSupportedModalities(@Authenticators.Types int authenticators) {
|
||||
checkInternalPermission();
|
||||
|
||||
Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators);
|
||||
|
||||
if (!Utils.isValidAuthenticatorConfig(authenticators)) {
|
||||
throw new SecurityException("Invalid authenticator configuration");
|
||||
}
|
||||
|
||||
@BiometricAuthenticator.Modality int modality =
|
||||
Utils.isCredentialRequested(authenticators)
|
||||
? BiometricAuthenticator.TYPE_CREDENTIAL
|
||||
: BiometricAuthenticator.TYPE_NONE;
|
||||
|
||||
if (Utils.isBiometricRequested(authenticators)) {
|
||||
@Authenticators.Types final int requestedStrength =
|
||||
Utils.getPublicBiometricStrength(authenticators);
|
||||
|
||||
// Add modalities of all biometric sensors that meet the authenticator requirements.
|
||||
for (final BiometricSensor sensor : mSensors) {
|
||||
@Authenticators.Types final int sensorStrength = sensor.getCurrentStrength();
|
||||
if (Utils.isAtLeastStrength(sensorStrength, requestedStrength)) {
|
||||
modality |= sensor.modality;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modality;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
|
||||
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
|
||||
@@ -845,6 +898,19 @@ public class BiometricService extends SystemService {
|
||||
"Must have USE_BIOMETRIC_INTERNAL permission");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private PreAuthInfo createPreAuthInfo(
|
||||
@NonNull String opPackageName,
|
||||
int userId,
|
||||
@Authenticators.Types int authenticators) throws RemoteException {
|
||||
|
||||
final PromptInfo promptInfo = new PromptInfo();
|
||||
promptInfo.setAuthenticators(authenticators);
|
||||
|
||||
return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors,
|
||||
userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for injecting dependencies into BiometricService.
|
||||
* TODO(b/141025588): Replace with a dependency injection framework (e.g. Guice, Dagger).
|
||||
|
||||
@@ -150,6 +150,16 @@ public class Utils {
|
||||
return getPublicBiometricStrength(promptInfo.getAuthenticators());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any of the publicly defined strengths are set.
|
||||
*
|
||||
* @param authenticators composed of one or more values from {@link Authenticators}
|
||||
* @return true if biometric authentication is allowed.
|
||||
*/
|
||||
static boolean isBiometricRequested(@Authenticators.Types int authenticators) {
|
||||
return getPublicBiometricStrength(authenticators) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any of the publicly defined strengths are set.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user