android开发中Fingerprint模块浅析
来源:互联网 发布:c webservice json 编辑:程序博客网 时间:2024/05/21 07:03
一、Fingerprint上层总体架构
Fingerprint模块架构图如下,这里分为application,framework,fingerprintd和FingerprintHal这几个部分,不涉及指纹的IC库和驱动这部分,这部分逻辑由指纹厂商来实现,目前了解的并不多。
二、Fingerprint framework初始化流程
在系统开机的时候,会启动各种Service,包括FingerprintService。从下图的开机log(sys_log.boot)中可以看出:
FingerprintService的启动在SystemServer.Java的startOtherService方法中:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
这里会通过PackageManager来判断是否支持指纹功能,这个判断是N新加的,如果支持的话,需要在framework/native/data/ect/目录下添加Android.hardware.fingerprint.xml来支持该功能,这样才能启动FingerprintService。
这里启动的时候,会将FingerprintService添加到ServiceManager中去,如下图:
将FingerprintService添加到ServiceManager中后,在SystemServiceRegistry.java中静态代码块中注册服务的时候,可以从ServiceManager中获取FingerprintService的Binder对象,从而可以构造出FingerprintManager对象,这样app端就可以通过Context来获取FingerprintManager对象。
这样,app端通过Context获取FingerprintManager,通过调用FingerprintManager的接口来实现相应的功能,FingerprintManager转调FingerprintService中方法,FingerprintService负责管理整个注册,识别、删除指纹、检查权限等流程的逻辑,FingerprintService调用fingerprintd的接口,通过fingerprintd和FingerprintHal层进行通信。
在FingerprintService的getFingerprintDaemon方法中有如下步骤:
//①获取fingerprintd
//②向fingerprintd注册回调函数mDaemonCallback
//③调用获取fingerprintd的openhal函数
//④建立fingerprint文件系统节点,设置节点访问权限,调用fingerprintd的setActiveGroup,将路径传下去。此路径一半用来存储指纹模板的图片等
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
1 FingerprintService在framework模块负责指纹的大部分逻辑,FingerprintService会在开机的时候初始化;
2 application调用framework通过FingerprintManager接口即可实现;
3 framework中FingerManager和FingerprintService的通信使用Binder机制实现,表现即使用aidl这个接口定义语言实现
4 framework调往fingerprintd的同样属于Binder通信,两者分属于不同的进程。不过这部分跟java层Binder处理有点不一样,是java层往native层的调用。
三、fingerprintd 部分的初始化
在system/core/fingerprintd目录下,有如下文件:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
fingerprintd在init.rc有相应的开机启动脚本,所以一开机就会跑它的main函数。fingerprintd作为一个独立的进程运行,负责将Framework和Hal层的通信连接起来。
fingerprintd 的main函数就是将fingerprintd添加到servicemanager中管理。然后开了一个线程,等待binder消息。
四、接下来简单介绍下IFingerprintDaemon是如何跟framework通信的。
来看下IFingerprintDaemon.h文件:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
java层到fingerprintd的通信这里同样是采用binder方式,注意到上面IFingerprintDaemon.h第30行的NOTE,需要手动保证IFingerprintDaemon.h文件与IFingerprintDaemon.aidl文件一致,由于java层aidl文件编译时会自动编译成IFingerprintDaemon.java文件。
当添加接口来调用指纹底层暴露的接口,在IFingerprintDaemon.h文件中添加类似上面35行到68行的枚举,枚举的值需要与java层aidl自动生成的java文件中的枚举保持一致。另外还需要在上面68行处加上描述这些接口的纯虚函数(c++中的纯虚函数类似java的抽象方法,用于定义接口的规范,在C++中,一个具有纯虚函数的基类被称为抽象类)。
如下面截图对比,我们发现IFingerprintDaemon.cpp和java层aidl生成的IFingerprintDaemon.java在onTransact是基本一致的。这样我们也就明白了为什么上面说需要手动和IFingerprintDaemon.aidl保持同步了,这样方式类似我们平时在三方应用使用aidl文件,需要保持client端和server端aidl文件一致。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
IFingerprintDaemon.aidl文件生成的IFingerprintDaemon.java文件
接着介绍下fingerprintd进程是如何和Fingerprint Hal层是如何传递数据的。
说到Hal层,即硬件抽象层,android系统为HAL层中的模块接口定义了规范,所有工作于HAL的模块必须按照这个规范来编写模块接口,否则将无法正常访问硬件。
指纹的HAL层规范fingerprint.h在/hardware/libhardware/include/hardware/下可以看到。
我们注意到在fingerprint.h中定义了两个结构体,分别是fingerprint_device_t和fingerprint_module_t,如下图。
fingerprint_device_t结构体,用于描述指纹硬件设备;fingerprint_module_t结构体,用于描述指纹硬件模块。在FingerprintDaemonProxy.cpp就是通过拿到fingerprint_device_t这个结构体来和Fingerprint HAL层通信的。
当需要添加接口调用指纹底层时,在这个fingerprint.h中同样需要添加函数指针,然后通过FingerprintDaemonProxy.cpp中拿到这个fingerprint_device_t来调用fingerprint.h中定义的函数指针,也就相当于调用指纹HAL层。
我们重点看一下它的openHal()函数。
openHal的方法这里主要看上面三个部分:
- ①根据名称获取指纹hal层模块。hw_module这个一般由指纹芯片厂商根据 fingerprint.h实现,hw_get_module是由HAL框架提供的一个公用的函数,这个函数的主要功能是根据模块ID(module_id)去查找注册在当前系统中与id对应的硬件对象,然后载入(load)其相应的HAL层驱动模块的*so文件。
- ②调用fingerprint_module_t的open函数
- ③向hal层注册消息回调函数,主要回调 注册指纹进度,识别结果,错误信息等等
- ④判断向hal层注册消息回调是否注册成功
目前关于指纹的上层流程大致就到这儿,指纹底层就不怎么介绍了,术业有专攻,和专业做指纹的还是有不少差距。
- android开发中Fingerprint模块浅析
- android开发中Fingerprint模块浅析
- android开发中Fingerprint模块浅析
- Android蓝牙开发浅析 及 Android蓝牙通讯模块源码(Android蓝牙开发浅析 续)
- android SHA1 fingerPrint
- Android Fingerprint -- Enroll流程
- Android Fingerprint -- Enroll流程
- Android Fingerprint -- Enroll流程
- android M fingerprint 解析
- Android开发中MVP模式浅析
- Android Fingerprint完全解析(一) :Fingerprint整体框架
- Android Fingerprint完全解析(二) :Fingerprint启动流程
- Android Fingerprint完全解析(三) :Fingerprint Hal层分析
- Android Fingerprint完全解析(一) :Fingerprint整体框架
- Android Fingerprint完全解析(二) :Fingerprint启动流程
- Android Fingerprint完全解析(三) :Fingerprint Hal层分析
- 网络游戏中网络模块浅析
- 网络游戏中网络模块浅析
- [Leetcode] 358. Rearrange String k Distance Apart 解题报告
- linux下安装PHP pcntl 扩展
- Bad Hair Day (单调栈)
- 微信小程序中使用富文本
- [python3.6 flask web学习]Flask项目目录结构
- android开发中Fingerprint模块浅析
- java的volatile关键字(笔记)
- 关于终端和控制台的一些解释
- CentOS 7安装Maven3.5
- 故障公告:docker swarm集群“群龙无首”造成部分站点无法访问
- 球钟问题
- Eclipse配置Maven
- 第二篇:JAVA集合之LinkedList源码剖析
- Can you make a water problem?