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

Commit bc00da21 authored by Diya Bera's avatar Diya Bera
Browse files

Use parent profile API to check for Identity Check toggle status

Flag: EXEMPT bug fix
Test: Manual - create new user, enable Identity Check, check for prompt
on any Identity Check protected surface; atest BiometricServiceTest
Fixes: 373598453

Change-Id: I3982535ae087ee2dab2ba8359837b8af62385426
parent fb7a8dfe
Loading
Loading
Loading
Loading
+53 −16
Original line number Diff line number Diff line
@@ -288,11 +288,13 @@ public class BiometricService extends SystemService {
         * @param handler The handler to run {@link #onChange} on, or null if none.
         */
        public SettingObserver(Context context, Handler handler,
                List<BiometricService.EnabledOnKeyguardCallback> callbacks) {
                List<BiometricService.EnabledOnKeyguardCallback> callbacks,
                UserManager userManager, FingerprintManager fingerprintManager,
                FaceManager faceManager) {
            super(handler);
            mContentResolver = context.getContentResolver();
            mCallbacks = callbacks;
            mUserManager = context.getSystemService(UserManager.class);
            mUserManager = userManager;

            final boolean hasFingerprint = context.getPackageManager()
                    .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
@@ -304,7 +306,7 @@ public class BiometricService extends SystemService {
                    Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.Q
                    && hasFace && !hasFingerprint;

            addBiometricListenersForMandatoryBiometrics(context);
            addBiometricListenersForMandatoryBiometrics(context, fingerprintManager, faceManager);
            updateContentObserver();
        }

@@ -431,11 +433,21 @@ public class BiometricService extends SystemService {

        public boolean getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId) {
            if (!mMandatoryBiometricsEnabled.containsKey(userId)) {
                Slog.d(TAG, "update mb toggle for user " + userId);
                updateMandatoryBiometricsForAllProfiles(userId);
            }
            if (!mMandatoryBiometricsRequirementsSatisfied.containsKey(userId)) {
                Slog.d(TAG, "update mb reqs for user " + userId);
                updateMandatoryBiometricsRequirementsForAllProfiles(userId);
            }

            Slog.d(TAG, mMandatoryBiometricsEnabled.getOrDefault(userId,
                    DEFAULT_MANDATORY_BIOMETRICS_STATUS)
                    + " " + mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
                    DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS)
                    + " " + getEnabledForApps(userId)
                    + " " + (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */)
                    || mFaceEnrolledForUser.getOrDefault(userId, false /* default */)));
            return mMandatoryBiometricsEnabled.getOrDefault(userId,
                    DEFAULT_MANDATORY_BIOMETRICS_STATUS)
                    && mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
@@ -456,25 +468,50 @@ public class BiometricService extends SystemService {

        private void updateMandatoryBiometricsForAllProfiles(int userId) {
            int effectiveUserId = userId;
            if (mUserManager.getMainUser() != null) {
                effectiveUserId = mUserManager.getMainUser().getIdentifier();
            final UserInfo parentProfile = mUserManager.getProfileParent(userId);

            if (parentProfile != null) {
                effectiveUserId = parentProfile.id;
            }
            for (int profileUserId: mUserManager.getEnabledProfileIds(effectiveUserId)) {

            final int[] enabledProfileIds = mUserManager.getEnabledProfileIds(effectiveUserId);
            if (enabledProfileIds != null) {
                for (int profileUserId : enabledProfileIds) {
                    mMandatoryBiometricsEnabled.put(profileUserId,
                            Settings.Secure.getIntForUser(
                                    mContentResolver, Settings.Secure.MANDATORY_BIOMETRICS,
                                    DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0,
                                    effectiveUserId) != 0);
                }
            } else {
                mMandatoryBiometricsEnabled.put(userId,
                        Settings.Secure.getIntForUser(
                                mContentResolver, Settings.Secure.MANDATORY_BIOMETRICS,
                                DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0,
                                effectiveUserId) != 0);
            }
        }

        private void updateMandatoryBiometricsRequirementsForAllProfiles(int userId) {
            int effectiveUserId = userId;
            if (mUserManager.getMainUser() != null) {
                effectiveUserId = mUserManager.getMainUser().getIdentifier();
            final UserInfo parentProfile = mUserManager.getProfileParent(userId);

            if (parentProfile != null) {
                effectiveUserId = parentProfile.id;
            }
            for (int profileUserId: mUserManager.getEnabledProfileIds(effectiveUserId)) {

            final int[] enabledProfileIds = mUserManager.getEnabledProfileIds(effectiveUserId);
            if (enabledProfileIds != null) {
                for (int profileUserId : enabledProfileIds) {
                    mMandatoryBiometricsRequirementsSatisfied.put(profileUserId,
                            Settings.Secure.getIntForUser(mContentResolver,
                                    Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
                                    DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS
                                            ? 1 : 0,
                                    effectiveUserId) != 0);
                }
            } else {
                mMandatoryBiometricsRequirementsSatisfied.put(userId,
                        Settings.Secure.getIntForUser(mContentResolver,
                                Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
                                DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS ? 1 : 0,
@@ -482,10 +519,8 @@ public class BiometricService extends SystemService {
            }
        }

        private void addBiometricListenersForMandatoryBiometrics(Context context) {
            final FingerprintManager fingerprintManager = context.getSystemService(
                    FingerprintManager.class);
            final FaceManager faceManager = context.getSystemService(FaceManager.class);
        private void addBiometricListenersForMandatoryBiometrics(Context context,
                FingerprintManager fingerprintManager, FaceManager faceManager) {
            if (fingerprintManager != null) {
                fingerprintManager.addAuthenticatorsRegisteredCallback(
                        new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
@@ -1169,7 +1204,9 @@ public class BiometricService extends SystemService {
         */
        public SettingObserver getSettingObserver(Context context, Handler handler,
                List<EnabledOnKeyguardCallback> callbacks) {
            return new SettingObserver(context, handler, callbacks);
            return new SettingObserver(context, handler, callbacks, context.getSystemService(
                    UserManager.class), context.getSystemService(FingerprintManager.class),
                    context.getSystemService(FaceManager.class));
        }

        /**
+90 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
@@ -70,8 +71,16 @@ import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorProperties;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.hardware.keymaster.HardwareAuthenticatorType;
import android.os.Binder;
import android.os.Handler;
@@ -84,6 +93,7 @@ import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.security.GateKeeper;
import android.security.KeyStoreAuthorization;
import android.service.gatekeeper.IGateKeeperService;
@@ -93,6 +103,7 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.WindowManager;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;

import com.android.internal.R;
@@ -111,6 +122,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@@ -144,6 +156,27 @@ public class BiometricServiceTest {

    private static final int SENSOR_ID_FINGERPRINT = 0;
    private static final int SENSOR_ID_FACE = 1;
    private final ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback.Stub>
            mFingerprintAuthenticatorRegisteredCallbackCaptor = ArgumentCaptor.forClass(
            IFingerprintAuthenticatorsRegisteredCallback.Stub.class);
    private final ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback.Stub>
            mFaceAuthenticatorRegisteredCallbackCaptor = ArgumentCaptor.forClass(
            IFaceAuthenticatorsRegisteredCallback.Stub.class);
    private final ArgumentCaptor<BiometricStateListener> mBiometricStateListenerArgumentCaptor =
            ArgumentCaptor.forClass(BiometricStateListener.class);
    private final List<FingerprintSensorPropertiesInternal>
            mFingerprintSensorPropertiesInternals = List.of(
                    new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT,
                            SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
                            List.of(), FingerprintSensorProperties.TYPE_UNKNOWN,
                            true /* resetLockoutRequiresHardwareAuthToken */));
    private final List<FaceSensorPropertiesInternal>
            mFaceSensorPropertiesInternals = List.of(
                    new FaceSensorPropertiesInternal(SENSOR_ID_FACE,
                            SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
                            List.of(), FaceSensorProperties.TYPE_UNKNOWN,
                            false /* supportsFaceDetection */, false /* supportsSelfIllumination */,
                            false /* resetLockoutRequiresChallenge */));

    private BiometricService mBiometricService;

@@ -192,6 +225,10 @@ public class BiometricServiceTest {

    @Mock
    private BiometricNotificationLogger mNotificationLogger;
    @Mock
    private FingerprintManager mFingerprintManager;
    @Mock
    private FaceManager mFaceManager;

    BiometricContextProvider mBiometricContextProvider;

@@ -1975,6 +2012,59 @@ public class BiometricServiceTest {
                eq(hardwareAuthenticators));
    }

    @Test
    public void testMandatoryBiometricsValue_whenParentProfileEnabled() throws RemoteException {
        final Context context = ApplicationProvider.getApplicationContext();
        final int profileParentId = context.getContentResolver().getUserId();
        final int userId = profileParentId + 1;
        final BiometricService.SettingObserver settingObserver =
                new BiometricService.SettingObserver(
                        context, mBiometricHandlerProvider.getBiometricCallbackHandler(),
                        new ArrayList<>(), mUserManager, mFingerprintManager, mFaceManager);

        verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
                mFingerprintAuthenticatorRegisteredCallbackCaptor.capture());
        verify(mFaceManager).addAuthenticatorsRegisteredCallback(
                mFaceAuthenticatorRegisteredCallbackCaptor.capture());

        mFingerprintAuthenticatorRegisteredCallbackCaptor.getValue().onAllAuthenticatorsRegistered(
                mFingerprintSensorPropertiesInternals);
        mFaceAuthenticatorRegisteredCallbackCaptor.getValue().onAllAuthenticatorsRegistered(
                mFaceSensorPropertiesInternals);

        verify(mFingerprintManager).registerBiometricStateListener(
                mBiometricStateListenerArgumentCaptor.capture());

        mBiometricStateListenerArgumentCaptor.getValue().onEnrollmentsChanged(userId,
                SENSOR_ID_FINGERPRINT, true /* hasEnrollments */);

        verify(mFaceManager).registerBiometricStateListener(
                mBiometricStateListenerArgumentCaptor.capture());

        mBiometricStateListenerArgumentCaptor.getValue().onEnrollmentsChanged(userId,
                SENSOR_ID_FACE, true /* hasEnrollments */);

        when(mUserManager.getProfileParent(userId)).thenReturn(new UserInfo(profileParentId,
                "", 0));
        when(mUserManager.getEnabledProfileIds(profileParentId)).thenReturn(new int[]{userId});

        //Disable Identity Check for profile user
        Settings.Secure.putIntForUser(context.getContentResolver(),
                Settings.Secure.MANDATORY_BIOMETRICS, 0, userId);
        Settings.Secure.putIntForUser(context.getContentResolver(),
                Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 0,
                userId);
        //Enable Identity Check for parent user
        Settings.Secure.putIntForUser(context.getContentResolver(),
                Settings.Secure.MANDATORY_BIOMETRICS, 1, profileParentId);
        Settings.Secure.putIntForUser(context.getContentResolver(),
                Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 1,
                profileParentId);

        assertTrue(settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(
                userId));
    }

    // Helper methods

    private int invokeCanAuthenticate(BiometricService service, int authenticators)