Loading services/core/java/com/android/server/biometrics/BiometricSensorPrivacy.java→services/core/java/com/android/server/biometrics/BiometricCameraManager.java +10 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,16 @@ package com.android.server.biometrics; /** * Interface for biometric operations to get camera privacy state. * Interface for biometrics to get camera status. */ public interface BiometricCameraManager { /** * Returns true if any camera is in use. */ boolean isAnyCameraUnavailable(); /** * Returns true if privacy is enabled and camera access is disabled. */ public interface BiometricSensorPrivacy { /* Returns true if privacy is enabled and camera access is disabled. */ boolean isCameraPrivacyEnabled(); } services/core/java/com/android/server/biometrics/BiometricSensorPrivacyImpl.java→services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java +68 −0 Original line number Diff line number Diff line Loading @@ -18,15 +18,46 @@ package com.android.server.biometrics; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import android.annotation.Nullable; import android.annotation.NonNull; import android.hardware.SensorPrivacyManager; import android.hardware.camera2.CameraManager; public class BiometricSensorPrivacyImpl implements BiometricSensorPrivacy { import java.util.concurrent.ConcurrentHashMap; public class BiometricCameraManagerImpl implements BiometricCameraManager { private final CameraManager mCameraManager; private final SensorPrivacyManager mSensorPrivacyManager; private final ConcurrentHashMap<String, Boolean> mIsCameraAvailable = new ConcurrentHashMap<>(); public BiometricSensorPrivacyImpl(@Nullable SensorPrivacyManager sensorPrivacyManager) { private final CameraManager.AvailabilityCallback mCameraAvailabilityCallback = new CameraManager.AvailabilityCallback() { @Override public void onCameraAvailable(@NonNull String cameraId) { mIsCameraAvailable.put(cameraId, true); } @Override public void onCameraUnavailable(@NonNull String cameraId) { mIsCameraAvailable.put(cameraId, false); } }; public BiometricCameraManagerImpl(@NonNull CameraManager cameraManager, @NonNull SensorPrivacyManager sensorPrivacyManager) { mCameraManager = cameraManager; mSensorPrivacyManager = sensorPrivacyManager; mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, null); } @Override public boolean isAnyCameraUnavailable() { for (String cameraId : mIsCameraAvailable.keySet()) { if (!mIsCameraAvailable.get(cameraId)) { return true; } } return false; } @Override Loading services/core/java/com/android/server/biometrics/BiometricService.java +8 −7 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.camera2.CameraManager; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.net.Uri; Loading Loading @@ -125,7 +126,7 @@ public class BiometricService extends SystemService { AuthSession mAuthSession; private final Handler mHandler = new Handler(Looper.getMainLooper()); private final BiometricSensorPrivacy mBiometricSensorPrivacy; private final BiometricCameraManager mBiometricCameraManager; /** * Tracks authenticatorId invalidation. For more details, see Loading Loading @@ -936,7 +937,7 @@ public class BiometricService extends SystemService { return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */, getContext(), mBiometricSensorPrivacy); getContext(), mBiometricCameraManager); } /** Loading Loading @@ -1030,9 +1031,9 @@ public class BiometricService extends SystemService { return context.getSystemService(UserManager.class); } public BiometricSensorPrivacy getBiometricSensorPrivacy(Context context) { return new BiometricSensorPrivacyImpl(context.getSystemService( SensorPrivacyManager.class)); public BiometricCameraManager getBiometricCameraManager(Context context) { return new BiometricCameraManagerImpl(context.getSystemService(CameraManager.class), context.getSystemService(SensorPrivacyManager.class)); } } Loading Loading @@ -1062,7 +1063,7 @@ public class BiometricService extends SystemService { mRequestCounter = mInjector.getRequestGenerator(); mBiometricContext = injector.getBiometricContext(context); mUserManager = injector.getUserManager(context); mBiometricSensorPrivacy = injector.getBiometricSensorPrivacy(context); mBiometricCameraManager = injector.getBiometricCameraManager(context); try { injector.getActivityManagerService().registerUserSwitchObserver( Loading Loading @@ -1299,7 +1300,7 @@ public class BiometricService extends SystemService { final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(), getContext(), mBiometricSensorPrivacy); getContext(), mBiometricCameraManager); final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus(); Loading services/core/java/com/android/server/biometrics/PreAuthInfo.java +15 −11 Original line number Diff line number Diff line Loading @@ -72,16 +72,16 @@ class PreAuthInfo { final Context context; private final boolean mBiometricRequested; private final int mBiometricStrengthRequested; private final BiometricSensorPrivacy mBiometricSensorPrivacy; private final BiometricCameraManager mBiometricCameraManager; private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested, boolean credentialRequested, List<BiometricSensor> eligibleSensors, List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable, boolean confirmationRequested, boolean ignoreEnrollmentState, int userId, Context context, BiometricSensorPrivacy biometricSensorPrivacy) { Context context, BiometricCameraManager biometricCameraManager) { mBiometricRequested = biometricRequested; mBiometricStrengthRequested = biometricStrengthRequested; mBiometricSensorPrivacy = biometricSensorPrivacy; mBiometricCameraManager = biometricCameraManager; this.credentialRequested = credentialRequested; this.eligibleSensors = eligibleSensors; Loading @@ -99,7 +99,7 @@ class PreAuthInfo { List<BiometricSensor> sensors, int userId, PromptInfo promptInfo, String opPackageName, boolean checkDevicePolicyManager, Context context, BiometricSensorPrivacy biometricSensorPrivacy) BiometricCameraManager biometricCameraManager) throws RemoteException { final boolean confirmationRequested = promptInfo.isConfirmationRequested(); Loading Loading @@ -127,7 +127,7 @@ class PreAuthInfo { checkDevicePolicyManager, requestedStrength, promptInfo.getAllowedSensorIds(), promptInfo.isIgnoreEnrollmentState(), biometricSensorPrivacy); biometricCameraManager); Slog.d(TAG, "Package: " + opPackageName + " Sensor ID: " + sensor.id Loading @@ -151,7 +151,7 @@ class PreAuthInfo { return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested, eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested, promptInfo.isIgnoreEnrollmentState(), userId, context, biometricSensorPrivacy); promptInfo.isIgnoreEnrollmentState(), userId, context, biometricCameraManager); } /** Loading @@ -168,12 +168,16 @@ class PreAuthInfo { BiometricSensor sensor, int userId, String opPackageName, boolean checkDevicePolicyManager, int requestedStrength, @NonNull List<Integer> requestedSensorIds, boolean ignoreEnrollmentState, BiometricSensorPrivacy biometricSensorPrivacy) { boolean ignoreEnrollmentState, BiometricCameraManager biometricCameraManager) { if (!requestedSensorIds.isEmpty() && !requestedSensorIds.contains(sensor.id)) { return BIOMETRIC_NO_HARDWARE; } if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) { return BIOMETRIC_HARDWARE_NOT_DETECTED; } final boolean wasStrongEnough = Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength); final boolean isStrongEnough = Loading @@ -195,8 +199,8 @@ class PreAuthInfo { return BIOMETRIC_NOT_ENROLLED; } if (biometricSensorPrivacy != null && sensor.modality == TYPE_FACE) { if (biometricSensorPrivacy.isCameraPrivacyEnabled()) { if (biometricCameraManager != null && sensor.modality == TYPE_FACE) { if (biometricCameraManager.isCameraPrivacyEnabled()) { //Camera privacy is enabled as the access is disabled return BIOMETRIC_SENSOR_PRIVACY_ENABLED; } Loading Loading @@ -307,8 +311,8 @@ class PreAuthInfo { @BiometricAuthenticator.Modality int modality = TYPE_NONE; boolean cameraPrivacyEnabled = false; if (mBiometricSensorPrivacy != null) { cameraPrivacyEnabled = mBiometricSensorPrivacy.isCameraPrivacyEnabled(); if (mBiometricCameraManager != null) { cameraPrivacyEnabled = mBiometricCameraManager.isCameraPrivacyEnabled(); } if (mBiometricRequested && credentialRequested) { Loading services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ public class AuthSessionTest { @Mock private KeyStore mKeyStore; @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver; @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger; @Mock BiometricSensorPrivacy mBiometricSensorPrivacy; @Mock private BiometricCameraManager mBiometricCameraManager; private Random mRandom; private IBinder mToken; Loading Loading @@ -609,7 +609,7 @@ public class AuthSessionTest { TEST_PACKAGE, checkDevicePolicyManager, mContext, mBiometricSensorPrivacy); mBiometricCameraManager); } private AuthSession createAuthSession(List<BiometricSensor> sensors, Loading Loading
services/core/java/com/android/server/biometrics/BiometricSensorPrivacy.java→services/core/java/com/android/server/biometrics/BiometricCameraManager.java +10 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,16 @@ package com.android.server.biometrics; /** * Interface for biometric operations to get camera privacy state. * Interface for biometrics to get camera status. */ public interface BiometricCameraManager { /** * Returns true if any camera is in use. */ boolean isAnyCameraUnavailable(); /** * Returns true if privacy is enabled and camera access is disabled. */ public interface BiometricSensorPrivacy { /* Returns true if privacy is enabled and camera access is disabled. */ boolean isCameraPrivacyEnabled(); }
services/core/java/com/android/server/biometrics/BiometricSensorPrivacyImpl.java→services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java +68 −0 Original line number Diff line number Diff line Loading @@ -18,15 +18,46 @@ package com.android.server.biometrics; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import android.annotation.Nullable; import android.annotation.NonNull; import android.hardware.SensorPrivacyManager; import android.hardware.camera2.CameraManager; public class BiometricSensorPrivacyImpl implements BiometricSensorPrivacy { import java.util.concurrent.ConcurrentHashMap; public class BiometricCameraManagerImpl implements BiometricCameraManager { private final CameraManager mCameraManager; private final SensorPrivacyManager mSensorPrivacyManager; private final ConcurrentHashMap<String, Boolean> mIsCameraAvailable = new ConcurrentHashMap<>(); public BiometricSensorPrivacyImpl(@Nullable SensorPrivacyManager sensorPrivacyManager) { private final CameraManager.AvailabilityCallback mCameraAvailabilityCallback = new CameraManager.AvailabilityCallback() { @Override public void onCameraAvailable(@NonNull String cameraId) { mIsCameraAvailable.put(cameraId, true); } @Override public void onCameraUnavailable(@NonNull String cameraId) { mIsCameraAvailable.put(cameraId, false); } }; public BiometricCameraManagerImpl(@NonNull CameraManager cameraManager, @NonNull SensorPrivacyManager sensorPrivacyManager) { mCameraManager = cameraManager; mSensorPrivacyManager = sensorPrivacyManager; mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, null); } @Override public boolean isAnyCameraUnavailable() { for (String cameraId : mIsCameraAvailable.keySet()) { if (!mIsCameraAvailable.get(cameraId)) { return true; } } return false; } @Override Loading
services/core/java/com/android/server/biometrics/BiometricService.java +8 −7 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.camera2.CameraManager; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.net.Uri; Loading Loading @@ -125,7 +126,7 @@ public class BiometricService extends SystemService { AuthSession mAuthSession; private final Handler mHandler = new Handler(Looper.getMainLooper()); private final BiometricSensorPrivacy mBiometricSensorPrivacy; private final BiometricCameraManager mBiometricCameraManager; /** * Tracks authenticatorId invalidation. For more details, see Loading Loading @@ -936,7 +937,7 @@ public class BiometricService extends SystemService { return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */, getContext(), mBiometricSensorPrivacy); getContext(), mBiometricCameraManager); } /** Loading Loading @@ -1030,9 +1031,9 @@ public class BiometricService extends SystemService { return context.getSystemService(UserManager.class); } public BiometricSensorPrivacy getBiometricSensorPrivacy(Context context) { return new BiometricSensorPrivacyImpl(context.getSystemService( SensorPrivacyManager.class)); public BiometricCameraManager getBiometricCameraManager(Context context) { return new BiometricCameraManagerImpl(context.getSystemService(CameraManager.class), context.getSystemService(SensorPrivacyManager.class)); } } Loading Loading @@ -1062,7 +1063,7 @@ public class BiometricService extends SystemService { mRequestCounter = mInjector.getRequestGenerator(); mBiometricContext = injector.getBiometricContext(context); mUserManager = injector.getUserManager(context); mBiometricSensorPrivacy = injector.getBiometricSensorPrivacy(context); mBiometricCameraManager = injector.getBiometricCameraManager(context); try { injector.getActivityManagerService().registerUserSwitchObserver( Loading Loading @@ -1299,7 +1300,7 @@ public class BiometricService extends SystemService { final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(), getContext(), mBiometricSensorPrivacy); getContext(), mBiometricCameraManager); final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus(); Loading
services/core/java/com/android/server/biometrics/PreAuthInfo.java +15 −11 Original line number Diff line number Diff line Loading @@ -72,16 +72,16 @@ class PreAuthInfo { final Context context; private final boolean mBiometricRequested; private final int mBiometricStrengthRequested; private final BiometricSensorPrivacy mBiometricSensorPrivacy; private final BiometricCameraManager mBiometricCameraManager; private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested, boolean credentialRequested, List<BiometricSensor> eligibleSensors, List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable, boolean confirmationRequested, boolean ignoreEnrollmentState, int userId, Context context, BiometricSensorPrivacy biometricSensorPrivacy) { Context context, BiometricCameraManager biometricCameraManager) { mBiometricRequested = biometricRequested; mBiometricStrengthRequested = biometricStrengthRequested; mBiometricSensorPrivacy = biometricSensorPrivacy; mBiometricCameraManager = biometricCameraManager; this.credentialRequested = credentialRequested; this.eligibleSensors = eligibleSensors; Loading @@ -99,7 +99,7 @@ class PreAuthInfo { List<BiometricSensor> sensors, int userId, PromptInfo promptInfo, String opPackageName, boolean checkDevicePolicyManager, Context context, BiometricSensorPrivacy biometricSensorPrivacy) BiometricCameraManager biometricCameraManager) throws RemoteException { final boolean confirmationRequested = promptInfo.isConfirmationRequested(); Loading Loading @@ -127,7 +127,7 @@ class PreAuthInfo { checkDevicePolicyManager, requestedStrength, promptInfo.getAllowedSensorIds(), promptInfo.isIgnoreEnrollmentState(), biometricSensorPrivacy); biometricCameraManager); Slog.d(TAG, "Package: " + opPackageName + " Sensor ID: " + sensor.id Loading @@ -151,7 +151,7 @@ class PreAuthInfo { return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested, eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested, promptInfo.isIgnoreEnrollmentState(), userId, context, biometricSensorPrivacy); promptInfo.isIgnoreEnrollmentState(), userId, context, biometricCameraManager); } /** Loading @@ -168,12 +168,16 @@ class PreAuthInfo { BiometricSensor sensor, int userId, String opPackageName, boolean checkDevicePolicyManager, int requestedStrength, @NonNull List<Integer> requestedSensorIds, boolean ignoreEnrollmentState, BiometricSensorPrivacy biometricSensorPrivacy) { boolean ignoreEnrollmentState, BiometricCameraManager biometricCameraManager) { if (!requestedSensorIds.isEmpty() && !requestedSensorIds.contains(sensor.id)) { return BIOMETRIC_NO_HARDWARE; } if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) { return BIOMETRIC_HARDWARE_NOT_DETECTED; } final boolean wasStrongEnough = Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength); final boolean isStrongEnough = Loading @@ -195,8 +199,8 @@ class PreAuthInfo { return BIOMETRIC_NOT_ENROLLED; } if (biometricSensorPrivacy != null && sensor.modality == TYPE_FACE) { if (biometricSensorPrivacy.isCameraPrivacyEnabled()) { if (biometricCameraManager != null && sensor.modality == TYPE_FACE) { if (biometricCameraManager.isCameraPrivacyEnabled()) { //Camera privacy is enabled as the access is disabled return BIOMETRIC_SENSOR_PRIVACY_ENABLED; } Loading Loading @@ -307,8 +311,8 @@ class PreAuthInfo { @BiometricAuthenticator.Modality int modality = TYPE_NONE; boolean cameraPrivacyEnabled = false; if (mBiometricSensorPrivacy != null) { cameraPrivacyEnabled = mBiometricSensorPrivacy.isCameraPrivacyEnabled(); if (mBiometricCameraManager != null) { cameraPrivacyEnabled = mBiometricCameraManager.isCameraPrivacyEnabled(); } if (mBiometricRequested && credentialRequested) { Loading
services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ public class AuthSessionTest { @Mock private KeyStore mKeyStore; @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver; @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger; @Mock BiometricSensorPrivacy mBiometricSensorPrivacy; @Mock private BiometricCameraManager mBiometricCameraManager; private Random mRandom; private IBinder mToken; Loading Loading @@ -609,7 +609,7 @@ public class AuthSessionTest { TEST_PACKAGE, checkDevicePolicyManager, mContext, mBiometricSensorPrivacy); mBiometricCameraManager); } private AuthSession createAuthSession(List<BiometricSensor> sensors, Loading