Revert "Expose `FaceManager` APIs as `@SystemApi`."
Revert submission 25750009-facemanager_20240110
Reason for revert: Project cancelled.
Reverted changes: /q/submissionid:25750009-facemanager_20240110
Test: Local
Change-Id: I7e329f311b3eb599195f415cf39dc28bb11139a1
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index d190c62..5cd3e63 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -403,7 +403,6 @@
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 @@
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";
@@ -5137,15 +5135,6 @@
}
-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 70d2c7a..c7e5d88 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5081,8 +5081,6 @@
* @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 8165d44..3ba8be4 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -28,10 +28,3 @@
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 066c45f..210ce2b 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -18,23 +18,18 @@
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.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.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 @@
@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 @@
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 @@
}
/**
- * 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 @@
}
/**
- * 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 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 @@
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 @@
}
/**
- * 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 @@
}
/**
- * 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 @@
PowerManager.PARTIAL_WAKE_LOCK,
"faceLockoutResetCallback");
wakeLock.acquire();
- mExecutor.execute(() -> {
+ mHandler.post(() -> {
try {
callback.onLockoutReset(sensorId);
} finally {
@@ -1352,6 +1270,70 @@
}
}
+ 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 b98c0cb..553d9f7 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -47,7 +47,7 @@
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 @@
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 @@
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 52bad21..d556b33 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 34f5841..3a872b5 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 @@
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 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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.Executor;
@Presubmit
@RunWith(MockitoJUnitRunner.class)
@@ -83,8 +78,6 @@
@Mock
private FaceManager.AuthenticationCallback mAuthCallback;
@Mock
- private BiometricPrompt.AuthenticationCallback mBioAuthCallback;
- @Mock
private FaceManager.EnrollmentCallback mEnrollmentCallback;
@Mock
private FaceManager.FaceDetectionCallback mFaceDetectionCallback;
@@ -98,16 +91,13 @@
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 @@
}
@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 051e73f..0f12438 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -455,7 +455,7 @@
<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 0c02f56..eb2d13d 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 68b4e3f..7ee2a7a 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 @@
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 @@
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 @@
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 5e5181b..0089d4c 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 c8a5583d..3aaac2e 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 @@
}
@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)