Pass face AIDL frame data through to FaceManager
Adds plumbing to send acquired frame info from the onAuthenticationFrame and onEnrollmentFrame AIDL callbacks to FaceManager. Currently, FaceManager drops most of this data and only passes the acquireInfo and vendorCode fields to appropriate authentication/enrollment callbacks. Test: atest CtsBiometricsTestCases Bug: 178414967 Change-Id: If997ddd13ce1d9bda2341df7c1f8d6347571f4e0
This commit is contained in:
21
core/java/android/hardware/face/FaceAuthenticationFrame.aidl
Normal file
21
core/java/android/hardware/face/FaceAuthenticationFrame.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.face;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
parcelable FaceAuthenticationFrame;
|
||||
@@ -62,6 +62,22 @@ public final class FaceDataFrame implements Parcelable {
|
||||
mIsCancellable = isCancellable;
|
||||
}
|
||||
|
||||
/**
|
||||
* A container for data common to {@link FaceAuthenticationFrame} and {@link FaceEnrollFrame}.
|
||||
*
|
||||
* @param acquiredInfo An integer corresponding to a known acquired message.
|
||||
* @param vendorCode An integer representing a custom vendor-specific message. Ignored unless
|
||||
* {@code acquiredInfo} is {@code FACE_ACQUIRED_VENDOR}.
|
||||
*/
|
||||
public FaceDataFrame(int acquiredInfo, int vendorCode) {
|
||||
mAcquiredInfo = acquiredInfo;
|
||||
mVendorCode = vendorCode;
|
||||
mPan = 0f;
|
||||
mTilt = 0f;
|
||||
mDistance = 0f;
|
||||
mIsCancellable = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An integer corresponding to a known acquired message.
|
||||
*
|
||||
|
||||
21
core/java/android/hardware/face/FaceEnrollFrame.aidl
Normal file
21
core/java/android/hardware/face/FaceEnrollFrame.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.face;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
parcelable FaceEnrollFrame;
|
||||
@@ -28,6 +28,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FaceEnrollStage.UNKNOWN,
|
||||
FaceEnrollStage.FIRST_FRAME_RECEIVED,
|
||||
FaceEnrollStage.WAITING_FOR_CENTERING,
|
||||
FaceEnrollStage.HOLD_STILL_IN_CENTER,
|
||||
@@ -36,6 +37,11 @@ import java.lang.annotation.RetentionPolicy;
|
||||
FaceEnrollStage.ENROLLMENT_FINISHED
|
||||
})
|
||||
public @interface FaceEnrollStage {
|
||||
/**
|
||||
* The current enrollment stage is not known.
|
||||
*/
|
||||
int UNKNOWN = -1;
|
||||
|
||||
/**
|
||||
* Enrollment has just begun. No action is needed from the user yet.
|
||||
*/
|
||||
|
||||
@@ -71,17 +71,19 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
private static final int MSG_FACE_DETECTED = 109;
|
||||
private static final int MSG_CHALLENGE_INTERRUPTED = 110;
|
||||
private static final int MSG_CHALLENGE_INTERRUPT_FINISHED = 111;
|
||||
private static final int MSG_AUTHENTICATION_FRAME = 112;
|
||||
private static final int MSG_ENROLLMENT_FRAME = 113;
|
||||
|
||||
private final IFaceService mService;
|
||||
private final Context mContext;
|
||||
private IBinder mToken = new Binder();
|
||||
private AuthenticationCallback mAuthenticationCallback;
|
||||
private FaceDetectionCallback mFaceDetectionCallback;
|
||||
private EnrollmentCallback mEnrollmentCallback;
|
||||
private RemovalCallback mRemovalCallback;
|
||||
private SetFeatureCallback mSetFeatureCallback;
|
||||
private GetFeatureCallback mGetFeatureCallback;
|
||||
private GenerateChallengeCallback mGenerateChallengeCallback;
|
||||
@Nullable private AuthenticationCallback mAuthenticationCallback;
|
||||
@Nullable private FaceDetectionCallback mFaceDetectionCallback;
|
||||
@Nullable private EnrollmentCallback mEnrollmentCallback;
|
||||
@Nullable private RemovalCallback mRemovalCallback;
|
||||
@Nullable private SetFeatureCallback mSetFeatureCallback;
|
||||
@Nullable private GetFeatureCallback mGetFeatureCallback;
|
||||
@Nullable private GenerateChallengeCallback mGenerateChallengeCallback;
|
||||
private CryptoObject mCryptoObject;
|
||||
private Face mRemovalFace;
|
||||
private Handler mHandler;
|
||||
@@ -154,6 +156,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
public void onChallengeInterruptFinished(int sensorId) {
|
||||
mHandler.obtainMessage(MSG_CHALLENGE_INTERRUPT_FINISHED, sensorId).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFrame(FaceAuthenticationFrame frame) {
|
||||
mHandler.obtainMessage(MSG_AUTHENTICATION_FRAME, frame).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnrollmentFrame(FaceEnrollFrame frame) {
|
||||
mHandler.obtainMessage(MSG_ENROLLMENT_FRAME, frame).sendToTarget();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1248,6 +1260,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
case MSG_CHALLENGE_INTERRUPT_FINISHED:
|
||||
sendChallengeInterruptFinished((int) msg.obj /* sensorId */);
|
||||
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);
|
||||
}
|
||||
@@ -1349,15 +1367,52 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
|
||||
private void sendAcquiredResult(int acquireInfo, int vendorCode) {
|
||||
if (mAuthenticationCallback != null) {
|
||||
mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
|
||||
}
|
||||
final String msg = getAcquiredString(mContext, acquireInfo, vendorCode);
|
||||
final int clientInfo = acquireInfo == FACE_ACQUIRED_VENDOR
|
||||
? (vendorCode + FACE_ACQUIRED_VENDOR_BASE) : acquireInfo;
|
||||
if (mEnrollmentCallback != null) {
|
||||
mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg);
|
||||
} else if (mAuthenticationCallback != null && msg != null) {
|
||||
mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg);
|
||||
final FaceAuthenticationFrame frame = new FaceAuthenticationFrame(
|
||||
new FaceDataFrame(acquireInfo, vendorCode));
|
||||
sendAuthenticationFrame(frame);
|
||||
} else if (mEnrollmentCallback != null) {
|
||||
final FaceEnrollFrame frame = new FaceEnrollFrame(
|
||||
null /* cell */,
|
||||
FaceEnrollStage.UNKNOWN,
|
||||
new FaceDataFrame(acquireInfo, vendorCode));
|
||||
sendEnrollmentFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendAuthenticationFrame(@Nullable FaceAuthenticationFrame frame) {
|
||||
if (frame == null) {
|
||||
Slog.w(TAG, "Received null authentication frame");
|
||||
} else if (mAuthenticationCallback != null) {
|
||||
// TODO(b/178414967): Send additional frame data to callback
|
||||
final int acquireInfo = frame.getData().getAcquiredInfo();
|
||||
final int vendorCode = frame.getData().getVendorCode();
|
||||
final int helpCode = getHelpCode(acquireInfo, vendorCode);
|
||||
final String helpMessage = getAcquiredString(mContext, acquireInfo, vendorCode);
|
||||
mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
|
||||
|
||||
// Ensure that only non-null help messages are sent.
|
||||
if (helpMessage != null) {
|
||||
mAuthenticationCallback.onAuthenticationHelp(helpCode, helpMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendEnrollmentFrame(@Nullable FaceEnrollFrame frame) {
|
||||
if (frame == null) {
|
||||
Slog.w(TAG, "Received null enrollment frame");
|
||||
} else if (mEnrollmentCallback != null) {
|
||||
// TODO(b/178414967): Send additional frame data to callback
|
||||
final int acquireInfo = frame.getData().getAcquiredInfo();
|
||||
final int vendorCode = frame.getData().getVendorCode();
|
||||
final int helpCode = getHelpCode(acquireInfo, vendorCode);
|
||||
final String helpMessage = getAcquiredString(mContext, acquireInfo, vendorCode);
|
||||
mEnrollmentCallback.onEnrollmentHelp(helpCode, helpMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getHelpCode(int acquireInfo, int vendorCode) {
|
||||
return acquireInfo == FACE_ACQUIRED_VENDOR
|
||||
? vendorCode + FACE_ACQUIRED_VENDOR_BASE
|
||||
: acquireInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package android.hardware.face;
|
||||
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceEnrollFrame;
|
||||
|
||||
/**
|
||||
* Communication channel from the FaceService back to FaceAuthenticationManager.
|
||||
@@ -34,4 +36,6 @@ oneway interface IFaceServiceReceiver {
|
||||
void onChallengeGenerated(int sensorId, long challenge);
|
||||
void onChallengeInterrupted(int sensorId);
|
||||
void onChallengeInterruptFinished(int sensorId);
|
||||
void onAuthenticationFrame(in FaceAuthenticationFrame frame);
|
||||
void onEnrollmentFrame(in FaceEnrollFrame frame);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package com.android.server.biometrics.sensors;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.IBiometricSensorReceiver;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceEnrollFrame;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
@@ -174,4 +177,33 @@ public class ClientMonitorCallbackConverter {
|
||||
mFingerprintServiceReceiver.onUdfpsPointerUp(sensorId);
|
||||
}
|
||||
}
|
||||
|
||||
// Face-specific callbacks for FaceManager only
|
||||
|
||||
/**
|
||||
* Called each time a new frame is received during face authentication.
|
||||
*
|
||||
* @param frame Information about the current frame.
|
||||
*
|
||||
* @throws RemoteException If the binder call to {@link IFaceServiceReceiver} fails.
|
||||
*/
|
||||
public void onAuthenticationFrame(@NonNull FaceAuthenticationFrame frame)
|
||||
throws RemoteException {
|
||||
if (mFaceServiceReceiver != null) {
|
||||
mFaceServiceReceiver.onAuthenticationFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called each time a new frame is received during face enrollment.
|
||||
*
|
||||
* @param frame Information about the current frame.
|
||||
*
|
||||
* @throws RemoteException If the binder call to {@link IFaceServiceReceiver} fails.
|
||||
*/
|
||||
public void onEnrollmentFrame(@NonNull FaceEnrollFrame frame) throws RemoteException {
|
||||
if (mFaceServiceReceiver != null) {
|
||||
mFaceServiceReceiver.onEnrollmentFrame(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.hardware.biometrics.ITestSession;
|
||||
import android.hardware.biometrics.face.AuthenticationFrame;
|
||||
import android.hardware.biometrics.face.BaseFrame;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceEnrollFrame;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.os.Binder;
|
||||
import android.util.Slog;
|
||||
@@ -117,6 +119,16 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
|
||||
public void onChallengeInterruptFinished(int sensorId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFrame(FaceAuthenticationFrame frame) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnrollmentFrame(FaceEnrollFrame frame) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
BiometricTestSessionImpl(@NonNull Context context, int sensorId,
|
||||
@@ -183,7 +195,7 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
|
||||
mSensor.getSessionForUser(userId).mHalSessionCallback.onAuthenticationFailed();
|
||||
}
|
||||
|
||||
// TODO(b/174619156): replace with notifyAuthenticationFrame and notifyEnrollmentFrame.
|
||||
// TODO(b/178414967): replace with notifyAuthenticationFrame and notifyEnrollmentFrame.
|
||||
@Override
|
||||
public void notifyAcquired(int userId, int acquireInfo) {
|
||||
Utils.checkPermission(mContext, TEST_BIOMETRIC);
|
||||
@@ -194,7 +206,7 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
|
||||
AuthenticationFrame authenticationFrame = new AuthenticationFrame();
|
||||
authenticationFrame.data = data;
|
||||
|
||||
// TODO(b/174619156): Currently onAuthenticationFrame and onEnrollmentFrame are the same.
|
||||
// TODO(b/178414967): Currently onAuthenticationFrame and onEnrollmentFrame are the same.
|
||||
// This will need to call the correct callback once the onAcquired callback is removed.
|
||||
mSensor.getSessionForUser(userId).mHalSessionCallback.onAuthenticationFrame(
|
||||
authenticationFrame);
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceDataFrame;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -179,19 +178,16 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
return isBiometricPrompt() ? mBiometricPromptIgnoreListVendor : mKeyguardIgnoreListVendor;
|
||||
}
|
||||
|
||||
private boolean shouldSend(int acquireInfo, int vendorCode) {
|
||||
if (acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR) {
|
||||
return !Utils.listContains(getAcquireVendorIgnorelist(), vendorCode);
|
||||
} else {
|
||||
return !Utils.listContains(getAcquireIgnorelist(), acquireInfo);
|
||||
}
|
||||
private boolean shouldSendAcquiredMessage(int acquireInfo, int vendorCode) {
|
||||
return acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR
|
||||
? !Utils.listContains(getAcquireVendorIgnorelist(), vendorCode)
|
||||
: !Utils.listContains(getAcquireIgnorelist(), acquireInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAcquired(int acquireInfo, int vendorCode) {
|
||||
mLastAcquire = acquireInfo;
|
||||
|
||||
final boolean shouldSend = shouldSend(acquireInfo, vendorCode);
|
||||
final boolean shouldSend = shouldSendAcquiredMessage(acquireInfo, vendorCode);
|
||||
onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
|
||||
}
|
||||
|
||||
@@ -201,9 +197,21 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
* @param frame Information about the current frame.
|
||||
*/
|
||||
public void onAuthenticationFrame(@NonNull FaceAuthenticationFrame frame) {
|
||||
// TODO(b/178414967): Send additional frame data to the client callback.
|
||||
final FaceDataFrame data = frame.getData();
|
||||
onAcquired(data.getAcquiredInfo(), data.getVendorCode());
|
||||
// Log acquisition but don't send it to the client yet, since that's handled below.
|
||||
final int acquireInfo = frame.getData().getAcquiredInfo();
|
||||
final int vendorCode = frame.getData().getVendorCode();
|
||||
mLastAcquire = acquireInfo;
|
||||
onAcquiredInternal(acquireInfo, vendorCode, false /* shouldSend */);
|
||||
|
||||
final boolean shouldSend = shouldSendAcquiredMessage(acquireInfo, vendorCode);
|
||||
if (shouldSend && getListener() != null) {
|
||||
try {
|
||||
getListener().onAuthenticationFrame(frame);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to send authentication frame", e);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onLockoutTimed(long durationMillis) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.hardware.biometrics.face.Feature;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceDataFrame;
|
||||
import android.hardware.face.FaceEnrollFrame;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.IBinder;
|
||||
@@ -101,14 +100,15 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
|
||||
getTargetUserId()).size() >= mMaxTemplatesPerUser;
|
||||
}
|
||||
|
||||
private boolean shouldSendAcquiredMessage(int acquireInfo, int vendorCode) {
|
||||
return acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR
|
||||
? !Utils.listContains(mEnrollIgnoreListVendor, vendorCode)
|
||||
: !Utils.listContains(mEnrollIgnoreList, acquireInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAcquired(int acquireInfo, int vendorCode) {
|
||||
final boolean shouldSend;
|
||||
if (acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR) {
|
||||
shouldSend = !Utils.listContains(mEnrollIgnoreListVendor, vendorCode);
|
||||
} else {
|
||||
shouldSend = !Utils.listContains(mEnrollIgnoreList, acquireInfo);
|
||||
}
|
||||
final boolean shouldSend = shouldSendAcquiredMessage(acquireInfo, vendorCode);
|
||||
onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
|
||||
}
|
||||
|
||||
@@ -118,9 +118,20 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
|
||||
* @param frame Information about the current frame.
|
||||
*/
|
||||
public void onEnrollmentFrame(@NonNull FaceEnrollFrame frame) {
|
||||
// TODO(b/178414967): Send additional frame data to the client callback.
|
||||
final FaceDataFrame data = frame.getData();
|
||||
onAcquired(data.getAcquiredInfo(), data.getVendorCode());
|
||||
// Log acquisition but don't send it to the client yet, since that's handled below.
|
||||
final int acquireInfo = frame.getData().getAcquiredInfo();
|
||||
final int vendorCode = frame.getData().getVendorCode();
|
||||
onAcquiredInternal(acquireInfo, vendorCode, false /* shouldSend */);
|
||||
|
||||
final boolean shouldSend = shouldSendAcquiredMessage(acquireInfo, vendorCode);
|
||||
if (shouldSend && getListener() != null) {
|
||||
try {
|
||||
getListener().onEnrollmentFrame(frame);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to send enrollment frame", e);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.ITestSession;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceEnrollFrame;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.os.Binder;
|
||||
import android.util.Slog;
|
||||
@@ -106,6 +108,16 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
|
||||
public void onChallengeInterruptFinished(int sensorId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFrame(FaceAuthenticationFrame frame) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnrollmentFrame(FaceEnrollFrame frame) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
BiometricTestSessionImpl(@NonNull Context context, int sensorId, @NonNull Face10 face10,
|
||||
|
||||
Reference in New Issue
Block a user