Android O指紋識別解析

Android O 指紋識別解析

一、前言 - Project Treble

衆所周知,Android 碎片化問題比較嚴重,新版本更新效率比較低,Google 爲了解決此類問題,發佈了 Project Treble 項目。Google 在Android O上,修改了框架.

Android O與之前的Android 版本相比,多出了一個vendor.img分區.在此之前的Android 系統架構當中,Android Framework 與Android HAL是打包成一個system.img的,而且Framework 與HAL之間是緊耦合的,通過鏈接的方式使用相應的硬件相關so庫。

老版本的android 的系統框架當中framework與HAL之間的一般架構框架是:

新框架

上面的框架結構中,Android framework跟Android HAL耦合度比較高,每次升級framework都需要升級對應的Hal,這個需要OEM廠商花費很大的精力。
老升級框架圖

Android O及之後的版本的框架:

在Android O以及以後的版本當中,Android 更新了框架,引入了一套叫HIDL的語言來定義Freamework與HAL之間的接口,新的架構如下圖
這裏寫圖片描述

跟之前的版本相比,Android O使用HIDL 來解耦Android Framework 與Vendor HAL Implemetation之間的聯繫。Framework 跟HAL 會放在不同的分區下面,以往的版本HAL是跟Framework 放到system 分區,會被打包成system.img.而在Android O 上面,HAL是跟Framework 會放到不同的系統分區中,Hal會放到新的分區Vendor分區中,framework 還是在system分區中。這樣就簡化降低了Android 系統升級的影響與難度。

新的升級框架

二、指紋啓動流程分析

在看這個之前,可以先看我的另外一篇文章Android Fingerprint完全解析(二) :Fingerprint啓動流程,對android O版本之前的指紋流程有一定的瞭解

1.frameworks\base\services\core\java\com\android\server\fingerprint\FingerprintService.java

    public synchronized IBiometricsFingerprint getFingerprintDaemon() {
    if (mDaemon == null) {
        Slog.v(TAG, "mDeamon 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(TAG, "Failed to get biometric interface", e);
        }
        if (mDaemon == null) {
            Slog.w(TAG, "fingerprint HIDL not available");
            return null;
        }

        mDaemon.asBinder().linkToDeath(this, 0);

        try {
            mHalDeviceId = mDaemon.setNotify(mDaemonCallback);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to open fingerprint HAL", e);
            mDaemon = null; // try again later!
        }

        if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
        if (mHalDeviceId != 0) {
            loadAuthenticatorIds();
            updateActiveGroup(ActivityManager.getCurrentUser(), null);
            doFingerprintCleanup(ActivityManager.getCurrentUser());
        } else {
            Slog.w(TAG, "Failed to open Fingerprint HAL!");
            MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1);
            mDaemon = null;
        }
    }
    return mDaemon;
}

mDaemon = IBiometricsFingerprint.getService();這句就是獲取類似AIDL中的,得到遠程服務對象中的本地代碼對象。其實這個就是HIDL接口,後邊會講到。我們先看下這個IBiometricsFingerprint 接口是在哪裏定義的,看下包名是在hardware 目錄下,我們在此目錄搜索

import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;

會看到,代碼結構如下圖所示。

IBiometricsFingerprint.hal 就是我們上面要找到的接口。當然,這只是一個接口,我們需要找到具體的實現地方。在本目錄中看到一個default文件夾。
biometrics
實現

上面中看到,BiometricsFingerprint.cpp 文件就是IBiometricsFingerprint接口的實現類。

[email protected]

service fps_hal /vendor/bin/hw/[email protected]
# "class hal" causes a race condition on some devices due to files created
# in /data. As a workaround, postpone startup until later in boot once
# /data is mounted.
class late_start
user system
group system input

上面的rc文件,會啓動fps_hal這個service。

#include <android/log.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
#include <android/hardware/biometrics/fingerprint/2.1/types.h>
#include "BiometricsFingerprint.h"

using android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
using android::hardware::biometrics::fingerprint::V2_1::implementation::BiometricsFingerprint;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;

int main() {
android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();

configureRpcThreadpool(1, true /*callerWillJoin*/);

if (bio != nullptr) {
    bio->registerAsService();
} else {
    ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
}

joinRpcThreadpool();

return 0; // should never get here
}

main函數中會把此service加入到serviceManager中。

BiometricsFingerprint.cpp 文件,會在構造函數中去打開HAL,
其他的地方跟android O 之前的分析就是一樣的。

BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) {
sInstance = this; // keep track of the most recent instance
mDevice = openHal();
if (!mDevice) {
    ALOGE("Can't open HAL module");
    }
}


fingerprint_device_t* BiometricsFingerprint::openHal() {
int err;
const hw_module_t *hw_mdl = nullptr;
ALOGD("Opening fingerprint hal library...");
if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) {
    ALOGE("Can't open fingerprint HW Module, error: %d", err);
    return nullptr;
}

if (hw_mdl == nullptr) {
    ALOGE("No valid fingerprint module");
    return nullptr;
}

fingerprint_module_t const *module =
    reinterpret_cast<const fingerprint_module_t*>(hw_mdl);
if (module->common.methods->open == nullptr) {
    ALOGE("No valid open method");
    return nullptr;
}

hw_device_t *device = nullptr;

if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) {
    ALOGE("Can't open fingerprint methods, error: %d", err);
    return nullptr;
}

if (kVersion != device->version) {
    // enforce version on new devices because of [email protected] translation layer
    ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
    return nullptr;
}

fingerprint_device_t* fp_device =
    reinterpret_cast<fingerprint_device_t*>(device);

if (0 != (err =
        fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {
    ALOGE("Can't register fingerprint module callback, error: %d", err);
    return nullptr;
}

return fp_device;
}

三、總結

1.android O 去掉了以前版本中的fingerprintd
2.fingerprintSetvice.java 調用HIDL接口,HIDl接口的實現類可以由
指紋廠家自行去實現。

3.其他的沒有變化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章