当前位置:网站首页>人脸注册,解锁,响应,一网打尽
人脸注册,解锁,响应,一网打尽
2022-06-23 12:59:00 【liujun3512159】
现代智能手机,基本上都有人脸解锁功能,那他是怎么实现的哦?下面从代码角度来分析下他。
先上流程图
略
人脸解锁,都要先录入(这部分后面会出其他博客),再注册,再人脸解锁,响应,下面从代码角度来分析他。
先从锁屏部分的类KeyguardUpdateMonitor入手,下面是人脸服务注册方法。
private void startListeningForFace() {
final int userId = getCurrentUser();
final boolean unlockPossible = isUnlockWithFacePossible(userId);
if (mFaceCancelSignal != null) {
Log.e(TAG, "Cancellation signal is not null, high chance of bug in face auth lifecycle"
+ " management. Face state: " + mFaceRunningState
+ ", unlockPossible: " + unlockPossible);
}
if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
return;
} else if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
// Waiting for ERROR_CANCELED before requesting auth again
return;
}
if (DEBUG) Log.v(TAG, "startListeningForFace(): " + mFaceRunningState);
if (unlockPossible) {
mFaceCancelSignal = new CancellationSignal();
// This would need to be updated for multi-sensor devices
final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
&& mFaceSensorProperties.get(0).supportsFaceDetection;
mFaceAuthUserId = userId;
if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
} else {
final boolean isBypassEnabled = mKeyguardBypassController != null
&& mKeyguardBypassController.isBypassEnabled();
mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
mFaceAuthenticationCallback, null /* handler */, userId, isBypassEnabled);
}
setFaceRunningState(BIOMETRIC_STATE_RUNNING);
}
}第31行,人脸注册,这里要注意下变量mFaceAuthenticationCallback,这是回调接口对象,底层设别结果的回传信息,会通过这个变量对象告知用户人脸解锁成功或失败或错误,等等。
@VisibleForTesting
final FaceManager.AuthenticationCallback mFaceAuthenticationCallback
= new FaceManager.AuthenticationCallback() {
@Override
public void onAuthenticationFailed() {
handleFaceAuthFailed();
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
}
}
@Override
public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
handleFaceAuthenticated(result.getUserId(), result.isStrongBiometric());
Trace.endSection();
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
}
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
handleFaceHelp(helpMsgId, helpString.toString());
}
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
handleFaceError(errMsgId, errString.toString());
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
}
}
@Override
public void onAuthenticationAcquired(int acquireInfo) {
handleFaceAcquired(acquireInfo);
}
};后面在设别结果回传的时候,再讨论。
回到代码mFaceManager#authenticate 部分,讨论下变量mFaceManager是如何定义的。
在KeyguardUpdateMonitor类的构造函数中定义的,如下,显然这是一个系统服务。
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
mFaceSensorProperties = mFaceManager.getSensorPropertiesInternal();
}
搜索关键字Context.FACE_SERVICE,在SystemServiceRegistry类中实现了系统服务注册。
registerService(Context.FACE_SERVICE, FaceManager.class,
new CachedServiceFetcher<FaceManager>() {
@Override
public FaceManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
final IBinder binder;
if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
binder = ServiceManager.getServiceOrThrow(Context.FACE_SERVICE);
} else {
binder = ServiceManager.getService(Context.FACE_SERVICE);
}
IFaceService service = IFaceService.Stub.asInterface(binder);
return new FaceManager(ctx.getOuterContext(), service);
}
});注意第12,13行,会获得跨进程对象FaceService对象实例,然后绑定到FaceManager系统对象实例中,然后在mFaceManager#authenticate方法中,使用mService 变量,调用到FaceService对象实例下的authenticate方法。
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
@NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId,
boolean isKeyguardBypassEnabled) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an authentication callback");
}
if (cancel != null && cancel.isCanceled()) {
Slog.w(TAG, "authentication already canceled");
return;
}
if (mService != null) {
try {
useHandler(handler);
mAuthenticationCallback = callback;
mCryptoObject = crypto;
final long operationId = crypto != null ? crypto.getOpId() : 0;
Trace.beginSection("FaceManager#authenticate");
final long authId = mService.authenticate(mToken, operationId, userId,
mServiceReceiver, mContext.getOpPackageName(), isKeyguardBypassEnabled);
if (cancel != null) {
cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
}
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception while authenticating: ", e);
// Though this may not be a hardware issue, it will cause apps to give up or
// try again later.
callback.onAuthenticationError(FACE_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */));
} finally {
Trace.endSection();
}
}
}边栏推荐
- Architecture design methods in technical practice
- Go write permissions to file writefile (FileName, data, 0644)?
- AAIG看全球6月刊(上)发布|AI人格真的觉醒了吗?NLP哪个细分方向最具社会价值?Get新观点新启发~
- Meta said that the UK security law will "scan all private information", which risks infringing on users' privacy
- How to enable the SMS function of alicloud for crmeb knowledge payment
- Technology sharing | wvp+zlmediakit realizes streaming playback of camera gb28181
- CRMEB 二开短信功能教程
- 逆向调试入门-了解PE结构文件
- Quickly understand the commonly used asymmetric encryption algorithm, and no longer have to worry about the interviewer's thorough inquiry
- What is the version of version 1.54 when connecting to Oracle?
猜你喜欢

怎么手写vite插件

LM05丨曾经的VIX(二代产品)

quartus调用&设计D触发器——仿真&时序波验证

Gradle Build Cache引发的Task缓存编译问题怎么解决

Hanyuan high tech USB2.0 optical transceiver USB2.0 optical fiber extender USB2.0 optical fiber transmitter USB2.0 interface to optical fiber

互联网技术发展内卷后的出路——iVX的诞生

Generics, generic defects and application scenarios that 90% of people do not understand

Hanyuan high tech new generation green energy-saving Ethernet access industrial switch high efficiency energy-saving Gigabit Industrial Ethernet switch

你管这破玩意儿叫 MQ?

Develop a powerful tool for increasing efficiency - vscode plug-in sharing in 2022
随机推荐
同花顺网上开户安全吗,需要注意什么
Tuikit audio and video low code solution navigation page
How to use sed -i command
Go写文件的权限 WriteFile(filename, data, 0644)?
OpenVINOTM 2022.1中AUTO插件和自动批处理的最佳实践
When did the redo log under InnoDB in mysql start to perform check point disk dropping?
Analysis and solution of connection failure caused by MySQL using replicationconnection
4E1 PDH optical transceiver 19 inch rack type single fiber transmission 20km E1 interface optical network optical transceiver
In flinksql, the Kafka flow table and MySQL latitude flow table are left joined, and the association is made according to I'd. false
5 technical vulnerabilities related to NFT
Online text entity extraction capability helps applications analyze massive text data
Esp32-c3 introductory tutorial problems ⑧ - blufi_ example. c:244: undefined reference to `esp_ ble_ gap_ start_ advertising
交换两个数的三种方法原理解析
AGCO AI frontier promotion (6.23)
Packaging and unpacking process of ESP message under IPSec transmission mode
Quarkus+saas multi tenant dynamic data source switching is simple and perfect
在线文本实体抽取能力,助力应用解析海量文本数据
How to solve the task cache compilation problem caused by gradle build cache
618的省钱技术攻略 来啦 -体验场景 领取10元猫超卡!
DBMS in Oracle_ output. put_ How to use line