Android8.0的指纹流程,相较于Android6.0和Android7.0来说,是一个版本更新。
Android系统对于fingerprint的支持,大体分为如下三种情况:
1、Android5.0及以前,没有集成指纹fingerprint。
2、Android6.0和Android7.0,集成了指纹fingerprint,但是6和7差异不大。
3、Android8.0和Android9.0相对于7.0来说,HAL层有所改动,还增加了hwbinder、HIDL等新特性。
博主预计Android8.0上面改善的这套fingerprint指纹架构,至少会维持4个Android大版本,比如Android8-Android11。
本文,就以Android8.0的指纹启动流程来进行解析,详细的说明指纹是如何启动的, 其内容基本也可以适用Android8.0以后的系统。
开机自启动系统服务,在文件:
/frameworks/base/services/java/com/android/server/SystemServer.java
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1512 traceBeginAndSlog("StartFingerprintSensor");
1513 mSystemServiceManager.startService(FingerprintService.class);
1514 traceEnd();
1515 }
可以看到,系统服务里面判断了是否系统里面集成了指纹功能,Android8.0是默认有的,所以会startService(FingerprintService)
所以我们进入到如下文件的startService方法:
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
120 public void startService(@NonNull final SystemService service) {
121 // Register it.
122 mServices.add(service);
123 // Start it.
124 long time = SystemClock.elapsedRealtime();
125 try {
126 service.onStart();
127 } catch (RuntimeException ex) {
128 throw new RuntimeException("Failed to start service " + service.getClass().getName()
129 + ": onStart threw an exception", ex);
130 }
131 warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
132 }
如上,我们看到一个关键的方法:service.onStart(),这个意思就是FingerprintService.java里面的onStart将被调用。
所以我们进入到如下文件:
/frameworks/base/services/core/java/com/android/server/fingerprint/FingerprintService.java
@Override
public void onStart() {
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
SystemServerInitThreadPool.get().submit(this::getFingerprintDaemon, TAG + ".onStart");
listenForUserSwitches();
}
我们看到,首先是创建了对象FingerprintServiceWrapper,这是一个很关键的对象,如下是部分截图:
我们可以看到,其是继承自IFingerprintService,并且里面的函数都写了“Binder call”,这也侧面反映了, 这是binder通信的接口,其实这一块并不是Android8.0才有的,而是Android6.0的时候,就已经差不多是这也了。
这里的binder是连接哪里和FingerprintService呢?答案是FingerprintManager.java。
如下图是IFingerprintService.aidl的部分截图:
是FingerprintManager.java通过AIDL,binder通信,和FingerprintService.java进行了通信。
举个例子:比如系统设置APP里面拿到了FingerprintManager,然后往FingerprintManager下发了注册或是识别的命令,这些命令就是通过AIDL传递到了FingerprintService里面了。
继续回到前面的FingerprintService,再来看如下流程:
@Override
public void onStart() {
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
SystemServerInitThreadPool.get().submit(this::getFingerprintDaemon, TAG + ".onStart");
listenForUserSwitches();
}
上面还有一个操作是调用this::getFingerprintDaemon,这是FingerprintService和HAL层进行通信了。
public synchronized IBiometricsFingerprint getFingerprintDaemon() {
if (mDaemon == null) {
Slog.v(TAG, "mDaemon was null, reconnect to fingerprint");
try {
mDaemon = IBiometricsFingerprint.getService();
} catch (java.util.NoSuchElementException e) {
// Service doesn't exist or cannot be opened. Logged below.
} catch (RemoteException e) {
Slog.e(TA