Merge "Add snapshot of ambient light value to log during enrollment and authentication operations." into sc-dev
This commit is contained in:
@@ -679,7 +679,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
|
||||
latency,
|
||||
mDebugEnabled,
|
||||
-1 /* sensorId */);
|
||||
-1 /* sensorId */,
|
||||
-1f /* ambientLightLux */);
|
||||
} else {
|
||||
final long latency = System.currentTimeMillis() - mStartTimeMs;
|
||||
|
||||
|
||||
@@ -69,6 +69,31 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
}
|
||||
}
|
||||
|
||||
/** Holder for wrapping multiple handlers into a single Callback. */
|
||||
protected static class CompositeCallback implements Callback {
|
||||
@NonNull
|
||||
private final Callback[] mCallbacks;
|
||||
|
||||
public CompositeCallback(@NonNull Callback... callbacks) {
|
||||
mCallbacks = callbacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
|
||||
for (int i = 0; i < mCallbacks.length; i++) {
|
||||
mCallbacks[i].onClientStarted(clientMonitor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
|
||||
boolean success) {
|
||||
for (int i = mCallbacks.length - 1; i >= 0; i--) {
|
||||
mCallbacks[i].onClientFinished(clientMonitor, success);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final int mSequentialId;
|
||||
@NonNull private final Context mContext;
|
||||
private final int mTargetUserId;
|
||||
@@ -125,7 +150,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
@Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction,
|
||||
int statsClient) {
|
||||
super(statsModality, statsAction, statsClient);
|
||||
super(context, statsModality, statsAction, statsClient);
|
||||
mSequentialId = sCount++;
|
||||
mContext = context;
|
||||
mToken = token;
|
||||
@@ -153,10 +178,19 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
* @param callback invoked when the operation is complete (succeeds, fails, etc)
|
||||
*/
|
||||
public void start(@NonNull Callback callback) {
|
||||
mCallback = callback;
|
||||
mCallback = wrapCallbackForStart(callback);
|
||||
mCallback.onClientStarted(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called during start to provide subclasses a hook for decorating the callback.
|
||||
*
|
||||
* Returns the original callback unless overridden.
|
||||
*/
|
||||
@NonNull
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return callback;
|
||||
}
|
||||
|
||||
public boolean isAlreadyDone() {
|
||||
return mAlreadyDone;
|
||||
|
||||
@@ -16,7 +16,13 @@
|
||||
|
||||
package com.android.server.biometrics.sensors;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.face.FaceManager;
|
||||
@@ -37,9 +43,41 @@ public abstract class LoggableMonitor {
|
||||
final int mStatsModality;
|
||||
private final int mStatsAction;
|
||||
private final int mStatsClient;
|
||||
@NonNull private final SensorManager mSensorManager;
|
||||
private long mFirstAcquireTimeMs;
|
||||
private boolean mLightSensorEnabled = false;
|
||||
private boolean mShouldLogMetrics = true;
|
||||
|
||||
// report only the most recent value
|
||||
// consider com.android.server.display.utils.AmbientFilter or similar if need arises
|
||||
private volatile float mLastAmbientLux = 0;
|
||||
|
||||
private final SensorEventListener mLightSensorListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
mLastAmbientLux = event.values[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// Not used.
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param context system_server context
|
||||
* @param statsModality One of {@link BiometricsProtoEnums} MODALITY_* constants.
|
||||
* @param statsAction One of {@link BiometricsProtoEnums} ACTION_* constants.
|
||||
* @param statsClient One of {@link BiometricsProtoEnums} CLIENT_* constants.
|
||||
*/
|
||||
public LoggableMonitor(@NonNull Context context, int statsModality, int statsAction,
|
||||
int statsClient) {
|
||||
mStatsModality = statsModality;
|
||||
mStatsAction = statsAction;
|
||||
mStatsClient = statsClient;
|
||||
mSensorManager = context.getSystemService(SensorManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only valid for AuthenticationClient.
|
||||
* @return true if the client is authenticating for a crypto operation.
|
||||
@@ -48,17 +86,6 @@ public abstract class LoggableMonitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param statsModality One of {@link BiometricsProtoEnums} MODALITY_* constants.
|
||||
* @param statsAction One of {@link BiometricsProtoEnums} ACTION_* constants.
|
||||
* @param statsClient One of {@link BiometricsProtoEnums} CLIENT_* constants.
|
||||
*/
|
||||
public LoggableMonitor(int statsModality, int statsAction, int statsClient) {
|
||||
mStatsModality = statsModality;
|
||||
mStatsAction = statsAction;
|
||||
mStatsClient = statsClient;
|
||||
}
|
||||
|
||||
protected void setShouldLog(boolean shouldLog) {
|
||||
mShouldLogMetrics = shouldLog;
|
||||
}
|
||||
@@ -131,7 +158,6 @@ public abstract class LoggableMonitor {
|
||||
}
|
||||
|
||||
protected final void logOnError(Context context, int error, int vendorCode, int targetUserId) {
|
||||
|
||||
if (!mShouldLogMetrics) {
|
||||
return;
|
||||
}
|
||||
@@ -199,7 +225,8 @@ public abstract class LoggableMonitor {
|
||||
+ ", Client: " + mStatsClient
|
||||
+ ", RequireConfirmation: " + requireConfirmation
|
||||
+ ", State: " + authState
|
||||
+ ", Latency: " + latency);
|
||||
+ ", Latency: " + latency
|
||||
+ ", Lux: " + mLastAmbientLux);
|
||||
} else {
|
||||
Slog.v(TAG, "Authentication latency: " + latency);
|
||||
}
|
||||
@@ -217,7 +244,8 @@ public abstract class LoggableMonitor {
|
||||
authState,
|
||||
sanitizeLatency(latency),
|
||||
Utils.isDebugEnabled(context, targetUserId),
|
||||
-1 /* sensorId */);
|
||||
-1 /* sensorId */,
|
||||
mLastAmbientLux /* ambientLightLux */);
|
||||
}
|
||||
|
||||
protected final void logOnEnrolled(int targetUserId, long latency, boolean enrollSuccessful) {
|
||||
@@ -230,6 +258,7 @@ public abstract class LoggableMonitor {
|
||||
+ ", User: " + targetUserId
|
||||
+ ", Client: " + mStatsClient
|
||||
+ ", Latency: " + latency
|
||||
+ ", Lux: " + mLastAmbientLux
|
||||
+ ", Success: " + enrollSuccessful);
|
||||
} else {
|
||||
Slog.v(TAG, "Enroll latency: " + latency);
|
||||
@@ -244,7 +273,8 @@ public abstract class LoggableMonitor {
|
||||
targetUserId,
|
||||
sanitizeLatency(latency),
|
||||
enrollSuccessful,
|
||||
-1 /* sensorId */);
|
||||
-1, /* sensorId */
|
||||
mLastAmbientLux /* ambientLightLux */);
|
||||
}
|
||||
|
||||
private long sanitizeLatency(long latency) {
|
||||
@@ -255,4 +285,46 @@ public abstract class LoggableMonitor {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/** Get a callback to start/stop ALS capture when client runs. */
|
||||
@NonNull
|
||||
protected BaseClientMonitor.Callback createALSCallback() {
|
||||
return new BaseClientMonitor.Callback() {
|
||||
@Override
|
||||
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
|
||||
setLightSensorLoggingEnabled(getAmbientLightSensor(mSensorManager));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
|
||||
boolean success) {
|
||||
setLightSensorLoggingEnabled(null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** The sensor to use for ALS logging. */
|
||||
@Nullable
|
||||
protected Sensor getAmbientLightSensor(@NonNull SensorManager sensorManager) {
|
||||
return mShouldLogMetrics ? sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) : null;
|
||||
}
|
||||
|
||||
private void setLightSensorLoggingEnabled(@Nullable Sensor lightSensor) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "capturing ambient light using: "
|
||||
+ (lightSensor != null ? lightSensor : "[disabled]"));
|
||||
}
|
||||
|
||||
if (lightSensor != null) {
|
||||
if (!mLightSensorEnabled) {
|
||||
mLightSensorEnabled = true;
|
||||
mLastAmbientLux = 0;
|
||||
mSensorManager.registerListener(mLightSensorListener, lightSensor,
|
||||
SensorManager.SENSOR_DELAY_NORMAL);
|
||||
}
|
||||
} else {
|
||||
mLightSensorEnabled = false;
|
||||
mLastAmbientLux = 0;
|
||||
mSensorManager.unregisterListener(mLightSensorListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,12 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
"face_custom_success_error", 0) == 1;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
try {
|
||||
@@ -229,7 +235,8 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onLockoutTimed(long durationMillis) {
|
||||
@Override
|
||||
public void onLockoutTimed(long durationMillis) {
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT;
|
||||
@@ -242,7 +249,8 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onLockoutPermanent() {
|
||||
@Override
|
||||
public void onLockoutPermanent() {
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
|
||||
|
||||
@@ -95,6 +95,12 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
|
||||
ReEnrollNotificationUtils.cancelNotification(getContext());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
try {
|
||||
|
||||
@@ -88,6 +88,12 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
"face_custom_success_error", 0) == 1;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
try {
|
||||
@@ -186,7 +192,6 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
|
||||
@Override
|
||||
public void onAcquired(int acquireInfo, int vendorCode) {
|
||||
|
||||
mLastAcquire = acquireInfo;
|
||||
|
||||
if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) {
|
||||
|
||||
@@ -68,6 +68,12 @@ public class FaceEnrollClient extends EnrollClient<IBiometricsFace> {
|
||||
.getIntArray(R.array.config_face_acquire_vendor_enroll_ignorelist);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasReachedEnrollmentLimit() {
|
||||
final int limit = getContext().getResources().getInteger(
|
||||
|
||||
@@ -70,6 +70,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||
boolean authenticated, ArrayList<Byte> token) {
|
||||
|
||||
@@ -79,6 +79,12 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
|
||||
super.onEnrollResult(identifier, remaining);
|
||||
|
||||
@@ -69,6 +69,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||
boolean authenticated, ArrayList<Byte> token) {
|
||||
|
||||
@@ -72,6 +72,12 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||
return new CompositeCallback(createALSCallback(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasReachedEnrollmentLimit() {
|
||||
final int limit = getContext().getResources().getInteger(
|
||||
|
||||
Reference in New Issue
Block a user