回調(diào)流程
FingerprintService啟動(dòng)同時(shí)啟動(dòng)FingerprintDaemon并傳入核心回調(diào)接口——IFingerprintDaemonCallback(8.1是IBiometricsFingerprintClientCallback)
該接口用于向ClientMonitor的4大實(shí)現(xiàn)類分發(fā)回調(diào)事件东羹。
- AuthenticationClient:指紋驗(yàn)證
- EnrollClient:指紋錄入
- EnumerateClient :
- RemovalClient:指紋移除
1. IFingerprintDaemonCallback
private IFingerprintDaemonCallback mDaemonCallback = new IFingerprintDaemonCallback.Stub() {
@Override
public void onEnrollResult(final long deviceId, final int fingerId, final int groupId,
final int remaining) {
mHandler.post(new Runnable() {
@Override
public void run() {
handleEnrollResult(deviceId, fingerId, groupId, remaining);
}
});
}
@Override
public void onAcquired(final long deviceId, final int acquiredInfo) {
mHandler.post(new Runnable() {
@Override
public void run() {
handleAcquired(deviceId, acquiredInfo);
}
});
}
@Override
public void onAuthenticated(final long deviceId, final int fingerId, final int groupId) {
mHandler.post(new Runnable() {
@Override
public void run() {
handleAuthenticated(deviceId, fingerId, groupId);
}
});
}
@Override
public void onError(final long deviceId, final int error) {
mHandler.post(new Runnable() {
@Override
public void run() {
handleError(deviceId, error);
}
});
}
@Override
public void onRemoved(final long deviceId, final int fingerId, final int groupId) {
mHandler.post(new Runnable() {
@Override
public void run() {
handleRemoved(deviceId, fingerId, groupId);
}
});
}
@Override
public void onEnumerate(final long deviceId, final int[] fingerIds, final int[] groupIds) {
mHandler.post(new Runnable() {
@Override
public void run() {
handleEnumerate(deviceId, fingerIds, groupIds);
}
});
}
};
各個(gè)client接收到回調(diào)事件,則會(huì)調(diào)用第二個(gè)接口FingerprintServiceReceiver
2. FingerprintServiceReceiver
FingerprintServiceReceiver是FingerprintManager中總的回調(diào)接口冤议,用于回調(diào)EnrollmentCallback,AuthenticationCallback等上層接口
private IFingerprintServiceReceiver mServiceReceiver = new Stub() {
public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
FingerprintManager.this.mHandler.obtainMessage(100, remaining, 0, new Fingerprint((CharSequence)null, groupId, fingerId, deviceId)).sendToTarget();
}
public void onAcquired(long deviceId, int acquireInfo) {
FingerprintManager.this.mHandler.obtainMessage(101, acquireInfo, 0, deviceId).sendToTarget();
}
public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
FingerprintManager.this.mHandler.obtainMessage(102, userId, 0, fp).sendToTarget();
}
public void onAuthenticationFailed(long deviceId) {FingerprintManager.this.mHandler.obtainMessage(103).sendToTarget();
}
public void onError(long deviceId, int error) {
FingerprintManager.this.mHandler.obtainMessage(104, error, 0, deviceId).sendToTarget();
}
public void onRemoved(long deviceId, int fingerId, int groupId) {
FingerprintManager.this.mHandler.obtainMessage(105, fingerId, groupId, deviceId).sendToTarget();
}
};
錄入指紋流程:
調(diào)用:
FingerprintManager.enroll(userId,receiver,...)
->service.enroll(userId,receiver,...)
->startEnrollment(userId,receiver,...)
- startEnrollment(userId,receiver,...)
private void startEnrollment(IBinder token, byte [] cryptoToken, int userId,
IFingerprintServiceReceiver receiver, int flags, boolean restricted,
String opPackageName) {
updateActiveGroup(userId, opPackageName);
//注意groupId = userId
final int groupId = userId; // default group for fingerprint enrollment
//保存receiver
EnrollClient client = new EnrollClient(getContext(), mHalDeviceId, token, receiver,
userId, groupId, cryptoToken, restricted, opPackageName) {
}
-> 初始化一個(gè)EnrollClient,調(diào)用startClient()
->client.start()
-> daemon.enroll(mCryptoToken, getGroupId(), timeout)開始錄入
(FingerprintManager中回調(diào)接口IFingerprintServiceReceiver會(huì)保存在EnrollClient中以待回調(diào))
回調(diào):
IFingerprintDaemonCallback
->onEnrollResult(fingerid 蕊温,deviceid,groupid发笔,remaining)
-> client.onEnrollResult()
- client.onEnrollResult(fingerId, groupId, remaining):
- 若錄入完成了讨,將id等信息保存xml
public boolean onEnrollResult(int fingerId, int groupId, int remaining) {
if (groupId != getGroupId()) {
Slog.w(TAG, "groupId != getGroupId(), groupId: " + groupId +
" getGroupId():" + getGroupId());
}
//錄入完成
if (remaining == 0) {
//#1
FingerprintUtils.getInstance().addFingerprintForUser(getContext(), fingerId,
getTargetUserId());
}
return sendEnrollResult(fingerId, groupId, remaining);
}
#1:保存該指紋信息
public void addFingerprintForUser(Context ctx, int fingerId, int userId) {
//#2:getStateForUser:獲取UserState量蕊,若沒有則初始化一個(gè)UserState艇挨。
//構(gòu)造方法中會(huì)根據(jù)該userId查詢之前保存的指紋File(xml),初始化一個(gè)mFingerprints集合缩滨。
//#3:addFingerprint:添加進(jìn)mFingerprints集合,寫入File苞冯。
//注意寫入的groupId就是userId舅锄。
getStateForUser(ctx, userId).addFingerprint(fingerId, userId);
}
- sendEnrollResult
->receiver.onEnrollResult
->FingerprintManafger.sendEnrollResult
private void sendEnrollResult(Fingerprint fp, int remaining) {
if (FingerprintManager.this.mEnrollmentCallback != null) {
FingerprintManager.this.mEnrollmentCallback.onEnrollmentProgress(remaining);
}
}
驗(yàn)證指紋流程:
調(diào)用:
FingerprintManager.authenticate(userId,receiver,...)
->service.authenticate (userId,receiver,...)
->初始化一個(gè)AuthenticationClient , 調(diào)用startClient(userId,receiver,...)
->client.start()
->daemon.authenticate(mOpId, getGroupId())開始驗(yàn)證
(FingerprintManager中回調(diào)接口IFingerprintServiceReceiver同樣會(huì)保存在AuthenticationClient中以待回調(diào))
回調(diào):
IFingerprintDaemonCallback
->onAuthenticated(fingerid 皇忿,deviceid鳍烁,groupid繁扎,token)
->client.onAuthenticated
- client.onAuthenticated:
根據(jù)指紋結(jié)果回調(diào)Receiver中的onAuthenticationSucceeded糊闽,onAuthenticationFailed等方法右犹。
修改
enroll錄入
因?yàn)镋nrollmentCallback沒有獲取正在錄制的指紋id參數(shù)接口念链,所以自己提供一個(gè)獲取方法莉炉。
- 新增enrollFingerId變量
private int enrollFingerId = -1;
- 新增getEnrollFingerId方法:
public int getEnrollFingerId() {
return this.enrollFingerId;
}
- enroll方法重置enrollFingerId
public void enroll(byte[] token, CancellationSignal cancel, int flags, int userId, FingerprintManager.EnrollmentCallback callback) {
this.enrollFingerId = -1;
}
- sendEnrollResult中enrollFingerId保存fingerId
private void sendEnrollResult(Fingerprint fp, int remaining) {
if (FingerprintManager.this.mEnrollmentCallback != null) {
//+++
FingerprintManager.this.enrollFingerId = fp.getFingerId();
FingerprintManager.this.mEnrollmentCallback.onEnrollmentProgress(remaining);
}
}
authenticate驗(yàn)證
因?yàn)樵贏uthenticationClient.onAuthenticated(int fingerId, int groupId)中isRestricted=true梆暮,從而在FingerprintManager的AuthenticationCallback.onAuthenticationSucceeded參數(shù)中的Fingerprint對象為null绍昂。
Fingerprint fp = !getIsRestricted()
? new Fingerprint("" /* TODO */, groupId, fingerId,
FingerprintUtils.isSoterSimulated() ?
548398617248L : getHalDeviceId())
: null;
FingerprintService修改:
private boolean isRestricted() {
// Only give privileged apps (like Settings) access to fingerprint info
// --- final boolean restricted = !hasPermission(MANAGE_FINGERPRINT);
// --- return restricted;
// +++
return false;
}