summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kevin Chyn <kchyn@google.com> 2020-11-02 18:09:46 -0800
committer Kevin Chyn <kchyn@google.com> 2020-11-13 20:05:16 -0800
commit3eb5c9c2d787605c0419dad5716aaeaeb6815af6 (patch)
tree4ee0439737fe0732e3b04021cdde7f94e1c32703
parentef4cd62246a2d72c06703c7817ecb84cd930bfa5 (diff)
Initial implementation of BiometricManager TestApis
1) Finishes Face10 test implementation 2) Adds createTestSession and getSensorProperties to IBiometricAuthenticator. This way, BiometricService, which is the source of truth for all sensors is able to implement or forward TestApi requests as appropriate. 3) Removes a few unused parameters (callingUid, callingPid, callingUserId) 4) Moves proto def to a biometric proto. This is basically the common TestApi equivalent for getting states of _any_ sensor service (FingerprintService, FaceService, etc) 5) Moves AuthSession states to biometric.proto 6) Updates SysUI components to use separate positive buttons for better readability and testing Bug: 171357779 Test: atest CtsBiometricsTestCases on fingerprint/face devices Test: atest com.android.server.biometrics Change-Id: I5d884d4a9f4afa3f947eb4587e869bacd6b2f805
-rw-r--r--core/java/android/hardware/biometrics/BiometricManager.java19
-rw-r--r--core/java/android/hardware/biometrics/IAuthService.aidl8
-rw-r--r--core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl16
-rw-r--r--core/java/android/hardware/biometrics/IBiometricService.aidl14
-rw-r--r--core/java/android/hardware/biometrics/SensorProperties.java8
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl16
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl12
-rw-r--r--core/proto/android/server/biometrics.proto130
-rw-r--r--core/proto/android/server/fingerprint.proto33
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java42
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java87
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricSensor.java23
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java78
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java34
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java51
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java13
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java193
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java377
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/TestHal.java132
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java30
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java46
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java18
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java11
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java133
31 files changed, 1153 insertions, 473 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 3b56dde69704..987d790601b4 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -208,7 +208,17 @@ public class BiometricManager {
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public List<SensorProperties> getSensorProperties() {
- return new ArrayList<>(); // TODO(169459906)
+ try {
+ final List<SensorPropertiesInternal> internalProperties =
+ mService.getSensorProperties(mContext.getOpPackageName());
+ final List<SensorProperties> properties = new ArrayList<>();
+ for (SensorPropertiesInternal internalProp : internalProperties) {
+ properties.add(SensorProperties.from(internalProp));
+ }
+ return properties;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -219,7 +229,12 @@ public class BiometricManager {
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public BiometricTestSession createTestSession(int sensorId) {
- return null; // TODO(169459906)
+ try {
+ return new BiometricTestSession(mContext,
+ mService.createTestSession(sensorId, mContext.getOpPackageName()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index b44327678ad4..8e7f5ce8a85d 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -18,7 +18,9 @@ package android.hardware.biometrics;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricServiceReceiver;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.PromptInfo;
+import android.hardware.biometrics.SensorPropertiesInternal;
/**
* Communication channel from BiometricPrompt and BiometricManager to AuthService. The
@@ -28,6 +30,12 @@ import android.hardware.biometrics.PromptInfo;
* @hide
*/
interface IAuthService {
+ // Creates a test session with the specified sensorId
+ ITestSession createTestSession(int sensorId, String opPackageName);
+
+ // Retrieve static sensor properties for all biometric sensors
+ List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
+
// Retrieve the package where BIometricOrompt's UI is implemented
String getUiPackage();
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index 5e6fe6885f9d..cb43943f4864 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -18,6 +18,8 @@ package android.hardware.biometrics;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.face.IFaceServiceReceiver;
import android.hardware.face.Face;
@@ -28,6 +30,15 @@ import android.hardware.face.Face;
*/
interface IBiometricAuthenticator {
+ // Creates a test session
+ ITestSession createTestSession(String opPackageName);
+
+ // Retrieve static sensor properties
+ SensorPropertiesInternal getSensorProperties(String opPackageName);
+
+ // Requests a proto dump of the service. See biometrics.proto
+ byte[] dumpSensorServiceStateProto();
+
// This method prepares the service to start authenticating, but doesn't start authentication.
// This is protected by the MANAGE_BIOMETRIC signature permission. This method should only be
// called from BiometricService. The additional uid, pid, userId arguments should be determined
@@ -35,14 +46,13 @@ interface IBiometricAuthenticator {
// startPreparedClient().
void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- int cookie, int callingUid, int callingPid, int callingUserId);
+ int cookie);
// Starts authentication with the previously prepared client.
void startPreparedClient(int cookie);
// Cancels authentication.
- void cancelAuthenticationFromService(IBinder token, String opPackageName,
- int callingUid, int callingPid, int callingUserId);
+ void cancelAuthenticationFromService(IBinder token, String opPackageName);
// Determine if HAL is loaded and ready
boolean isHardwareDetected(String opPackageName);
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 005ed324da77..6f7bcb68cc8d 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -19,22 +19,28 @@ package android.hardware.biometrics;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IBiometricAuthenticator;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.PromptInfo;
+import android.hardware.biometrics.SensorPropertiesInternal;
/**
* Communication channel from AuthService to BiometricService.
* @hide
*/
interface IBiometricService {
+ // Creates a test session with the specified sensorId
+ ITestSession createTestSession(int sensorId, String opPackageName);
+
+ // Retrieve static sensor properties for all biometric sensors
+ List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
+
// Requests authentication. The service choose the appropriate biometric to use, and show
// the corresponding BiometricDialog.
void authenticate(IBinder token, long operationId, int userId,
- IBiometricServiceReceiver receiver, String opPackageName, in PromptInfo promptInfo,
- int callingUid, int callingPid, int callingUserId);
+ IBiometricServiceReceiver receiver, String opPackageName, in PromptInfo promptInfo);
// Cancel authentication for the given session.
- void cancelAuthentication(IBinder token, String opPackageName, int callingUid, int callingPid,
- int callingUserId);
+ void cancelAuthentication(IBinder token, String opPackageName);
// Checks if biometrics can be used.
int canAuthenticate(String opPackageName, int userId, int callingUserId, int authenticators);
diff --git a/core/java/android/hardware/biometrics/SensorProperties.java b/core/java/android/hardware/biometrics/SensorProperties.java
index 5b1b5e612c73..360f138815c0 100644
--- a/core/java/android/hardware/biometrics/SensorProperties.java
+++ b/core/java/android/hardware/biometrics/SensorProperties.java
@@ -81,4 +81,12 @@ public class SensorProperties {
public int getSensorStrength() {
return mSensorStrength;
}
+
+ /**
+ * Constructs a {@link SensorProperties} from the internal parcelable representation.
+ * @hide
+ */
+ public static SensorProperties from(SensorPropertiesInternal internalProp) {
+ return new SensorProperties(internalProp.sensorId, internalProp.sensorStrength);
+ }
}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 27cdda7b0723..c5c51e4661c5 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -17,6 +17,7 @@ package android.hardware.face;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.biometrics.ITestSession;
import android.hardware.face.IFaceServiceReceiver;
import android.hardware.face.Face;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -28,9 +29,19 @@ import android.view.Surface;
* @hide
*/
interface IFaceService {
+
+ // Creates a test session with the specified sensorId
+ ITestSession createTestSession(int sensorId, String opPackageName);
+
+ // Requests a proto dump of the service to the specified fd
+ byte[] dumpSensorServiceStateProto();
+
// Retrieve static sensor properties for all face sensors
List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
+ // Retrieve static sensor properties for the specified sensor
+ FaceSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
+
// Authenticate the given sessionId with a face
void authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
String opPackageName);
@@ -46,7 +57,7 @@ interface IFaceService {
// startPreparedClient().
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- int cookie, int callingUid, int callingPid, int callingUserId);
+ int cookie);
// Starts authentication with the previously prepared client.
void startPreparedClient(int sensorId, int cookie);
@@ -58,8 +69,7 @@ interface IFaceService {
void cancelFaceDetect(IBinder token, String opPackageName);
// Same as above, with extra arguments.
- void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName,
- int callingUid, int callingPid, int callingUserId);
+ void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName);
// Start face enrollment
void enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 2128d67f80ae..9248b08f260d 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -34,9 +34,15 @@ interface IFingerprintService {
// Creates a test session with the specified sensorId
ITestSession createTestSession(int sensorId, String opPackageName);
+ // Requests a proto dump of the service to the specified fd
+ byte[] dumpSensorServiceStateProto();
+
// Retrieve static sensor properties for all fingerprint sensors
List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
+ // Retrieve static sensor properties for the specified sensor
+ FingerprintSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
+
// Authenticate the given sessionId with a fingerprint. This is protected by
// USE_FINGERPRINT/USE_BIOMETRIC permission. This is effectively deprecated, since it only comes
// through FingerprintManager now.
@@ -54,8 +60,7 @@ 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,
- int callingUid, int callingPid, int callingUserId);
+ IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie);
// Starts authentication with the previously prepared client.
void startPreparedClient(int sensorId, int cookie);
@@ -68,8 +73,7 @@ interface IFingerprintService {
// Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes
// an additional uid, pid, userid.
- void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName,
- int callingUid, int callingPid, int callingUserId);
+ void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName);
// Start fingerprint enrollment
void enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver,
diff --git a/core/proto/android/server/biometrics.proto b/core/proto/android/server/biometrics.proto
new file mode 100644
index 000000000000..632c1e5d419e
--- /dev/null
+++ b/core/proto/android/server/biometrics.proto
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 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.
+ */
+
+syntax = "proto2";
+package com.android.server.biometrics;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "BiometricsProto";
+
+// Overall state of BiometricService (and not <Biometric>Service), including any
+// <Biomteric>Service(s), for example FingerprintService or FaceService.
+message BiometricServiceStateProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ enum AuthSessionState {
+ /**
+ * Authentication either just called and we have not transitioned to the CALLED state, or
+ * authentication terminated (success or error).
+ */
+ STATE_AUTH_IDLE = 0;
+
+ /**
+ * Authentication was called and we are waiting for the <Biometric>Services to return their
+ * cookies before starting the hardware and showing the BiometricPrompt.
+ */
+ STATE_AUTH_CALLED = 1;
+
+ /**
+ * Authentication started, BiometricPrompt is showing and the hardware is authenticating.
+ */
+ STATE_AUTH_STARTED = 2;
+
+ /**
+ * Same as {@link #STATE_AUTH_STARTED}, except the BiometricPrompt UI is done animating in.
+ */
+ STATE_AUTH_STARTED_UI_SHOWING = 3;
+
+ /**
+ * Authentication is paused, waiting for the user to press "try again" button. Only
+ * passive modalities such as Face or Iris should have this state. Note that for passive
+ * modalities, the HAL enters the idle state after onAuthenticated(false) which differs from
+ * fingerprint.
+ */
+ STATE_AUTH_PAUSED = 4;
+
+ /**
+ * Paused, but "try again" was pressed. Sensors have new cookies and we're now waiting for
+ * all cookies to be returned.
+ */
+ STATE_AUTH_PAUSED_RESUMING = 5;
+
+ /**
+ * Authentication is successful, but we're waiting for the user to press "confirm" button.
+ */
+ STATE_AUTH_PENDING_CONFIRM = 6;
+
+ /**
+ * Biometric authenticated, waiting for SysUI to finish animation
+ */
+ STATE_AUTHENTICATED_PENDING_SYSUI = 7;
+
+ /**
+ * Biometric error, waiting for SysUI to finish animation
+ */
+ STATE_ERROR_PENDING_SYSUI = 8;
+
+ /**
+ * Device credential in AuthController is showing
+ */
+ STATE_SHOWING_DEVICE_CREDENTIAL = 9;
+
+ /**
+ * The client binder died, and sensors were authenticating at the time. Cancel has been
+ * requested and we're waiting for the HAL(s) to send ERROR_CANCELED.
+ */
+ STATE_CLIENT_DIED_CANCELLING = 10;
+ }
+
+ repeated SensorServiceStateProto sensor_service_states = 1;
+
+ optional AuthSessionState auth_session_state = 2;
+}
+
+// Overall state for an instance of a <Biometric>Service, for example FingerprintService or
+// FaceService. Note that a single service may provide multiple sensors.
+message SensorServiceStateProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated SensorStateProto sensor_states = 1;
+}
+
+// State of a single sensor.
+message SensorStateProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Unique sensorId
+ optional int32 sensor_id = 1;
+
+ // State of the sensor's scheduler. True if currently handling an operation, false if idle.
+ optional bool is_busy = 2;
+
+ // User states for this sensor.
+ repeated UserStateProto user_states = 3;
+}
+
+// State of a specific user for a specific sensor.
+message UserStateProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Android user ID
+ optional int32 user_id = 1;
+
+ // Number of fingerprints enrolled
+ optional int32 num_enrolled = 2;
+} \ No newline at end of file
diff --git a/core/proto/android/server/fingerprint.proto b/core/proto/android/server/fingerprint.proto
index a49a1adcc619..e6b2df5d12ec 100644
--- a/core/proto/android/server/fingerprint.proto
+++ b/core/proto/android/server/fingerprint.proto
@@ -65,37 +65,4 @@ message PerformanceStatsProto {
// Total number of permanent lockouts.
optional int32 permanent_lockout = 5;
-}
-
-// Internal FingerprintService states. The above messages (FingerprintServiceDumpProto, etc)
-// are used for legacy metrics and should not be modified.
-message FingerprintServiceStateProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated SensorStateProto sensor_states = 1;
-}
-
-// State of a single sensor.
-message SensorStateProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Unique sensorId
- optional int32 sensor_id = 1;
-
- // State of the sensor's scheduler. True if currently handling an operation, false if idle.
- optional bool is_busy = 2;
-
- // User states for this sensor.
- repeated UserStateProto user_states = 3;
-}
-
-// State of a specific user for a specific sensor.
-message UserStateProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Android user ID
- optional int32 user_id = 1;
-
- // Number of fingerprints enrolled
- optional int32 num_enrolled = 2;
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 27b39c69758f..cf8bfbc547f8 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -29,6 +29,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
import static android.hardware.biometrics.BiometricManager.Authenticators;
+import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -37,7 +38,9 @@ import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceReceiver;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.PromptInfo;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.face.IFaceService;
import android.hardware.fingerprint.IFingerprintService;
import android.hardware.iris.IIrisService;
@@ -55,6 +58,8 @@ import com.android.server.biometrics.sensors.face.FaceAuthenticator;
import com.android.server.biometrics.sensors.fingerprint.FingerprintAuthenticator;
import com.android.server.biometrics.sensors.iris.IrisAuthenticator;
+import java.util.List;
+
/**
* System service that provides an interface for authenticating with biometrics and
* PIN/pattern/password to BiometricPrompt and lock screen.
@@ -138,6 +143,34 @@ public class AuthService extends SystemService {
private final class AuthServiceImpl extends IAuthService.Stub {
@Override
+ public ITestSession createTestSession(int sensorId, @NonNull String opPackageName)
+ throws RemoteException {
+ Utils.checkPermission(getContext(), TEST_BIOMETRIC);
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mInjector.getBiometricService().createTestSession(sensorId, opPackageName);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
+ throws RemoteException {
+ Utils.checkPermission(getContext(), TEST_BIOMETRIC);
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ // Get the result from BiometricService, since it is the source of truth for all
+ // biometric sensors.
+ return mInjector.getBiometricService().getSensorProperties(opPackageName);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public String getUiPackage() {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
@@ -185,8 +218,7 @@ public class AuthService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
mBiometricService.authenticate(
- token, sessionId, userId, receiver, opPackageName, promptInfo, callingUid,
- callingPid, callingUserId);
+ token, sessionId, userId, receiver, opPackageName, promptInfo);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -202,13 +234,9 @@ public class AuthService extends SystemService {
return;
}
- final int callingUid = Binder.getCallingUid();
- final int callingPid = Binder.getCallingPid();
- final int callingUserId = UserHandle.getCallingUserId();
final long identity = Binder.clearCallingIdentity();
try {
- mBiometricService.cancelAuthentication(token, opPackageName, callingUid,
- callingPid, callingUserId);
+ mBiometricService.cancelAuthentication(token, opPackageName);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 637a8963402e..efc025dd7b0c 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -20,6 +20,8 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
+import static com.android.server.biometrics.BiometricServiceStateProto.*;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -48,7 +50,6 @@ import com.android.internal.util.FrameworkStatsLog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@@ -61,60 +62,11 @@ public final class AuthSession implements IBinder.DeathRecipient {
private static final String TAG = "BiometricService/AuthSession";
private static final boolean DEBUG = false;
- /**
- * Authentication either just called and we have not transitioned to the CALLED state, or
- * authentication terminated (success or error).
- */
- static final int STATE_AUTH_IDLE = 0;
- /**
- * Authentication was called and we are waiting for the <Biometric>Services to return their
- * cookies before starting the hardware and showing the BiometricPrompt.
- */
- static final int STATE_AUTH_CALLED = 1;
- /**
- * Authentication started, BiometricPrompt is showing and the hardware is authenticating. At
- * this point, the BiometricPrompt UI has been requested, but is not necessarily done animating
- * in yet.
- */
- static final int STATE_AUTH_STARTED = 2;
- /**
- * Same as {@link #STATE_AUTH_STARTED}, except the BiometricPrompt UI is done animating in.
- */
- static final int STATE_AUTH_STARTED_UI_SHOWING = 3;
- /**
- * Authentication is paused, waiting for the user to press "try again" button. Only
- * passive modalities such as Face or Iris should have this state. Note that for passive
- * modalities, the HAL enters the idle state after onAuthenticated(false) which differs from
- * fingerprint.
- */
- static final int STATE_AUTH_PAUSED = 4;
- /**
- * Paused, but "try again" was pressed. Sensors have new cookies and we're now waiting for all
- * cookies to be returned.
- */
- static final int STATE_AUTH_PAUSED_RESUMING = 5;
- /**
- * Authentication is successful, but we're waiting for the user to press "confirm" button.
- */
- static final int STATE_AUTH_PENDING_CONFIRM = 6;
- /**
- * Biometric authenticated, waiting for SysUI to finish animation
- */
- static final int STATE_AUTHENTICATED_PENDING_SYSUI = 7;
- /**
- * Biometric error, waiting for SysUI to finish animation
- */
- static final int STATE_ERROR_PENDING_SYSUI = 8;
- /**
- * Device credential in AuthController is showing
- */
- static final int STATE_SHOWING_DEVICE_CREDENTIAL = 9;
- /**
- * The client binder died, and sensors were authenticating at the time. Cancel has been
- * requested and we're waiting for the HAL(s) to send ERROR_CANCELED.
- */
- static final int STATE_CLIENT_DIED_CANCELLING = 10;
+
+ /*
+ * Defined in biometrics.proto
+ */
@IntDef({
STATE_AUTH_IDLE,
STATE_AUTH_CALLED,
@@ -157,9 +109,6 @@ public final class AuthSession implements IBinder.DeathRecipient {
// Original receiver from BiometricPrompt.
private final IBiometricServiceReceiver mClientReceiver;
private final String mOpPackageName;
- private final int mCallingUid;
- private final int mCallingPid;
- private final int mCallingUserId;
private final boolean mDebugEnabled;
private final List<FingerprintSensorPropertiesInternal> mFingerprintSensorProperties;
@@ -191,9 +140,6 @@ public final class AuthSession implements IBinder.DeathRecipient {
@NonNull IBiometricServiceReceiver clientReceiver,
@NonNull String opPackageName,
@NonNull PromptInfo promptInfo,
- int callingUid,
- int callingPid,
- int callingUserId,
boolean debugEnabled,
@NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties) {
mContext = context;
@@ -210,9 +156,6 @@ public final class AuthSession implements IBinder.DeathRecipient {
mClientReceiver = clientReceiver;
mOpPackageName = opPackageName;
mPromptInfo = promptInfo;
- mCallingUid = callingUid;
- mCallingPid = callingPid;
- mCallingUserId = callingUserId;
mDebugEnabled = debugEnabled;
mFingerprintSensorProperties = fingerprintSensorProperties;
@@ -254,8 +197,7 @@ 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, mCallingUid, mCallingPid,
- mCallingUserId);
+ mUserId, mSensorReceiver, mOpPackageName, cookie);
}
}
@@ -264,7 +206,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
// Only device credential should be shown. In this case, we don't need to wait,
// since LockSettingsService/Gatekeeper is always ready to check for credential.
// SystemUI invokes that path.
- mState = AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL;
+ mState = STATE_SHOWING_DEVICE_CREDENTIAL;
mStatusBarService.showAuthenticationDialog(
mPromptInfo,
@@ -278,7 +220,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
} else if (!mPreAuthInfo.eligibleSensors.isEmpty()) {
// Some combination of biometric or biometric|credential is requested
setSensorsToStateWaitingForCookie();
- mState = AuthSession.STATE_AUTH_CALLED;
+ mState = STATE_AUTH_CALLED;
} else {
// No authenticators requested. This should never happen - an exception should have
// been thrown earlier in the pipeline.
@@ -386,8 +328,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
// sending the final error callback to the application.
for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
try {
- sensor.goToStateCancelling(mToken, mOpPackageName, mCallingUid, mCallingPid,
- mCallingUserId);
+ sensor.goToStateCancelling(mToken, mOpPackageName);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to cancel authentication");
}
@@ -429,7 +370,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
authenticators = Utils.removeBiometricBits(authenticators);
mPromptInfo.setAuthenticators(authenticators);
- mState = AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL;
+ mState = STATE_SHOWING_DEVICE_CREDENTIAL;
mStatusBarService.showAuthenticationDialog(
mPromptInfo,
@@ -453,7 +394,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|| error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
if (isAllowDeviceCredential() && errorLockout) {
// SystemUI handles transition from biometric to device credential.
- mState = AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL;
+ mState = STATE_SHOWING_DEVICE_CREDENTIAL;
mStatusBarService.onBiometricError(modality, error, vendorCode);
} else if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
mStatusBarService.hideAuthenticationDialog();
@@ -463,7 +404,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mClientReceiver.onError(modality, error, vendorCode);
return true;
} else {
- mState = AuthSession.STATE_ERROR_PENDING_SYSUI;
+ mState = STATE_ERROR_PENDING_SYSUI;
mStatusBarService.onBiometricError(modality, error, vendorCode);
}
break;
@@ -582,7 +523,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
if (hasPausableBiometric()) {
// Pause authentication. onBiometricAuthenticated(false) causes the
// dialog to show a "try again" button for passive modalities.
- mState = AuthSession.STATE_AUTH_PAUSED;
+ mState = STATE_AUTH_PAUSED;
}
mClientReceiver.onAuthenticationFailed();
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index 09d058383e78..17ec11233c4e 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -16,6 +16,8 @@
package com.android.server.biometrics;
+import static android.hardware.biometrics.BiometricManager.Authenticators;
+
import android.annotation.IntDef;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
@@ -61,11 +63,11 @@ public abstract class BiometricSensor {
@interface SensorState {}
public final int id;
- public final int oemStrength; // strength as configured by the OEM
+ public final @Authenticators.Types int oemStrength; // strength as configured by the OEM
public final int modality;
public final IBiometricAuthenticator impl;
- private int mUpdatedStrength; // strength updated by BiometricStrengthController
+ private @Authenticators.Types int mUpdatedStrength; // updated by BiometricStrengthController
private @SensorState int mSensorState;
private @BiometricConstants.Errors int mError;
@@ -82,7 +84,7 @@ public abstract class BiometricSensor {
*/
abstract boolean confirmationSupported();
- BiometricSensor(int id, int modality, int strength,
+ BiometricSensor(int id, int modality, @Authenticators.Types int strength,
IBiometricAuthenticator impl) {
this.id = id;
this.modality = modality;
@@ -101,12 +103,11 @@ public abstract class BiometricSensor {
void goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- int cookie, int callingUid, int callingPid, int callingUserId)
+ int cookie)
throws RemoteException {
mCookie = cookie;
impl.prepareForAuthentication(requireConfirmation, token,
- sessionId, userId, sensorReceiver, opPackageName, mCookie,
- callingUid, callingPid, callingUserId);
+ sessionId, userId, sensorReceiver, opPackageName, mCookie);
mSensorState = STATE_WAITING_FOR_COOKIE;
}
@@ -122,10 +123,8 @@ public abstract class BiometricSensor {
mSensorState = STATE_AUTHENTICATING;
}
- void goToStateCancelling(IBinder token, String opPackageName, int callingUid,
- int callingPid, int callingUserId) throws RemoteException {
- impl.cancelAuthenticationFromService(token, opPackageName, callingUid, callingPid,
- callingUserId);
+ void goToStateCancelling(IBinder token, String opPackageName) throws RemoteException {
+ impl.cancelAuthenticationFromService(token, opPackageName);
mSensorState = STATE_CANCELING;
}
@@ -143,7 +142,7 @@ public abstract class BiometricSensor {
* strength.
* @return a bitfield, see {@link BiometricManager.Authenticators}
*/
- int getCurrentStrength() {
+ @Authenticators.Types int getCurrentStrength() {
return oemStrength | mUpdatedStrength;
}
@@ -160,7 +159,7 @@ public abstract class BiometricSensor {
* is checked.
* @param newStrength
*/
- void updateStrength(int newStrength) {
+ void updateStrength(@Authenticators.Types int newStrength) {
String log = "updateStrength: Before(" + toString() + ")";
mUpdatedStrength = newStrength;
log += " After(" + toString() + ")";
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 196582a6c0d6..a471664b19b7 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -19,6 +19,9 @@ package com.android.server.biometrics;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricManager.Authenticators;
+import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;
+
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IActivityManager;
@@ -38,7 +41,9 @@ import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IBiometricSysuiReceiver;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.PromptInfo;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.net.Uri;
@@ -56,6 +61,7 @@ import android.security.KeyStore;
import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -185,10 +191,7 @@ public class BiometricService extends SystemService {
args.argi1 /* userid */,
(IBiometricServiceReceiver) args.arg3 /* receiver */,
(String) args.arg4 /* opPackageName */,
- (PromptInfo) args.arg5 /* promptInfo */,
- args.argi2 /* callingUid */,
- args.argi3 /* callingPid */,
- args.argi4 /* callingUserId */);
+ (PromptInfo) args.arg5 /* promptInfo */);
args.recycle();
break;
}
@@ -476,6 +479,34 @@ public class BiometricService extends SystemService {
*/
private final class BiometricServiceWrapper extends IBiometricService.Stub {
@Override // Binder call
+ public ITestSession createTestSession(int sensorId, @NonNull String opPackageName)
+ throws RemoteException {
+ checkInternalPermission();
+
+ for (BiometricSensor sensor : mSensors) {
+ if (sensor.id == sensorId) {
+ return sensor.impl.createTestSession(opPackageName);
+ }
+ }
+
+ Slog.e(TAG, "Unknown sensor for createTestSession: " + sensorId);
+ return null;
+ }
+
+ @Override // Binder call
+ public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
+ throws RemoteException {
+ checkInternalPermission();
+
+ final List<SensorPropertiesInternal> sensors = new ArrayList<>();
+ for (BiometricSensor sensor : mSensors) {
+ sensors.add(sensor.impl.getSensorProperties(opPackageName));
+ }
+
+ return sensors;
+ }
+
+ @Override // Binder call
public void onReadyForAuthentication(int cookie) {
checkInternalPermission();
@@ -486,8 +517,7 @@ public class BiometricService extends SystemService {
@Override // Binder call
public void authenticate(IBinder token, long operationId, int userId,
- IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo,
- int callingUid, int callingPid, int callingUserId) {
+ IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
checkInternalPermission();
if (token == null || receiver == null || opPackageName == null || promptInfo == null) {
@@ -516,16 +546,12 @@ public class BiometricService extends SystemService {
args.arg3 = receiver;
args.arg4 = opPackageName;
args.arg5 = promptInfo;
- args.argi2 = callingUid;
- args.argi3 = callingPid;
- args.argi4 = callingUserId;
mHandler.obtainMessage(MSG_AUTHENTICATE, args).sendToTarget();
}
@Override // Binder call
- public void cancelAuthentication(IBinder token, String opPackageName,
- int callingUid, int callingPid, int callingUserId) {
+ public void cancelAuthentication(IBinder token, String opPackageName) {
checkInternalPermission();
mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION).sendToTarget();
@@ -577,7 +603,7 @@ public class BiometricService extends SystemService {
}
@Override
- public void registerAuthenticator(int id, int modality, int strength,
+ public void registerAuthenticator(int id, int modality, @Authenticators.Types int strength,
IBiometricAuthenticator authenticator) {
checkInternalPermission();
@@ -677,14 +703,28 @@ public class BiometricService extends SystemService {
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
return;
}
final long ident = Binder.clearCallingIdentity();
try {
- dumpInternal(pw);
+ if (args.length > 0 && "--proto".equals(args[0])) {
+ final ProtoOutputStream proto = new ProtoOutputStream(fd);
+ proto.write(BiometricServiceStateProto.AUTH_SESSION_STATE,
+ mCurrentAuthSession != null ? mCurrentAuthSession.getState()
+ : STATE_AUTH_IDLE);
+ for (BiometricSensor sensor : mSensors) {
+ byte[] serviceState = sensor.impl.dumpSensorServiceStateProto();
+ proto.write(BiometricServiceStateProto.SENSOR_SERVICE_STATES, serviceState);
+ }
+ proto.flush();
+ } else {
+ dumpInternal(pw);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -992,8 +1032,7 @@ public class BiometricService extends SystemService {
}
private void handleAuthenticate(IBinder token, long operationId, int userId,
- IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo,
- int callingUid, int callingPid, int callingUserId) {
+ IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
mHandler.post(() -> {
try {
@@ -1017,7 +1056,7 @@ public class BiometricService extends SystemService {
}
authenticateInternal(token, operationId, userId, receiver, opPackageName,
- promptInfo, callingUid, callingPid, callingUserId, preAuthInfo);
+ promptInfo, preAuthInfo);
} else {
receiver.onError(preAuthStatus.first /* modality */,
preAuthStatus.second /* errorCode */,
@@ -1040,7 +1079,7 @@ public class BiometricService extends SystemService {
*/
private void authenticateInternal(IBinder token, long operationId, int userId,
IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo,
- int callingUid, int callingPid, int callingUserId, PreAuthInfo preAuthInfo) {
+ PreAuthInfo preAuthInfo) {
Slog.d(TAG, "Creating authSession with authRequest: " + preAuthInfo);
// No need to dismiss dialog / send error yet if we're continuing authentication, e.g.
@@ -1057,8 +1096,7 @@ public class BiometricService extends SystemService {
final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId);
mCurrentAuthSession = new AuthSession(getContext(), mStatusBarService, mSysuiReceiver,
mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, token, operationId, userId,
- mBiometricSensorReceiver, receiver, opPackageName, promptInfo, callingUid,
- callingPid, callingUserId, debugEnabled,
+ mBiometricSensorReceiver, receiver, opPackageName, promptInfo, debugEnabled,
mInjector.getFingerprintSensorProperties(getContext()));
try {
mCurrentAuthSession.goToInitialState();
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index b3e6cad0e666..62c9295adda5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -16,8 +16,11 @@
package com.android.server.biometrics.sensors.face;
+import android.annotation.NonNull;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
+import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.face.IFaceService;
import android.os.IBinder;
import android.os.RemoteException;
@@ -32,20 +35,34 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
private final IFaceService mFaceService;
private final int mSensorId;
- public FaceAuthenticator(IFaceService faceService, int sensorId)
- throws RemoteException {
+ public FaceAuthenticator(IFaceService faceService, int sensorId) throws RemoteException {
mFaceService = faceService;
mSensorId = sensorId;
}
@Override
+ public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException {
+ return mFaceService.createTestSession(mSensorId, opPackageName);
+ }
+
+ @Override
+ public SensorPropertiesInternal getSensorProperties(@NonNull String opPackageName)
+ throws RemoteException {
+ return mFaceService.getSensorProperties(mSensorId, opPackageName);
+ }
+
+ @Override
+ public byte[] dumpSensorServiceStateProto() throws RemoteException {
+ return mFaceService.dumpSensorServiceStateProto();
+ }
+
+ @Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, int cookie, int callingUid, int callingPid, int callingUserId)
+ String opPackageName, int cookie)
throws RemoteException {
mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
- userId, sensorReceiver, opPackageName, cookie, callingUid, callingPid,
- callingUserId);
+ userId, sensorReceiver, opPackageName, cookie);
}
@Override
@@ -54,10 +71,9 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
}
@Override
- public void cancelAuthenticationFromService(IBinder token, String opPackageName, int callingUid,
- int callingPid, int callingUserId) throws RemoteException {
- mFaceService.cancelAuthenticationFromService(mSensorId, token, opPackageName, callingUid,
- callingPid, callingUserId);
+ public void cancelAuthenticationFromService(IBinder token, String opPackageName)
+ throws RemoteException {
+ mFaceService.cancelAuthenticationFromService(mSensorId, token, opPackageName);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 1e0764a275c5..4906aacd06c0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -29,6 +29,7 @@ import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.face.Face;
@@ -38,8 +39,8 @@ import android.hardware.face.IFaceServiceReceiver;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Process;
import android.os.NativeHandle;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -140,6 +141,34 @@ public class FaceService extends SystemService implements BiometricServiceCallba
* Receives the incoming binder calls from FaceManager.
*/
private final class FaceServiceWrapper extends IFaceService.Stub {
+ @Override
+ public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
+
+ if (provider == null) {
+ Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
+ return null;
+ }
+
+ return provider.createTestSession(sensorId, opPackageName);
+ }
+
+ @Override
+ public byte[] dumpSensorServiceStateProto() {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+ final ProtoOutputStream proto = new ProtoOutputStream();
+ for (ServiceProvider provider : mServiceProviders) {
+ for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
+ provider.dumpProtoState(props.sensorId, proto);
+ }
+ }
+ proto.flush();
+ return proto.getBytes();
+ }
+
@Override // Binder call
public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
String opPackageName) {
@@ -154,6 +183,21 @@ public class FaceService extends SystemService implements BiometricServiceCallba
}
@Override // Binder call
+ public FaceSensorPropertiesInternal getSensorProperties(int sensorId,
+ @NonNull String opPackageName) {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
+ if (provider == null) {
+ Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
+ + ", caller: " + opPackageName);
+ return null;
+ }
+
+ return provider.getSensorProperties(sensorId);
+ }
+
+ @Override // Binder call
public void generateChallenge(IBinder token, int sensorId, int userId,
IFaceServiceReceiver receiver, String opPackageName) {
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
@@ -270,8 +314,7 @@ 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,
- int callingUid, int callingPid, int callingUserId) {
+ IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -326,7 +369,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba
@Override // Binder call
public void cancelAuthenticationFromService(int sensorId, final IBinder token,
- final String opPackageName, int callingUid, int callingPid, int callingUserId) {
+ final String opPackageName) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index e3fb750a1e14..d1578fa7bbf3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -18,7 +18,9 @@ package com.android.server.biometrics.sensors.face;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.hardware.biometrics.ITestSession;
import android.hardware.face.Face;
+import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceServiceReceiver;
import android.os.IBinder;
@@ -61,6 +63,9 @@ public interface ServiceProvider {
List<FaceSensorPropertiesInternal> getSensorProperties();
@NonNull
+ FaceSensorPropertiesInternal getSensorProperties(int sensorId);
+
+ @NonNull
List<Face> getEnrolledFaces(int sensorId, int userId);
@LockoutTracker.LockoutMode
@@ -110,4 +115,7 @@ public interface ServiceProvider {
void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
void dumpInternal(int sensorId, @NonNull PrintWriter pw);
+
+ @NonNull
+ ITestSession createTestSession(int sensorId, @NonNull String opPackageName);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 590579adbe1a..01c16fd1f4a6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -24,6 +24,7 @@ import android.app.IActivityTaskManager;
import android.app.TaskStackListener;
import android.content.Context;
import android.content.pm.UserInfo;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.face.Face;
@@ -254,6 +255,12 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
@NonNull
@Override
+ public FaceSensorPropertiesInternal getSensorProperties(int sensorId) {
+ return mSensors.get(sensorId).getSensorProperties();
+ }
+
+ @NonNull
+ @Override
public List<Face> getEnrolledFaces(int sensorId, int userId) {
return FaceUtils.getInstance(sensorId).getBiometricsForUser(mContext, userId);
}
@@ -566,6 +573,12 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
mUsageStats.print(pw);
}
+ @NonNull
+ @Override
+ public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
+ return null; // TODO
+ }
+
@Override
public void binderDied() {
Slog.e(getTag(), "HAL died");
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
new file mode 100644
index 000000000000..4c983fb5fa6c
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 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 com.android.server.biometrics.sensors.face.hidl;
+
+import static android.Manifest.permission.TEST_BIOMETRIC;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.hardware.biometrics.ITestSession;
+import android.hardware.face.Face;
+import android.hardware.face.IFaceServiceReceiver;
+import android.os.Binder;
+import android.util.Slog;
+
+import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.sensors.face.FaceUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+public class BiometricTestSessionImpl extends ITestSession.Stub {
+ private static final String TAG = "BiometricTestSessionImpl";
+
+ @NonNull private final Context mContext;
+ private final int mSensorId;
+ @NonNull private final Face10 mFace10;
+ @NonNull private final Face10.HalResultController mHalResultController;
+ @NonNull private final Set<Integer> mEnrollmentIds;
+ @NonNull private final Random mRandom;
+
+ private final IFaceServiceReceiver mReceiver = new IFaceServiceReceiver.Stub() {
+ @Override
+ public void onEnrollResult(Face face, int remaining) {
+
+ }
+
+ @Override
+ public void onAcquired(int acquiredInfo, int vendorCode) {
+
+ }
+
+ @Override
+ public void onAuthenticationSucceeded(Face face, int userId, boolean isStrongBiometric) {
+
+ }
+
+ @Override
+ public void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric) {
+
+ }
+
+ @Override
+ public void onAuthenticationFailed() {
+
+ }
+
+ @Override
+ public void onError(int error, int vendorCode) {
+
+ }
+
+ @Override
+ public void onRemoved(Face face, int remaining) {
+
+ }
+
+ @Override
+ public void onFeatureSet(boolean success, int feature) {
+
+ }
+
+ @Override
+ public void onFeatureGet(boolean success, int feature, boolean value) {
+
+ }
+
+ @Override
+ public void onChallengeGenerated(int sensorId, long challenge) {
+
+ }
+
+ @Override
+ public void onChallengeInterrupted(int sensorId) {
+
+ }
+
+ @Override
+ public void onChallengeInterruptFinished(int sensorId) {
+
+ }
+ };
+
+ BiometricTestSessionImpl(@NonNull Context context, int sensorId, @NonNull Face10 face10,
+ @NonNull Face10.HalResultController halResultController) {
+ mContext = context;
+ mSensorId = sensorId;
+ mFace10 = face10;
+ mHalResultController = halResultController;
+ mEnrollmentIds = new HashSet<>();
+ mRandom = new Random();
+ }
+
+ @Override
+ public void setTestHalEnabled(boolean enabled) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ mFace10.setTestHalEnabled(enabled);
+ }
+
+ @Override
+ public void startEnroll(int userId) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ mFace10.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
+ mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
+ null /* surfaceHandle */);
+ }
+
+ @Override
+ public void finishEnroll(int userId) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ int nextRandomId = mRandom.nextInt();
+ while (mEnrollmentIds.contains(nextRandomId)) {
+ nextRandomId = mRandom.nextInt();
+ }
+
+ mEnrollmentIds.add(nextRandomId);
+ mHalResultController.onEnrollResult(0 /* deviceId */,
+ nextRandomId /* faceId */, userId, 0);
+ }
+
+ @Override
+ public void acceptAuthentication(int userId) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ // Fake authentication with any of the existing fingers
+ List<Face> faces = FaceUtils.getInstance().getBiometricsForUser(mContext, userId);
+ if (faces.isEmpty()) {
+ Slog.w(TAG, "No faces, returning");
+ return;
+ }
+ final int fid = faces.get(0).getBiometricId();
+ final ArrayList<Byte> hat = new ArrayList<>(Collections.nCopies(69, (byte) 0));
+ mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
+ }
+
+ @Override
+ public void rejectAuthentication(int userId) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* faceId */, userId, null);
+ }
+
+ @Override
+ public void notifyAcquired(int userId, int acquireInfo) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ mHalResultController.onAcquired(0 /* deviceId */, userId, acquireInfo, 0 /* vendorCode */);
+ }
+
+ @Override
+ public void notifyError(int userId, int errorCode) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ mHalResultController.onError(0 /* deviceId */, userId, errorCode, 0 /* vendorCode */);
+ }
+
+ @Override
+ public void cleanupInternalState(int userId) {
+ Utils.checkPermission(mContext, TEST_BIOMETRIC);
+
+ mFace10.scheduleInternalCleanup(mSensorId, userId);
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 7b70bd8a8730..27ca33de415d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -28,6 +28,7 @@ import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
import android.hardware.face.Face;
@@ -51,6 +52,9 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.SensorServiceStateProto;
+import com.android.server.biometrics.SensorStateProto;
+import com.android.server.biometrics.UserStateProto;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
@@ -67,6 +71,7 @@ import com.android.server.biometrics.sensors.face.FaceUtils;
import com.android.server.biometrics.sensors.face.LockoutHalImpl;
import com.android.server.biometrics.sensors.face.ServiceProvider;
import com.android.server.biometrics.sensors.face.UsageStats;
+import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import org.json.JSONArray;
import org.json.JSONException;
@@ -93,6 +98,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
static final String NOTIFICATION_TAG = "FaceService";
static final int NOTIFICATION_ID = 1;
+ private boolean mTestHalEnabled;
+
@NonNull private final FaceSensorPropertiesInternal mSensorProperties;
@NonNull private final Context mContext;
@NonNull private final BiometricScheduler mScheduler;
@@ -104,6 +111,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
@NonNull private final NotificationManager mNotificationManager;
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
@Nullable private IBiometricsFace mDaemon;
+ @NonNull private final HalResultController mHalResultController;
// If a challenge is generated, keep track of its owner. Since IBiometricsFace@1.0 only
// supports a single in-flight challenge, we must notify the interrupted owner that its
// challenge is no longer valid. The interrupted owner will be notified when the interrupter
@@ -122,174 +130,207 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
};
- private final IBiometricsFaceClientCallback mDaemonCallback =
- new IBiometricsFaceClientCallback.Stub() {
- @Override
- public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
- mHandler.post(() -> {
- final CharSequence name = FaceUtils.getInstance()
- .getUniqueName(mContext, userId);
- final Face face = new Face(name, faceId, deviceId);
-
- final ClientMonitor<?> client = mScheduler.getCurrentClient();
- if (!(client instanceof FaceEnrollClient)) {
- Slog.e(TAG, "onEnrollResult for non-enroll client: "
- + Utils.getClientName(client));
- return;
- }
+ public static class HalResultController extends IBiometricsFaceClientCallback.Stub {
+ /**
+ * Interface to sends results to the HalResultController's owner.
+ */
+ public interface Callback {
+ /**
+ * Invoked when the HAL sends ERROR_HW_UNAVAILABLE.
+ */
+ void onHardwareUnavailable();
+ }
- final FaceEnrollClient enrollClient = (FaceEnrollClient) client;
- enrollClient.onEnrollResult(face, remaining);
- });
- }
+ private final int mSensorId;
+ @NonNull private final Context mContext;
+ @NonNull private final Handler mHandler;
+ @NonNull private final BiometricScheduler mScheduler;
+ @Nullable private Callback mCallback;
+ @NonNull private final LockoutHalImpl mLockoutTracker;
+ @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
+
+ HalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
+ @NonNull BiometricScheduler scheduler, @NonNull LockoutHalImpl lockoutTracker,
+ @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
+ mSensorId = sensorId;
+ mContext = context;
+ mHandler = handler;
+ mScheduler = scheduler;
+ mLockoutTracker = lockoutTracker;
+ mLockoutResetDispatcher = lockoutResetDispatcher;
+ }
- @Override
- public void onAuthenticated(long deviceId, int faceId, int userId,
- ArrayList<Byte> token) {
- mHandler.post(() -> {
- final ClientMonitor<?> client = mScheduler.getCurrentClient();
- if (!(client instanceof AuthenticationConsumer)) {
- Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
- + Utils.getClientName(client));
- return;
- }
+ public void setCallback(@Nullable Callback callback) {
+ mCallback = callback;
+ }
- final AuthenticationConsumer authenticationConsumer =
- (AuthenticationConsumer) client;
- final boolean authenticated = faceId != 0;
- final Face face = new Face("", faceId, deviceId);
- authenticationConsumer.onAuthenticated(face, authenticated, token);
- });
+ @Override
+ public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
+ mHandler.post(() -> {
+ final CharSequence name = FaceUtils.getInstance()
+ .getUniqueName(mContext, userId);
+ final Face face = new Face(name, faceId, deviceId);
+
+ final ClientMonitor<?> client = mScheduler.getCurrentClient();
+ if (!(client instanceof FaceEnrollClient)) {
+ Slog.e(TAG, "onEnrollResult for non-enroll client: "
+ + Utils.getClientName(client));
+ return;
}
- @Override
- public void onAcquired(long deviceId, int userId, int acquiredInfo,
- int vendorCode) {
- mHandler.post(() -> {
- final ClientMonitor<?> client = mScheduler.getCurrentClient();
- if (!(client instanceof AcquisitionClient)) {
- Slog.e(TAG, "onAcquired for non-acquire client: "
- + Utils.getClientName(client));
- return;
- }
+ final FaceEnrollClient enrollClient = (FaceEnrollClient) client;
+ enrollClient.onEnrollResult(face, remaining);
+ });
+ }
- final AcquisitionClient<?> acquisitionClient =
- (AcquisitionClient<?>) client;
- acquisitionClient.onAcquired(acquiredInfo, vendorCode);
- });
+ @Override
+ public void onAuthenticated(long deviceId, int faceId, int userId,
+ ArrayList<Byte> token) {
+ mHandler.post(() -> {
+ final ClientMonitor<?> client = mScheduler.getCurrentClient();
+ if (!(client instanceof AuthenticationConsumer)) {
+ Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
+ + Utils.getClientName(client));
+ return;
}
- @Override
- public void onError(long deviceId, int userId, int error, int vendorCode) {
- mHandler.post(() -> {
- final ClientMonitor<?> client = mScheduler.getCurrentClient();
- Slog.d(TAG, "handleError"
- + ", client: " + (client != null ? client.getOwnerString() : null)
- + ", error: " + error
- + ", vendorCode: " + vendorCode);
- if (!(client instanceof Interruptable)) {
- Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(
- client));
- return;
- }
+ final AuthenticationConsumer authenticationConsumer =
+ (AuthenticationConsumer) client;
+ final boolean authenticated = faceId != 0;
+ final Face face = new Face("", faceId, deviceId);
+ authenticationConsumer.onAuthenticated(face, authenticated, token);
+ });
+ }
+
+ @Override
+ public void onAcquired(long deviceId, int userId, int acquiredInfo,
+ int vendorCode) {
+ mHandler.post(() -> {
+ final ClientMonitor<?> client = mScheduler.getCurrentClient();
+ if (!(client instanceof AcquisitionClient)) {
+ Slog.e(TAG, "onAcquired for non-acquire client: "
+ + Utils.getClientName(client));
+ return;
+ }
- final Interruptable interruptable = (Interruptable) client;
- interruptable.onError(error, vendorCode);
+ final AcquisitionClient<?> acquisitionClient =
+ (AcquisitionClient<?>) client;
+ acquisitionClient.onAcquired(acquiredInfo, vendorCode);
+ });
+ }
- if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
- Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
- mDaemon = null;
- mCurrentUserId = UserHandle.USER_NULL;
- }
- });
+ @Override
+ public void onError(long deviceId, int userId, int error, int vendorCode) {
+ mHandler.post(() -> {
+ final ClientMonitor<?> client = mScheduler.getCurrentClient();
+ Slog.d(TAG, "handleError"
+ + ", client: " + (client != null ? client.getOwnerString() : null)
+ + ", error: " + error
+ + ", vendorCode: " + vendorCode);
+ if (!(client instanceof Interruptable)) {
+ Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(
+ client));
+ return;
}
- @Override
- public void onRemoved(long deviceId, ArrayList<Integer> removed, int userId) {
- mHandler.post(() -> {
- final ClientMonitor<?> client = mScheduler.getCurrentClient();
- if (!(client instanceof RemovalConsumer)) {
- Slog.e(TAG, "onRemoved for non-removal consumer: "
- + Utils.getClientName(client));
- return;
- }
+ final Interruptable interruptable = (Interruptable) client;
+ interruptable.onError(error, vendorCode);
- final RemovalConsumer removalConsumer = (RemovalConsumer) client;
-
- if (!removed.isEmpty()) {
- // Convert to old fingerprint-like behavior, where remove() receives
- // one removal
- // at a time. This way, remove can share some more common code.
- for (int i = 0; i < removed.size(); i++) {
- final int id = removed.get(i);
- final Face face = new Face("", id, deviceId);
- final int remaining = removed.size() - i - 1;
- Slog.d(TAG, "Removed, faceId: " + id + ", remaining: " + remaining);
- removalConsumer.onRemoved(face, remaining);
- }
- } else {
- removalConsumer.onRemoved(null, 0 /* remaining */);
- }
+ if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
+ Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
+ if (mCallback != null) {
+ mCallback.onHardwareUnavailable();
+ }
+ }
+ });
+ }
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
- });
+ @Override
+ public void onRemoved(long deviceId, ArrayList<Integer> removed, int userId) {
+ mHandler.post(() -> {
+ final ClientMonitor<?> client = mScheduler.getCurrentClient();
+ if (!(client instanceof RemovalConsumer)) {
+ Slog.e(TAG, "onRemoved for non-removal consumer: "
+ + Utils.getClientName(client));
+ return;
}
- @Override
- public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId) {
- mHandler.post(() -> {
- final ClientMonitor<?> client = mScheduler.getCurrentClient();
- if (!(client instanceof EnumerateConsumer)) {
- Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
- + Utils.getClientName(client));
- return;
- }
+ final RemovalConsumer removalConsumer = (RemovalConsumer) client;
+
+ if (!removed.isEmpty()) {
+ // Convert to old fingerprint-like behavior, where remove() receives
+ // one removal
+ // at a time. This way, remove can share some more common code.
+ for (int i = 0; i < removed.size(); i++) {
+ final int id = removed.get(i);
+ final Face face = new Face("", id, deviceId);
+ final int remaining = removed.size() - i - 1;
+ Slog.d(TAG, "Removed, faceId: " + id + ", remaining: " + remaining);
+ removalConsumer.onRemoved(face, remaining);
+ }
+ } else {
+ removalConsumer.onRemoved(null, 0 /* remaining */);
+ }
- final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
+ });
+ }
- if (!faceIds.isEmpty()) {
- // Convert to old fingerprint-like behavior, where enumerate()
- // receives one
- // template at a time. This way, enumerate can share some more common
- // code.
- for (int i = 0; i < faceIds.size(); i++) {
- final Face face = new Face("", faceIds.get(i), deviceId);
- enumerateConsumer.onEnumerationResult(face, faceIds.size() - i - 1);
- }
- } else {
- // For face, the HIDL contract is to receive an empty list when there
- // are no
- // templates enrolled. Send a null identifier since we don't consume
- // them
- // anywhere, and send remaining == 0 so this code can be shared with
- // Fingerprint@2.1
- enumerateConsumer.onEnumerationResult(null /* identifier */, 0);
- }
- });
+ @Override
+ public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId) {
+ mHandler.post(() -> {
+ final ClientMonitor<?> client = mScheduler.getCurrentClient();
+ if (!(client instanceof EnumerateConsumer)) {
+ Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
+ + Utils.getClientName(client));
+ return;
}
- @Override
- public void onLockoutChanged(long duration) {
- mHandler.post(() -> {
- Slog.d(TAG, "onLockoutChanged: " + duration);
- final @LockoutTracker.LockoutMode int lockoutMode;
- if (duration == 0) {
- lockoutMode = LockoutTracker.LOCKOUT_NONE;
- } else if (duration == -1 || duration == Long.MAX_VALUE) {
- lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
- } else {
- lockoutMode = LockoutTracker.LOCKOUT_TIMED;
- }
+ final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
- mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
+ if (!faceIds.isEmpty()) {
+ // Convert to old fingerprint-like behavior, where enumerate()
+ // receives one
+ // template at a time. This way, enumerate can share some more common
+ // code.
+ for (int i = 0; i < faceIds.size(); i++) {
+ final Face face = new Face("", faceIds.get(i), deviceId);
+ enumerateConsumer.onEnumerationResult(face, faceIds.size() - i - 1);
+ }
+ } else {
+ // For face, the HIDL contract is to receive an empty list when there
+ // are no
+ // templates enrolled. Send a null identifier since we don't consume
+ // them
+ // anywhere, and send remaining == 0 so this code can be shared with
+ // Fingerprint@2.1
+ enumerateConsumer.onEnumerationResult(null /* identifier */, 0);
+ }
+ });
+ }
- if (duration == 0) {
- mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorId);
- }
- });
+ @Override
+ public void onLockoutChanged(long duration) {
+ mHandler.post(() -> {
+ Slog.d(TAG, "onLockoutChanged: " + duration);
+ final @LockoutTracker.LockoutMode int lockoutMode;
+ if (duration == 0) {
+ lockoutMode = LockoutTracker.LOCKOUT_NONE;
+ } else if (duration == -1 || duration == Long.MAX_VALUE) {
+ lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
+ } else {
+ lockoutMode = LockoutTracker.LOCKOUT_TIMED;
+ }
+
+ mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
+
+ if (duration == 0) {
+ mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorId);
}
- };
+ });
+ }
+ }
@VisibleForTesting
public Face10(@NonNull Context context, int sensorId,
@@ -309,6 +350,12 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
mNotificationManager = mContext.getSystemService(NotificationManager.class);
mLockoutTracker = new LockoutHalImpl();
mLockoutResetDispatcher = lockoutResetDispatcher;
+ mHalResultController = new HalResultController(sensorId, context, mHandler, mScheduler,
+ mLockoutTracker, lockoutResetDispatcher);
+ mHalResultController.setCallback(() -> {
+ mDaemon = null;
+ mCurrentUserId = UserHandle.USER_NULL;
+ });
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
@@ -351,6 +398,12 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
private synchronized IBiometricsFace getDaemon() {
+ if (mTestHalEnabled) {
+ final TestHal testHal = new TestHal();
+ testHal.setCallback(mHalResultController);
+ return testHal;
+ }
+
if (mDaemon != null) {
return mDaemon;
}
@@ -378,7 +431,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
// successfully set.
long halId = 0;
try {
- halId = mDaemon.setCallback(mDaemonCallback).value;
+ halId = mDaemon.setCallback(mHalResultController).value;
} catch (RemoteException e) {
Slog.e(TAG, "Failed to set callback for face HAL", e);
mDaemon = null;
@@ -413,6 +466,12 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
return properties;
}
+ @NonNull
+ @Override
+ public FaceSensorPropertiesInternal getSensorProperties(int sensorId) {
+ return mSensorProperties;
+ }
+
@Override
@NonNull
public List<Face> getEnrolledFaces(int sensorId, int userId) {
@@ -712,6 +771,22 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
@Override
public void dumpProtoState(int sensorId, ProtoOutputStream proto) {
+ final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
+
+ proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
+ proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
+
+ for (UserInfo user : UserManager.get(mContext).getUsers()) {
+ final int userId = user.getUserHandle().getIdentifier();
+
+ final long userToken = proto.start(SensorStateProto.USER_STATES);
+ proto.write(UserStateProto.USER_ID, userId);
+ proto.write(UserStateProto.NUM_ENROLLED, FaceUtils.getInstance()
+ .getBiometricsForUser(mContext, userId).size());
+ proto.end(userToken);
+ }
+
+ proto.end(sensorToken);
}
@Override
@@ -844,4 +919,14 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
}
}
+
+ void setTestHalEnabled(boolean enabled) {
+ mTestHalEnabled = enabled;
+ }
+
+ @NonNull
+ @Override
+ public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
+ return new BiometricTestSessionImpl(mContext, mSensorId, this, mHalResultController);
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/TestHal.java
new file mode 100644
index 000000000000..bab1114dc70d
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/TestHal.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 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 com.android.server.biometrics.sensors.face.hidl;
+
+import android.annotation.Nullable;
+import android.hardware.biometrics.face.V1_0.FaceError;
+import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
+import android.hardware.biometrics.face.V1_0.OptionalBool;
+import android.hardware.biometrics.face.V1_0.OptionalUint64;
+import android.hardware.biometrics.face.V1_0.Status;
+import android.hardware.biometrics.face.V1_1.IBiometricsFace;
+import android.os.NativeHandle;
+import android.os.RemoteException;
+
+import java.util.ArrayList;
+
+public class TestHal extends IBiometricsFace.Stub {
+ @Nullable
+ private IBiometricsFaceClientCallback mCallback;
+
+ @Override
+ public OptionalUint64 setCallback(IBiometricsFaceClientCallback clientCallback) {
+ mCallback = clientCallback;
+ final OptionalUint64 result = new OptionalUint64();
+ result.status = Status.OK;
+ return new OptionalUint64();
+ }
+
+ @Override
+ public int setActiveUser(int userId, String storePath) {
+ return 0;
+ }
+
+ @Override
+ public OptionalUint64 generateChallenge(int challengeTimeoutSec) {
+ final OptionalUint64 result = new OptionalUint64();
+ result.status = Status.OK;
+ result.value = 0;
+ return result;
+ }
+
+ @Override
+ public int enroll(ArrayList<Byte> hat, int timeoutSec, ArrayList<Integer> disabledFeatures) {
+ return 0;
+ }
+
+ @Override
+ public int revokeChallenge() {
+ return 0;
+ }
+
+ @Override
+ public int setFeature(int feature, boolean enabled, ArrayList<Byte> hat, int faceId) {
+ return 0;
+ }
+
+ @Override
+ public OptionalBool getFeature(int feature, int faceId) {
+ final OptionalBool result = new OptionalBool();
+ result.status = Status.OK;
+ result.value = true;
+ return result;
+ }
+
+ @Override
+ public OptionalUint64 getAuthenticatorId() {
+ final OptionalUint64 result = new OptionalUint64();
+ result.status = Status.OK;
+ result.value = 0;
+ return result;
+ }
+
+ @Override
+ public int cancel() throws RemoteException {
+ if (mCallback != null) {
+ mCallback.onError(0 /* deviceId */, 0 /* userId */, FaceError.CANCELED,
+ 0 /* vendorCode */);
+ }
+ return 0;
+ }
+
+ @Override
+ public int enumerate() {
+ return 0;
+ }
+
+ @Override
+ public int remove(int faceId) {
+ return 0;
+ }
+
+ @Override
+ public int authenticate(long operationId) {
+ return 0;
+ }
+
+ @Override
+ public int userActivity() {
+ return 0;
+ }
+
+ @Override
+ public int resetLockout(ArrayList<Byte> hat) {
+ return 0;
+ }
+
+ @Override
+ public int enrollRemotely(ArrayList<Byte> hat, int timeoutSec,
+ ArrayList<Integer> disabledFeatures) {
+ return 0;
+ }
+
+ @Override
+ public int enroll_1_1(ArrayList<Byte> hat, int timeoutSec, ArrayList<Integer> disabledFeatures,
+ NativeHandle nativeHandle) {
+ return 0;
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index 9f9d9cca2158..1616457e09a9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -16,8 +16,11 @@
package com.android.server.biometrics.sensors.fingerprint;
+import android.annotation.NonNull;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
+import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintService;
import android.os.IBinder;
import android.os.RemoteException;
@@ -39,12 +42,28 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
}
@Override
+ public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException {
+ return mFingerprintService.createTestSession(mSensorId, opPackageName);
+ }
+
+ @Override
+ public SensorPropertiesInternal getSensorProperties(@NonNull String opPackageName)
+ throws RemoteException {
+ return mFingerprintService.getSensorProperties(mSensorId, opPackageName);
+ }
+
+ @Override
+ public byte[] dumpSensorServiceStateProto() throws RemoteException {
+ return mFingerprintService.dumpSensorServiceStateProto();
+ }
+
+ @Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, int cookie, int callingUid, int callingPid, int callingUserId)
+ String opPackageName, int cookie)
throws RemoteException {
mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId,
- sensorReceiver, opPackageName, cookie, callingUid, callingPid, callingUserId);
+ sensorReceiver, opPackageName, cookie);
}
@Override
@@ -53,10 +72,9 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
}
@Override
- public void cancelAuthenticationFromService(IBinder token, String opPackageName, int callingUid,
- int callingPid, int callingUserId) throws RemoteException {
- mFingerprintService.cancelAuthenticationFromService(mSensorId, token, opPackageName,
- callingUid, callingPid, callingUserId);
+ public void cancelAuthenticationFromService(IBinder token, String opPackageName)
+ throws RemoteException {
+ mFingerprintService.cancelAuthenticationFromService(mSensorId, token, opPackageName);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index b84d0958e426..af0935fa799a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -100,21 +100,37 @@ public class FingerprintService extends SystemService implements BiometricServic
*/
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override
- public ITestSession createTestSession(int sensorId, String opPackageName) {
+ public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
+ final ServiceProvider provider = getProviderForSensor(sensorId);
+
+ if (provider == null) {
+ Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
+ return null;
+ }
+
+ return provider.createTestSession(sensorId, opPackageName);
+ }
+
+ @Override
+ public byte[] dumpSensorServiceStateProto() {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+ final ProtoOutputStream proto = new ProtoOutputStream();
for (ServiceProvider provider : mServiceProviders) {
- if (provider.containsSensor(sensorId)) {
- return provider.createTestSession(sensorId, opPackageName);
+ for (FingerprintSensorPropertiesInternal props
+ : provider.getSensorProperties()) {
+ provider.dumpProtoState(props.sensorId, proto);
}
}
-
- return null;
+ proto.flush();
+ return proto.getBytes();
}
@Override // Binder call
public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(
- String opPackageName) {
+ @NonNull String opPackageName) {
if (getContext().checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
!= PackageManager.PERMISSION_GRANTED) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
@@ -128,6 +144,20 @@ public class FingerprintService extends SystemService implements BiometricServic
return properties;
}
+ @Override
+ public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId,
+ @NonNull String opPackageName) {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+ final ServiceProvider provider = getProviderForSensor(sensorId);
+ if (provider == null) {
+ Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
+ + ", caller: " + opPackageName);
+ return null;
+ }
+ return provider.getSensorProperties(sensorId);
+ }
+
@Override // Binder call
public void generateChallenge(IBinder token, int sensorId, int userId,
IFingerprintServiceReceiver receiver, String opPackageName) {
@@ -262,7 +292,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 callingUid, int callingPid, int callingUserId) {
+ int cookie) {
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -334,7 +364,7 @@ public class FingerprintService extends SystemService implements BiometricServic
@Override // Binder call
public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
- final String opPackageName, int callingUid, int callingPid, int callingUserId) {
+ final String opPackageName) {
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index c13a6569b16a..6e36cd24b2e7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -64,6 +64,9 @@ public interface ServiceProvider {
@NonNull
List<FingerprintSensorPropertiesInternal> getSensorProperties();
+ @NonNull
+ FingerprintSensorPropertiesInternal getSensorProperties(int sensorId);
+
void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken);
void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 0ebfe9381d15..5f3be488c12c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -226,6 +226,12 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
return props;
}
+ @NonNull
+ @Override
+ public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId) {
+ return mSensors.get(sensorId).getSensorProperties();
+ }
+
private void scheduleLoadAuthenticatorIds(int sensorId) {
for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
scheduleLoadAuthenticatorIdsForUser(sensorId, user.id);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index 2e78912703f2..380608f1b0a9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -39,10 +39,10 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.biometrics.HardwareAuthTokenUtils;
+import com.android.server.biometrics.SensorServiceStateProto;
+import com.android.server.biometrics.SensorStateProto;
+import com.android.server.biometrics.UserStateProto;
import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.fingerprint.FingerprintServiceStateProto;
-import com.android.server.biometrics.fingerprint.SensorStateProto;
-import com.android.server.biometrics.fingerprint.UserStateProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BiometricScheduler;
@@ -491,7 +491,7 @@ class Sensor implements IBinder.DeathRecipient {
}
void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
- final long sensorToken = proto.start(FingerprintServiceStateProto.SENSOR_STATES);
+ final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 8c766d682bf7..9924d4710436 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -49,13 +49,13 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.SensorServiceStateProto;
+import com.android.server.biometrics.SensorStateProto;
+import com.android.server.biometrics.UserStateProto;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.fingerprint.FingerprintServiceDumpProto;
-import com.android.server.biometrics.fingerprint.FingerprintServiceStateProto;
import com.android.server.biometrics.fingerprint.FingerprintUserStatsProto;
import com.android.server.biometrics.fingerprint.PerformanceStatsProto;
-import com.android.server.biometrics.fingerprint.SensorStateProto;
-import com.android.server.biometrics.fingerprint.UserStateProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
@@ -397,7 +397,9 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
private synchronized IBiometricsFingerprint getDaemon() {
if (mTestHalEnabled) {
- return new TestHal();
+ final TestHal testHal = new TestHal();
+ testHal.setNotify(mHalResultController);
+ return testHal;
}
if (mDaemon != null) {
@@ -504,6 +506,12 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
return properties;
}
+ @NonNull
+ @Override
+ public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId) {
+ return mSensorProperties;
+ }
+
@Override
public void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) {
// Fingerprint2.1 keeps track of lockout in the framework. Let's just do it on the handler
@@ -701,7 +709,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
@Override
public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
- final long sensorToken = proto.start(FingerprintServiceStateProto.SENSOR_STATES);
+ final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java
index 86c0875af48c..b7aec0ed2731 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java
@@ -16,6 +16,8 @@
package com.android.server.biometrics.sensors.fingerprint.hidl;
+import android.annotation.Nullable;
+import android.hardware.biometrics.fingerprint.V2_1.FingerprintError;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;
import android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint;
import android.os.RemoteException;
@@ -24,6 +26,9 @@ import android.os.RemoteException;
* Test HAL that provides only provides no-ops.
*/
public class TestHal extends IBiometricsFingerprint.Stub {
+ @Nullable
+ private IBiometricsFingerprintClientCallback mCallback;
+
@Override
public boolean isUdfps(int sensorId) {
return false;
@@ -41,6 +46,7 @@ public class TestHal extends IBiometricsFingerprint.Stub {
@Override
public long setNotify(IBiometricsFingerprintClientCallback clientCallback) {
+ mCallback = clientCallback;
return 0;
}
@@ -65,7 +71,10 @@ public class TestHal extends IBiometricsFingerprint.Stub {
}
@Override
- public int cancel() {
+ public int cancel() throws RemoteException {
+ if (mCallback != null) {
+ mCallback.onError(0, FingerprintError.ERROR_CANCELED, 0 /* vendorCode */);
+ }
return 0;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
index b756d8e87fd6..6f437a7c31d2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
@@ -16,8 +16,11 @@
package com.android.server.biometrics.sensors.iris;
+import android.annotation.NonNull;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
+import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.iris.IIrisService;
import android.os.IBinder;
import android.os.RemoteException;
@@ -36,10 +39,25 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
}
@Override
+ public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException {
+ return null;
+ }
+
+ @Override
+ public SensorPropertiesInternal getSensorProperties(@NonNull String opPackageName)
+ throws RemoteException {
+ return null;
+ }
+
+ @Override
+ public byte[] dumpSensorServiceStateProto() throws RemoteException {
+ return null;
+ }
+
+ @Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long sessionId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, int cookie, int callingUid, int callingPid, int callingUserId)
- throws RemoteException {
+ String opPackageName, int cookie) throws RemoteException {
}
@Override
@@ -47,8 +65,8 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
}
@Override
- public void cancelAuthenticationFromService(IBinder token, String opPackageName, int callingUid,
- int callingPid, int callingUserId) throws RemoteException {
+ public void cancelAuthenticationFromService(IBinder token, String opPackageName)
+ throws RemoteException {
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index e011c797777e..e4be448f6b18 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -47,7 +47,6 @@ import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.AdditionalMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -170,10 +169,7 @@ public class AuthServiceTest {
eq(userId),
eq(mReceiver),
eq(TEST_OP_PACKAGE_NAME),
- eq(promptInfo),
- eq(Binder.getCallingUid()),
- eq(Binder.getCallingPid()),
- eq(UserHandle.getCallingUserId()));
+ eq(promptInfo));
}
@Test
@@ -202,10 +198,7 @@ public class AuthServiceTest {
eq(userId),
eq(mReceiver),
eq(TEST_OP_PACKAGE_NAME),
- eq(promptInfo),
- eq(Binder.getCallingUid()),
- eq(Binder.getCallingPid()),
- eq(UserHandle.getCallingUserId()));
+ eq(promptInfo));
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 6b000f39aba2..8d890b9cd606 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -19,6 +19,8 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static com.android.server.biometrics.BiometricServiceStateProto.*;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -29,7 +31,6 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -108,10 +109,7 @@ public class AuthSessionTest {
false /* checkDevicePolicyManager */,
Authenticators.BIOMETRIC_STRONG,
0 /* operationId */,
- 0 /* userId */,
- 0 /* callingUid */,
- 0 /* callingPid */,
- 0 /* callingUserId */);
+ 0 /* userId */);
for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
@@ -126,18 +124,12 @@ public class AuthSessionTest {
final boolean requireConfirmation = true;
final long operationId = 123;
final int userId = 10;
- final int callingUid = 100;
- final int callingPid = 1000;
- final int callingUserId = 10000;
final AuthSession session = createAuthSession(mSensors,
false /* checkDevicePolicyManager */,
Authenticators.BIOMETRIC_STRONG,
operationId,
- userId,
- callingUid,
- callingPid,
- callingUserId);
+ userId);
assertEquals(mSensors.size(), session.mPreAuthInfo.eligibleSensors.size());
for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
@@ -156,10 +148,7 @@ public class AuthSessionTest {
eq(userId),
eq(mSensorReceiver),
eq(TEST_PACKAGE),
- eq(sensor.getCookie()),
- eq(callingUid),
- eq(callingPid),
- eq(callingUserId));
+ eq(sensor.getCookie()));
}
final int cookie1 = session.mPreAuthInfo.eligibleSensors.get(0).getCookie();
@@ -200,10 +189,7 @@ public class AuthSessionTest {
false /* checkDevicePolicyManager */,
Authenticators.BIOMETRIC_STRONG,
operationId,
- userId,
- callingUid,
- callingPid,
- callingUserId);
+ userId);
assertEquals(mSensors.size(), session.mPreAuthInfo.eligibleSensors.size());
for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
@@ -225,13 +211,13 @@ public class AuthSessionTest {
assertTrue(session.allCookiesReceived());
// UDFPS does not start even if all cookies are received
- assertEquals(AuthSession.STATE_AUTH_STARTED, session.getState());
+ assertEquals(STATE_AUTH_STARTED, session.getState());
verify(mStatusBarService).showAuthenticationDialog(any(), any(), any(),
anyBoolean(), anyBoolean(), anyInt(), any(), anyLong());
// Notify AuthSession that the UI is shown. Then, UDFPS sensor should be started.
session.onDialogAnimatedIn();
- assertEquals(AuthSession.STATE_AUTH_STARTED_UI_SHOWING, session.getState());
+ assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
assertEquals(BiometricSensor.STATE_AUTHENTICATING,
session.mPreAuthInfo.eligibleSensors.get(0).getSensorState());
@@ -251,9 +237,7 @@ public class AuthSessionTest {
private AuthSession createAuthSession(List<BiometricSensor> sensors,
boolean checkDevicePolicyManager, @Authenticators.Types int authenticators,
- long operationId, int userId,
- int callingUid, int callingPid, int callingUserId)
- throws RemoteException {
+ long operationId, int userId) throws RemoteException {
final PromptInfo promptInfo = createPromptInfo(authenticators);
@@ -261,8 +245,8 @@ public class AuthSessionTest {
checkDevicePolicyManager);
return new AuthSession(mContext, mStatusBarService, mSysuiReceiver, mKeyStore,
mRandom, mClientDeathReceiver, preAuthInfo, mToken, operationId, userId,
- mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo, callingUid,
- callingPid, callingUserId, false /* debugEnabled */, mFingerprintSensorProps);
+ mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo,
+ false /* debugEnabled */, mFingerprintSensorProps);
}
private PromptInfo createPromptInfo(@Authenticators.Types int authenticators) {
@@ -299,7 +283,7 @@ public class AuthSessionTest {
}
private void setupFace(int id, boolean confirmationAlwaysRequired) throws RemoteException {
- IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+ IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
when(faceAuthenticator.isHardwareDetected(any())).thenReturn(true);
when(faceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
mSensors.add(new BiometricSensor(id,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 435c7008ca59..0c95e05342c8 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -18,6 +18,8 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricManager.Authenticators;
+import static com.android.server.biometrics.BiometricServiceStateProto.*;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -174,8 +176,7 @@ public class BiometricServiceTest {
0 /* vendorCode */);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_PAUSED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
mBiometricService.mCurrentAuthSession.binderDied();
waitForIdle();
@@ -195,22 +196,18 @@ public class BiometricServiceTest {
verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession),
anyInt());
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
mBiometricService.mCurrentAuthSession.binderDied();
waitForIdle();
assertNotNull(mBiometricService.mCurrentAuthSession);
verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
- assertEquals(AuthSession.STATE_CLIENT_DIED_CANCELLING,
+ assertEquals(STATE_CLIENT_DIED_CANCELLING,
mBiometricService.mCurrentAuthSession.getState());
verify(mBiometricService.mCurrentAuthSession.mPreAuthInfo.eligibleSensors.get(0).impl)
.cancelAuthenticationFromService(any(),
- any(),
- anyInt(),
- anyInt(),
- anyInt());
+ any());
// Simulate ERROR_CANCELED received from HAL
mBiometricService.mBiometricSensorReceiver.onError(
@@ -256,7 +253,7 @@ public class BiometricServiceTest {
waitForIdle();
assertNotNull(mBiometricService.mCurrentAuthSession);
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
// StatusBar showBiometricDialog invoked
verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
@@ -406,7 +403,7 @@ public class BiometricServiceTest {
HAT);
waitForIdle();
// Confirmation is required
- assertEquals(AuthSession.STATE_AUTH_PENDING_CONFIRM,
+ assertEquals(STATE_AUTH_PENDING_CONFIRM,
mBiometricService.mCurrentAuthSession.getState());
// Enrolled, not disabled in settings, user doesn't require confirmation in settings
@@ -422,7 +419,7 @@ public class BiometricServiceTest {
HAT);
waitForIdle();
// Confirmation not required, waiting for dialog to dismiss
- assertEquals(AuthSession.STATE_AUTHENTICATED_PENDING_SYSUI,
+ assertEquals(STATE_AUTHENTICATED_PENDING_SYSUI,
mBiometricService.mCurrentAuthSession.getState());
}
@@ -447,8 +444,7 @@ public class BiometricServiceTest {
waitForIdle();
// Creates a pending auth session with the correct initial states
- assertEquals(AuthSession.STATE_AUTH_CALLED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
// Invokes <Modality>Service#prepareForAuthentication
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -460,16 +456,12 @@ public class BiometricServiceTest {
anyInt() /* userId */,
any(IBiometricSensorReceiver.class),
anyString() /* opPackageName */,
- cookieCaptor.capture() /* cookie */,
- anyInt() /* callingUid */,
- anyInt() /* callingPid */,
- anyInt() /* callingUserId */);
+ cookieCaptor.capture() /* cookie */);
// onReadyForAuthentication, mCurrentAuthSession state OK
mBiometricService.mImpl.onReadyForAuthentication(cookieCaptor.getValue());
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
// startPreparedClient invoked
verify(mBiometricService.mSensors.get(0).impl)
@@ -493,7 +485,7 @@ public class BiometricServiceTest {
HAT);
waitForIdle();
// Waiting for SystemUI to send dismissed callback
- assertEquals(AuthSession.STATE_AUTHENTICATED_PENDING_SYSUI,
+ assertEquals(STATE_AUTHENTICATED_PENDING_SYSUI,
mBiometricService.mCurrentAuthSession.getState());
// Notify SystemUI hardware authenticated
verify(mBiometricService.mStatusBarService).onBiometricAuthenticated();
@@ -526,7 +518,7 @@ public class BiometricServiceTest {
Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
waitForIdle();
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
assertEquals(Authenticators.DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.mPromptInfo.getAuthenticators());
@@ -566,8 +558,7 @@ public class BiometricServiceTest {
HAT);
waitForIdle();
// Waiting for SystemUI to send confirmation callback
- assertEquals(AuthSession.STATE_AUTH_PENDING_CONFIRM,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_PENDING_CONFIRM, mBiometricService.mCurrentAuthSession.getState());
verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
// SystemUI sends confirm, HAT is sent to keystore and client is notified.
@@ -615,8 +606,7 @@ public class BiometricServiceTest {
eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
eq(0 /* vendorCode */));
verify(mReceiver1).onAuthenticationFailed();
- assertEquals(AuthSession.STATE_AUTH_PAUSED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
}
@Test
@@ -634,8 +624,7 @@ public class BiometricServiceTest {
eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
eq(0 /* vendorCode */));
verify(mReceiver1).onAuthenticationFailed();
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
}
@Test
@@ -670,8 +659,7 @@ public class BiometricServiceTest {
0 /* vendorCode */);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_PAUSED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
verify(mBiometricService.mStatusBarService).onBiometricError(
eq(BiometricAuthenticator.TYPE_FACE),
eq(BiometricConstants.BIOMETRIC_ERROR_TIMEOUT),
@@ -680,8 +668,7 @@ public class BiometricServiceTest {
verify(mReceiver1, never()).onAuthenticationFailed();
// No auth session. Pressing try again will create one.
- assertEquals(AuthSession.STATE_AUTH_PAUSED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
// Pressing "Try again" on SystemUI
mBiometricService.mSysuiReceiver.onTryAgainPressed();
@@ -689,8 +676,7 @@ public class BiometricServiceTest {
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
// AuthSession is now resuming
- assertEquals(AuthSession.STATE_AUTH_PAUSED_RESUMING,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_PAUSED_RESUMING, mBiometricService.mCurrentAuthSession.getState());
// Test resuming when hardware becomes ready. SystemUI should not be requested to
// show another dialog since it's already showing.
@@ -755,8 +741,7 @@ public class BiometricServiceTest {
waitForIdle();
// Sends error to SystemUI and does not notify client yet
- assertEquals(AuthSession.STATE_ERROR_PENDING_SYSUI,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_ERROR_PENDING_SYSUI, mBiometricService.mCurrentAuthSession.getState());
verify(mBiometricService.mStatusBarService).onBiometricError(
eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
@@ -783,8 +768,7 @@ public class BiometricServiceTest {
Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_CALLED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
mBiometricService.mBiometricSensorReceiver.onError(
SENSOR_ID_FINGERPRINT,
getCookieForPendingSession(mBiometricService.mCurrentAuthSession),
@@ -794,7 +778,7 @@ public class BiometricServiceTest {
// We should be showing device credential now
assertNotNull(mBiometricService.mCurrentAuthSession);
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
assertEquals(Authenticators.DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.mPromptInfo.getAuthenticators());
@@ -873,7 +857,7 @@ public class BiometricServiceTest {
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
assertNotNull(mBiometricService.mCurrentAuthSession);
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
assertEquals(Authenticators.DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.mPromptInfo.getAuthenticators());
@@ -950,7 +934,7 @@ public class BiometricServiceTest {
mBiometricService.mSysuiReceiver.onDeviceCredentialPressed();
waitForIdle();
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
@@ -961,7 +945,7 @@ public class BiometricServiceTest {
0 /* vendorCode */);
waitForIdle();
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
}
@@ -973,8 +957,7 @@ public class BiometricServiceTest {
false /* requireConfirmation */,
Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
mBiometricService.mBiometricSensorReceiver.onError(
SENSOR_ID_FINGERPRINT,
@@ -983,7 +966,7 @@ public class BiometricServiceTest {
0 /* vendorCode */);
waitForIdle();
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
verify(mBiometricService.mStatusBarService).onBiometricError(
eq(BiometricAuthenticator.TYPE_FINGERPRINT),
@@ -997,8 +980,7 @@ public class BiometricServiceTest {
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
false /* requireConfirmation */, null /* authenticators */);
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
mBiometricService.mBiometricSensorReceiver.onError(
SENSOR_ID_FINGERPRINT,
@@ -1007,7 +989,7 @@ public class BiometricServiceTest {
0 /* vendorCode */);
waitForIdle();
- assertEquals(AuthSession.STATE_ERROR_PENDING_SYSUI,
+ assertEquals(STATE_ERROR_PENDING_SYSUI,
mBiometricService.mCurrentAuthSession.getState());
verify(mBiometricService.mStatusBarService).onBiometricError(
eq(BiometricAuthenticator.TYPE_FINGERPRINT),
@@ -1031,10 +1013,7 @@ public class BiometricServiceTest {
eq(0 /* vendorCode */));
verify(mBiometricService.mSensors.get(0).impl).cancelAuthenticationFromService(
any(),
- any(),
- anyInt(),
- anyInt(),
- anyInt());
+ any());
assertNull(mBiometricService.mCurrentAuthSession);
}
@@ -1056,10 +1035,7 @@ public class BiometricServiceTest {
verify(mBiometricService.mSensors.get(0).impl,
never()).cancelAuthenticationFromService(
any(),
- any(),
- anyInt(),
- anyInt(),
- anyInt());
+ any());
}
@Test
@@ -1081,10 +1057,7 @@ public class BiometricServiceTest {
verify(mBiometricService.mSensors.get(0).impl,
never()).cancelAuthenticationFromService(
any(),
- any(),
- anyInt(),
- anyInt(),
- anyInt());
+ any());
}
@Test
@@ -1104,10 +1077,7 @@ public class BiometricServiceTest {
verify(mBiometricService.mSensors.get(0).impl,
never()).cancelAuthenticationFromService(
any(),
- any(),
- anyInt(),
- anyInt(),
- anyInt());
+ any());
verify(mReceiver1).onError(
eq(BiometricAuthenticator.TYPE_FACE),
eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
@@ -1134,8 +1104,7 @@ public class BiometricServiceTest {
// string is retrieved for now, but it's also very unlikely to break anyway.
verify(mBiometricService.mStatusBarService)
.onBiometricHelp(anyString());
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
}
@Test
@@ -1145,7 +1114,7 @@ public class BiometricServiceTest {
false /* requireConfirmation */, null /* authenticators */);
mBiometricService.mImpl.cancelAuthentication(mBiometricService.mCurrentAuthSession.mToken,
- TEST_PACKAGE_NAME, 0 /* callingUId */, 0 /* callingPid */, 0 /* callingUserId */);
+ TEST_PACKAGE_NAME);
waitForIdle();
// Pretend that the HAL has responded to cancel with ERROR_CANCELED
@@ -1491,12 +1460,10 @@ public class BiometricServiceTest {
invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
Authenticators.BIOMETRIC_STRONG);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_CALLED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
startPendingAuthSession(mBiometricService);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
}
@Test
@@ -1508,8 +1475,7 @@ public class BiometricServiceTest {
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
false /* requireConfirmation */, Authenticators.BIOMETRIC_STRONG);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
}
@Test
@@ -1522,12 +1488,10 @@ public class BiometricServiceTest {
invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
Authenticators.BIOMETRIC_STRONG);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_CALLED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
startPendingAuthSession(mBiometricService);
waitForIdle();
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
}
@Test
@@ -1549,7 +1513,7 @@ public class BiometricServiceTest {
Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
waitForIdle();
assertNotNull(mBiometricService.mCurrentAuthSession);
- assertEquals(AuthSession.STATE_SHOWING_DEVICE_CREDENTIAL,
+ assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.getState());
verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
}
@@ -1647,8 +1611,7 @@ public class BiometricServiceTest {
waitForIdle();
assertNotNull(mBiometricService.mCurrentAuthSession);
- assertEquals(AuthSession.STATE_AUTH_STARTED,
- mBiometricService.mCurrentAuthSession.getState());
+ assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
}
private static void startPendingAuthSession(BiometricService service) throws Exception {
@@ -1674,10 +1637,7 @@ public class BiometricServiceTest {
receiver,
TEST_PACKAGE_NAME /* packageName */,
createTestPromptInfo(requireConfirmation, authenticators,
- false /* checkDevicePolicy */),
- 0 /* callingUid */,
- 0 /* callingPid */,
- 0 /* callingUserId */);
+ false /* checkDevicePolicy */));
}
private static void invokeAuthenticateForWorkApp(IBiometricService.Stub service,
@@ -1689,10 +1649,7 @@ public class BiometricServiceTest {
receiver,
TEST_PACKAGE_NAME /* packageName */,
createTestPromptInfo(false /* requireConfirmation */, authenticators,
- true /* checkDevicePolicy */),
- 0 /* callingUid */,
- 0 /* callingPid */,
- 0 /* callingUserId */);
+ true /* checkDevicePolicy */));
}
private static PromptInfo createTestPromptInfo(