Android系統開發小記:Fingerprint-settings

黃燜雞米花發表於2018-10-14

android 指紋用上也有好幾年了。現在已經出現結構光face ID,屏下指紋等新的生物識別技術,不過受成本限制還只能在旗艦機上使用。
目前來看使用最廣泛的還是傳統的按壓指紋識別技術。

標準的fingerprint結構可以分為3層結構HAL層,framework層,應用層。
因為主要做系統層開發,所以應用層用settings解析。

結構

目錄結構
android-P\packages\apps\Settings\src\com\android\settings\fingerprint\
系統中用到指紋的地方主要是指紋的錄入和管理。
包括開機嚮導中的指紋錄入,和開機後的指紋增刪管理,甚至應用鎖之類的功能。

Android 8.0 Settigns中的指紋放在“安全性和位置” subsettigns 下。首次新增指紋時,需要先設定解鎖方式。

Android系統開發小記:Fingerprint-settings

設定好解鎖方式後,進入指紋錄入階段,首先顯示感測器位置示意頁面,此時觸控一次指紋識別區域,進入到指紋錄入進度介面,此介面中的指紋錄入進度動畫是根據HAL層返回的值來載入的,在framework層會有介紹。

Android系統開發小記:Fingerprint-settings

成功設定指紋後,“安全性和位置”介面點選 指紋 會進入到指紋管理 subsettings。

Android系統開發小記:Fingerprint-settings

錄入

因為不同廠商的settings定製化不同,settings流程存在差異。不過指紋錄入階段大體相同。以下按照AOSP settigns來說明。
FingerprintEnrollBase
FingerprintEnrollFindSensor
FingerprintEnrollEnrolling
FingerprintEnrollFinish
FingerprintEnrollIntroduction
FingerprintEnrollSidecar

按照上面圖2的4個步驟來看,首先進入到的是 FingerprintEnrollFindSensor ,從類名可以看出,這裡是用來提示使用者裝置錄入指紋晶片位置的。市面上裝置普遍為前置指紋,後置指紋,少數側面指紋。最新出來有屏下指紋等。在次頁面,展示圖片或動畫提示使用者觸控指紋識別區域。
首次錄入,會進入到 startLookingForFingerprint()

    if (mToken == null && !mLaunchedConfirmLock) {
            launchConfirmLock();
    } else if (mToken != null) {
        startLookingForFingerprint(); // already confirmed, so start looking for fingerprint
    }
複製程式碼

看 startLookingForFingerprint() 目的是例項化 FingerprintEnrollSidecar 物件,實現 Listener 介面的監聽。

    private void startLookingForFingerprint() {
        mSidecar = (FingerprintEnrollSidecar) getFragmentManager().findFragmentByTag(
                FingerprintEnrollEnrolling.TAG_SIDECAR);
        if (mSidecar == null) {
            mSidecar = new FingerprintEnrollSidecar();
            getFragmentManager().beginTransaction()
                    .add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR).commit();
        }
        mSidecar.setListener(new Listener() {
            @Override
            public void onEnrollmentProgressChange(int steps, int remaining) {
                mNextClicked = true;
                proceedToEnrolling(true /* cancelEnrollment */);
            }

            @Override
            public void onEnrollmentHelp(CharSequence helpString) {
            }

            @Override
            public void onEnrollmentError(int errMsgId, CharSequence errString) {
                if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
                    mNextClicked = false;
                    proceedToEnrolling(false /* cancelEnrollment */);
                }
            }
        });
    }
複製程式碼

從生命週期來看,此時觸控一次將進入到正式錄入介面。

FingerprintEnrollFindSensor( 1548): onCreate
FingerprintEnrollFindSensor( 1548): startLookingForFingerprint
FingerprintEnrollSidecar( 1548): onCreate  
FingerprintEnrollSidecar( 1548): onStart  
FingerprintEnrollSidecar( 1548): startEnrollment
複製程式碼

觸控指紋識別區域

FingerprintEnrollSidecar( 1548): onEnrollmentProgress,remaining:11
FingerprintEnrollFindSensor( 1548): onEnrollmentProgressChange
複製程式碼

FingerprintEnrollFindSensor 接收到指紋變化後,執行 proceedToEnrolling

public void onEnrollmentProgressChange(int steps, int remaining) {
        mNextClicked = true;
        proceedToEnrolling(true /* cancelEnrollment */);
}
複製程式碼

頁面跳轉到 FingerprintEnrollEnrolling ,圖2-2. FingerprintEnrollEnrolling 繼承了 FingerprintEnrollSidecar.Listener ,因此在指紋狀態變化時會收到回撥。

FingerprintEnrollSidecar( 1548): onEnrollmentProgress,remaining:11
FingerprintEnrollEnrolling( 1548): onEnrollmentProgressChange steps:11 remaining:11
FingerprintEnrollEnrolling( 1548): getProgress,steps:11 remaining:11
複製程式碼

若在錄入過程中發生錯誤,會有類似如下流程

FingerprintEnrollSidecar( 1548): onEnrollmentHelp,helpMsgId:1001 helpString:每次需要錄入指紋的不同區域,請略微移動手指,重新嘗試。
FingerprintEnrollSidecar( 1548): onEnrollmentHelp,helpMsgId:2 helpString:無法處理指紋,請重試。
FingerprintEnrollSidecar( 1548): onEnrollmentHelp,helpMsgId:1 helpString:僅檢測到部分指紋,請重試。
複製程式碼

最後一次錄入如下。當remaining=0,即為錄入結束,結束當前頁。

FingerprintEnrollSidecar( 1548): onEnrollmentProgress,remaining:0
FingerprintEnrollEnrolling( 1548): onEnrollmentProgressChange steps:11 remaining:0
FingerprintEnrollEnrolling( 1548): getProgress,steps:11 remaining:0
複製程式碼

至此錄入指紋的簡單流程已經完成。至於 FingerprintEnrollSidecar 是如何獲得指紋晶片訊息等流程,將在framework層再分析。

相關文章