Merge "Add BiometricPrompt.Builder#setAllowBackgroundAuthentication TestApi" into sc-dev

This commit is contained in:
Kevin Chyn
2021-03-19 17:26:18 +00:00
committed by Android (Google) Code Review
26 changed files with 97 additions and 40 deletions

View File

@@ -1035,9 +1035,11 @@ package android.hardware.biometrics {
public class BiometricPrompt {
method @NonNull public java.util.List<java.lang.Integer> getAllowedSensorIds();
method public boolean isAllowBackgroundAuthentication();
}
public static class BiometricPrompt.Builder {
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.TEST_BIOMETRIC, "android.permission.USE_BIOMETRIC_INTERNAL"}) public android.hardware.biometrics.BiometricPrompt.Builder setAllowBackgroundAuthentication(boolean);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.TEST_BIOMETRIC, "android.permission.USE_BIOMETRIC_INTERNAL"}) public android.hardware.biometrics.BiometricPrompt.Builder setAllowedSensorIds(@NonNull java.util.List<java.lang.Integer>);
}

View File

@@ -367,6 +367,20 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
return this;
}
/**
* @param allow If true, allows authentication when the calling package is not in the
* foreground. This is set to false by default.
* @return This builder
* @hide
*/
@TestApi
@NonNull
@RequiresPermission(anyOf = {TEST_BIOMETRIC, USE_BIOMETRIC_INTERNAL})
public Builder setAllowBackgroundAuthentication(boolean allow) {
mPromptInfo.setAllowBackgroundAuthentication(allow);
return this;
}
/**
* If set check the Device Policy Manager for disabled biometrics.
*
@@ -619,6 +633,15 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
return mPromptInfo.getAllowedSensorIds();
}
/**
* @return The value set by {@link Builder#setAllowBackgroundAuthentication(boolean)}
* @hide
*/
@TestApi
public boolean isAllowBackgroundAuthentication() {
return mPromptInfo.isAllowBackgroundAuthentication();
}
/**
* A wrapper class for the cryptographic operations supported by BiometricPrompt.
*

View File

@@ -48,7 +48,7 @@ interface IBiometricAuthenticator {
// startPreparedClient().
void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
int cookie);
int cookie, boolean allowBackgroundAuthentication);
// Starts authentication with the previously prepared client.
void startPreparedClient(int cookie);

View File

@@ -44,6 +44,7 @@ public class PromptInfo implements Parcelable {
private boolean mDisallowBiometricsIfPolicyExists;
private boolean mReceiveSystemEvents;
@NonNull private List<Integer> mAllowedSensorIds = new ArrayList<>();
private boolean mAllowBackgroundAuthentication;
public PromptInfo() {
@@ -64,6 +65,7 @@ public class PromptInfo implements Parcelable {
mDisallowBiometricsIfPolicyExists = in.readBoolean();
mReceiveSystemEvents = in.readBoolean();
mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader());
mAllowBackgroundAuthentication = in.readBoolean();
}
public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() {
@@ -99,11 +101,14 @@ public class PromptInfo implements Parcelable {
dest.writeBoolean(mDisallowBiometricsIfPolicyExists);
dest.writeBoolean(mReceiveSystemEvents);
dest.writeList(mAllowedSensorIds);
dest.writeBoolean(mAllowBackgroundAuthentication);
}
public boolean containsTestConfigurations() {
if (!mAllowedSensorIds.isEmpty()) {
return true;
} else if (mAllowBackgroundAuthentication) {
return true;
}
return false;
}
@@ -183,6 +188,10 @@ public class PromptInfo implements Parcelable {
mAllowedSensorIds = sensorIds;
}
public void setAllowBackgroundAuthentication(boolean allow) {
mAllowBackgroundAuthentication = allow;
}
// Getters
public CharSequence getTitle() {
@@ -248,4 +257,8 @@ public class PromptInfo implements Parcelable {
public List<Integer> getAllowedSensorIds() {
return mAllowedSensorIds;
}
public boolean isAllowBackgroundAuthentication() {
return mAllowBackgroundAuthentication;
}
}

View File

@@ -59,7 +59,7 @@ interface IFaceService {
// startPreparedClient().
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
int cookie);
int cookie, boolean allowBackgroundAuthentication);
// Starts authentication with the previously prepared client.
void startPreparedClient(int sensorId, int cookie);

View File

@@ -62,7 +62,8 @@ interface IFingerprintService {
// by BiometricService. To start authentication after the clients are ready, use
// startPreparedClient().
void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie);
IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie,
boolean allowBackgroundAuthentication);
// Starts authentication with the previously prepared client.
void startPreparedClient(int sensorId, int cookie);

View File

@@ -195,7 +195,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
final int cookie = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
final boolean requireConfirmation = isConfirmationRequired(sensor);
sensor.goToStateWaitingForCookie(requireConfirmation, mToken, mOperationId,
mUserId, mSensorReceiver, mOpPackageName, cookie);
mUserId, mSensorReceiver, mOpPackageName, cookie,
mPromptInfo.isAllowBackgroundAuthentication());
}
}

View File

@@ -103,11 +103,12 @@ public abstract class BiometricSensor {
void goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
int cookie)
int cookie, boolean allowBackgroundAuthentication)
throws RemoteException {
mCookie = cookie;
impl.prepareForAuthentication(requireConfirmation, token,
sessionId, userId, sensorReceiver, opPackageName, mCookie);
sessionId, userId, sensorReceiver, opPackageName, mCookie,
allowBackgroundAuthentication);
mSensorState = STATE_WAITING_FOR_COOKIE;
}

View File

@@ -55,7 +55,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
@Nullable private final TaskStackListener mTaskStackListener;
private final LockoutTracker mLockoutTracker;
private final boolean mIsRestricted;
private final boolean mIsKeyguard;
private final boolean mAllowBackgroundAuthentication;
protected final long mOperationId;
@@ -68,7 +68,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
int targetUserId, long operationId, boolean restricted, @NonNull String owner,
int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric,
int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener,
@NonNull LockoutTracker lockoutTracker, boolean isKeyguard) {
@NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication) {
super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
mIsStrongBiometric = isStrongBiometric;
@@ -79,7 +79,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
mTaskStackListener = taskStackListener;
mLockoutTracker = lockoutTracker;
mIsRestricted = restricted;
mIsKeyguard = isKeyguard;
mAllowBackgroundAuthentication = allowBackgroundAuthentication;
}
public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
@@ -120,7 +120,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
}
public boolean isKeyguard() {
return mIsKeyguard;
return Utils.isKeyguard(getContext(), getOwnerString());
}
@Override
@@ -152,9 +152,15 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
pm.incrementAuthForUser(getTargetUserId(), authenticated);
}
if (mAllowBackgroundAuthentication) {
Slog.w(TAG, "Allowing background authentication,"
+ " this is allowed only for platform or test invocations");
}
// Ensure authentication only succeeds if the client activity is on top.
boolean isBackgroundAuth = false;
if (authenticated && !Utils.isKeyguard(getContext(), getOwnerString())
if (!mAllowBackgroundAuthentication && authenticated
&& !Utils.isKeyguard(getContext(), getOwnerString())
&& !Utils.isSystem(getContext(), getOwnerString())) {
final List<ActivityManager.RunningTaskInfo> tasks =
mActivityTaskManager.getTasks(1);

View File

@@ -61,10 +61,10 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, int cookie)
String opPackageName, int cookie, boolean allowBackgroundAuthentication)
throws RemoteException {
mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
userId, sensorReceiver, opPackageName, cookie);
userId, sensorReceiver, opPackageName, cookie, allowBackgroundAuthentication);
}
@Override

View File

@@ -306,7 +306,8 @@ public class FaceService extends SystemService implements BiometricServiceCallba
@Override // Binder call
public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
IBinder token, long operationId, int userId,
IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie) {
IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie,
boolean allowBackgroundAuthentication) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -318,7 +319,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, false /* isKeyguard */);
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication);
}
@Override // Binder call

