Make get/set feature async between settings and service
Fixes: 127382095
Test: None
Change-Id: Ib5495bf5a39bc3a2939aad5c721e32375dd9dde3
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 3e8c334..6035f40 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -45,6 +45,7 @@
import android.util.Slog;
import com.android.internal.R;
+import com.android.internal.os.SomeArgs;
import java.util.List;
@@ -63,6 +64,8 @@
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;
@@ -70,6 +73,8 @@
private AuthenticationCallback mAuthenticationCallback;
private EnrollmentCallback mEnrollmentCallback;
private RemovalCallback mRemovalCallback;
+ private SetFeatureCallback mSetFeatureCallback;
+ private GetFeatureCallback mGetFeatureCallback;
private CryptoObject mCryptoObject;
private Face mRemovalFace;
private Handler mHandler;
@@ -112,6 +117,20 @@
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();
+ }
};
/**
@@ -286,31 +305,31 @@
* @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;
}
/**
@@ -874,6 +893,20 @@
}
}
+ /**
+ * @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() {
@@ -926,9 +959,36 @@
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) {
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 5043d4c..601be75 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -51,7 +51,7 @@
// Start face enrollment
void enroll(IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
- String opPackageName, in int [] disabledFeatures);
+ String opPackageName, in int [] disabledFeatures);
// Cancel enrollment in progress
void cancelEnrollment(IBinder token);
@@ -98,9 +98,10 @@
// 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();
}
diff --git a/core/java/android/hardware/face/IFaceServiceReceiver.aidl b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
index cec9fd8..2176902 100644
--- a/core/java/android/hardware/face/IFaceServiceReceiver.aidl
+++ b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
@@ -29,4 +29,6 @@
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);
}
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 5e4bf33..c573bbb 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -397,61 +397,62 @@
}
@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);
- if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
- Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
- return false;
- }
-
- final ArrayList<Byte> byteToken = new ArrayList<>();
- for (int i = 0; i < token.length; i++) {
- byteToken.add(token[i]);
- }
-
- // TODO: Support multiple faces
- final int faceId = getFirstTemplateForUser(mCurrentUserId);
-
- if (mDaemon != null) {
- try {
- return mDaemon.setFeature(feature, enabled, byteToken, faceId) == Status.OK;
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled,
- e);
+ mHandler.post(() -> {
+ if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+ Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
+ return;
}
- }
- return false;
+
+ final ArrayList<Byte> byteToken = new ArrayList<>();
+ for (int i = 0; i < token.length; i++) {
+ byteToken.add(token[i]);
+ }
+
+ // TODO: Support multiple faces
+ final int faceId = getFirstTemplateForUser(mCurrentUserId);
+
+ if (mDaemon != null) {
+ try {
+ 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);
+ }
+ }
+ });
+
}
@Override
- public boolean getFeature(int feature) {
+ public void getFeature(int feature, IFaceServiceReceiver receiver) {
checkPermission(MANAGE_BIOMETRIC);
- // 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;
- }
-
- // TODO: Support multiple faces
- final int faceId = getFirstTemplateForUser(mCurrentUserId);
-
- 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;
- }
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to getRequireAttention", e);
+ 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;
}
- }
- return false;
+
+ // TODO: Support multiple faces
+ final int faceId = getFirstTemplateForUser(mCurrentUserId);
+
+ if (mDaemon != null) {
+ try {
+ OptionalBool result = mDaemon.getFeature(feature, faceId);
+ receiver.onFeatureGet(result.status == Status.OK, feature, result.value);
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "Unable to getRequireAttention", e);
+ }
+ }
+ });
+
}
@Override