diff options
12 files changed, 116 insertions, 245 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index afb796b7687a..48ddd3049ff8 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -403,7 +403,6 @@ package android { field @Deprecated public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES"; field public static final String UPGRADE_RUNTIME_PERMISSIONS = "android.permission.UPGRADE_RUNTIME_PERMISSIONS"; field public static final String USER_ACTIVITY = "android.permission.USER_ACTIVITY"; - field @FlaggedApi("android.hardware.biometrics.face_background_authentication") public static final String USE_BACKGROUND_FACE_AUTHENTICATION = "android.permission.USE_BACKGROUND_FACE_AUTHENTICATION"; field public static final String USE_COLORIZED_NOTIFICATIONS = "android.permission.USE_COLORIZED_NOTIFICATIONS"; field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public static final String USE_ON_DEVICE_INTELLIGENCE = "android.permission.USE_ON_DEVICE_INTELLIGENCE"; field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK"; @@ -3759,7 +3758,6 @@ package android.content { field @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public static final String ECM_ENHANCED_CONFIRMATION_SERVICE = "ecm_enhanced_confirmation"; field public static final String ETHERNET_SERVICE = "ethernet"; field public static final String EUICC_CARD_SERVICE = "euicc_card"; - field @FlaggedApi("android.hardware.biometrics.face_background_authentication") public static final String FACE_SERVICE = "face"; field public static final String FONT_SERVICE = "font"; field public static final String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final String MEDIA_TRANSCODING_SERVICE = "media_transcoding"; @@ -5131,15 +5129,6 @@ package android.hardware.display { } -package android.hardware.face { - - @FlaggedApi("android.hardware.biometrics.face_background_authentication") public class FaceManager { - method @FlaggedApi("android.hardware.biometrics.face_background_authentication") @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION) public void authenticateInBackground(@Nullable java.util.concurrent.Executor, @Nullable android.hardware.biometrics.BiometricPrompt.CryptoObject, @Nullable android.os.CancellationSignal, @NonNull android.hardware.biometrics.BiometricPrompt.AuthenticationCallback); - method @FlaggedApi("android.hardware.biometrics.face_background_authentication") @RequiresPermission(anyOf={"android.permission.USE_BIOMETRIC_INTERNAL", android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION}) public boolean hasEnrolledTemplates(); - } - -} - package android.hardware.hdmi { public abstract class HdmiClient { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 70d2c7a3a41a..c7e5d88c299d 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5081,8 +5081,6 @@ public abstract class Context { * @see #getSystemService * @see android.hardware.face.FaceManager */ - @FlaggedApi(android.hardware.biometrics.Flags.FLAG_FACE_BACKGROUND_AUTHENTICATION) - @SystemApi public static final String FACE_SERVICE = "face"; /** diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig index 8165d44b251a..3ba8be4cc2ab 100644 --- a/core/java/android/hardware/biometrics/flags.aconfig +++ b/core/java/android/hardware/biometrics/flags.aconfig @@ -28,10 +28,3 @@ flag { bug: "302735104" } -flag { - name: "face_background_authentication" - namespace: "biometrics_framework" - description: "Feature flag for allowing face background authentication with USE_BACKGROUND_FACE_AUTHENTICATION." - bug: "318584190" -} - diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 066c45f03ec4..210ce2b78fca 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -18,23 +18,18 @@ package android.hardware.face; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.MANAGE_BIOMETRIC; -import static android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION; import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE; -import static android.hardware.biometrics.Flags.FLAG_FACE_BACKGROUND_AUTHENTICATION; -import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricFaceConstants; -import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricStateListener; import android.hardware.biometrics.CryptoObject; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; @@ -42,9 +37,9 @@ import android.os.Binder; import android.os.CancellationSignal; import android.os.CancellationSignal.OnCancelListener; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.IBinder; import android.os.IRemoteCallback; +import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; import android.os.Trace; @@ -54,21 +49,15 @@ import android.util.Slog; import android.view.Surface; import com.android.internal.R; +import com.android.internal.os.SomeArgs; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executor; /** * A class that coordinates access to the face authentication hardware. - * - * <p>Please use {@link BiometricPrompt} for face authentication unless the experience must be - * customized for unique system-level utilities, like the lock screen or ambient background usage. - * * @hide */ -@FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION) -@SystemApi @SystemService(Context.FACE_SERVICE) public class FaceManager implements BiometricAuthenticator, BiometricFaceConstants { @@ -99,76 +88,81 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan @Nullable private GenerateChallengeCallback mGenerateChallengeCallback; private CryptoObject mCryptoObject; private Face mRemovalFace; - private Executor mExecutor; + private Handler mHandler; private List<FaceSensorPropertiesInternal> mProps = new ArrayList<>(); private final IFaceServiceReceiver mServiceReceiver = new IFaceServiceReceiver.Stub() { @Override // binder call public void onEnrollResult(Face face, int remaining) { - mExecutor.execute(() -> sendEnrollResult(face, remaining)); + mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0, face).sendToTarget(); } @Override // binder call public void onAcquired(int acquireInfo, int vendorCode) { - mExecutor.execute(() -> sendAcquiredResult(acquireInfo, vendorCode)); + mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, vendorCode).sendToTarget(); } @Override // binder call public void onAuthenticationSucceeded(Face face, int userId, boolean isStrongBiometric) { - mExecutor.execute(() -> sendAuthenticatedSucceeded(face, userId, isStrongBiometric)); + mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, + isStrongBiometric ? 1 : 0, face).sendToTarget(); } @Override // binder call public void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric) { - mExecutor.execute(() -> sendFaceDetected(sensorId, userId, isStrongBiometric)); + mHandler.obtainMessage(MSG_FACE_DETECTED, sensorId, userId, isStrongBiometric) + .sendToTarget(); } @Override // binder call public void onAuthenticationFailed() { - mExecutor.execute(() -> sendAuthenticatedFailed()); + mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget(); } @Override // binder call public void onError(int error, int vendorCode) { - mExecutor.execute(() -> sendErrorResult(error, vendorCode)); + mHandler.obtainMessage(MSG_ERROR, error, vendorCode).sendToTarget(); } @Override // binder call public void onRemoved(Face face, int remaining) { - mExecutor.execute(() -> { - sendRemovedResult(face, remaining); - if (remaining == 0) { - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, - UserHandle.USER_CURRENT); - } - }); + mHandler.obtainMessage(MSG_REMOVED, remaining, 0, face).sendToTarget(); + if (remaining == 0) { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, + UserHandle.USER_CURRENT); + } } @Override public void onFeatureSet(boolean success, int feature) { - mExecutor.execute(() -> sendSetFeatureCompleted(success, feature)); + mHandler.obtainMessage(MSG_SET_FEATURE_COMPLETED, feature, 0, success).sendToTarget(); } @Override public void onFeatureGet(boolean success, int[] features, boolean[] featureState) { - mExecutor.execute(() -> sendGetFeatureCompleted(success, features, featureState)); + SomeArgs args = SomeArgs.obtain(); + args.arg1 = success; + args.arg2 = features; + args.arg3 = featureState; + mHandler.obtainMessage(MSG_GET_FEATURE_COMPLETED, args).sendToTarget(); } @Override public void onChallengeGenerated(int sensorId, int userId, long challenge) { - mExecutor.execute(() -> sendChallengeGenerated(sensorId, userId, challenge)); + mHandler.obtainMessage(MSG_CHALLENGE_GENERATED, sensorId, userId, challenge) + .sendToTarget(); } @Override public void onAuthenticationFrame(FaceAuthenticationFrame frame) { - mExecutor.execute(() -> sendAuthenticationFrame(frame)); + mHandler.obtainMessage(MSG_AUTHENTICATION_FRAME, frame).sendToTarget(); } @Override public void onEnrollmentFrame(FaceEnrollFrame frame) { - mExecutor.execute(() -> sendEnrollmentFrame(frame)); + mHandler.obtainMessage(MSG_ENROLLMENT_FRAME, frame).sendToTarget(); } }; @@ -181,7 +175,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan if (mService == null) { Slog.v(TAG, "FaceAuthenticationManagerService was null"); } - mExecutor = context.getMainExecutor(); + mHandler = new MyHandler(context); if (context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL) == PackageManager.PERMISSION_GRANTED) { addAuthenticatorsRegisteredCallback(new IFaceAuthenticatorsRegisteredCallback.Stub() { @@ -195,16 +189,18 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } /** - * Returns an {@link Executor} for the given {@link Handler} or the main {@link Executor} if - * {@code handler} is {@code null}. + * Use the provided handler thread for events. */ - private @NonNull Executor createExecutorForHandlerIfNeeded(@Nullable Handler handler) { - return handler != null ? new HandlerExecutor(handler) : mContext.getMainExecutor(); + private void useHandler(Handler handler) { + if (handler != null) { + mHandler = new MyHandler(handler.getLooper()); + } else if (mHandler.getLooper() != mContext.getMainLooper()) { + mHandler = new MyHandler(mContext.getMainLooper()); + } } /** * @deprecated use {@link #authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, Handler, FaceAuthenticateOptions)}. - * @hide */ @Deprecated @RequiresPermission(USE_BIOMETRIC_INTERNAL) @@ -216,22 +212,17 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } /** - * Request authentication. - * - * <p>This call operates the face recognition hardware and starts capturing images. + * Request authentication. This call operates the face recognition hardware and starts capturing images. * It terminates when * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at * which point the object is no longer valid. The operation can be canceled by using the - * provided {@code cancel} object. + * provided cancel object. * - * @param crypto the cryptographic operations to use for authentication or {@code null} if - * none required - * @param cancel an object that can be used to cancel authentication or {@code null} if not - * needed + * @param crypto object associated with the call or null if none required + * @param cancel an object that can be used to cancel authentication * @param callback an object to receive authentication events - * @param handler an optional handler to handle callback events or {@code null} to obtain main - * {@link Executor} from {@link Context} + * @param handler an optional handler to handle callback events * @param options additional options to customize this request * @throws IllegalArgumentException if the crypto operation is not supported or is not backed * by @@ -244,14 +235,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback, @Nullable Handler handler, @NonNull FaceAuthenticateOptions options) { - authenticate(crypto, cancel, callback, createExecutorForHandlerIfNeeded(handler), - options, false /* allowBackgroundAuthentication */); - } - - @RequiresPermission(anyOf = {USE_BIOMETRIC_INTERNAL, USE_BACKGROUND_FACE_AUTHENTICATION}) - private void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, - @NonNull AuthenticationCallback callback, @NonNull Executor executor, - @NonNull FaceAuthenticateOptions options, boolean allowBackgroundAuthentication) { if (callback == null) { throw new IllegalArgumentException("Must supply an authentication callback"); } @@ -266,15 +249,13 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan if (mService != null) { try { - mExecutor = executor; + useHandler(handler); mAuthenticationCallback = callback; mCryptoObject = crypto; final long operationId = crypto != null ? crypto.getOpId() : 0; Trace.beginSection("FaceManager#authenticate"); - final long authId = allowBackgroundAuthentication - ? mService.authenticateInBackground( - mToken, operationId, mServiceReceiver, options) - : mService.authenticate(mToken, operationId, mServiceReceiver, options); + final long authId = mService.authenticate( + mToken, operationId, mServiceReceiver, options); if (cancel != null) { cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId)); } @@ -292,67 +273,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } /** - * Request background face authentication. - * - * <p>This call operates the face recognition hardware and starts capturing images. - * It terminates when - * {@link BiometricPrompt.AuthenticationCallback#onAuthenticationError(int, CharSequence)} or - * {@link BiometricPrompt.AuthenticationCallback#onAuthenticationSucceeded( - * BiometricPrompt.AuthenticationResult)} is called, at which point the object is no longer - * valid. The operation can be canceled by using the provided cancel object. - * - * <p>See {@link BiometricPrompt#authenticate} for more details. Please use - * {@link BiometricPrompt} for face authentication unless the experience must be customized for - * unique system-level utilities, like the lock screen or ambient background usage. - * - * @param executor the specified {@link Executor} to handle callback events; if {@code null}, - * the callback will be executed on the main {@link Executor}. - * @param crypto the cryptographic operations to use for authentication or {@code null} if - * none required. - * @param cancel an object that can be used to cancel authentication or {@code null} if not - * needed. - * @param callback an object to receive authentication events. - * @throws IllegalArgumentException if the crypto operation is not supported or is not backed - * by - * <a href="{@docRoot}training/articles/keystore.html">Android - * Keystore facility</a>. - * @hide - */ - @RequiresPermission(USE_BACKGROUND_FACE_AUTHENTICATION) - @FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION) - @SystemApi - public void authenticateInBackground(@Nullable Executor executor, - @Nullable BiometricPrompt.CryptoObject crypto, @Nullable CancellationSignal cancel, - @NonNull BiometricPrompt.AuthenticationCallback callback) { - authenticate(crypto, cancel, new AuthenticationCallback() { - @Override - public void onAuthenticationError(int errorCode, CharSequence errString) { - callback.onAuthenticationError(errorCode, errString); - } - - @Override - public void onAuthenticationHelp(int helpCode, CharSequence helpString) { - callback.onAuthenticationHelp(helpCode, helpString); - } - - @Override - public void onAuthenticationSucceeded(AuthenticationResult result) { - callback.onAuthenticationSucceeded( - new BiometricPrompt.AuthenticationResult( - crypto, - BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC)); - } - - @Override - public void onAuthenticationFailed() { - callback.onAuthenticationFailed(); - } - }, executor == null ? mContext.getMainExecutor() : executor, - new FaceAuthenticateOptions.Builder().build(), - true /* allowBackgroundAuthentication */); - } - - /** * Uses the face hardware to detect for the presence of a face, without giving details about * accept/reject/lockout. * @hide @@ -710,14 +630,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } /** - * Determine if there are enrolled {@link Face} templates. + * Determine if there is a face enrolled. * - * @return {@code true} if there are enrolled {@link Face} templates, {@code false} otherwise + * @return true if a face is enrolled, false otherwise * @hide */ - @RequiresPermission(anyOf = {USE_BIOMETRIC_INTERNAL, USE_BACKGROUND_FACE_AUTHENTICATION}) - @FlaggedApi(FLAG_FACE_BACKGROUND_AUTHENTICATION) - @SystemApi + @RequiresPermission(USE_BIOMETRIC_INTERNAL) public boolean hasEnrolledTemplates() { return hasEnrolledTemplates(UserHandle.myUserId()); } @@ -882,7 +800,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan PowerManager.PARTIAL_WAKE_LOCK, "faceLockoutResetCallback"); wakeLock.acquire(); - mExecutor.execute(() -> { + mHandler.post(() -> { try { callback.onLockoutReset(sensorId); } finally { @@ -1352,6 +1270,70 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } } + private class MyHandler extends Handler { + private MyHandler(Context context) { + super(context.getMainLooper()); + } + + private MyHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(android.os.Message msg) { + Trace.beginSection("FaceManager#handleMessage: " + Integer.toString(msg.what)); + switch (msg.what) { + case MSG_ENROLL_RESULT: + sendEnrollResult((Face) msg.obj, msg.arg1 /* remaining */); + break; + case MSG_ACQUIRED: + sendAcquiredResult(msg.arg1 /* acquire info */, msg.arg2 /* vendorCode */); + break; + case MSG_AUTHENTICATION_SUCCEEDED: + sendAuthenticatedSucceeded((Face) msg.obj, msg.arg1 /* userId */, + msg.arg2 == 1 /* isStrongBiometric */); + break; + case MSG_AUTHENTICATION_FAILED: + sendAuthenticatedFailed(); + break; + case MSG_ERROR: + sendErrorResult(msg.arg1 /* errMsgId */, msg.arg2 /* vendorCode */); + break; + case MSG_REMOVED: + sendRemovedResult((Face) msg.obj, msg.arg1 /* remaining */); + break; + case MSG_SET_FEATURE_COMPLETED: + sendSetFeatureCompleted((boolean) msg.obj /* success */, + msg.arg1 /* feature */); + break; + case MSG_GET_FEATURE_COMPLETED: + SomeArgs args = (SomeArgs) msg.obj; + sendGetFeatureCompleted((boolean) args.arg1 /* success */, + (int[]) args.arg2 /* features */, + (boolean[]) args.arg3 /* featureState */); + args.recycle(); + break; + case MSG_CHALLENGE_GENERATED: + sendChallengeGenerated(msg.arg1 /* sensorId */, msg.arg2 /* userId */, + (long) msg.obj /* challenge */); + break; + case MSG_FACE_DETECTED: + sendFaceDetected(msg.arg1 /* sensorId */, msg.arg2 /* userId */, + (boolean) msg.obj /* isStrongBiometric */); + break; + case MSG_AUTHENTICATION_FRAME: + sendAuthenticationFrame((FaceAuthenticationFrame) msg.obj /* frame */); + break; + case MSG_ENROLLMENT_FRAME: + sendEnrollmentFrame((FaceEnrollFrame) msg.obj /* frame */); + break; + default: + Slog.w(TAG, "Unknown message: " + msg.what); + } + Trace.endSection(); + } + } + private void sendSetFeatureCompleted(boolean success, int feature) { if (mSetFeatureCallback == null) { return; diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index b98c0cb41ac9..553d9f76bd01 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -47,7 +47,7 @@ interface IFaceService { byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer); // Retrieve static sensor properties for all face sensors - @EnforcePermission(anyOf = {"USE_BIOMETRIC_INTERNAL", "USE_BACKGROUND_FACE_AUTHENTICATION"}) + @EnforcePermission("USE_BIOMETRIC_INTERNAL") List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName); // Retrieve static sensor properties for the specified sensor @@ -59,11 +59,6 @@ interface IFaceService { long authenticate(IBinder token, long operationId, IFaceServiceReceiver receiver, in FaceAuthenticateOptions options); - // Authenticate with a face. A requestId is returned that can be used to cancel this operation. - @EnforcePermission("USE_BACKGROUND_FACE_AUTHENTICATION") - long authenticateInBackground(IBinder token, long operationId, IFaceServiceReceiver receiver, - in FaceAuthenticateOptions options); - // Uses the face hardware to detect for the presence of a face, without giving details // about accept/reject/lockout. A requestId is returned that can be used to cancel this // operation. @@ -138,7 +133,7 @@ interface IFaceService { void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge); // Determine if a user has at least one enrolled face - @EnforcePermission(anyOf = {"USE_BIOMETRIC_INTERNAL", "USE_BACKGROUND_FACE_AUTHENTICATION"}) + @EnforcePermission("USE_BIOMETRIC_INTERNAL") boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName); // Return the LockoutTracker status for the specified user diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 487b5be9ef5c..92fee519b582 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6772,13 +6772,6 @@ <permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" android:protectionLevel="signature" /> - <!-- Allows privileged apps to access the background face authentication. - @SystemApi - @FlaggedApi("android.hardware.biometrics.face_background_authentication") - @hide --> - <permission android:name="android.permission.USE_BACKGROUND_FACE_AUTHENTICATION" - android:protectionLevel="signature|privileged" /> - <!-- Allows the system to control the BiometricDialog (SystemUI). Reserved for the system. @hide --> <permission android:name="android.permission.MANAGE_BIOMETRIC_DIALOG" android:protectionLevel="signature" /> diff --git a/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java b/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java index 34f5841aef72..3a872b50af75 100644 --- a/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java +++ b/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java @@ -18,7 +18,6 @@ package android.hardware.face; import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE; import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS; -import static android.hardware.biometrics.Flags.FLAG_FACE_BACKGROUND_AUTHENTICATION; import static com.google.common.truth.Truth.assertThat; @@ -36,15 +35,12 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; -import android.hardware.biometrics.BiometricPrompt; import android.os.CancellationSignal; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.IBinder; import android.os.RemoteException; import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; -import android.platform.test.annotations.RequiresFlagsEnabled; import com.android.internal.R; @@ -62,7 +58,6 @@ import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.Executor; @Presubmit @RunWith(MockitoJUnitRunner.class) @@ -83,8 +78,6 @@ public class FaceManagerTest { @Mock private FaceManager.AuthenticationCallback mAuthCallback; @Mock - private BiometricPrompt.AuthenticationCallback mBioAuthCallback; - @Mock private FaceManager.EnrollmentCallback mEnrollmentCallback; @Mock private FaceManager.FaceDetectionCallback mFaceDetectionCallback; @@ -98,16 +91,13 @@ public class FaceManagerTest { private TestLooper mLooper; private Handler mHandler; private FaceManager mFaceManager; - private Executor mExecutor; @Before public void setUp() throws Exception { mLooper = new TestLooper(); mHandler = new Handler(mLooper.getLooper()); - mExecutor = new HandlerExecutor(mHandler); when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - when(mContext.getMainExecutor()).thenReturn(mExecutor); when(mContext.getOpPackageName()).thenReturn(PACKAGE_NAME); when(mContext.getAttributionTag()).thenReturn(ATTRIBUTION_TAG); when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo()); @@ -169,19 +159,6 @@ public class FaceManagerTest { } @Test - @RequiresFlagsEnabled(FLAG_FACE_BACKGROUND_AUTHENTICATION) - public void authenticateInBackground_errorWhenUnavailable() throws Exception { - when(mService.authenticateInBackground(any(), anyLong(), any(), any())) - .thenThrow(new RemoteException()); - - mFaceManager.authenticateInBackground(mExecutor, null, new CancellationSignal(), - mBioAuthCallback); - mLooper.dispatchAll(); - - verify(mBioAuthCallback).onAuthenticationError(eq(FACE_ERROR_HW_UNAVAILABLE), any()); - } - - @Test public void enrollment_errorWhenFaceEnrollmentExists() throws RemoteException { when(mResources.getInteger(R.integer.config_faceMaxTemplatesPerUser)).thenReturn(1); when(mService.getEnrolledFaces(anyInt(), anyInt(), anyString())) diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 051e73f4d4c8..0f12438613cf 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -455,7 +455,7 @@ applications that come with the platform <permission name="android.permission.USE_BIOMETRIC" /> <permission name="android.permission.TEST_BIOMETRIC" /> <permission name="android.permission.SET_BIOMETRIC_DIALOG_LOGO" /> - <permission name="android.permission.USE_BACKGROUND_FACE_AUTHENTICATION" /> + <permission name="android.permission.MANAGE_BIOMETRIC_DIALOG" /> <!-- Permissions required for CTS test - CtsContactsProviderTestCases --> <permission name="android.contacts.permission.MANAGE_SIM_ACCOUNTS" /> <!-- Permissions required for CTS test - CtsHdmiCecHostTestCases --> diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 0c02f56ab294..eb2d13dc9eb5 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -566,9 +566,6 @@ <!-- Permission required for CTS test - android.server.biometrics --> <uses-permission android:name="android.permission.SET_BIOMETRIC_DIALOG_LOGO" /> - <!-- Permission required for CTS test - android.server.biometrics --> - <uses-permission android:name="android.permission.USE_BACKGROUND_FACE_AUTHENTICATION" /> - <!-- Permissions required for CTS test - NotificationManagerTest --> <uses-permission android:name="android.permission.MANAGE_NOTIFICATION_LISTENERS" /> diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java index 68b4e3fb51ba..7ee2a7ababb3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java @@ -149,11 +149,7 @@ public class FaceService extends SystemService { return proto.getBytes(); } - @android.annotation.EnforcePermission( - anyOf = { - android.Manifest.permission.USE_BIOMETRIC_INTERNAL, - android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION - }) + @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) @Override // Binder call public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal( String opPackageName) { @@ -297,29 +293,6 @@ public class FaceService extends SystemService { restricted, statsClient, isKeyguard); } - @android.annotation.EnforcePermission( - android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION) - @Override // Binder call - public long authenticateInBackground(final IBinder token, final long operationId, - final IFaceServiceReceiver receiver, final FaceAuthenticateOptions options) { - // TODO(b/152413782): If the sensor supports face detect and the device is encrypted or - // lockdown, something wrong happened. See similar path in FingerprintService. - - super.authenticateInBackground_enforcePermission(); - - final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider(); - if (provider == null) { - Slog.w(TAG, "Null provider for authenticate"); - return -1; - } - options.setSensorId(provider.first); - - return provider.second.scheduleAuthenticate(token, operationId, - 0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options, - false /* restricted */, BiometricsProtoEnums.CLIENT_UNKNOWN /* statsClient */, - true /* allowBackgroundAuthentication */); - } - @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) @Override // Binder call public long detectFace(final IBinder token, @@ -583,11 +556,7 @@ public class FaceService extends SystemService { return provider.getEnrolledFaces(sensorId, userId); } - @android.annotation.EnforcePermission( - anyOf = { - android.Manifest.permission.USE_BIOMETRIC_INTERNAL, - android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION - }) + @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) @Override // Binder call public boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName) { super.hasEnrolledFaces_enforcePermission(); diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 5e5181bdfeeb..0089d4cafaad 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -109,7 +109,6 @@ <uses-permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES" /> <uses-permission android:name="android.permission.ACCESS_CONTEXT_HUB" /> <uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" /> - <uses-permission android:name="android.permission.USE_BACKGROUND_FACE_AUTHENTICATION" /> <uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION" /> <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" /> diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java index c8a5583de0b2..3aaac2e9cf1b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java @@ -16,7 +16,6 @@ package com.android.server.biometrics.sensors.face; -import static android.Manifest.permission.USE_BACKGROUND_FACE_AUTHENTICATION; import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; import static android.hardware.face.FaceSensorProperties.TYPE_UNKNOWN; @@ -235,26 +234,6 @@ public class FaceServiceTest { } @Test - public void testAuthenticateInBackground() throws Exception { - FaceAuthenticateOptions faceAuthenticateOptions = new FaceAuthenticateOptions.Builder() - .build(); - initService(); - mFaceService.mServiceWrapper.registerAuthenticators(List.of()); - waitForRegistration(); - - mContext.getTestablePermissions().setPermission( - USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_DENIED); - mContext.getTestablePermissions().setPermission( - USE_BACKGROUND_FACE_AUTHENTICATION, PackageManager.PERMISSION_GRANTED); - - final long operationId = 5; - mFaceService.mServiceWrapper.authenticateInBackground(mToken, operationId, - mFaceServiceReceiver, faceAuthenticateOptions); - - assertThat(faceAuthenticateOptions.getSensorId()).isEqualTo(ID_DEFAULT); - } - - @Test public void testOptionsForDetect() throws Exception { FaceAuthenticateOptions faceAuthenticateOptions = new FaceAuthenticateOptions.Builder() .setOpPackageName(ComponentName.unflattenFromString(OP_PACKAGE_NAME) |