View File

@@ -103,7 +103,8 @@ public interface ServiceProvider {
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient, boolean isKeyguard);
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication);
void cancelAuthentication(int sensorId, @NonNull IBinder token);

View File

@@ -69,11 +69,11 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
boolean isStrongBiometric, int statsClient, @NonNull UsageStats usageStats,
@NonNull LockoutCache lockoutCache, boolean isKeyguard) {
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
lockoutCache, isKeyguard);
lockoutCache, allowBackgroundAuthentication);
mUsageStats = usageStats;
mLockoutCache = lockoutCache;
mNotificationManager = context.getSystemService(NotificationManager.class);

View File

@@ -445,7 +445,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean isKeyguard) {
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
final IFace daemon = getHalInstance();
if (daemon == null) {
@@ -466,7 +466,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
operationId, restricted, opPackageName, cookie,
false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
mUsageStats, mSensors.get(sensorId).getLockoutCache(), isKeyguard);
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
allowBackgroundAuthentication);
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
} catch (RemoteException e) {
Slog.e(getTag(), "Remote exception when scheduling authenticate", e);

View File

@@ -638,7 +638,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean isKeyguard) {
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
@@ -646,7 +646,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
mLazyDaemon, token, receiver, userId, operationId, restricted, opPackageName,
cookie, false /* requireConfirmation */, mSensorId, isStrongBiometric,
statsClient, mLockoutTracker, mUsageStats, isKeyguard);
statsClient, mLockoutTracker, mUsageStats, allowBackgroundAuthentication);
mScheduler.scheduleClientMonitor(client);
});
}

