当前位置:网站首页>人脸注册,解锁,响应,一网打尽
人脸注册,解锁,响应,一网打尽
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();
}
}
}边栏推荐
- [Yunzhou said live room] - digital security special session will be officially launched tomorrow afternoon
- Gradle Build Cache引发的Task缓存编译问题怎么解决
- 火绒安全与英特尔vPro平台合作 共筑软硬件协同安全新格局
- 腾讯的技术牛人们,是如何完成全面上云这件事儿的?
- Quarkus+saas multi tenant dynamic data source switching is simple and perfect
- ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
- 2 万字 + 30 张图 |MySQL 日志:undo log、redo log、binlog 有什么用?
- 服务稳定性治理
- First exposure! The only Alibaba cloud native security panorama behind the highest level in the whole domain
- 通过 OpenVINO Model Server和 TensorFlow Serving简化部署
猜你喜欢

Common usage of OS (picture example)
React query tutorial ④ - cache status and debugging tools

The way out after the development of Internet technology -- the birth of IVX

Overview of national parks in the United States

OS的常见用法(图片示例)

How did Tencent's technology bulls complete the overall cloud launch?

实战监听Eureka client的缓存更新

使用OpenVINOTM预处理API进一步提升YOLOv5推理性能

在線文本過濾小於指定長度工具

Hanyuan hi tech 8-way telephone +1-way 100M Ethernet RJ11 telephone optical transceiver 8-way PCM telephone optical transceiver
随机推荐
何小鹏:如果可以回到创业的时候 不会以自己的名字给产品命名
AAIG看全球6月刊(上)发布|AI人格真的觉醒了吗?NLP哪个细分方向最具社会价值?Get新观点新启发~
Hanyuan hi tech 8-way telephone +1-way 100M Ethernet RJ11 telephone optical transceiver 8-way PCM telephone optical transceiver
【深入理解TcaplusDB技术】单据受理之事务执行
R language is used to build ordered multi classification logistic regression model, ordinal or. The display function obtains the summary statistical information of the ordered logistic regression mode
How to use androd gradle module dependency replacement
What is the principle of live CDN in the process of building the source code of live streaming apps with goods?
前AMD芯片架构师吐槽,取消 K12 处理器项目是因为 AMD 怂了!
同花顺网上开户安全吗,需要注意什么
POW consensus mechanism
After the uncommitted transactions in the redo log buffer of MySQL InnoDB are persisted to the redo log, what happens if the transaction rollback occurs?
在线文本实体抽取能力,助力应用解析海量文本数据
Homekit supports the matter protocol. What does this imply?
腾讯的技术牛人们,是如何完成全面上云这件事儿的?
Has aaig really awakened its AI personality after reading the global June issue (Part 1)? Which segment of NLP has the most social value? Get new ideas and inspiration ~
Esp32-c3 introductory tutorial problem ⑦ - fatal error: ESP_ Bt.h: no such file or directory ESP not found_ bt.h
R language dplyr package arrange function sorts dataframe data and sorts dataframe data through multiple data columns (ascending sort by default)
逆向调试入门-了解PE结构文件
MIT 6.031 Reading5 : Version Control学习心得
quartus调用&设计D触发器——仿真&时序波验证