在进行屏下指纹相关功能的开发时,需要增加一个判断指纹重复的错误提示,这个需要底层判断后返回一个info和vendorcode 上来。
这个是android 专门设计的一个标准流程,用来给指纹厂商适配的。
info相关字段的定义在frameworks/base/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
/**
* @hide
*/
@IntDef({FINGERPRINT_ACQUIRED_GOOD,
FINGERPRINT_ACQUIRED_PARTIAL,
FINGERPRINT_ACQUIRED_INSUFFICIENT,
FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
FINGERPRINT_ACQUIRED_TOO_SLOW,
FINGERPRINT_ACQUIRED_TOO_FAST,
FINGERPRINT_ACQUIRED_VENDOR,
FINGERPRINT_ACQUIRED_START,
FINGERPRINT_ACQUIRED_UNKNOWN,
FINGERPRINT_ACQUIRED_IMMOBILE,
FINGERPRINT_ACQUIRED_TOO_BRIGHT,
FINGERPRINT_ACQUIRED_POWER_PRESSED,
FINGERPRINT_ACQUIRED_RE_ENROLL})
@Retention(RetentionPolicy.SOURCE)
@interface FingerprintAcquired {}
/**
* The image acquired was good.
*/
int FINGERPRINT_ACQUIRED_GOOD = 0;
/**
* Only a partial fingerprint image was detected. During enrollment, the user should be
* informed on what needs to happen to resolve this problem, e.g. "press firmly on sensor."
*/
int FINGERPRINT_ACQUIRED_PARTIAL = 1;
/**
* The fingerprint image was too noisy to process due to a detected condition (i.e. dry skin) or
* a possibly dirty sensor (See {@link #FINGERPRINT_ACQUIRED_IMAGER_DIRTY}).
*/
int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
/**
* The fingerprint image was too noisy due to suspected or detected dirt on the sensor.
* For example, it's reasonable return this after multiple
* {@link #FINGERPRINT_ACQUIRED_INSUFFICIENT} or actual detection of dirt on the sensor
* (stuck pixels, swaths, etc.). The user is expected to take action to clean the sensor
* when this is returned.
*/
int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3;
/**
* The fingerprint image was unreadable due to lack of motion. This is most appropriate for
* linear array sensors that require a swipe motion.
*/
int FINGERPRINT_ACQUIRED_TOO_SLOW = 4;
/**
* The fingerprint image was incomplete due to quick motion. While mostly appropriate for
* linear array sensors, this could also happen if the finger was moved during acquisition.
* The user should be asked to move the finger slower (linear) or leave the finger on the sensor
* longer.
*/
int FINGERPRINT_ACQUIRED_TOO_FAST = 5;
/**
* Hardware vendors may extend this list if there are conditions that do not fall under one of
* the above categories. Vendors are responsible for providing error strings for these errors.
*
* @hide
*/
int FINGERPRINT_ACQUIRED_VENDOR = 6;
/**
* This message represents the earliest message sent at the beginning of the authentication
* pipeline. It is expected to be used to measure latency. Note this should be sent whenever
* authentication is restarted.
* The framework will measure latency based on the time between the last START message and the
* onAuthenticated callback.
*
* @hide
*/
int FINGERPRINT_ACQUIRED_START = 7;
/**
* Unknown acquired code received from the HAL.
* @hide
*/
int FINGERPRINT_ACQUIRED_UNKNOWN = 8;
/**
* This message may be sent during enrollment if the same area of the finger has already
* been captured during this enrollment session. In general, enrolling multiple areas of the
* same finger can help against false rejections.
* @hide
*/
int FINGERPRINT_ACQUIRED_IMMOBILE = 9;
/**
* For sensors that require illumination, such as optical under-display fingerprint sensors,
* the image was too bright to be used for matching.
* @hide
*/
int FINGERPRINT_ACQUIRED_TOO_BRIGHT = 10;
/**
* For sensors that have the power button co-located with their sensor, this event will
* be sent during enrollment.
* @hide
*/
int FINGERPRINT_ACQUIRED_POWER_PRESSED = 11;
/**
* This message is sent to encourage the user to re-enroll their fingerprints.
* @hide
*/
int FINGERPRINT_ACQUIRED_RE_ENROLL = 12;
/**
* @hide
*/
int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
底层发送信息的方法:(也有可能不一样)
case ON_ACQUIRED_MSG: {
session->mCb->onAcquired(static_cast<AcquiredInfo>(para_1), 0);
} break;
在上层接收信息的位置在frameworks/base/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@Override
public void onAcquired(byte info, int vendorCode) {
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (!(client instanceof AcquisitionClient)) {
Slog.e(mTag, "onAcquired for non-acquisition client: "
+ Utils.getClientName(client));
return;
}
final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
acquisitionClient.onAcquired(AidlConversionUtils.toFrameworkAcquiredInfo(info),
vendorCode);
Log.d("xz", "Sensor.java onAcquired: info = " + info + " AidlConversionUtils.toFrameworkAcquiredInfo(info) = " + AidlConversionUtils.toFrameworkAcquiredInfo(info) + " vendorCode" + vendorCode);
});
}
这个方法里面要注意一下,这里在接受到info后回去处理一下,就是这个地方出现了问题。
这里会和AcquiredInfo去做对比然后返回对应的值。但是AcquiredInfo 里面的值和BiometricFingerprintConstants里面的值不一样。所以需要厂商按照AcquiredInfo里面的值来返回相应的info值。或者也可以在上层对接收到的值在进行一下处理。 比如加个 aidlAcquiredInfo += 1;
public static @BiometricFingerprintConstants.FingerprintAcquired int toFrameworkAcquiredInfo(
byte aidlAcquiredInfo) {
if (aidlAcquiredInfo == AcquiredInfo.UNKNOWN) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
} else if (aidlAcquiredInfo == AcquiredInfo.GOOD) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
} else if (aidlAcquiredInfo == AcquiredInfo.PARTIAL) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL;
} else if (aidlAcquiredInfo == AcquiredInfo.INSUFFICIENT) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_INSUFFICIENT;
} else if (aidlAcquiredInfo == AcquiredInfo.SENSOR_DIRTY) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMAGER_DIRTY;
} else if (aidlAcquiredInfo == AcquiredInfo.TOO_SLOW) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_SLOW;
} else if (aidlAcquiredInfo == AcquiredInfo.TOO_FAST) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_FAST;
} else if (aidlAcquiredInfo == AcquiredInfo.VENDOR) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
} else if (aidlAcquiredInfo == AcquiredInfo.START) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
} else if (aidlAcquiredInfo == AcquiredInfo.TOO_DARK) {
// No framework constant available
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
} else if (aidlAcquiredInfo == AcquiredInfo.TOO_BRIGHT) {
// No framework constant available
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_BRIGHT;
} else if (aidlAcquiredInfo == AcquiredInfo.IMMOBILE) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
} else if (aidlAcquiredInfo == AcquiredInfo.RETRYING_CAPTURE) {
// No framework constant available
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
} else if (aidlAcquiredInfo == AcquiredInfo.POWER_PRESS) {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED;
} else {
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
}
}
out/soong/.intermediates/hardware/interfaces/biometrics/fingerprint/aidl/android.hardware.biometrics.fingerprint-V3-java-source/gen/android/hardware/biometrics/fingerprint/AcquiredInfo.java
在源码里面定义这个AcquiredInfo的有几个文件,我也不是很确定是哪个。所以看了一下out目录里面编译出来的文件。
这个是out目录编译出来的的, 可以看到和BiometricFingerprintConstants很不一样。其实这里面的值一般不会全都用到。
就是因为两边不一样,所以返回的值到上层也不一样了。所以导致提示词错误。
package android.hardware.biometrics.fingerprint;
/** @hide */
public @interface AcquiredInfo {
public static final byte UNKNOWN = 0;
public static final byte GOOD = 1;
public static final byte PARTIAL = 2;
public static final byte INSUFFICIENT = 3;
public static final byte SENSOR_DIRTY = 4;
public static final byte TOO_SLOW = 5;
public static final byte TOO_FAST = 6;
public static final byte VENDOR = 7;
public static final byte START = 8;
public static final byte TOO_DARK = 9;
public static final byte TOO_BRIGHT = 10;
public static final byte IMMOBILE = 11;
public static final byte RETRYING_CAPTURE = 12;
public static final byte LIFT_TOO_SOON = 13;
public static final byte POWER_PRESS = 14;
}
在Sensor.java 之后会调用到 frameworks/base/core/java/android/hardware/fingerprint/FingerprintManager.java
private void sendAcquiredResult(int acquireInfo, int vendorCode) {
if (mAuthenticationCallback != null) {
mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
}
if (mEnrollmentCallback != null && acquireInfo != FINGERPRINT_ACQUIRED_START) {
mEnrollmentCallback.onAcquired(acquireInfo == FINGERPRINT_ACQUIRED_GOOD);
}
final String msg = getAcquiredString(mContext, acquireInfo, vendorCode);
if (msg == null) {
return;
}
// emulate HAL 2.1 behavior and send real acquiredInfo
final int clientInfo = acquireInfo == FINGERPRINT_ACQUIRED_VENDOR
? (vendorCode + FINGERPRINT_ACQUIRED_VENDOR_BASE) : acquireInfo;
if (mEnrollmentCallback != null) {
mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg);
} else if (mAuthenticationCallback != null) {
if (acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START) {
mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg);
}
}
}
final String msg = getAcquiredString(mContext, acquireInfo, vendorCode);
这一句会根据acquireInfo 返回对应的字符串。然后将字符串发送到指纹录入界面上面的ui上,进行更新。