全面解析Android系統(tǒng)指紋啟動(dòng)流程
本章主要整理Android 指紋啟動(dòng)流程,側(cè)重于hal和framework部分。
一.從Android系統(tǒng)啟動(dòng)流程看指紋啟動(dòng)流程
下圖圖片出處 →

第一階段
Boot ROM,Android設(shè)備上電后,首先會(huì)從處理器片上ROM的啟動(dòng)引導(dǎo)代碼開始執(zhí)行,片上ROM會(huì)尋找Bootloader代碼,并加載到內(nèi)存。主要就是上電讓系統(tǒng)啟動(dòng)。
第二階段
Bootloader開始執(zhí)行,首先負(fù)責(zé)完成硬件的初始化,然后找到Linux內(nèi)核代碼,并加載到內(nèi)存。
啟動(dòng)過程中,bootloader(默認(rèn)是bootable/bootloader/lk)會(huì)根據(jù)機(jī)器硬件信息選擇合適的devicetree(dts)裝入內(nèi)存,如果采用pin id兼容,那么在此時(shí)就可以通過讀取ID pin的值(這個(gè)是硬件拉的,跟硬件工程師確認(rèn)是怎么對(duì)應(yīng)IC的即可)判斷指紋的IC了。
第三階段
Kernel,Linux內(nèi)核開始啟動(dòng),初始化各種軟硬件環(huán)境,加載驅(qū)動(dòng)程序,掛載根文件系統(tǒng),在系統(tǒng)文件中尋找init.rc文件,并啟動(dòng)init進(jìn)程。Kernel中,加載指紋驅(qū)動(dòng),根據(jù)傳入的dts信息創(chuàng)建設(shè)備節(jié)點(diǎn),注冊(cè)設(shè)備。
第四階段
Init,初始化和啟動(dòng)屬性服務(wù),并且啟動(dòng)Zygote進(jìn)程。
找到android.hardware.biometrics.fingerprint@2.1-service.rc,啟動(dòng)android.hardware.biometrics.fingerprint@2.1-service,會(huì)去open fingerprint.deault.so,等待與上層通信。
第五階段
Zygote進(jìn)程啟動(dòng),創(chuàng)建java虛擬機(jī)并為java虛擬機(jī)注冊(cè)JNI方法,創(chuàng)建服務(wù)器端Socket,啟動(dòng)SystemServer進(jìn)程。
第六階段
SystemServer進(jìn)程啟動(dòng),啟動(dòng)Binder線程池和SystemServiceManager,并且啟動(dòng)各種系統(tǒng)服務(wù)。會(huì)啟動(dòng)Fingerprintservice
以上是從Android啟動(dòng)流程看每個(gè)階段指紋的啟動(dòng)流程 ,下面依次詳細(xì)展開介紹。
二.驅(qū)動(dòng)層
主要就是設(shè)備節(jié)點(diǎn)驅(qū)動(dòng)的注冊(cè),在此不再詳細(xì)說了,重點(diǎn)關(guān)注probe函數(shù)。
三.hal層
首先,hardware/interfaces/biometrics/fingerprint/2.1/default/android.hardware.biometrics.fingerprint@2.1-service.rc(以下簡稱2.1 rc)
service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service
# "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
writepid /dev/cpuset/system-background/tasks
會(huì)使位于系統(tǒng)vendor/bin/hw下的android.hardware.biometrics.fingerprint@2.1-service(以下簡稱2.1 bin)開機(jī)自啟動(dòng),啟動(dòng)后會(huì)注冊(cè)2.1 service
該bin服務(wù)對(duì)應(yīng)的代碼在:hardware/interfaces/biometrics/fingerprint/2.1/default/service.cpp,整個(gè)注冊(cè)過程只有兩步,首先實(shí)例化傳入的 IBiometricsFingerprint 接口對(duì)象,然后通過 registerAsService 將服務(wù)注冊(cè)到 hwservicemanager。
int main() {
android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();
configureRpcThreadpool(1, true /*callerWillJoin*/);
if (bio != nullptr) {
if (::android::OK != bio->registerAsService()) { //*****注冊(cè)服務(wù)*****
return 1;
}
} else {
ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
}
joinRpcThreadpool();
return 0; // should never get here
}
hardware/interfaces/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp,重點(diǎn)關(guān)注openHal函數(shù),會(huì)去打開fingerprint.default.so
fingerprint_device_t* BiometricsFingerprint::openHal() {
int err;
const hw_module_t *hw_mdl = nullptr;
ALOGD("Opening fingerprint hal library...");
//*******打開fingerprint.default.so********
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 HIDL@2.1 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;
}
關(guān)于fingerprint.default.so這個(gè)都是供應(yīng)商提供的,一般都不開源,不過Android原生也是有這部分代碼的(當(dāng)然只是看看,并不能使用)
hardware/libhardware/include/hardware/fingerprint.h
hardware/libhardware/modules/fingerprint/fingerprint.c
這部分代碼不再展開貼在這里了,大家可以自行去看看,主要就是fingerprint_open打開設(shè)備(設(shè)備節(jié)點(diǎn)),然后定義了一系列函數(shù)。
dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = FINGERPRINT_MODULE_API_VERSION_2_0; dev->common.module = (struct hw_module_t*) module; dev->common.close = fingerprint_close; dev->pre_enroll = fingerprint_pre_enroll; dev->enroll = fingerprint_enroll; dev->get_authenticator_id = fingerprint_get_auth_id; dev->cancel = fingerprint_cancel; dev->remove = fingerprint_remove; dev->set_active_group = fingerprint_set_active_group; dev->authenticate = fingerprint_authenticate; dev->set_notify = set_notify_callback;
四.framework層
首先是SystemServer啟動(dòng)后,會(huì)去判斷設(shè)備是否支持指紋,如果有start FingerprintService
frameworks/base/services/java/com/android/server/SystemServer.java
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
traceBeginAndSlog("StartFingerprintSensor");
mSystemServiceManager.startService(FingerprintService.class);
traceEnd();
}
此處mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)的判斷,大家可以去frameworks/base/core/java/android/content/pm/PackageManager.java中追代碼看看,邏輯很簡單。
就是判斷系統(tǒng)內(nèi)vendor/etc/permissions目錄下是否有:android.hardware.fingerprint.xml 文件
調(diào)試的那篇說過這個(gè)配置是setting里有沒有指紋選項(xiàng)的關(guān)鍵:
PRODUCT_COPY_FILES := frameworks/native/data/etc/android.hardware.fingerprint.xml:vendor/etc/permissions/android.hardware.fingerprint.xml
下面轉(zhuǎn)到,frameworks/base/services/core/java/com/android/server/fingerprint/FingerprintService.java,以下代碼前半部分是與hal 2.1 service通信的部分,通過mDaemon = IBiometricsFingerprint.getService(),獲取2.1 service
后半部分可以看出其繼承IFingerprintService.aidl,這個(gè)aidl類就是實(shí)現(xiàn)Manager和Service通信的橋梁。
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(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);
doFingerprintCleanupForUser(ActivityManager.getCurrentUser());
} else {
Slog.w(TAG, "Failed to open Fingerprint HAL!");
MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1);
mDaemon = null;
}
//************************************************************************************//
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override // Binder call
public long preEnroll(IBinder token) {
checkPermission(MANAGE_FINGERPRINT);
return startPreEnroll(token);
}
@Override // Binder call
public int postEnroll(IBinder token) {
checkPermission(MANAGE_FINGERPRINT);
return startPostEnroll(token);
}
@Override // Binder call
public void enroll(final IBinder token, final byte[] cryptoToken, final int userId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
checkPermission(MANAGE_FINGERPRINT);
final int limit = mContext.getResources().getInteger(
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
final int enrolled = FingerprintService.this.getEnrolledFingerprints(userId).size();
if (enrolled >= limit) {
Slog.w(TAG, "Too many fingerprints registered");
return;
}
}
return mDaemon;
}
對(duì)FingerprintService再往上一層的封裝是FingerprintManager,應(yīng)用app可以直接和它通信
frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.java (以下為搜索mService的代碼,大家可以自己去看看)
private IFingerprintService mService;
if (mService != null) try {
mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
if (mService != null) {
mService.authenticate(mToken, sessionId, userId, mServiceReceiver,
if (mService != null) try {
mService.enroll(mToken, token, userId, mServiceReceiver, flags,
if (mService != null) try {
result = mService.preEnroll(mToken);
if (mService != null) try {
result = mService.postEnroll(mToken);
if (mService != null) try {
mService.setActiveUser(userId);
if (mService != null) try {
mService.remove(mToken, fp.getFingerId(), fp.getGroupId(), userId, mServiceReceiver);
mService.remove(mToken, fp.getFingerId(), fp.getGroupId(), userId, mServiceReceiver);
if (mService != null) try {
mService.enumerate(mToken, userId, mServiceReceiver);
if (mService != null) {
mService.rename(fpId, userId, newName);
if (mService != null) try {
return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
if (mService != null) try {
return mService.hasEnrolledFingerprints(
if (mService != null) try {
return mService.hasEnrolledFingerprints(userId, mContext.getOpPackageName());
if (mService != null) {
return mService.isHardwareDetected(deviceId, mContext.getOpPackageName());
if (mService != null) {
return mService.getAuthenticatorId(mContext.getOpPackageName());
if (mService != null) {
mService.resetTimeout(token);
if (mService == null) {
if (mService != null) try {
mService.cancelEnrollment(mToken);
if (mService != null) try {
mService.cancelAuthentication(mToken, mContext.getOpPackageName());
以上代碼大家可以發(fā)現(xiàn)FingerprintManager其實(shí)并沒有真正實(shí)現(xiàn)什么接口,都是調(diào)用的IFingerprintService,這里就用到aidl了,F(xiàn)ingerprintManager通過aidl的Stub獲取了Fingerprintservice,然后在這里去調(diào)用這個(gè)service的方法,以操作service,這就是aidl的作用。
frameworks/base/core/java/android/hardware/fingerprint/IFingerprintService.aidl (大家如果去看完整的代碼,這里的接口是和FingerprintManager中調(diào)用的完全一致的)
interface IFingerprintService {
// Authenticate the given sessionId with a fingerprint
void authenticate(IBinder token, long sessionId, int userId,
IFingerprintServiceReceiver receiver, int flags, String opPackageName,
in Bundle bundle, IBiometricPromptReceiver dialogReceiver);
// Cancel authentication for the given sessionId
void cancelAuthentication(IBinder token, String opPackageName);
// Start fingerprint enrollment
void enroll(IBinder token, in byte [] cryptoToken, int groupId, IFingerprintServiceReceiver receiver,
int flags, String opPackageName);
// Cancel enrollment in progress
void cancelEnrollment(IBinder token);
// Any errors resulting from this call will be returned to the listener
void remove(IBinder token, int fingerId, int groupId, int userId,
IFingerprintServiceReceiver receiver);
// Rename the fingerprint specified by fingerId and groupId to the given name
void rename(int fingerId, int groupId, String name);
// Get a list of enrolled fingerprints in the given group.
List<Fingerprint> getEnrolledFingerprints(int groupId, String opPackageName);
// Determine if HAL is loaded and ready
boolean isHardwareDetected(long deviceId, String opPackageName);
// Get a pre-enrollment authentication token
long preEnroll(IBinder token);
// Finish an enrollment sequence and invalidate the authentication token
int postEnroll(IBinder token);
五.總結(jié)
根據(jù)以上可以畫出這樣一張流程圖(以下以匯頂指紋為例,流程上都是一樣的)
System APP下發(fā)注冊(cè)命令->FingerprintManager收到命令->FingerprintService收到命令->(2.1 service)BiometricsFingerprint收到命令->(fingerprint.default.so)Fingerprint.cpp收到命令->指紋CA收到命令->指紋TA收到命令->SPI采集數(shù)據(jù)\算法進(jìn)行注冊(cè)等

以上就是全面解析Android系統(tǒng)指紋啟動(dòng)流程的詳細(xì)內(nèi)容,更多關(guān)于Android啟動(dòng)流程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android應(yīng)用開發(fā)中使用Fragment的入門學(xué)習(xí)教程
這篇文章主要介紹了Android應(yīng)用開發(fā)中Fragment的入門學(xué)習(xí)教程,可以把Fragment看作為Activity基礎(chǔ)之上的模塊,需要的朋友可以參考下2016-02-02
Android recycleView的應(yīng)用和點(diǎn)擊事件實(shí)例詳解
這篇文章主要介紹了Android recycleView的應(yīng)用和點(diǎn)擊事件實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12
android開發(fā)教程之實(shí)現(xiàn)滑動(dòng)關(guān)閉fragment示例
這篇文章主要介紹了android實(shí)現(xiàn)滑動(dòng)關(guān)閉fragment示例,需要的朋友可以參考下2014-03-03
Android實(shí)現(xiàn)手勢(shì)密碼功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)手勢(shì)密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android中invalidate()和postInvalidate() 的區(qū)別及使用方法
Android中實(shí)現(xiàn)view的更新有兩組方法,一組是invalidate,另一組是postInvalidate,其中前者是在UI線程自身中使用,而后者在非UI線程中使用。本文給大家介紹Android中invalidate()和postInvalidate() 的區(qū)別及使用方法,感興趣的朋友一起學(xué)習(xí)吧2016-05-05
Android使用ViewPager實(shí)現(xiàn)類似laucher左右拖動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android使用ViewPager實(shí)現(xiàn)類似laucher左右拖動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android自定義控件實(shí)現(xiàn)隨手指移動(dòng)的小球
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)隨手指移動(dòng)的小球,隨著手指觸摸移動(dòng)而移動(dòng)的效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10