View File

@@ -62,11 +62,11 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
boolean isStrongBiometric, int statsClient, @NonNull LockoutTracker lockoutTracker,
@NonNull UsageStats usageStats, boolean isKeyguard) {
@NonNull UsageStats usageStats, boolean allowBackgroundAuthentication) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
lockoutTracker, isKeyguard);
lockoutTracker, allowBackgroundAuthentication);
mUsageStats = usageStats;
final Resources resources = getContext().getResources();

View File

@@ -62,10 +62,10 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, int cookie)
String opPackageName, int cookie, boolean allowBackgroundAuthentication)
throws RemoteException {
mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId,
sensorReceiver, opPackageName, cookie);
sensorReceiver, opPackageName, cookie, allowBackgroundAuthentication);
}
@Override

View File

@@ -403,7 +403,7 @@ public class FingerprintService extends SystemService implements BiometricServic
@Override // Binder call
public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
int cookie) {
int cookie, boolean allowBackgroundAuthentication) {
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -415,7 +415,7 @@ public class FingerprintService extends SystemService implements BiometricServic
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, false /* isKeyguard */);
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication);
}
@Override // Binder call

View File

@@ -96,7 +96,8 @@ public interface ServiceProvider {
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient, boolean isKeyguard);
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication);
void startPreparedClient(int sensorId, int cookie);

View File

@@ -59,11 +59,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation,
int sensorId, boolean isStrongBiometric, int statsClient,
@Nullable TaskStackListener taskStackListener, @NonNull LockoutCache lockoutCache,
@Nullable IUdfpsOverlayController udfpsOverlayController, boolean isKeyguard) {
@Nullable IUdfpsOverlayController udfpsOverlayController,
boolean allowBackgroundAuthentication) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner,
cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
lockoutCache, isKeyguard);
lockoutCache, allowBackgroundAuthentication);
mLockoutCache = lockoutCache;
mUdfpsOverlayController = udfpsOverlayController;
}

View File

@@ -469,7 +469,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean isKeyguard) {
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
final IFingerprint daemon = getHalInstance();
if (daemon == null) {
@@ -491,7 +491,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
operationId, restricted, opPackageName, cookie,
false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
mUdfpsOverlayController, isKeyguard);
mUdfpsOverlayController, allowBackgroundAuthentication);
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
} catch (RemoteException e) {
Slog.e(getTag(), "Remote exception when scheduling authenticate", e);

View File

@@ -611,7 +611,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean isKeyguard) {
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
@@ -620,7 +620,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
mContext, mLazyDaemon, token, listener, userId, operationId, restricted,
opPackageName, cookie, false /* requireConfirmation */,
mSensorProperties.sensorId, isStrongBiometric, statsClient,
mTaskStackListener, mLockoutTracker, mUdfpsOverlayController, isKeyguard);
mTaskStackListener, mLockoutTracker, mUdfpsOverlayController,
allowBackgroundAuthentication);
mScheduler.scheduleClientMonitor(client);
});
}

View File

@@ -59,11 +59,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
int sensorId, boolean isStrongBiometric, int statsClient,
@NonNull TaskStackListener taskStackListener,
@NonNull LockoutFrameworkImpl lockoutTracker,
@Nullable IUdfpsOverlayController udfpsOverlayController, boolean isKeyguard) {
@Nullable IUdfpsOverlayController udfpsOverlayController,
boolean allowBackgroundAuthentication) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
lockoutTracker, isKeyguard);
lockoutTracker, allowBackgroundAuthentication);
mLockoutFrameworkImpl = lockoutTracker;
mUdfpsOverlayController = udfpsOverlayController;
}

View File

@@ -59,7 +59,8 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long sessionId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, int cookie) throws RemoteException {
String opPackageName, int cookie, boolean allowBackgroundAuthentication)
throws RemoteException {
}
@Override

View File

@@ -151,7 +151,8 @@ public class AuthSessionTest {
eq(userId),
eq(mSensorReceiver),
eq(TEST_PACKAGE),
eq(sensor.getCookie()));
eq(sensor.getCookie()),
anyBoolean() /* allowBackgroundAuthentication */);
}
final int cookie1 = session.mPreAuthInfo.eligibleSensors.get(0).getCookie();

View File

@@ -456,7 +456,8 @@ public class BiometricServiceTest {
anyInt() /* userId */,
any(IBiometricSensorReceiver.class),
anyString() /* opPackageName */,
cookieCaptor.capture() /* cookie */);
cookieCaptor.capture() /* cookie */,
anyBoolean() /* allowBackgroundAuthentication */);
// onReadyForAuthentication, mCurrentAuthSession state OK
mBiometricService.mImpl.onReadyForAuthentication(cookieCaptor.getValue());