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

Commit 1a336b00 authored by Haining Chen's avatar Haining Chen
Browse files

Switch to use addAuthenticatorsRegisteredCallback to get sensor props

Directly using getSensorPropertiesInternal to get fingerprint/face
sensor props is fine but may potentially have issues of race condition
or HAL taking too long to response during initialization.

Switch to use addAuthenticatorsRegisteredCallback which is safer. The
callback will be invoked immediately if sensor props are already
available, or invoked until registration of all sensors is done.

Fix: 266709333
Test: atest BinaryTransparencyServiceTest
Test: Mannually set the flag to true/false via:
      adb shell device_config put biometrics
          enable_biometric_property_verification true/false
      Then check whether data is logged via:
      m statsd_testdrive && statsd_testdrive 587
Change-Id: Ief69fe426e3beb8983e64032a845b7e5e3cf6c28
parent fc16dc4b
Loading
Loading
Loading
Loading
+45 −16
Original line number Original line Diff line number Diff line
@@ -53,9 +53,12 @@ import android.hardware.biometrics.SensorProperties;
import android.hardware.biometrics.SensorProperties.ComponentInfo;
import android.hardware.biometrics.SensorProperties.ComponentInfo;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Binder;
import android.os.Build;
import android.os.Build;
@@ -1371,26 +1374,52 @@ public class BinaryTransparencyService extends SystemService {
        }
        }


        if (fpManager != null) {
        if (fpManager != null) {
            final int fpModality = FrameworkStatsLog
                    .BIOMETRIC_PROPERTIES_COLLECTED__MODALITY__MODALITY_FINGERPRINT;
            fpManager.addAuthenticatorsRegisteredCallback(
                    new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
                        @Override
                        public void onAllAuthenticatorsRegistered(
                                List<FingerprintSensorPropertiesInternal> sensors) {
                            if (DEBUG) {
                                Slog.d(TAG, "Retrieve fingerprint sensor properties. "
                                        + "sensors.size()=" + sensors.size());
                            }
                            // Log data for each fingerprint sensor
                            // Log data for each fingerprint sensor
            for (FingerprintSensorPropertiesInternal propInternal :
                            for (FingerprintSensorPropertiesInternal propInternal : sensors) {
                    fpManager.getSensorPropertiesInternal()) {
                                final FingerprintSensorProperties prop =
                                final FingerprintSensorProperties prop =
                                        FingerprintSensorProperties.from(propInternal);
                                        FingerprintSensorProperties.from(propInternal);
                                logBiometricProperties(prop,
                                logBiometricProperties(prop,
                        FrameworkStatsLog
                                        fpModality,
                                .BIOMETRIC_PROPERTIES_COLLECTED__MODALITY__MODALITY_FINGERPRINT,
                                        toFingerprintSensorType(prop.getSensorType()));
                                        toFingerprintSensorType(prop.getSensorType()));
                            }
                            }
                        }
                        }
                    });
        }


        if (faceManager != null) {
        if (faceManager != null) {
            final int faceModality = FrameworkStatsLog
                    .BIOMETRIC_PROPERTIES_COLLECTED__MODALITY__MODALITY_FACE;
            faceManager.addAuthenticatorsRegisteredCallback(
                    new IFaceAuthenticatorsRegisteredCallback.Stub() {
                        @Override
                        public void onAllAuthenticatorsRegistered(
                                List<FaceSensorPropertiesInternal> sensors) {
                            if (DEBUG) {
                                Slog.d(TAG, "Retrieve face sensor properties. sensors.size()="
                                        + sensors.size());
                            }
                            // Log data for each face sensor
                            // Log data for each face sensor
            for (FaceSensorProperties prop : faceManager.getSensorProperties()) {
                            for (FaceSensorPropertiesInternal propInternal : sensors) {
                                final FaceSensorProperties prop =
                                        FaceSensorProperties.from(propInternal);
                                logBiometricProperties(prop,
                                logBiometricProperties(prop,
                        FrameworkStatsLog.BIOMETRIC_PROPERTIES_COLLECTED__MODALITY__MODALITY_FACE,
                                        faceModality,
                                        toFaceSensorType(prop.getSensorType()));
                                        toFaceSensorType(prop.getSensorType()));
                            }
                            }
                        }
                        }
                    });
        }
    }
    }


    private void getVBMetaDigestInformation() {
    private void getVBMetaDigestInformation() {
+52 −35
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server;
package com.android.server;


import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.never;
@@ -33,9 +35,11 @@ import android.hardware.biometrics.SensorProperties;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Bundle;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ResultReceiver;
@@ -53,6 +57,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;


@@ -74,6 +80,15 @@ public class BinaryTransparencyServiceTest {
    private FingerprintManager mFpManager;
    private FingerprintManager mFpManager;
    @Mock
    @Mock
    private FaceManager mFaceManager;
    private FaceManager mFaceManager;
    @Mock
    private PackageManager mPackageManager;

    @Captor
    private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback>
            mFpAuthenticatorsRegisteredCaptor;
    @Captor
    private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback>
            mFaceAuthenticatorsRegisteredCaptor;


    @Before
    @Before
    public void setUp() {
    public void setUp() {
@@ -83,9 +98,6 @@ public class BinaryTransparencyServiceTest {
        mBinaryTransparencyService = new BinaryTransparencyService(mContext, mBiometricLogger);
        mBinaryTransparencyService = new BinaryTransparencyService(mContext, mBiometricLogger);
        mTestInterface = mBinaryTransparencyService.new BinaryTransparencyServiceImpl();
        mTestInterface = mBinaryTransparencyService.new BinaryTransparencyServiceImpl();
        mOriginalBiometricsFlags = DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BIOMETRICS);
        mOriginalBiometricsFlags = DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BIOMETRICS);

        when(mContext.getSystemService(FingerprintManager.class)).thenReturn(mFpManager);
        when(mContext.getSystemService(FaceManager.class)).thenReturn(mFaceManager);
    }
    }


    @After
    @After
@@ -112,6 +124,14 @@ public class BinaryTransparencyServiceTest {
                args, null, new ResultReceiver(null));
                args, null, new ResultReceiver(null));
    }
    }


    private void prepBiometricsTesting() {
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
        when(mContext.getSystemService(FingerprintManager.class)).thenReturn(mFpManager);
        when(mContext.getSystemService(FaceManager.class)).thenReturn(mFaceManager);
    }

    @Test
    @Test
    public void getSignedImageInfo_preInitialize_returnsUninitializedString() {
    public void getSignedImageInfo_preInitialize_returnsUninitializedString() {
        String result = mTestInterface.getSignedImageInfo();
        String result = mTestInterface.getSignedImageInfo();
@@ -175,25 +195,14 @@ public class BinaryTransparencyServiceTest {


        mBinaryTransparencyService.collectBiometricProperties();
        mBinaryTransparencyService.collectBiometricProperties();


        verify(mFpManager, never()).getSensorPropertiesInternal();
        verify(mBiometricLogger, never()).logStats(anyInt(), anyInt(), anyInt(), anyInt(),
        verify(mFaceManager, never()).getSensorProperties();
                anyString(), anyString(), anyString(), anyString(), anyString());
    }

    @Test
    public void testCollectBiometricProperties_enablesFeature() {
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS,
                BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION,
                Boolean.TRUE.toString(),
                false /* makeDefault */);

        mBinaryTransparencyService.collectBiometricProperties();

        verify(mFpManager, times(1)).getSensorPropertiesInternal();
        verify(mFaceManager, times(1)).getSensorProperties();
    }
    }


    @Test
    @Test
    public void testCollectBiometricProperties_enablesFeature_logsFingerprintProperties() {
    public void testCollectBiometricProperties_enablesFeature_logsFingerprintProperties()
            throws RemoteException {
        prepBiometricsTesting();
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS,
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS,
                BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION,
                BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION,
                Boolean.TRUE.toString(),
                Boolean.TRUE.toString(),
@@ -209,10 +218,13 @@ public class BinaryTransparencyServiceTest {
                                "" /* softwareVersion */)),
                                "" /* softwareVersion */)),
                        FingerprintSensorProperties.TYPE_REAR,
                        FingerprintSensorProperties.TYPE_REAR,
                        true /* resetLockoutRequiresHardwareAuthToken */));
                        true /* resetLockoutRequiresHardwareAuthToken */));
        when(mFpManager.getSensorPropertiesInternal()).thenReturn(props);


        mBinaryTransparencyService.collectBiometricProperties();
        mBinaryTransparencyService.collectBiometricProperties();


        verify(mFpManager).addAuthenticatorsRegisteredCallback(mFpAuthenticatorsRegisteredCaptor
                .capture());
        mFpAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(props);

        verify(mBiometricLogger, times(1)).logStats(
        verify(mBiometricLogger, times(1)).logStats(
                eq(1) /* sensorId */,
                eq(1) /* sensorId */,
                eq(FrameworkStatsLog
                eq(FrameworkStatsLog
@@ -230,12 +242,14 @@ public class BinaryTransparencyServiceTest {
    }
    }


    @Test
    @Test
    public void testCollectBiometricProperties_enablesFeature_logsFaceProperties() {
    public void testCollectBiometricProperties_enablesFeature_logsFaceProperties()
            throws RemoteException {
        prepBiometricsTesting();
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS,
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS,
                BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION,
                BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION,
                Boolean.TRUE.toString(),
                Boolean.TRUE.toString(),
                false /* makeDefault */);
                false /* makeDefault */);
        final List<FaceSensorProperties> props = List.of(FaceSensorProperties.from(
        final List<FaceSensorPropertiesInternal> props = List.of(
                new FaceSensorPropertiesInternal(
                new FaceSensorPropertiesInternal(
                        1 /* sensorId */,
                        1 /* sensorId */,
                        SensorProperties.STRENGTH_CONVENIENCE,
                        SensorProperties.STRENGTH_CONVENIENCE,
@@ -247,11 +261,14 @@ public class BinaryTransparencyServiceTest {
                        FaceSensorProperties.TYPE_RGB,
                        FaceSensorProperties.TYPE_RGB,
                        true /* supportsFaceDetection */,
                        true /* supportsFaceDetection */,
                        true /* supportsSelfIllumination */,
                        true /* supportsSelfIllumination */,
                                true /* resetLockoutRequiresHardwareAuthToken */)));
                        true /* resetLockoutRequiresHardwareAuthToken */));
        when(mFaceManager.getSensorProperties()).thenReturn(props);


        mBinaryTransparencyService.collectBiometricProperties();
        mBinaryTransparencyService.collectBiometricProperties();


        verify(mFaceManager).addAuthenticatorsRegisteredCallback(mFaceAuthenticatorsRegisteredCaptor
                .capture());
        mFaceAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(props);

        verify(mBiometricLogger, times(1)).logStats(
        verify(mBiometricLogger, times(1)).logStats(
                eq(1) /* sensorId */,
                eq(1) /* sensorId */,
                eq(FrameworkStatsLog
                eq(FrameworkStatsLog