Add SensorPrivacy error message to FaceService.
If the camera privacy sensor is enabled, show an error message on Keyguard. Test: Verified that the sensor privacy error is shown when privacy sensor is enabled. Bug: 201045056 Change-Id: Ib7709596d378caa690a782294197a5b26e55857f
This commit is contained in:
@@ -69,7 +69,7 @@ public interface BiometricFaceConstants {
|
||||
BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
|
||||
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
|
||||
BIOMETRIC_ERROR_RE_ENROLL,
|
||||
FACE_ERROR_UNKNOWN
|
||||
FACE_ERROR_UNKNOWN,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface FaceError {}
|
||||
|
||||
@@ -219,6 +219,9 @@
|
||||
<!-- Face hint message when finger was not recognized. [CHAR LIMIT=20] -->
|
||||
<string name="kg_face_not_recognized">Not recognized</string>
|
||||
|
||||
<!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=NONE] -->
|
||||
<string name="kg_face_sensor_privacy_enabled">To use Face Unlock, turn on <b>Camera access</b> in Settings > Privacy</string>
|
||||
|
||||
<!-- Instructions telling the user remaining times when enter SIM PIN view. -->
|
||||
<plurals name="kg_password_default_pin_message">
|
||||
<item quantity="one">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining
|
||||
|
||||
@@ -51,6 +51,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
||||
@@ -322,6 +323,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
private boolean mLockIconPressed;
|
||||
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private final Executor mBackgroundExecutor;
|
||||
private SensorPrivacyManager mSensorPrivacyManager;
|
||||
private int mFaceAuthUserId;
|
||||
|
||||
/**
|
||||
* Short delay before restarting fingerprint authentication after a successful try. This should
|
||||
@@ -993,6 +996,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
|
||||
// Error is always the end of authentication lifecycle
|
||||
mFaceCancelSignal = null;
|
||||
boolean cameraPrivacyEnabled = false;
|
||||
if (mSensorPrivacyManager != null) {
|
||||
cameraPrivacyEnabled = mSensorPrivacyManager
|
||||
.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
|
||||
mFaceAuthUserId);
|
||||
}
|
||||
|
||||
if (msgId == FaceManager.FACE_ERROR_CANCELED
|
||||
&& mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
|
||||
@@ -1002,7 +1011,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
setFaceRunningState(BIOMETRIC_STATE_STOPPED);
|
||||
}
|
||||
|
||||
if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE
|
||||
final boolean isHwUnavailable = msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE;
|
||||
|
||||
if (isHwUnavailable
|
||||
|| msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) {
|
||||
if (mHardwareFaceUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
|
||||
mHardwareFaceUnavailableRetryCount++;
|
||||
@@ -1018,6 +1029,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
requireStrongAuthIfAllLockedOut();
|
||||
}
|
||||
|
||||
if (isHwUnavailable && cameraPrivacyEnabled) {
|
||||
errString = mContext.getString(R.string.kg_face_sensor_privacy_enabled);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||
if (cb != null) {
|
||||
@@ -1791,6 +1806,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mAuthController = authController;
|
||||
dumpManager.registerDumpable(getClass().getName(), this);
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
mHandler = new Handler(mainLooper) {
|
||||
@Override
|
||||
@@ -2476,6 +2492,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
// This would need to be updated for multi-sensor devices
|
||||
final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
|
||||
&& mFaceSensorProperties.get(0).supportsFaceDetection;
|
||||
mFaceAuthUserId = userId;
|
||||
if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
|
||||
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
|
||||
} else {
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
@@ -56,6 +57,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
@NonNull private final LockoutCache mLockoutCache;
|
||||
@Nullable private final NotificationManager mNotificationManager;
|
||||
@Nullable private ICancellationSignal mCancellationSignal;
|
||||
@Nullable private SensorPrivacyManager mSensorPrivacyManager;
|
||||
|
||||
private final int[] mBiometricPromptIgnoreList;
|
||||
private final int[] mBiometricPromptIgnoreListVendor;
|
||||
@@ -81,6 +83,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
mUsageStats = usageStats;
|
||||
mLockoutCache = lockoutCache;
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
final Resources resources = getContext().getResources();
|
||||
mBiometricPromptIgnoreList = resources.getIntArray(
|
||||
@@ -108,7 +111,16 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
try {
|
||||
mCancellationSignal = getFreshDaemon().authenticate(mOperationId);
|
||||
if (mSensorPrivacyManager != null
|
||||
&& mSensorPrivacyManager
|
||||
.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
|
||||
getTargetUserId())) {
|
||||
onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
} else {
|
||||
mCancellationSignal = getFreshDaemon().authenticate(mOperationId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception when requesting auth", e);
|
||||
onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.server.biometrics.sensors.face.aidl;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
@@ -41,6 +43,7 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det
|
||||
|
||||
private final boolean mIsStrongBiometric;
|
||||
@Nullable private ICancellationSignal mCancellationSignal;
|
||||
@Nullable private SensorPrivacyManager mSensorPrivacyManager;
|
||||
|
||||
public FaceDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@@ -51,6 +54,7 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det
|
||||
BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
|
||||
setRequestId(requestId);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +77,14 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
if (mSensorPrivacyManager != null
|
||||
&& mSensorPrivacyManager
|
||||
.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
|
||||
onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mCancellationSignal = getFreshDaemon().detectInteraction();
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors.face.hidl;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
@@ -55,6 +56,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
private final int[] mKeyguardIgnoreListVendor;
|
||||
|
||||
private int mLastAcquire;
|
||||
private SensorPrivacyManager mSensorPrivacyManager;
|
||||
|
||||
FaceAuthenticationClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<IBiometricsFace> lazyDaemon,
|
||||
@@ -71,6 +73,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
isKeyguardBypassEnabled);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
final Resources resources = getContext().getResources();
|
||||
mBiometricPromptIgnoreList = resources.getIntArray(
|
||||
@@ -97,6 +100,15 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
|
||||
if (mSensorPrivacyManager != null
|
||||
&& mSensorPrivacyManager
|
||||
.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
|
||||
onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
getFreshDaemon().authenticate(mOperationId);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
Reference in New Issue
Block a user