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,
|
FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
|
||||||
latency,
|
latency,
|
||||||
mDebugEnabled,
|
mDebugEnabled,
|
||||||
-1 /* sensorId */);
|
-1 /* sensorId */,
|
||||||
|
-1f /* ambientLightLux */);
|
||||||
} else {
|
} else {
|
||||||
final long latency = System.currentTimeMillis() - mStartTimeMs;
|
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;
|
private final int mSequentialId;
|
||||||
@NonNull private final Context mContext;
|
@NonNull private final Context mContext;
|
||||||
private final int mTargetUserId;
|
private final int mTargetUserId;
|
||||||
@@ -125,7 +150,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
|||||||
@Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
|
@Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
|
||||||
@NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction,
|
@NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction,
|
||||||
int statsClient) {
|
int statsClient) {
|
||||||
super(statsModality, statsAction, statsClient);
|
super(context, statsModality, statsAction, statsClient);
|
||||||
mSequentialId = sCount++;
|
mSequentialId = sCount++;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mToken = token;
|
mToken = token;
|
||||||
@@ -153,10 +178,19 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
|||||||
* @param callback invoked when the operation is complete (succeeds, fails, etc)
|
* @param callback invoked when the operation is complete (succeeds, fails, etc)
|
||||||
*/
|
*/
|
||||||
public void start(@NonNull Callback callback) {
|
public void start(@NonNull Callback callback) {
|
||||||
mCallback = callback;
|
mCallback = wrapCallbackForStart(callback);
|
||||||
mCallback.onClientStarted(this);
|
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() {
|
public boolean isAlreadyDone() {
|
||||||
return mAlreadyDone;
|
return mAlreadyDone;
|
||||||
|
|||||||
@@ -16,7 +16,13 @@
|
|||||||
|
|
||||||
package com.android.server.biometrics.sensors;
|
package com.android.server.biometrics.sensors;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
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.BiometricConstants;
|
||||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||||
import android.hardware.face.FaceManager;
|
import android.hardware.face.FaceManager;
|
||||||
@@ -37,9 +43,41 @@ public abstract class LoggableMonitor {
|
|||||||
final int mStatsModality;
|
final int mStatsModality;
|
||||||
private final int mStatsAction;
|
private final int mStatsAction;
|
||||||
private final int mStatsClient;
|
private final int mStatsClient;
|
||||||
|
@NonNull private final SensorManager mSensorManager;
|
||||||
private long mFirstAcquireTimeMs;
|
private long mFirstAcquireTimeMs;
|
||||||
|
private boolean mLightSensorEnabled = false;
|
||||||
private boolean mShouldLogMetrics = true;
|
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.
|
* Only valid for AuthenticationClient.
|
||||||
* @return true if the client is authenticating for a crypto operation.
|
* @return true if the client is authenticating for a crypto operation.
|
||||||
@@ -48,17 +86,6 @@ public abstract class LoggableMonitor {
|
|||||||
return false;
|
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) {
|
protected void setShouldLog(boolean shouldLog) {
|
||||||
mShouldLogMetrics = shouldLog;
|
mShouldLogMetrics = shouldLog;
|
||||||
}
|
}
|
||||||
@@ -131,7 +158,6 @@ public abstract class LoggableMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final void logOnError(Context context, int error, int vendorCode, int targetUserId) {
|
protected final void logOnError(Context context, int error, int vendorCode, int targetUserId) {
|
||||||
|
|
||||||
if (!mShouldLogMetrics) {
|
if (!mShouldLogMetrics) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -199,7 +225,8 @@ public abstract class LoggableMonitor {
|
|||||||
+ ", Client: " + mStatsClient
|
+ ", Client: " + mStatsClient
|
||||||
+ ", RequireConfirmation: " + requireConfirmation
|
+ ", RequireConfirmation: " + requireConfirmation
|
||||||
+ ", State: " + authState
|
+ ", State: " + authState
|
||||||
+ ", Latency: " + latency);
|
+ ", Latency: " + latency
|
||||||
|
+ ", Lux: " + mLastAmbientLux);
|
||||||
} else {
|
} else {
|
||||||
Slog.v(TAG, "Authentication latency: " + latency);
|
Slog.v(TAG, "Authentication latency: " + latency);
|
||||||
}
|
}
|
||||||
@@ -217,7 +244,8 @@ public abstract class LoggableMonitor {
|
|||||||
authState,
|
authState,
|
||||||
sanitizeLatency(latency),
|
sanitizeLatency(latency),
|
||||||
Utils.isDebugEnabled(context, targetUserId),
|
Utils.isDebugEnabled(context, targetUserId),
|
||||||
-1 /* sensorId */);
|
-1 /* sensorId */,
|
||||||
|
mLastAmbientLux /* ambientLightLux */);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void logOnEnrolled(int targetUserId, long latency, boolean enrollSuccessful) {
|
protected final void logOnEnrolled(int targetUserId, long latency, boolean enrollSuccessful) {
|
||||||
@@ -230,6 +258,7 @@ public abstract class LoggableMonitor {
|
|||||||
+ ", User: " + targetUserId
|
+ ", User: " + targetUserId
|
||||||
+ ", Client: " + mStatsClient
|
+ ", Client: " + mStatsClient
|
||||||
+ ", Latency: " + latency
|
+ ", Latency: " + latency
|
||||||
|
+ ", Lux: " + mLastAmbientLux
|
||||||
+ ", Success: " + enrollSuccessful);
|
+ ", Success: " + enrollSuccessful);
|
||||||
} else {
|
} else {
|
||||||
Slog.v(TAG, "Enroll latency: " + latency);
|
Slog.v(TAG, "Enroll latency: " + latency);
|
||||||
@@ -244,7 +273,8 @@ public abstract class LoggableMonitor {
|
|||||||
targetUserId,
|
targetUserId,
|
||||||
sanitizeLatency(latency),
|
sanitizeLatency(latency),
|
||||||
enrollSuccessful,
|
enrollSuccessful,
|
||||||
-1 /* sensorId */);
|
-1, /* sensorId */
|
||||||
|
mLastAmbientLux /* ambientLightLux */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long sanitizeLatency(long latency) {
|
private long sanitizeLatency(long latency) {
|
||||||
@@ -255,4 +285,46 @@ public abstract class LoggableMonitor {
|
|||||||
return latency;
|
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;
|
"face_custom_success_error", 0) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||||
|
return new CompositeCallback(createALSCallback(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startHalOperation() {
|
protected void startHalOperation() {
|
||||||
try {
|
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);
|
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
|
||||||
// Lockout metrics are logged as an error code.
|
// Lockout metrics are logged as an error code.
|
||||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT;
|
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);
|
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
|
||||||
// Lockout metrics are logged as an error code.
|
// Lockout metrics are logged as an error code.
|
||||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
|
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
|
||||||
|
|||||||
@@ -95,6 +95,12 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
|
|||||||
ReEnrollNotificationUtils.cancelNotification(getContext());
|
ReEnrollNotificationUtils.cancelNotification(getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||||
|
return new CompositeCallback(createALSCallback(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -88,6 +88,12 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
|||||||
"face_custom_success_error", 0) == 1;
|
"face_custom_success_error", 0) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||||
|
return new CompositeCallback(createALSCallback(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startHalOperation() {
|
protected void startHalOperation() {
|
||||||
try {
|
try {
|
||||||
@@ -186,7 +192,6 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAcquired(int acquireInfo, int vendorCode) {
|
public void onAcquired(int acquireInfo, int vendorCode) {
|
||||||
|
|
||||||
mLastAcquire = acquireInfo;
|
mLastAcquire = acquireInfo;
|
||||||
|
|
||||||
if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) {
|
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);
|
.getIntArray(R.array.config_face_acquire_vendor_enroll_ignorelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||||
|
return new CompositeCallback(createALSCallback(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasReachedEnrollmentLimit() {
|
protected boolean hasReachedEnrollmentLimit() {
|
||||||
final int limit = getContext().getResources().getInteger(
|
final int limit = getContext().getResources().getInteger(
|
||||||
|
|||||||
@@ -70,6 +70,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
|||||||
mUdfpsOverlayController = udfpsOverlayController;
|
mUdfpsOverlayController = udfpsOverlayController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||||
|
return new CompositeCallback(createALSCallback(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||||
boolean authenticated, ArrayList<Byte> token) {
|
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
|
@Override
|
||||||
public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
|
public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
|
||||||
super.onEnrollResult(identifier, remaining);
|
super.onEnrollResult(identifier, remaining);
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
|||||||
mUdfpsOverlayController = udfpsOverlayController;
|
mUdfpsOverlayController = udfpsOverlayController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
|
||||||
|
return new CompositeCallback(createALSCallback(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||||
boolean authenticated, ArrayList<Byte> token) {
|
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
|
@Override
|
||||||
protected boolean hasReachedEnrollmentLimit() {
|
protected boolean hasReachedEnrollmentLimit() {
|
||||||
final int limit = getContext().getResources().getInteger(
|
final int limit = getContext().getResources().getInteger(
|
||||||
|
|||||||
Reference in New Issue
Block a user