mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Fingerprint virtual HAL checkin (part 2)
- acquiredInfo support for HAL operations
- error insertions
- FPS configurations
Bug: 230515082
Bug: 230515086
Test: atest FakeFingerprintEngineTest
atest FakeFingerprintEngineUdfpsTest
atest --no-bazel-mode VtsHalBiometricsFingerprintTargetTest
Change-Id: Iedd1056e516358c3c0a99bd4a720016cc0f880e4
This commit is contained in:
@@ -56,43 +56,58 @@ void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
|
||||
return;
|
||||
}
|
||||
|
||||
if (FingerprintHalProperties::operation_enroll_fails().value_or(false)) {
|
||||
LOG(ERROR) << "Fail: operation_enroll_fails";
|
||||
cb->onError(Error::VENDOR, 0 /* vendorError */);
|
||||
// Force error-out
|
||||
auto err = FingerprintHalProperties::operation_enroll_error().value_or(0);
|
||||
if (err != 0) {
|
||||
LOG(ERROR) << "Fail: operation_enroll_error";
|
||||
auto ec = convertError(err);
|
||||
cb->onError(ec.first, ec.second);
|
||||
return;
|
||||
}
|
||||
|
||||
// format is "<id>:<progress_ms>,<progress_ms>,...:<result>
|
||||
// Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
|
||||
auto nextEnroll = FingerprintHalProperties::next_enrollment().value_or("");
|
||||
auto parts = Util::split(nextEnroll, ":");
|
||||
if (parts.size() != 3) {
|
||||
LOG(ERROR) << "Fail: invalid next_enrollment";
|
||||
LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
|
||||
cb->onError(Error::VENDOR, 0 /* vendorError */);
|
||||
return;
|
||||
}
|
||||
auto enrollmentId = std::stoi(parts[0]);
|
||||
auto progress = Util::split(parts[1], ",");
|
||||
for (size_t i = 0; i < progress.size(); i++) {
|
||||
auto left = progress.size() - i - 1;
|
||||
SLEEP_MS(std::stoi(progress[i]));
|
||||
auto progress = parseEnrollmentCapture(parts[1]);
|
||||
for (size_t i = 0; i < progress.size(); i += 2) {
|
||||
auto left = (progress.size() - i) / 2 - 1;
|
||||
auto duration = progress[i][0];
|
||||
auto acquired = progress[i + 1];
|
||||
auto N = acquired.size();
|
||||
|
||||
if (shouldCancel(cancel)) {
|
||||
LOG(ERROR) << "Fail: cancel";
|
||||
cb->onError(Error::CANCELED, 0 /* vendorCode */);
|
||||
return;
|
||||
for (int j = 0; j < N; j++) {
|
||||
SLEEP_MS(duration / N);
|
||||
|
||||
if (shouldCancel(cancel)) {
|
||||
LOG(ERROR) << "Fail: cancel";
|
||||
cb->onError(Error::CANCELED, 0 /* vendorCode */);
|
||||
return;
|
||||
}
|
||||
auto ac = convertAcquiredInfo(acquired[j]);
|
||||
cb->onAcquired(ac.first, ac.second);
|
||||
}
|
||||
|
||||
cb->onAcquired(AcquiredInfo::GOOD, 0 /* vendorCode */);
|
||||
if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
|
||||
LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
|
||||
FingerprintHalProperties::next_enrollment({});
|
||||
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
|
||||
} else { // progress and update props if last time
|
||||
LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
|
||||
if (left == 0) {
|
||||
auto enrollments = FingerprintHalProperties::enrollments();
|
||||
enrollments.emplace_back(enrollmentId);
|
||||
FingerprintHalProperties::enrollments(enrollments);
|
||||
FingerprintHalProperties::next_enrollment({});
|
||||
// change authenticatorId after new enrollment
|
||||
auto id = FingerprintHalProperties::authenticator_id().value_or(0);
|
||||
auto newId = id + 1;
|
||||
FingerprintHalProperties::authenticator_id(newId);
|
||||
LOG(INFO) << "Enrolled: " << enrollmentId;
|
||||
}
|
||||
cb->onEnrollmentProgress(enrollmentId, left);
|
||||
@@ -104,12 +119,31 @@ void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* op
|
||||
const std::future<void>& cancel) {
|
||||
BEGIN_OP(FingerprintHalProperties::operation_authenticate_latency().value_or(DEFAULT_LATENCY));
|
||||
|
||||
auto now = Util::getSystemNanoTime();
|
||||
int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(0);
|
||||
int64_t now = Util::getSystemNanoTime();
|
||||
int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(10);
|
||||
auto acquired = FingerprintHalProperties::operation_authenticate_acquired().value_or("1");
|
||||
auto acquiredInfos = parseIntSequence(acquired);
|
||||
int N = acquiredInfos.size();
|
||||
|
||||
if (N == 0) {
|
||||
LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
|
||||
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
do {
|
||||
if (FingerprintHalProperties::operation_authenticate_fails().value_or(false)) {
|
||||
LOG(ERROR) << "Fail: operation_authenticate_fails";
|
||||
cb->onError(Error::VENDOR, 0 /* vendorError */);
|
||||
cb->onAuthenticationFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
|
||||
if (err != 0) {
|
||||
LOG(ERROR) << "Fail: operation_authenticate_error";
|
||||
auto ec = convertError(err);
|
||||
cb->onError(ec.first, ec.second);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -126,20 +160,25 @@ void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* op
|
||||
return;
|
||||
}
|
||||
|
||||
auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
|
||||
auto enrolls = FingerprintHalProperties::enrollments();
|
||||
auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
|
||||
if (id > 0 && isEnrolled) {
|
||||
cb->onAuthenticationSucceeded(id, {} /* hat */);
|
||||
return;
|
||||
if (i < N) {
|
||||
auto ac = convertAcquiredInfo(acquiredInfos[i]);
|
||||
cb->onAcquired(ac.first, ac.second);
|
||||
i++;
|
||||
}
|
||||
|
||||
SLEEP_MS(100);
|
||||
SLEEP_MS(duration / N);
|
||||
} while (!Util::hasElapsed(now, duration));
|
||||
|
||||
LOG(ERROR) << "Fail: not enrolled";
|
||||
cb->onAuthenticationFailed();
|
||||
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
|
||||
auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
|
||||
auto enrolls = FingerprintHalProperties::enrollments();
|
||||
auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
|
||||
if (id > 0 && isEnrolled) {
|
||||
cb->onAuthenticationSucceeded(id, {} /* hat */);
|
||||
return;
|
||||
} else {
|
||||
LOG(ERROR) << "Fail: fingerprint not enrolled";
|
||||
cb->onAuthenticationFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
|
||||
@@ -147,17 +186,42 @@ void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
|
||||
BEGIN_OP(FingerprintHalProperties::operation_detect_interaction_latency().value_or(
|
||||
DEFAULT_LATENCY));
|
||||
|
||||
if (FingerprintHalProperties::operation_detect_interaction_fails().value_or(false)) {
|
||||
LOG(ERROR) << "Fail: operation_detect_interaction_fails";
|
||||
cb->onError(Error::VENDOR, 0 /* vendorError */);
|
||||
int64_t duration =
|
||||
FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
|
||||
auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
|
||||
auto acquiredInfos = parseIntSequence(acquired);
|
||||
int N = acquiredInfos.size();
|
||||
int64_t now = Util::getSystemNanoTime();
|
||||
|
||||
if (N == 0) {
|
||||
LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
|
||||
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldCancel(cancel)) {
|
||||
LOG(ERROR) << "Fail: cancel";
|
||||
cb->onError(Error::CANCELED, 0 /* vendorCode */);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
do {
|
||||
auto err = FingerprintHalProperties::operation_detect_interaction_error().value_or(0);
|
||||
if (err != 0) {
|
||||
LOG(ERROR) << "Fail: operation_detect_interaction_error";
|
||||
auto ec = convertError(err);
|
||||
cb->onError(ec.first, ec.second);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldCancel(cancel)) {
|
||||
LOG(ERROR) << "Fail: cancel";
|
||||
cb->onError(Error::CANCELED, 0 /* vendorCode */);
|
||||
return;
|
||||
}
|
||||
|
||||
if (i < N) {
|
||||
auto ac = convertAcquiredInfo(acquiredInfos[i]);
|
||||
cb->onAcquired(ac.first, ac.second);
|
||||
i++;
|
||||
}
|
||||
SLEEP_MS(duration / N);
|
||||
} while (!Util::hasElapsed(now, duration));
|
||||
|
||||
auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
|
||||
auto enrolls = FingerprintHalProperties::enrollments();
|
||||
@@ -211,24 +275,37 @@ void FakeFingerprintEngine::removeEnrollmentsImpl(ISessionCallback* cb,
|
||||
|
||||
void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
|
||||
BEGIN_OP(0);
|
||||
int64_t authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
|
||||
if (FingerprintHalProperties::enrollments().size() > 0 && authenticatorId == 0) {
|
||||
authenticatorId = 99999999; // default authenticatorId, TODO(b/230515082)
|
||||
int64_t authenticatorId;
|
||||
if (FingerprintHalProperties::enrollments().size() == 0) {
|
||||
authenticatorId = 0;
|
||||
} else {
|
||||
authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
|
||||
if (authenticatorId == 0) authenticatorId = 1;
|
||||
}
|
||||
cb->onAuthenticatorIdRetrieved(authenticatorId);
|
||||
}
|
||||
|
||||
void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
|
||||
BEGIN_OP(0);
|
||||
auto id = FingerprintHalProperties::authenticator_id().value_or(0);
|
||||
auto newId = id + 1;
|
||||
int64_t newId;
|
||||
if (FingerprintHalProperties::enrollments().size() == 0) {
|
||||
newId = 0;
|
||||
} else {
|
||||
auto id = FingerprintHalProperties::authenticator_id().value_or(0);
|
||||
newId = id + 1;
|
||||
}
|
||||
FingerprintHalProperties::authenticator_id(newId);
|
||||
cb->onAuthenticatorIdInvalidated(newId);
|
||||
}
|
||||
|
||||
void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
|
||||
const keymaster::HardwareAuthToken& /*hat*/) {
|
||||
const keymaster::HardwareAuthToken& hat) {
|
||||
BEGIN_OP(0);
|
||||
if (hat.mac.empty()) {
|
||||
LOG(ERROR) << "Fail: hat in resetLockout()";
|
||||
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
|
||||
return;
|
||||
}
|
||||
FingerprintHalProperties::lockout(false);
|
||||
cb->onLockoutCleared();
|
||||
}
|
||||
@@ -286,4 +363,96 @@ SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
|
||||
return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
|
||||
0 /* sensorRadius */, "" /* display */};
|
||||
}
|
||||
|
||||
std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
|
||||
const std::string& sep) {
|
||||
std::vector<std::string> seqs = Util::split(str, sep);
|
||||
std::vector<int32_t> res;
|
||||
|
||||
for (const auto& seq : seqs) {
|
||||
int32_t val;
|
||||
if (ParseInt(seq, &val)) {
|
||||
res.push_back(val);
|
||||
} else {
|
||||
LOG(WARNING) << "Invalid int sequence:" + str;
|
||||
res.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::vector<int32_t>> FakeFingerprintEngine::parseEnrollmentCapture(
|
||||
const std::string& str) {
|
||||
std::vector<int32_t> defaultAcquiredInfo = {(int32_t)AcquiredInfo::GOOD};
|
||||
std::vector<std::vector<int32_t>> res;
|
||||
int i = 0, N = str.length();
|
||||
std::size_t found = 0;
|
||||
bool aborted = true;
|
||||
|
||||
while (found != std::string::npos) {
|
||||
std::string durationStr, acquiredStr;
|
||||
found = str.find_first_of("-,", i);
|
||||
if (found == std::string::npos) {
|
||||
if (N - i < 1) break;
|
||||
durationStr = str.substr(i, N - i);
|
||||
} else {
|
||||
durationStr = str.substr(i, found - i);
|
||||
if (str[found] == '-') {
|
||||
found = str.find_first_of('[', found + 1);
|
||||
if (found == std::string::npos) break;
|
||||
i = found + 1;
|
||||
found = str.find_first_of(']', found + 1);
|
||||
if (found == std::string::npos) break;
|
||||
acquiredStr = str.substr(i, found - i);
|
||||
found = str.find_first_of(',', found + 1);
|
||||
}
|
||||
}
|
||||
std::vector<int32_t> duration{0};
|
||||
if (!ParseInt(durationStr, &duration[0])) break;
|
||||
res.push_back(duration);
|
||||
if (!acquiredStr.empty()) {
|
||||
std::vector<int32_t> acquiredInfo = parseIntSequence(acquiredStr);
|
||||
if (acquiredInfo.empty()) break;
|
||||
res.push_back(acquiredInfo);
|
||||
} else
|
||||
res.push_back(defaultAcquiredInfo);
|
||||
|
||||
i = found + 1;
|
||||
if (found == std::string::npos || found == N - 1) aborted = false;
|
||||
}
|
||||
|
||||
if (aborted) {
|
||||
LOG(ERROR) << "Failed to parse enrollment captures:" + str;
|
||||
res.clear();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
|
||||
std::pair<AcquiredInfo, int32_t> res;
|
||||
if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
|
||||
res.first = AcquiredInfo::VENDOR;
|
||||
res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
|
||||
} else {
|
||||
res.first = (AcquiredInfo)code;
|
||||
res.second = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
|
||||
std::pair<Error, int32_t> res;
|
||||
if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
|
||||
res.first = Error::VENDOR;
|
||||
res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
|
||||
} else {
|
||||
res.first = (Error)code;
|
||||
res.second = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
||||
|
||||
@@ -65,8 +65,18 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
|
||||
{SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
|
||||
"" /* serialNumber */, SW_VERSION}};
|
||||
|
||||
common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER,
|
||||
componentInfo};
|
||||
auto sensorId = FingerprintHalProperties::sensor_id().value_or(SENSOR_ID);
|
||||
auto sensorStrength =
|
||||
FingerprintHalProperties::sensor_strength().value_or((int)SENSOR_STRENGTH);
|
||||
auto maxEnrollments =
|
||||
FingerprintHalProperties::max_enrollments().value_or(MAX_ENROLLMENTS_PER_USER);
|
||||
auto navigationGuesture = FingerprintHalProperties::navigation_guesture().value_or(false);
|
||||
auto detectInteraction = FingerprintHalProperties::detect_interaction().value_or(false);
|
||||
auto displayTouch = FingerprintHalProperties::display_touch().value_or(true);
|
||||
auto controlIllumination = FingerprintHalProperties::control_illumination().value_or(false);
|
||||
|
||||
common::CommonProps commonProps = {sensorId, (common::SensorStrength)sensorStrength,
|
||||
maxEnrollments, componentInfo};
|
||||
|
||||
SensorLocation sensorLocation = mEngine->getSensorLocation();
|
||||
|
||||
@@ -75,8 +85,10 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
|
||||
*out = {{commonProps,
|
||||
mSensorType,
|
||||
{sensorLocation},
|
||||
SUPPORTS_NAVIGATION_GESTURES,
|
||||
false /* supportsDetectInteraction */}};
|
||||
navigationGuesture,
|
||||
detectInteraction,
|
||||
displayTouch,
|
||||
controlIllumination}};
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ $ adb shell cmd fingerprint sync
|
||||
$ adb shell getprop persist.vendor.fingerprint.virtual.enrollments
|
||||
```
|
||||
|
||||
### Authenticate
|
||||
## Authenticate
|
||||
|
||||
To authenticate successfully set the enrolled id that should succeed. Unset it
|
||||
or change the value to make authenticate operations fail:
|
||||
@@ -74,7 +74,52 @@ or change the value to make authenticate operations fail:
|
||||
$ adb shell setprop vendor.fingerprint.virtual.enrollment_hit 1
|
||||
````
|
||||
|
||||
### View HAL State
|
||||
## Acquired Info Insertion
|
||||
|
||||
Fingerprint image acquisition states at HAL are reported to framework via onAcquired() callback. The valid acquired state info for AIDL HAL include
|
||||
|
||||
{UNKNOWN(0), GOOD(1), PARTIAL(2), INSUFFICIENT(3), SENSOR_DIRTY(4), TOO_SLOW(5), TOO_FAST(6), VENDOR(7), START(8), TOO_DARK(9), TOO_BRIGHT(10), IMMOBILE(11), RETRYING_CAPTURE(12)}
|
||||
|
||||
Refer to [AcquiredInfo.aidl](../android/hardware/biometrics/fingerprint/AcquiredInfo.aidl) for details
|
||||
|
||||
|
||||
The states can be specified in sequence for the HAL operations involving fingerprint image captures, namely authenticate, enrollment and detectInteraction
|
||||
|
||||
```shell
|
||||
$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_acquired 6,9,1
|
||||
$ adb shell setprop vendor.fingerprint.virtual.operation_detect_interaction_acquired 6,1
|
||||
$ adb shell setprop vendor.fingerprint.virtual.next_enrollment 2:1000-[5,1],500:true
|
||||
|
||||
#next_enrollment format example:
|
||||
.---------------------- enrollment id (2)
|
||||
| .------------------ the image capture 1 duration (1000ms)
|
||||
| | .-------------- acquired info first (TOO_SLOW)
|
||||
| | | .------------ acquired info second (GOOD)
|
||||
| | | | .-------- the image capture 2 duration (500ms)
|
||||
| | | | | .---- enrollment end status (success)
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
2:1000-[5,1],500:true
|
||||
```
|
||||
For vendor specific acquired info, acquiredInfo = 1000 + vendorAcquiredInfo
|
||||
|
||||
## Error Insertion
|
||||
The valid error codes for AIDL HAL include
|
||||
|
||||
{UNKNOWN(0), HW_UNAVAILABLE(1), UNABLE_TO_PROCESS(2), TIMEOUT(3), NO_SPACE(4), CANCELED(5), UNABLE_TO_REMOVE(6), VENDOR(7), BAD_CALIBRATION(8)}
|
||||
|
||||
Refer to [Error.aidl](../android/hardware/biometrics/fingerprint/Error.aidl) for details
|
||||
|
||||
|
||||
There are many HAL operations which can result in errors, refer to [here](fingerprint.sysprop) file for details.
|
||||
|
||||
```shell
|
||||
$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_error 8
|
||||
```
|
||||
For vendor specific error, errorCode = 1000 + vendorErrorCode
|
||||
|
||||
## View HAL State
|
||||
|
||||
To view all the properties of the HAL (see `fingerprint.sysprop` file for the API):
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ props {
|
||||
api_name: "authenticator_id"
|
||||
type: Long
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.authenticator_id"
|
||||
prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
|
||||
}
|
||||
prop {
|
||||
api_name: "challenge"
|
||||
@@ -13,6 +13,21 @@ props {
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.challenge"
|
||||
}
|
||||
prop {
|
||||
api_name: "control_illumination"
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
|
||||
}
|
||||
prop {
|
||||
api_name: "detect_interaction"
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
|
||||
}
|
||||
prop {
|
||||
api_name: "display_touch"
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
|
||||
}
|
||||
prop {
|
||||
api_name: "enrollment_hit"
|
||||
type: Integer
|
||||
@@ -28,7 +43,18 @@ props {
|
||||
prop {
|
||||
api_name: "lockout"
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.lockout"
|
||||
prop_name: "persist.vendor.fingerprint.virtual.lockout"
|
||||
}
|
||||
prop {
|
||||
api_name: "max_enrollments"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
|
||||
}
|
||||
prop {
|
||||
api_name: "navigation_guesture"
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
|
||||
}
|
||||
prop {
|
||||
api_name: "next_enrollment"
|
||||
@@ -36,12 +62,24 @@ props {
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.next_enrollment"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_authenticate_acquired"
|
||||
type: String
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_authenticate_duration"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_authenticate_error"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_authenticate_fails"
|
||||
access: ReadWrite
|
||||
@@ -54,9 +92,22 @@ props {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_detect_interaction_fails"
|
||||
api_name: "operation_detect_interaction_acquired"
|
||||
type: String
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_fails"
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_detect_interaction_duration"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_detect_interaction_error"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_detect_interaction_latency"
|
||||
@@ -65,9 +116,10 @@ props {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_enroll_fails"
|
||||
api_name: "operation_enroll_error"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_enroll_fails"
|
||||
prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
|
||||
}
|
||||
prop {
|
||||
api_name: "operation_enroll_latency"
|
||||
@@ -75,12 +127,24 @@ props {
|
||||
access: ReadWrite
|
||||
prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
|
||||
}
|
||||
prop {
|
||||
api_name: "sensor_id"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
|
||||
}
|
||||
prop {
|
||||
api_name: "sensor_location"
|
||||
type: String
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
|
||||
}
|
||||
prop {
|
||||
api_name: "sensor_strength"
|
||||
type: Integer
|
||||
access: ReadWrite
|
||||
prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
|
||||
}
|
||||
prop {
|
||||
api_name: "type"
|
||||
type: String
|
||||
|
||||
@@ -32,8 +32,12 @@ prop {
|
||||
api_name: "enrollment_hit"
|
||||
}
|
||||
|
||||
# the next enrollment in the format: "<id>:<delay>,<delay>,...:<result>"
|
||||
# for example: "2:0:true"
|
||||
# the next enrollment in the format of:
|
||||
# "<id>:<delay>,<delay>,...:<result>"
|
||||
# <delay> = <duration-[acquiredInfos]>
|
||||
# [acquiredInfos] = [acquiredInfo1, acquiredInfo2, ...]
|
||||
# (refer to README.md file for acquiredInfo values)
|
||||
# e.g. "2:100,20:true", "2:100-[5,1],20:true"
|
||||
# this property is reset after enroll completes
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.next_enrollment"
|
||||
@@ -45,7 +49,7 @@ prop {
|
||||
|
||||
# value for getAuthenticatorId or 0
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.authenticator_id"
|
||||
prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
|
||||
type: Long
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
@@ -63,7 +67,7 @@ prop {
|
||||
|
||||
# if locked out
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.lockout"
|
||||
prop_name: "persist.vendor.fingerprint.virtual.lockout"
|
||||
type: Boolean
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
@@ -79,22 +83,26 @@ prop {
|
||||
api_name: "operation_authenticate_fails"
|
||||
}
|
||||
|
||||
# force all detectInteraction operations to fail
|
||||
# force all detectInteraction operations to error out
|
||||
# error consists of errorCode and vendorErrorCode
|
||||
# valid errorCodes are listed in README.md file
|
||||
# vendorErrorCode = (error>1000) ? error-1000 : 0
|
||||
# e.g. error(1002) --> errorCode(7) and vendorErrorCode(2)
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_fails"
|
||||
type: Boolean
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "operation_detect_interaction_fails"
|
||||
api_name: "operation_detect_interaction_error"
|
||||
}
|
||||
|
||||
# force all enroll operations to fail
|
||||
# force all enroll operations to result in error
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_enroll_fails"
|
||||
type: Boolean
|
||||
prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "operation_enroll_fails"
|
||||
api_name: "operation_enroll_error"
|
||||
}
|
||||
|
||||
# add a latency to authentication operations
|
||||
@@ -134,6 +142,15 @@ prop {
|
||||
api_name: "operation_authenticate_duration"
|
||||
}
|
||||
|
||||
# insert error for authenticate operations
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "operation_authenticate_error"
|
||||
}
|
||||
|
||||
# sensor location
|
||||
# <x>:<y>:<radius> in pixel
|
||||
prop {
|
||||
@@ -143,3 +160,99 @@ prop {
|
||||
access: ReadWrite
|
||||
api_name: "sensor_location"
|
||||
}
|
||||
|
||||
# acquired info during authentication in format of sequence
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
|
||||
type: String
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "operation_authenticate_acquired"
|
||||
}
|
||||
|
||||
# millisecond duration for detect interaction operations
|
||||
# (waits for changes to enrollment_hit)
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "operation_detect_interaction_duration"
|
||||
}
|
||||
|
||||
# acquired info during detect interaction operation in format of sequence
|
||||
# e.g. 5,6,1 (TOO_SLOW, TOO_FAST, GOOD)
|
||||
# onAcquired() callback will be invoked in sequence
|
||||
# vendorAcquiredCode = (acquired>1000) ? acquired-1000 : 0
|
||||
prop {
|
||||
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
|
||||
type: String
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "operation_detect_interaction_acquired"
|
||||
}
|
||||
|
||||
# sensor id (default: 5)
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "sensor_id"
|
||||
}
|
||||
|
||||
# sensor strength (default: 2)
|
||||
# [0=CONVENECE, 1=WEAK, 2=STRONG]
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "sensor_strength"
|
||||
}
|
||||
|
||||
# max enrollments per user (default: 5)
|
||||
#
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
|
||||
type: Integer
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "max_enrollments"
|
||||
}
|
||||
|
||||
# whether support navigation guestures (default: false)
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
|
||||
type: Boolean
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "navigation_guesture"
|
||||
}
|
||||
|
||||
# whether support detect interaction (default: false)
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
|
||||
type: Boolean
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "detect_interaction"
|
||||
}
|
||||
|
||||
# whether support display touch by hal (default: true)
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
|
||||
type: Boolean
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "display_touch"
|
||||
}
|
||||
|
||||
# whether support illumination control by hal (default: false)
|
||||
prop {
|
||||
prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
|
||||
type: Boolean
|
||||
scope: Public
|
||||
access: ReadWrite
|
||||
api_name: "control_illumination"
|
||||
}
|
||||
|
||||
@@ -59,7 +59,17 @@ class FakeFingerprintEngine {
|
||||
|
||||
virtual SensorLocation defaultSensorLocation();
|
||||
|
||||
std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");
|
||||
|
||||
std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
|
||||
|
||||
std::mt19937 mRandom;
|
||||
|
||||
private:
|
||||
static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
|
||||
static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
|
||||
std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
|
||||
std::pair<Error, int32_t> convertError(int32_t code);
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
||||
|
||||
@@ -38,8 +38,9 @@ class TestSessionCallback : public BnSessionCallback {
|
||||
mLastChallengeRevoked = challenge;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
};
|
||||
::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t) override {
|
||||
::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t vendorCode) override {
|
||||
mError = error;
|
||||
mErrorVendorCode = vendorCode;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
};
|
||||
::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
|
||||
@@ -62,7 +63,10 @@ class TestSessionCallback : public BnSessionCallback {
|
||||
mInteractionDetectedCount++;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
};
|
||||
ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
|
||||
ndk::ScopedAStatus onAcquired(AcquiredInfo info, int32_t vendorCode) override {
|
||||
mLastAcquiredInfo = (int32_t)info;
|
||||
mLastAcquiredVendorCode = vendorCode;
|
||||
mLastAcquiredCount++;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onEnrollmentsEnumerated(
|
||||
@@ -94,6 +98,7 @@ class TestSessionCallback : public BnSessionCallback {
|
||||
ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
|
||||
|
||||
Error mError = Error::UNKNOWN;
|
||||
int32_t mErrorVendorCode = 0;
|
||||
int64_t mLastChallenge = -1;
|
||||
int64_t mLastChallengeRevoked = -1;
|
||||
int32_t mLastEnrolled = -1;
|
||||
@@ -105,6 +110,9 @@ class TestSessionCallback : public BnSessionCallback {
|
||||
bool mAuthenticatorIdInvalidated = false;
|
||||
bool mLockoutPermanent = false;
|
||||
int mInteractionDetectedCount = 0;
|
||||
int32_t mLastAcquiredInfo = -1;
|
||||
int32_t mLastAcquiredVendorCode = -1;
|
||||
int32_t mLastAcquiredCount = 0;
|
||||
};
|
||||
|
||||
class FakeFingerprintEngineTest : public ::testing::Test {
|
||||
@@ -116,6 +124,12 @@ class FakeFingerprintEngineTest : public ::testing::Test {
|
||||
mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
FingerprintHalProperties::operation_authenticate_error(0);
|
||||
FingerprintHalProperties::operation_detect_interaction_error(0);
|
||||
FingerprintHalProperties::operation_authenticate_acquired("");
|
||||
}
|
||||
|
||||
FakeFingerprintEngine mEngine;
|
||||
std::shared_ptr<TestSessionCallback> mCallback;
|
||||
std::promise<void> mCancel;
|
||||
@@ -135,11 +149,13 @@ TEST_F(FakeFingerprintEngineTest, RevokeChallenge) {
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, ResetLockout) {
|
||||
FingerprintHalProperties::lockout(true);
|
||||
mEngine.resetLockoutImpl(mCallback.get(), {});
|
||||
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
|
||||
mEngine.resetLockoutImpl(mCallback.get(), hat);
|
||||
ASSERT_FALSE(FingerprintHalProperties::lockout().value_or(true));
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticatorId) {
|
||||
FingerprintHalProperties::enrollments({1});
|
||||
FingerprintHalProperties::authenticator_id(50);
|
||||
mEngine.getAuthenticatorIdImpl(mCallback.get());
|
||||
ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
|
||||
@@ -162,6 +178,7 @@ TEST_F(FakeFingerprintEngineTest, Enroll) {
|
||||
ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
|
||||
ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
|
||||
ASSERT_EQ(4, mCallback->mLastEnrolled);
|
||||
ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
|
||||
@@ -189,12 +206,28 @@ TEST_F(FakeFingerprintEngineTest, EnrollFail) {
|
||||
ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, EnrollAcquired) {
|
||||
FingerprintHalProperties::enrollments({});
|
||||
FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
|
||||
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
|
||||
int32_t prevCnt = mCallback->mLastAcquiredCount;
|
||||
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
|
||||
ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
|
||||
ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
|
||||
ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
|
||||
ASSERT_EQ(4, mCallback->mLastEnrolled);
|
||||
ASSERT_EQ(prevCnt + 3, mCallback->mLastAcquiredCount);
|
||||
ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
|
||||
ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, Authenticate) {
|
||||
FingerprintHalProperties::enrollments({1, 2});
|
||||
FingerprintHalProperties::enrollment_hit(2);
|
||||
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
|
||||
ASSERT_FALSE(mCallback->mAuthenticateFailed);
|
||||
ASSERT_EQ(2, mCallback->mLastAuthenticated);
|
||||
ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
|
||||
@@ -211,7 +244,6 @@ TEST_F(FakeFingerprintEngineTest, AuthenticateNotSet) {
|
||||
FingerprintHalProperties::enrollment_hit({});
|
||||
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
|
||||
ASSERT_TRUE(mCallback->mAuthenticateFailed);
|
||||
ASSERT_EQ(mCallback->mError, Error::UNABLE_TO_PROCESS);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
|
||||
@@ -219,7 +251,6 @@ TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
|
||||
FingerprintHalProperties::enrollment_hit(3);
|
||||
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
|
||||
ASSERT_TRUE(mCallback->mAuthenticateFailed);
|
||||
ASSERT_EQ(mCallback->mError, Error::UNABLE_TO_PROCESS);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
|
||||
@@ -231,11 +262,41 @@ TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
|
||||
ASSERT_NE(mCallback->mError, Error::UNKNOWN);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
|
||||
FingerprintHalProperties::operation_authenticate_error(8);
|
||||
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
|
||||
ASSERT_EQ(mCallback->mError, (Error)8);
|
||||
ASSERT_EQ(mCallback->mErrorVendorCode, 0);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
|
||||
FingerprintHalProperties::operation_authenticate_error(1009);
|
||||
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
|
||||
ASSERT_EQ(mCallback->mError, (Error)7);
|
||||
ASSERT_EQ(mCallback->mErrorVendorCode, 9);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
|
||||
FingerprintHalProperties::lockout(false);
|
||||
FingerprintHalProperties::enrollments({1, 2});
|
||||
FingerprintHalProperties::enrollment_hit(2);
|
||||
FingerprintHalProperties::operation_authenticate_acquired("4,1009");
|
||||
int32_t prevCount = mCallback->mLastAcquiredCount;
|
||||
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
|
||||
ASSERT_FALSE(mCallback->mAuthenticateFailed);
|
||||
ASSERT_EQ(2, mCallback->mLastAuthenticated);
|
||||
ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
|
||||
ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
|
||||
ASSERT_EQ(9, mCallback->mLastAcquiredVendorCode);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
|
||||
FingerprintHalProperties::enrollments({1, 2});
|
||||
FingerprintHalProperties::enrollment_hit(2);
|
||||
FingerprintHalProperties::operation_detect_interaction_acquired("");
|
||||
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
|
||||
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
|
||||
ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
|
||||
@@ -261,6 +322,26 @@ TEST_F(FakeFingerprintEngineTest, InteractionDetectNotEnrolled) {
|
||||
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
|
||||
FingerprintHalProperties::operation_detect_interaction_error(8);
|
||||
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
|
||||
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
|
||||
ASSERT_EQ(mCallback->mError, (Error)8);
|
||||
ASSERT_EQ(mCallback->mErrorVendorCode, 0);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
|
||||
FingerprintHalProperties::enrollments({1, 2});
|
||||
FingerprintHalProperties::enrollment_hit(2);
|
||||
FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
|
||||
int32_t prevCount = mCallback->mLastAcquiredCount;
|
||||
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
|
||||
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
|
||||
ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
|
||||
ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
|
||||
ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
|
||||
FingerprintHalProperties::enrollments({2, 4, 8});
|
||||
mEngine.enumerateEnrollmentsImpl(mCallback.get());
|
||||
@@ -290,6 +371,76 @@ TEST_F(FakeFingerprintEngineTest, RemoveEnrolled) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, parseIntSequence) {
|
||||
std::vector<int32_t> seqV;
|
||||
seqV = mEngine.parseIntSequence("");
|
||||
ASSERT_EQ(0, seqV.size());
|
||||
seqV = mEngine.parseIntSequence("2");
|
||||
ASSERT_EQ(1, seqV.size());
|
||||
ASSERT_EQ(2, seqV[0]);
|
||||
seqV = mEngine.parseIntSequence("2,3,4");
|
||||
std::vector<int32_t> expV{2, 3, 4};
|
||||
ASSERT_EQ(expV, seqV);
|
||||
seqV = mEngine.parseIntSequence("2,3,a");
|
||||
ASSERT_EQ(0, seqV.size());
|
||||
seqV = mEngine.parseIntSequence("2, 3, 4");
|
||||
ASSERT_EQ(expV, seqV);
|
||||
seqV = mEngine.parseIntSequence("123,456");
|
||||
ASSERT_EQ(2, seqV.size());
|
||||
std::vector<int32_t> expV1{123, 456};
|
||||
ASSERT_EQ(expV1, seqV);
|
||||
seqV = mEngine.parseIntSequence("12f3,456");
|
||||
ASSERT_EQ(0, seqV.size());
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureOk) {
|
||||
std::vector<std::vector<int32_t>> ecV;
|
||||
ecV = mEngine.parseEnrollmentCapture("100,200,300");
|
||||
ASSERT_EQ(6, ecV.size());
|
||||
std::vector<std::vector<int32_t>> expE{{100}, {200}, {300}};
|
||||
std::vector<int32_t> defC{1};
|
||||
for (int i = 0; i < ecV.size(); i += 2) {
|
||||
ASSERT_EQ(expE[i / 2], ecV[i]);
|
||||
ASSERT_EQ(defC, ecV[i + 1]);
|
||||
}
|
||||
ecV = mEngine.parseEnrollmentCapture("100");
|
||||
ASSERT_EQ(2, ecV.size());
|
||||
ASSERT_EQ(expE[0], ecV[0]);
|
||||
ASSERT_EQ(defC, ecV[1]);
|
||||
|
||||
ecV = mEngine.parseEnrollmentCapture("100-[5,6,7]");
|
||||
std::vector<int32_t> expC{5, 6, 7};
|
||||
ASSERT_EQ(2, ecV.size());
|
||||
for (int i = 0; i < ecV.size(); i += 2) {
|
||||
ASSERT_EQ(expE[i / 2], ecV[i]);
|
||||
ASSERT_EQ(expC, ecV[i + 1]);
|
||||
}
|
||||
ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200, 300-[9,10]");
|
||||
std::vector<std::vector<int32_t>> expC1{{5, 6, 7}, {1}, {9, 10}};
|
||||
ASSERT_EQ(6, ecV.size());
|
||||
for (int i = 0; i < ecV.size(); i += 2) {
|
||||
ASSERT_EQ(expE[i / 2], ecV[i]);
|
||||
ASSERT_EQ(expC1[i / 2], ecV[i + 1]);
|
||||
}
|
||||
ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200-[2,1], 300-[9]");
|
||||
std::vector<std::vector<int32_t>> expC2{{5, 6, 7}, {2, 1}, {9}};
|
||||
ASSERT_EQ(ecV.size(), 6);
|
||||
for (int i = 0; i < ecV.size(); i += 2) {
|
||||
ASSERT_EQ(expE[i / 2], ecV[i]);
|
||||
ASSERT_EQ(expC2[i / 2], ecV[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureFail) {
|
||||
std::vector<std::string> badStr{"10c", "100-5", "100-[5,6,7", "100-5,6,7]",
|
||||
"100,2x0,300", "200-[f]", "a,b"};
|
||||
std::vector<std::vector<int32_t>> ecV;
|
||||
for (const auto s : badStr) {
|
||||
ecV = mEngine.parseEnrollmentCapture(s);
|
||||
ASSERT_EQ(ecV.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
@@ -47,14 +47,10 @@ bool isDefaultLocation(SensorLocation& sc) {
|
||||
sc.sensorRadius == FakeFingerprintEngineUdfps::defaultSensorRadius && sc.display == "");
|
||||
}
|
||||
|
||||
TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocation) {
|
||||
FingerprintHalProperties::sensor_location("");
|
||||
SensorLocation sc = mEngine.getSensorLocation();
|
||||
ASSERT_TRUE(isDefaultLocation(sc));
|
||||
|
||||
TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationOk) {
|
||||
auto loc = "100:200:30";
|
||||
FingerprintHalProperties::sensor_location(loc);
|
||||
sc = mEngine.getSensorLocation();
|
||||
SensorLocation sc = mEngine.getSensorLocation();
|
||||
ASSERT_TRUE(sc.sensorLocationX == 100);
|
||||
ASSERT_TRUE(sc.sensorLocationY == 200);
|
||||
ASSERT_TRUE(sc.sensorRadius == 30);
|
||||
@@ -66,8 +62,14 @@ TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocation) {
|
||||
ASSERT_TRUE(sc.sensorLocationY == 200);
|
||||
ASSERT_TRUE(sc.sensorRadius == 30);
|
||||
ASSERT_TRUE(sc.display == "screen1");
|
||||
}
|
||||
|
||||
loc = "100";
|
||||
TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationBad) {
|
||||
FingerprintHalProperties::sensor_location("");
|
||||
SensorLocation sc = mEngine.getSensorLocation();
|
||||
ASSERT_TRUE(isDefaultLocation(sc));
|
||||
|
||||
auto loc = "100";
|
||||
FingerprintHalProperties::sensor_location(loc);
|
||||
sc = mEngine.getSensorLocation();
|
||||
ASSERT_TRUE(isDefaultLocation(sc));
|
||||
|
||||
Reference in New Issue
Block a user