当有指纹解锁时,会执行AuthenticationClient.java-->onAuthenticated()一直在监听解锁行为
@Override
public boolean onAuthenticated(int fingerId, int groupId) {
boolean result = false;
boolean authenticated = fingerId != 0;
IFingerprintServiceReceiver receiver = getReceiver();
if (receiver != null) {
try {
MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_AUTH,
authenticated);
if (!authenticated) {
receiver.onAuthenticationFailed(getHalDeviceId());
} else {
if (DEBUG) {
Slog.v(TAG, "onAuthenticated(owner=" + getOwnerString()
+ ", id=" + fingerId + ", gp=" + groupId + ")");
}
Fingerprint fp = !getIsRestricted()
? new Fingerprint("" /* TODO */, groupId, fingerId, getHalDeviceId())
: null;
receiver.onAuthenticationSucceeded(getHalDeviceId(), fp, getTargetUserId());//解锁成功
}
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify Authenticated:", e);
result = true; // client failed
}
} else {
result = true; // client not listening
}
if (!authenticated) {
if (receiver != null) {
vibrateError();
}
// allow system-defined limit of number of attempts before giving up
int lockoutMode = handleFailedAttempt();
if (lockoutMode != LOCKOUT_NONE) {
try {
Slog.w(TAG, "Forcing lockout (fp driver code should do this!), mode(" +
lockoutMode + ")");
stop(false);
int errorCode = lockoutMode == LOCKOUT_TIMED ?
FingerprintManager.FINGERPRINT_ERROR_LOCKOUT :
FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
receiver.onError(getHalDeviceId(), FingerprintManager.FINGERPRINT_ERROR_FORCING_LOCKOUT, 0 /* vendorCode */);//Add By [email protected] 2018/1/20 Defect:5880186 //当解锁失败会执行
receiver.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify lockout:", e);
}
}
result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
} else {
if (receiver != null) {
vibrateSuccess();
}
result |= true; // we have a valid fingerprint, done
resetFailedAttempts();
}
return result;
}
先看看int lockoutMode = handleFailedAttempt();他是在FingerprintService.java中实现,因为它监听了该方法
private void startAuthentication(IBinder token, long opId, int callingUserId, int groupId,
IFingerprintServiceReceiver receiver, int flags, boolean restricted,
String opPackageName) {
updateActiveGroup(groupId, opPackageName);
if (DEBUG) Slog.v(TAG, "startAuthentication(" + opPackageName + ")");
AuthenticationClient client = new AuthenticationClient(getContext(), mHalDeviceId, token,
receiver, mCurrentUserId, groupId, opId, restricted, opPackageName) {
@Override
public int handleFailedAttempt() {
mFailedAttempts++;
mTimedLockoutCleared = false;
final int lockoutMode = getLockoutMode();
if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
mPerformanceStats.permanentLockout++;
} else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
mPerformanceStats.lockout++;
}
// Failing multiple times will continue to push out the lockout time
if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
scheduleLockoutReset();
return lockoutMode;
}
return AuthenticationClient.LOCKOUT_NONE;
}
@Override
public void resetFailedAttempts() {
FingerprintService.this.resetFailedAttempts(true /* clearAttemptCounter */);
}
@Override
public void notifyUserActivity() {
FingerprintService.this.userActivity();
}
@Override
public IBiometricsFingerprint getFingerprintDaemon() {
return FingerprintService.this.getFingerprintDaemon();
}
};
int lockoutMode = getLockoutMode();
if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
Slog.v(TAG, "In lockout mode(" + lockoutMode +
") ; disallowing authentication");
int errorCode = lockoutMode == AuthenticationClient.LOCKOUT_TIMED ?
FingerprintManager.FINGERPRINT_ERROR_LOCKOUT :
FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
if (!client.onError(errorCode, 0 /* vendorCode */)) {
Slog.w(TAG, "Cannot send permanent lockout message to client");
}
return;
}
startClient(client, true /* initiatedByClient */);
}
看到这个方法可以明白,他是记录指纹识别错误的次数及一些行为,当mFailedAttempts为5的倍数时,会返回AuthenticationClient.LOCKOUT_TIMED
private int getLockoutMode() {
if (mFailedAttempts >= MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT) {
return AuthenticationClient.LOCKOUT_PERMANENT;
} else if (mFailedAttempts > 0 && mTimedLockoutCleared == false &&
(mFailedAttempts % MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED == 0)) {
return AuthenticationClient.LOCKOUT_TIMED;
}
return AuthenticationClient.LOCKOUT_NONE;
}
回到AuthenticationClient.java-->onAuthenticated(),可以看到receiver.onError()方法,传入了一些状态码,而receiver是在FingerprintManager.java指纹监听的时候有实现
private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
@Override // binder call
public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
}
@Override // binder call
public void onAcquired(long deviceId, int acquireInfo, int vendorCode) {
mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, vendorCode, deviceId).sendToTarget();
}
@Override // binder call
public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, fp).sendToTarget();
}
@Override // binder call
public void onAuthenticationFailed(long deviceId) {
mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();
}
@Override // binder call
public void onError(long deviceId, int error, int vendorCode) {
mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget();//向上层发送消失反馈
}
@Override // binder call
public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
mHandler.obtainMessage(MSG_REMOVED, remaining, 0,
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
}
@Override // binder call
public void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) {
// TODO: propagate remaining
mHandler.obtainMessage(MSG_ENUMERATED, fingerId, groupId, deviceId).sendToTarget();
}
};
利用Handler接收了MSG_ERROR执行了sendErrorResult,具体的switch就不贴出来了
private void sendErrorResult(long deviceId, int errMsgId, int vendorCode) {
// emulate HAL 2.1 behavior and send real errMsgId
final int clientErrMsgId = errMsgId == FINGERPRINT_ERROR_VENDOR
? (vendorCode + FINGERPRINT_ERROR_VENDOR_BASE) : errMsgId;
if (mEnrollmentCallback != null) {
mEnrollmentCallback.onEnrollmentError(clientErrMsgId,
getErrorString(errMsgId, vendorCode));
} else if (mAuthenticationCallback != null) {
mAuthenticationCallback.onAuthenticationError(clientErrMsgId,
getErrorString(errMsgId, vendorCode));
} else if (mRemovalCallback != null) {
mRemovalCallback.onRemovalError(mRemovalFingerprint, clientErrMsgId,
getErrorString(errMsgId, vendorCode));
} else if (mEnumerateCallback != null) {
mEnumerateCallback.onEnumerateError(clientErrMsgId,
getErrorString(errMsgId, vendorCode));
}
}
mAuthenticationCallback其实是FingerprintManager.java中的一个回调接口,在上层KeyguardUpdateMonitor.java中有实现
因为之前指纹解锁时一直在监听:mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);就等待mAuthenticationCallback返回结果。
private FingerprintManager.AuthenticationCallback mAuthenticationCallback
= new AuthenticationCallback() {
@Override
public void onAuthenticationFailed() {
handleFingerprintAuthFailed();
};
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
handleFingerprintAuthenticated(result.getUserId());
Trace.endSection();
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
handleFingerprintHelp(helpMsgId, helpString.toString());
}
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
handleFingerprintError(errMsgId, errString.toString());//更新错误信息
}
@Override
public void onAuthenticationAcquired(int acquireInfo) {
handleFingerprintAcquired(acquireInfo);
}
};
看到这个方法可以明白,它是根据不同的状态码处理不同的消息,当状态码为7时,也就是FingerprintManager.FINGERPRINT_ERROR_FORCING_LOCKOUT=7,此时已经输错了5次,因为当输错了5次,指定了状态码为7,用7来处理后续的操作,会通过亮屏显示指纹识别错误信息。
private void handleFingerprintError(int msgId, String errString) {
Log.d(TAG, "Fingerprint handleFingerprintError: msgId = "+msgId);
if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
&& mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
startListeningForFingerprint();
}
//Add by [email protected] for defect[5880186] 20180120, fingerprint unlock the device failed 5 times without any prompts, begin
if (msgId == FingerprintManager.FINGERPRINT_ERROR_FORCING_LOCKOUT){
Log.d(TAG, "Fingerprint unlock the device failed 5 times, wakeup screen and show prompt.");
setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPM.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "Wakeup Sreen");
mWakeLock.acquire();
mWakeLock.release();
mWakeLock = null;
mPM = null;
}
//Add by [email protected] for defect[5880186] 20180120, fingerprint unlock the device failed 5 times without any prompts, end
else {
setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
}
if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
if (mHardwareUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
mHardwareUnavailableRetryCount++;
mHandler.removeCallbacks(mRetryFingerprintAuthentication);
mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
}
}
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
mLockPatternUtils.requireStrongAuth(
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
getCurrentUser());
}
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
cb.onFingerprintError(msgId, errString);//会更新界面错误信息,在FingerprintUnlockController.java中有实现
}
}
}
此时,指纹识别错误5次,亮屏且提示错误信息已经解析完毕。