Loading core/java/android/hardware/face/FaceManager.java +68 −8 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.Log; import android.util.Slog; import com.android.internal.R; import com.android.internal.os.SomeArgs; import java.util.List; Loading @@ -63,6 +64,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan private static final int MSG_AUTHENTICATION_FAILED = 103; private static final int MSG_ERROR = 104; private static final int MSG_REMOVED = 105; private static final int MSG_GET_FEATURE_COMPLETED = 106; private static final int MSG_SET_FEATURE_COMPLETED = 107; private IFaceService mService; private final Context mContext; Loading @@ -70,6 +73,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan private AuthenticationCallback mAuthenticationCallback; private EnrollmentCallback mEnrollmentCallback; private RemovalCallback mRemovalCallback; private SetFeatureCallback mSetFeatureCallback; private GetFeatureCallback mGetFeatureCallback; private CryptoObject mCryptoObject; private Face mRemovalFace; private Handler mHandler; Loading Loading @@ -112,6 +117,20 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan public void onEnumerated(long deviceId, int faceId, int remaining) { // TODO: Finish. Low priority since it's not used. } @Override public void onFeatureSet(boolean success, int feature) { mHandler.obtainMessage(MSG_SET_FEATURE_COMPLETED, feature, 0, success).sendToTarget(); } @Override public void onFeatureGet(boolean success, int feature, boolean value) { SomeArgs args = SomeArgs.obtain(); args.arg1 = success; args.argi1 = feature; args.arg2 = value; mHandler.obtainMessage(MSG_GET_FEATURE_COMPLETED, args).sendToTarget(); } }; /** Loading Loading @@ -286,31 +305,31 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan * @hide */ @RequiresPermission(MANAGE_BIOMETRIC) public boolean setFeature(int feature, boolean enabled, byte[] token) { public void setFeature(int feature, boolean enabled, byte[] token, SetFeatureCallback callback) { if (mService != null) { try { return mService.setFeature(feature, enabled, token); mSetFeatureCallback = callback; mService.setFeature(feature, enabled, token, mServiceReceiver); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * @hide */ @RequiresPermission(MANAGE_BIOMETRIC) public boolean getFeature(int feature) { boolean result = true; public void getFeature(int feature, GetFeatureCallback callback) { if (mService != null) { try { result = mService.getFeature(feature); mGetFeatureCallback = callback; mService.getFeature(feature, mServiceReceiver); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return result; } /** Loading Loading @@ -874,6 +893,20 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } } /** * @hide */ public abstract static class SetFeatureCallback { public abstract void onCompleted(boolean success, int feature); } /** * @hide */ public abstract static class GetFeatureCallback { public abstract void onCompleted(boolean success, int feature, boolean value); } private class OnEnrollCancelListener implements OnCancelListener { @Override public void onCancel() { Loading Loading @@ -926,9 +959,36 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan 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 */, args.argi1 /* feature */, (boolean) args.arg2 /* value */); args.recycle(); break; default: Log.w(TAG, "Unknown message: " + msg.what); } } }; } private void sendSetFeatureCompleted(boolean success, int feature) { if (mSetFeatureCallback == null) { return; } mSetFeatureCallback.onCompleted(success, feature); } private void sendGetFeatureCompleted(boolean success, int feature, boolean value) { if (mGetFeatureCallback == null) { return; } mGetFeatureCallback.onCompleted(success, feature, value); } private void sendRemovedResult(Face face, int remaining) { if (mRemovalCallback == null) { Loading core/java/android/hardware/face/IFaceService.aidl +4 −3 Original line number Diff line number Diff line Loading @@ -98,9 +98,10 @@ interface IFaceService { // Enumerate all faces void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver); boolean setFeature(int feature, boolean enabled, in byte [] token); void setFeature(int feature, boolean enabled, in byte [] token, IFaceServiceReceiver receiver); boolean getFeature(int feature); void getFeature(int feature, IFaceServiceReceiver receiver); void userActivity(); } core/java/android/hardware/face/IFaceServiceReceiver.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -29,4 +29,6 @@ oneway interface IFaceServiceReceiver { void onError(long deviceId, int error, int vendorCode); void onRemoved(long deviceId, int faceId, int remaining); void onEnumerated(long deviceId, int faceId, int remaining); void onFeatureSet(boolean success, int feature); void onFeatureGet(boolean success, int feature, boolean value); } services/core/java/com/android/server/biometrics/face/FaceService.java +41 −40 Original line number Diff line number Diff line Loading @@ -397,12 +397,14 @@ public class FaceService extends BiometricServiceBase { } @Override public boolean setFeature(int feature, boolean enabled, final byte[] token) { public void setFeature(int feature, boolean enabled, final byte[] token, IFaceServiceReceiver receiver) { checkPermission(MANAGE_BIOMETRIC); mHandler.post(() -> { if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) { Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature); return false; return; } final ArrayList<Byte> byteToken = new ArrayList<>(); Loading @@ -415,24 +417,27 @@ public class FaceService extends BiometricServiceBase { if (mDaemon != null) { try { return mDaemon.setFeature(feature, enabled, byteToken, faceId) == Status.OK; final int result = mDaemon.setFeature(feature, enabled, byteToken, faceId); receiver.onFeatureSet(result == Status.OK, feature); } catch (RemoteException e) { Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled, e); Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled, e); } } return false; }); } @Override public boolean getFeature(int feature) { public void getFeature(int feature, IFaceServiceReceiver receiver) { checkPermission(MANAGE_BIOMETRIC); mHandler.post(() -> { // This should ideally return tri-state, but the user isn't shown settings unless // they are enrolled so it's fine for now. if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) { Slog.e(TAG, "No enrolled biometrics while getting feature: " + feature); return false; return; } // TODO: Support multiple faces Loading @@ -441,17 +446,13 @@ public class FaceService extends BiometricServiceBase { if (mDaemon != null) { try { OptionalBool result = mDaemon.getFeature(feature, faceId); if (result.status == Status.OK) { return result.value; } else { // Same tri-state comment applies here. return false; } receiver.onFeatureGet(result.status == Status.OK, feature, result.value); } catch (RemoteException e) { Slog.e(getTag(), "Unable to getRequireAttention", e); } } return false; }); } @Override Loading Loading
core/java/android/hardware/face/FaceManager.java +68 −8 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.Log; import android.util.Slog; import com.android.internal.R; import com.android.internal.os.SomeArgs; import java.util.List; Loading @@ -63,6 +64,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan private static final int MSG_AUTHENTICATION_FAILED = 103; private static final int MSG_ERROR = 104; private static final int MSG_REMOVED = 105; private static final int MSG_GET_FEATURE_COMPLETED = 106; private static final int MSG_SET_FEATURE_COMPLETED = 107; private IFaceService mService; private final Context mContext; Loading @@ -70,6 +73,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan private AuthenticationCallback mAuthenticationCallback; private EnrollmentCallback mEnrollmentCallback; private RemovalCallback mRemovalCallback; private SetFeatureCallback mSetFeatureCallback; private GetFeatureCallback mGetFeatureCallback; private CryptoObject mCryptoObject; private Face mRemovalFace; private Handler mHandler; Loading Loading @@ -112,6 +117,20 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan public void onEnumerated(long deviceId, int faceId, int remaining) { // TODO: Finish. Low priority since it's not used. } @Override public void onFeatureSet(boolean success, int feature) { mHandler.obtainMessage(MSG_SET_FEATURE_COMPLETED, feature, 0, success).sendToTarget(); } @Override public void onFeatureGet(boolean success, int feature, boolean value) { SomeArgs args = SomeArgs.obtain(); args.arg1 = success; args.argi1 = feature; args.arg2 = value; mHandler.obtainMessage(MSG_GET_FEATURE_COMPLETED, args).sendToTarget(); } }; /** Loading Loading @@ -286,31 +305,31 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan * @hide */ @RequiresPermission(MANAGE_BIOMETRIC) public boolean setFeature(int feature, boolean enabled, byte[] token) { public void setFeature(int feature, boolean enabled, byte[] token, SetFeatureCallback callback) { if (mService != null) { try { return mService.setFeature(feature, enabled, token); mSetFeatureCallback = callback; mService.setFeature(feature, enabled, token, mServiceReceiver); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * @hide */ @RequiresPermission(MANAGE_BIOMETRIC) public boolean getFeature(int feature) { boolean result = true; public void getFeature(int feature, GetFeatureCallback callback) { if (mService != null) { try { result = mService.getFeature(feature); mGetFeatureCallback = callback; mService.getFeature(feature, mServiceReceiver); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return result; } /** Loading Loading @@ -874,6 +893,20 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } } /** * @hide */ public abstract static class SetFeatureCallback { public abstract void onCompleted(boolean success, int feature); } /** * @hide */ public abstract static class GetFeatureCallback { public abstract void onCompleted(boolean success, int feature, boolean value); } private class OnEnrollCancelListener implements OnCancelListener { @Override public void onCancel() { Loading Loading @@ -926,9 +959,36 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan 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 */, args.argi1 /* feature */, (boolean) args.arg2 /* value */); args.recycle(); break; default: Log.w(TAG, "Unknown message: " + msg.what); } } }; } private void sendSetFeatureCompleted(boolean success, int feature) { if (mSetFeatureCallback == null) { return; } mSetFeatureCallback.onCompleted(success, feature); } private void sendGetFeatureCompleted(boolean success, int feature, boolean value) { if (mGetFeatureCallback == null) { return; } mGetFeatureCallback.onCompleted(success, feature, value); } private void sendRemovedResult(Face face, int remaining) { if (mRemovalCallback == null) { Loading
core/java/android/hardware/face/IFaceService.aidl +4 −3 Original line number Diff line number Diff line Loading @@ -98,9 +98,10 @@ interface IFaceService { // Enumerate all faces void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver); boolean setFeature(int feature, boolean enabled, in byte [] token); void setFeature(int feature, boolean enabled, in byte [] token, IFaceServiceReceiver receiver); boolean getFeature(int feature); void getFeature(int feature, IFaceServiceReceiver receiver); void userActivity(); }
core/java/android/hardware/face/IFaceServiceReceiver.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -29,4 +29,6 @@ oneway interface IFaceServiceReceiver { void onError(long deviceId, int error, int vendorCode); void onRemoved(long deviceId, int faceId, int remaining); void onEnumerated(long deviceId, int faceId, int remaining); void onFeatureSet(boolean success, int feature); void onFeatureGet(boolean success, int feature, boolean value); }
services/core/java/com/android/server/biometrics/face/FaceService.java +41 −40 Original line number Diff line number Diff line Loading @@ -397,12 +397,14 @@ public class FaceService extends BiometricServiceBase { } @Override public boolean setFeature(int feature, boolean enabled, final byte[] token) { public void setFeature(int feature, boolean enabled, final byte[] token, IFaceServiceReceiver receiver) { checkPermission(MANAGE_BIOMETRIC); mHandler.post(() -> { if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) { Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature); return false; return; } final ArrayList<Byte> byteToken = new ArrayList<>(); Loading @@ -415,24 +417,27 @@ public class FaceService extends BiometricServiceBase { if (mDaemon != null) { try { return mDaemon.setFeature(feature, enabled, byteToken, faceId) == Status.OK; final int result = mDaemon.setFeature(feature, enabled, byteToken, faceId); receiver.onFeatureSet(result == Status.OK, feature); } catch (RemoteException e) { Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled, e); Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled, e); } } return false; }); } @Override public boolean getFeature(int feature) { public void getFeature(int feature, IFaceServiceReceiver receiver) { checkPermission(MANAGE_BIOMETRIC); mHandler.post(() -> { // This should ideally return tri-state, but the user isn't shown settings unless // they are enrolled so it's fine for now. if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) { Slog.e(TAG, "No enrolled biometrics while getting feature: " + feature); return false; return; } // TODO: Support multiple faces Loading @@ -441,17 +446,13 @@ public class FaceService extends BiometricServiceBase { if (mDaemon != null) { try { OptionalBool result = mDaemon.getFeature(feature, faceId); if (result.status == Status.OK) { return result.value; } else { // Same tri-state comment applies here. return false; } receiver.onFeatureGet(result.status == Status.OK, feature, result.value); } catch (RemoteException e) { Slog.e(getTag(), "Unable to getRequireAttention", e); } } return false; }); } @Override Loading