當然可以!以下是一篇基於你提供的 CSDN 博客文章(原文鏈接)整理而成的技術博客,保留了關鍵代碼、流程説明和架構分析,並進行了邏輯梳理與語言優化,適合用於技術分享或學習筆記。
Android 人臉解鎖源碼剖析:從錄入到認證全流程解析
作者:Qwen
參考來源:CSDN 原文《Android 人臉解鎖源碼剖析》
在 Android 10 中,Google 引入了全新的人臉識別身份驗證堆棧(Face Authentication Stack),以支持更安全、隱私友好的人臉識別解鎖功能。本文將深入 Android 源碼,系統性地解析人臉錄入(Enrollment)、匹配(Authentication)以及屏幕解鎖(Unlock)三大核心流程,並結合關鍵代碼片段進行説明。
一、整體架構概覽
Android 人臉識別基於 BiometricPrompt API 統一框架,支持指紋、人臉、虹膜等多種生物識別方式。其核心組件如下:
- FaceManager:私有接口,供 Keyguard 調用人臉硬件,應用層不可直接訪問。
- FaceService:運行在 system_server 中的服務,管理人臉註冊/認證狀態機,禁止加載廠商代碼。
- faced:Linux 可執行程序,實現
IBiometricsFace@1.0HIDL 接口,由廠商提供。 - HIDL 接口:
IBiometricsFace.halIBiometricsFaceClientCallback.haltype.hal
✅ 所有廠商實現必須通過 HIDL 與 FaceService 通信,確保系統安全隔離。
二、人臉錄入流程(Enrollment)
1. 入口:Settings 中的 FaceEnrollEnrolling
用户在「設置 > 安全 > 人臉識別」中點擊“添加人臉”,進入 FaceEnrollEnrolling.java:
// packages/apps/Settings/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
@Override
public void startEnrollment() {
super.startEnrollment(); // 調用父類
if (mUserId != UserHandle.USER_NULL) {
mFaceManager.setActiveUser(mUserId);
}
mFaceManager.enroll(mToken, mEnrollmentCancel, mEnrollmentCallback, mDisabledFeatures);
}
2. 調用 FaceManager.enroll()
// frameworks/base/core/java/android/hardware/face/FaceManager.java
public void enroll(byte[] token, CancellationSignal cancel,
EnrollmentCallback callback, int[] disabledFeatures) {
if (mService != null) {
try {
mService.enroll(mToken, token, mServiceReceiver,
mContext.getOpPackageName(), disabledFeatures);
} catch (RemoteException e) {
// 錯誤處理
}
}
}
3. FaceService 處理請求
// frameworks/base/services/core/java/com/android/server/biometrics/face/FaceService.java
public void enroll(final IBinder token, final byte[] cryptoToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures) {
EnrollClientImpl client = new EnrollClientImpl(...);
enrollInternal(client, mCurrentUserId);
}
最終調用 startClient(client) → client.start():
// EnrollClient.java
@Override
public int start() {
final int result = getDaemonWrapper().enroll(mCryptoToken, getGroupId(), timeout, disabledFeatures);
return result;
}
🔧 此處
getDaemonWrapper().enroll()實際調用的是faced進程(通過 Binder),由廠商 HAL 實現。
4. 進度回調機制
HAL 層在每次採集後通過 onEnrollResult 回調:
// FaceManager.java 內部接收器
private IFaceServiceReceiver mServiceReceiver = new IFaceServiceReceiver.Stub() {
@Override
public void onEnrollResult(long deviceId, int faceId, int remaining) {
mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0, new Face(null, faceId, deviceId))
.sendToTarget();
}
};
// 處理消息
private void sendEnrollResult(Face face, int remaining) {
if (mEnrollmentCallback != null) {
mEnrollmentCallback.onEnrollmentProgress(remaining); // 更新 UI 進度
}
}
當 remaining == 0 時,表示錄入完成,跳轉至結束頁面:
// ParticleCollection.java
@Override
public void onEnrollmentProgressChange(int steps, int remaining) {
if (remaining == 0) {
updateState(STATE_COMPLETE);
}
}
三、人臉匹配流程(Authentication)
1. 觸發時機:設備滅屏後喚醒
當設備滅屏再亮起時,Keyguard 會啓動人臉監聽:
// KeyguardUpdateMonitor.java
private void startListeningForFace() {
if (isUnlockWithFacePossible(userId)) {
mFaceCancelSignal = new CancellationSignal();
mFaceManager.authenticate(null, mFaceCancelSignal, 0,
mFaceAuthenticationCallback, null, userId);
setFaceRunningState(BIOMETRIC_STATE_RUNNING);
}
}
2. FaceManager.authenticate()
// FaceManager.java
public void authenticate(@Nullable CryptoObject crypto,
@Nullable CancellationSignal cancel,
int flags,
@NonNull AuthenticationCallback callback,
@Nullable Handler handler,
int userId) {
mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags, opPackageName);
}
3. FaceService 啓動認證客户端
類似錄入流程,創建 FaceAuthClient 並調用 start():
// AuthenticationClient.java
public int start() {
final int result = getDaemonWrapper().authenticate(mOpId, getGroupId());
return result;
}
⚠️ 底層
faced開始實時比對攝像頭幀與已註冊模板。
4. 認證結果回調
成功時,HAL 調用 onAuthenticated:
// BiometricServiceBase.java
public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
boolean authenticated,
ArrayList<Byte> token) {
if (authenticated && listener != null) {
listener.onAuthenticationSucceeded(getHalDeviceId(), identifier, getTargetUserId());
}
}
最終傳遞到 FaceManager 的 Handler:
// FaceManager.java
private IFaceServiceReceiver mServiceReceiver = new IFaceServiceReceiver.Stub() {
@Override
public void onAuthenticationSucceeded(long deviceId, Face face, int userId) {
mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, face)
.sendToTarget();
}
};
private void sendAuthenticatedSucceeded(Face face, int userId) {
if (mAuthenticationCallback != null) {
AuthenticationResult result = new AuthenticationResult(mCryptoObject, face, userId);
mAuthenticationCallback.onAuthenticationSucceeded(result);
}
}
四、人臉解鎖屏幕(Keyguard Unlock)
1. Keyguard 監聽認證成功
KeyguardUpdateMonitor 實現了 FaceManager.AuthenticationCallback:
// KeyguardUpdateMonitor.java
FaceManager.AuthenticationCallback mFaceAuthenticationCallback =
new FaceManager.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
handleFaceAuthenticated(result.getUserId());
}
};
2. 觸發解鎖邏輯
private void handleFaceAuthenticated(int authUserId) {
onFaceAuthenticated(authUserId);
}
protected void onFaceAuthenticated(int userId) {
// 標記用户已通過人臉認證
mUserFaceAuthenticated.put(userId, true);
// 通知所有回調(包括 BiometricUnlockController)
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
cb.onBiometricAuthenticated(userId, BiometricSourceType.FACE);
}
}
}
3. BiometricUnlockController 執行解鎖
// BiometricUnlockController.java
@Override
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType) {
startWakeAndUnlock(calculateMode(biometricSourceType));
}
public void startWakeAndUnlock(int mode) {
// 喚醒屏幕
mPowerManager.wakeUp(SystemClock.uptimeMillis(), ...);
// 通知 Keyguard 解鎖
mKeyguardViewMediator.onWakeAndUnlocking();
// 隱藏鎖屏界面
mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(false);
}
至此,人臉解鎖完成,用户進入主屏幕。
五、總結
Android 人臉解鎖流程高度模塊化,遵循“應用 → Framework → Service → HAL → Kernel” 的分層設計:
- 安全性:廠商代碼僅運行在
faced進程,與 system_server 隔離。 - 統一性:通過
BiometricPrompt和BiometricServiceBase抽象,支持多模態生物識別。 - 可擴展性:HIDL 接口標準化,便於不同廠商適配。
📌 注意:人臉解鎖在 Android 中默認為 Class 2(弱生物識別),不能用於高安全場景(如支付),除非廠商實現 Strong Biometric(需滿足活體檢測、防欺騙等要求)。
參考資料
- Android 官方文檔 - Biometric Authentication
- Android 10 新特性:人臉識別身份驗證
- 原文:CSDN《Android 人臉解鎖源碼剖析》
希望這篇整理對你理解 Android 人臉解鎖機制有所幫助!歡迎點贊、收藏或在評論區交流~