生物识别弹框是Android系统提供的一个组件,由Settings、Framework、SystemUi共同实现,供上层(三方)应用使用。本文将简单介绍一下Q版本该模块的整体架构,然后重点介绍下SystemUi部分的实现和逻辑。

一. 整体架构

1.1 常规流程

  1. 上层应用通过android.hardware.biometrics.BiometricPrompt#authenticate(android.hardware.biometrics.BiometricPrompt.CryptoObject, CancellationSignal, Executor, android.hardware.biometrics.BiometricPrompt.AuthenticationCallback) 发起会话;

  2. com.android.server.biometrics.BiometricService 在 方法android.hardware.biometrics.BiometricPrompt#authenticate(android.hardware.biometrics.BiometricPrompt.CryptoObject, CancellationSignal, Executor, android.hardware.biometrics.BiometricPrompt.AuthenticationCallback) 中,一方面 拉起设置认证activity:ConfirmDeviceCredentialActivity$InternalActivity;另一方面 向指纹/人脸服务 发起来自上层应用的注册申请;

  3. 当准备完成后,BiometricService 通过IStatusbarService::showBiometricDialog() 通知systemUi addView,从而完成加载。
    即通常情况下,上层应用发起会话与指纹注册,systemUi维护具体的view;

1.2 BiometricPrompt

上层应用如何使用对应接口,在官方文档里面有详细的^接口说明^使用教程。这里不再赘述,建议读者亲自编写一个apk,并添加好关键log,跟踪一下整个处理流程。 这里推荐一个这方面文章质量很高的博主:CSDN 小小写。 关于Q上面的整个^使用方式^log流程都有比较详细的说明。

二. systemUi部分

本文重点介绍一下systemUi相关的处理逻辑,为后面R版本的大变动做好分析准备。

2.1 目录结构

Q版本systemUi 相关类
Q版本上BiometricPrompt systemUi部分的整体架构还是非常简单明了的,这里就不用类图来展示类的关系了。

  1. com.android.systemui.biometrics.BiometricDialogImpl 处理主要的逻辑内容;
  2. com.android.systemui.biometrics.BiometricDialogView 是指纹/人脸view的抽象基类;com.android.systemui.biometrics.FaceDialogView和com.android.systemui.biometrics.FingerprintDialogView则是展示不同生物类型的内容;
  3. com.android.systemui.biometrics.DialogViewCallback 是个接口,供view回调;

2.2 流程分析

2.2.1 showBiometricDialog

  1. BiometricDialogImpl实现CommandQueue.Callbacks接口,com.android.systemui.biometrics.BiometricDialogImpl#showBiometricDialog为从框架正式进入systemui的入口。向主线程handler发送消息MSG_SHOW_DIALOG。
  2. com.android.systemui.biometrics.BiometricDialogImpl#handleShowDialog 正式处理。主要逻辑为初始化view并为其注入userId等信息,最后addview。这里值得注意的一点是会首先判断创建类型是否为指纹,然后才是人脸。所以当用户同时注册了指纹和人脸时,调用生物识别弹框首先使用的是指纹识别功能。
  3. addview时传入的LayoutParams相对简单,需要了解的两点是窗口层级为:TYPE_STATUS_BAR_PANEL;layer名称为:BiometricDialogView,下文的分析会用到这两处。

2.2.2 处理认证结果

认证共有三种返回结果,均由框架通知:

  1. com.android.systemui.biometrics.BiometricDialogImpl#onBiometricAuthenticated 认证成功时,一方面通知view更新组件状态,另一方面延时执行com.android.systemui.biometrics.BiometricDialogImpl#handleHideDialog。
  2. com.android.systemui.biometrics.BiometricDialogImpl#handleBiometricHelp 一般情况下,是手指按压时间过短、移动过快等情况导致无法校验指纹时回调,区别与校验失败。 当收到此回调时,会回调view的onHelpReceived方法,一方面更新组件状态,另一方面弹出toast展示对应信息。
  3. com.android.systemui.biometrics.BiometricDialogImpl#handleBiometricError 这是进行校验并校验为错误指纹时的回调,比handleBiometricHelp时多了showTryAgainButton的处理,并且要处理5次校验失败触发密码校验等流程的情况。这里涉及到了指纹、密码等模块的机制,暂时不展开细讲。

2.2.3 handleHideDialog

  1. 触发使弹框消失的原因有很多,但最终都调到com.android.systemui.biometrics.BiometricDialogImpl#handleHideDialog方法。一方面使view执行退场动画并消失,另一方面通知框架onDialogDismissed。
  2. 我们来看一下onDialogDismissed方法。此方法最终会执行com.android.server.biometrics.BiometricService#handleOnDismissed,根据不同的原因,分别通知上层应用和指纹/人脸服务 执行对应的操作。值得注意的一点是这里会判断是否使用的允许密码校验的逻辑,涉及到了Q版本和R版本最大的不同:调用密码校验的方式。 此部分对比会在后面的文章中详细分析。

2.3 view部分的设计逻辑

此部分会在后文中R版本部分作为对比来详细讲述,此处暂不展开。


总结:本文简略的展示了Q版本生物识别弹框的调用逻辑,仅做了解。分析的重点会放在R版本上。

三. 参考资料

请见文中各注脚部分。

  1. https://developer.android.google.cn/reference/android/hardware/biometrics/BiometricPrompt
  2. https://developer.android.com/training/sign-in/biometric-auth
  3. https://blog.csdn.net/u013398960/article/details/105161421
  4. https://blog.csdn.net/u013398960/article/details/105161958