Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c053a9b authored by Joe Bolinger's avatar Joe Bolinger Committed by Automerger Merge Worker
Browse files

Merge "Add snapshot of ambient light value to log during enrollment and...

Merge "Add snapshot of ambient light value to log during enrollment and authentication operations." into sc-dev am: d4fce118

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14785964

Change-Id: I33e304262d6d33b1145b841583afb04548b9fe2b
parents 25bdff42 d4fce118
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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;

+36 −2
Original line number Diff line number Diff line
@@ -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;
+84 −12
Original line number Diff line number Diff line
@@ -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,26 +43,47 @@ 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;

    /**
     * Only valid for AuthenticationClient.
     * @return true if the client is authenticating for a crypto operation.
     */
    protected boolean isCryptoOperation() {
        return false;
    // 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(int statsModality, int statsAction, int statsClient) {
    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.
     */
    protected boolean isCryptoOperation() {
        return false;
    }

    protected void setShouldLog(boolean 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);
        }
    }
}
+10 −2
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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 {
Loading