Merge "Added Fingerprint Virtual HAL AIDL extension" into main
This commit is contained in:
commit
012679e371
15 changed files with 1078 additions and 41 deletions
|
@ -34,7 +34,7 @@ ConfigValue Config::parseBool(const std::string& value) {
|
|||
else if (value == "false")
|
||||
res.emplace(false);
|
||||
else
|
||||
LOG(ERROR) << "ERROR: invalid bool " << value;
|
||||
LOG(FATAL) << "ERROR: invalid bool " << value;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,11 @@ ConfigValue Config::parseInt32(const std::string& value) {
|
|||
OptInt32 res;
|
||||
if (!value.empty()) {
|
||||
std::int32_t val;
|
||||
if (ParseInt(value, &val)) res.emplace(val);
|
||||
if (ParseInt(value, &val)) {
|
||||
res.emplace(val);
|
||||
} else {
|
||||
LOG(FATAL) << "ERROR: Could not parse " << value << " as Int32";
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -59,6 +63,8 @@ ConfigValue Config::parseInt64(const std::string& value) {
|
|||
std::int64_t val = std::strtoull(value.c_str(), nullptr, 10);
|
||||
if (val != 0LL or (val == 0LL && value == "0")) {
|
||||
res.emplace(val);
|
||||
} else {
|
||||
LOG(FATAL) << "ERROR: Could not parse " << value << " as Int64";
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -87,7 +93,7 @@ void Config::init() {
|
|||
bool Config::setParam(const std::string& name, const std::string& value) {
|
||||
auto it = mMap.find(name);
|
||||
if (it == mMap.end()) {
|
||||
LOG(ERROR) << "ERROR: setParam unknown config name " << name;
|
||||
LOG(FATAL) << "ERROR: setParam unknown config name " << name;
|
||||
return false;
|
||||
}
|
||||
LOG(INFO) << "setParam name=" << name << "=" << value;
|
||||
|
@ -102,7 +108,7 @@ bool Config::setParam(const std::string& name, const std::string& value) {
|
|||
ConfigValue Config::getInternal(const std::string& name) {
|
||||
ConfigValue res;
|
||||
|
||||
auto data = mMap[name];
|
||||
auto& data = mMap[name];
|
||||
switch (mSource) {
|
||||
case ConfigSourceType::SOURCE_SYSPROP:
|
||||
res = data.getter();
|
||||
|
@ -111,10 +117,10 @@ ConfigValue Config::getInternal(const std::string& name) {
|
|||
res = data.value;
|
||||
break;
|
||||
case ConfigSourceType::SOURCE_FILE:
|
||||
LOG(WARNING) << "Unsupported";
|
||||
UNIMPLEMENTED(ERROR) << " File-based config is not supported yet";
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << " wrong srouce type " << (int)mSource;
|
||||
LOG(FATAL) << "Wrong srouce type " << (int)mSource;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -127,7 +133,7 @@ ConfigValue Config::getDefault(const std::string& name) {
|
|||
|
||||
bool Config::setInternal(const std::string& name, const ConfigValue& val) {
|
||||
bool res = false;
|
||||
auto data = mMap[name];
|
||||
auto& data = mMap[name];
|
||||
|
||||
switch (mSource) {
|
||||
case ConfigSourceType::SOURCE_SYSPROP:
|
||||
|
@ -138,10 +144,10 @@ bool Config::setInternal(const std::string& name, const ConfigValue& val) {
|
|||
res = true;
|
||||
break;
|
||||
case ConfigSourceType::SOURCE_FILE:
|
||||
LOG(WARNING) << "Unsupported";
|
||||
UNIMPLEMENTED(ERROR) << " File-based config is not supported yet";
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << " wrong srouce type " << (int)mSource;
|
||||
LOG(FATAL) << "Wrong srouce type " << (int)mSource;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,33 @@ class Config {
|
|||
virtual Config::Data* getConfigData(int* size) = 0;
|
||||
bool setParam(const std::string& name, const std::string& value);
|
||||
|
||||
void sourcedFromAidl() { mSource = ConfigSourceType::SOURCE_AIDL; }
|
||||
std::string toString(const ConfigValue& v) const {
|
||||
std::ostringstream os;
|
||||
if (std::holds_alternative<OptInt32>(v)) {
|
||||
OptInt32 ov = std::get<OptInt32>(v);
|
||||
if (ov.has_value()) os << ov.value();
|
||||
} else if (std::holds_alternative<OptInt64>(v)) {
|
||||
OptInt64 ov = std::get<OptInt64>(v);
|
||||
if (ov.has_value()) os << ov.value();
|
||||
} else if (std::holds_alternative<OptBool>(v)) {
|
||||
OptBool ov = std::get<OptBool>(v);
|
||||
if (ov.has_value()) os << ov.value();
|
||||
os << std::get<OptBool>(v).value();
|
||||
} else if (std::holds_alternative<OptIntVec>(v)) {
|
||||
for (auto x : std::get<OptIntVec>(v))
|
||||
if (x.has_value()) os << x.value() << " ";
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
std::string toString() const {
|
||||
std::ostringstream os;
|
||||
for (auto const& [k, v] : mMap) {
|
||||
os << k << ":" << toString(v.value) << std::endl;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
ConfigValue parseBool(const std::string& value);
|
||||
ConfigValue parseString(const std::string& name);
|
||||
ConfigValue parseInt32(const std::string& value);
|
||||
|
|
|
@ -115,7 +115,7 @@ class ConfigTest : public ::testing::Test {
|
|||
void SetUp() override { cfg.init(); }
|
||||
void TearDown() override {}
|
||||
|
||||
void switch2aidl() { cfg.setParam("astring", "astring"); }
|
||||
void switch2aidl() { cfg.sourcedFromAidl(); }
|
||||
|
||||
TestConfig cfg;
|
||||
};
|
||||
|
@ -129,7 +129,6 @@ TEST_F(ConfigTest, parseInt32) {
|
|||
{"1234", 1234},
|
||||
{"0", 0},
|
||||
{"", defval},
|
||||
{"xyz", defval},
|
||||
};
|
||||
for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||
ASSERT_EQ((std::get<OptInt32>(cfg.parseInt32(values[i].strval))).value_or(defval),
|
||||
|
@ -143,8 +142,10 @@ TEST_F(ConfigTest, parseInt64) {
|
|||
std::string strval;
|
||||
std::int64_t expval;
|
||||
} values[] = {
|
||||
{"1234", 1234}, {"12345678909876", 12345678909876}, {"0", 0}, {"", defval},
|
||||
{"xyz", defval},
|
||||
{"1234", 1234},
|
||||
{"12345678909876", 12345678909876},
|
||||
{"0", 0},
|
||||
{"", defval},
|
||||
};
|
||||
for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||
ASSERT_EQ((std::get<OptInt64>(cfg.parseInt64(values[i].strval))).value_or(defval),
|
||||
|
@ -160,8 +161,6 @@ TEST_F(ConfigTest, parseBool) {
|
|||
} values[] = {
|
||||
{"false", false},
|
||||
{"true", true},
|
||||
{"", defval},
|
||||
{"xyz", defval},
|
||||
};
|
||||
for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||
ASSERT_EQ((std::get<OptBool>(cfg.parseBool(values[i].strval))).value_or(defval),
|
||||
|
@ -174,9 +173,7 @@ TEST_F(ConfigTest, parseIntVec) {
|
|||
struct {
|
||||
std::string strval;
|
||||
std::vector<std::optional<int>> expval;
|
||||
} values[] = {
|
||||
{"1", {1}}, {"1,2,3", {1, 2, 3}}, {"1,2,b", defval}, {"", defval}, {"xyz", defval},
|
||||
};
|
||||
} values[] = {{"1", {1}}, {"1,2,3", {1, 2, 3}}, {"1,2,b", defval}, {"", defval}};
|
||||
for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||
ASSERT_EQ(std::get<OptIntVec>(cfg.parseIntVec(values[i].strval)), values[i].expval);
|
||||
}
|
||||
|
@ -255,12 +252,4 @@ TEST_F(ConfigTest, setters_aidl) {
|
|||
EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), val_avector_new);
|
||||
}
|
||||
|
||||
TEST_F(ConfigTest, setParam) {
|
||||
ASSERT_TRUE(cfg.setParam("aint32", "789"));
|
||||
ASSERT_EQ(cfg.get<std::int32_t>("aint32"), 789);
|
||||
ASSERT_TRUE(cfg.setParam("avector", "7,8,9,10"));
|
||||
OptIntVec val_avector_new{7, 8, 9, 10};
|
||||
EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), val_avector_new);
|
||||
ASSERT_FALSE(cfg.setParam("unknown", "any"));
|
||||
}
|
||||
} // namespace aidl::android::hardware::biometrics
|
||||
|
|
|
@ -57,5 +57,5 @@ aidl_interface {
|
|||
},
|
||||
|
||||
],
|
||||
frozen: true,
|
||||
frozen: false,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.biometrics.fingerprint;
|
||||
/* @hide */
|
||||
@VintfStability
|
||||
interface IVirtualHal {
|
||||
oneway void setEnrollments(in int[] id);
|
||||
oneway void setEnrollmentHit(in int hit_id);
|
||||
oneway void setAuthenticatorId(in long id);
|
||||
oneway void setChallenge(in long challenge);
|
||||
oneway void setOperationAuthenticateFails(in boolean fail);
|
||||
oneway void setOperationAuthenticateLatency(in int[] latencyMs);
|
||||
oneway void setOperationAuthenticateDuration(in int durationMs);
|
||||
oneway void setOperationAuthenticateError(in int error);
|
||||
oneway void setOperationAuthenticateAcquired(in int[] acquired);
|
||||
oneway void setOperationEnrollError(in int error);
|
||||
oneway void setOperationEnrollLatency(in int[] latencyMs);
|
||||
oneway void setOperationDetectInteractionLatency(in int[] latencyMs);
|
||||
oneway void setOperationDetectInteractionError(in int error);
|
||||
oneway void setOperationDetectInteractionDuration(in int durationMs);
|
||||
oneway void setOperationDetectInteractionAcquired(in int[] acquired);
|
||||
oneway void setLockout(in boolean lockout);
|
||||
oneway void setLockoutEnable(in boolean enable);
|
||||
oneway void setLockoutTimedThreshold(in int threshold);
|
||||
oneway void setLockoutTimedDuration(in int durationMs);
|
||||
oneway void setLockoutPermanentThreshold(in int threshold);
|
||||
oneway void setType(in android.hardware.biometrics.fingerprint.FingerprintSensorType type);
|
||||
oneway void setSensorId(in int id);
|
||||
oneway void setSensorStrength(in android.hardware.biometrics.common.SensorStrength strength);
|
||||
oneway void setMaxEnrollmentPerUser(in int max);
|
||||
oneway void setSensorLocation(in android.hardware.biometrics.fingerprint.SensorLocation loc);
|
||||
oneway void setNavigationGuesture(in boolean v);
|
||||
oneway void setDetectInteraction(in boolean v);
|
||||
oneway void setDisplayTouch(in boolean v);
|
||||
oneway void setControlIllumination(in boolean v);
|
||||
const int STATUS_INVALID_PARAMETER = 1;
|
||||
}
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.biometrics.fingerprint;
|
||||
|
||||
import android.hardware.biometrics.common.SensorStrength;
|
||||
import android.hardware.biometrics.fingerprint.FingerprintSensorType;
|
||||
import android.hardware.biometrics.fingerprint.SensorLocation;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@VintfStability
|
||||
oneway interface IVirtualHal {
|
||||
/**
|
||||
* The operation failed due to invalid input parameters, the error messages should
|
||||
* gives more details
|
||||
*/
|
||||
const int STATUS_INVALID_PARAMETER = 1;
|
||||
|
||||
/**
|
||||
* Set Fingerprint Virtual HAL behavior parameters
|
||||
*/
|
||||
|
||||
/**
|
||||
* setEnrollments
|
||||
*
|
||||
* Set the ids of the fingerprints that were currently enrolled in the Virtual HAL,
|
||||
*
|
||||
* @param ids ids can contain 1 or more ids, each must be larger than 0
|
||||
*/
|
||||
void setEnrollments(in int[] id);
|
||||
|
||||
/**
|
||||
* setEnrollmentHit
|
||||
*
|
||||
* Set current fingerprint enrollment ids in Fingerprint Virtual HAL,
|
||||
*
|
||||
* @param ids ids can contain 1 or more ids, each must be larger than 0
|
||||
*/
|
||||
void setEnrollmentHit(in int hit_id);
|
||||
|
||||
/**
|
||||
* setAuthenticatorId
|
||||
*
|
||||
* Set authenticator id in virtual HAL, the id is returned in ISession#getAuthenticatorId() call
|
||||
*
|
||||
* @param id authenticator id value, only applied to the sensor with SensorStrength::STRONG.
|
||||
*/
|
||||
void setAuthenticatorId(in long id);
|
||||
|
||||
/**
|
||||
* setChallenge
|
||||
*
|
||||
* Set the challenge generated by the virtual HAL, which is returned in
|
||||
* ISessionCallback#onChallengeGenerated()
|
||||
*
|
||||
* @param challenge
|
||||
*/
|
||||
void setChallenge(in long challenge);
|
||||
|
||||
/**
|
||||
* setOperationAuthenticateFails
|
||||
*
|
||||
* Set whether to force authentication to fail. If true, the virtual hal will report failure on
|
||||
* authentication attempt until it is set to false
|
||||
*
|
||||
* @param fail if true, then the next authentication will fail
|
||||
*/
|
||||
void setOperationAuthenticateFails(in boolean fail);
|
||||
|
||||
/**
|
||||
* setOperationAuthenticateLatency
|
||||
*
|
||||
* Set authentication latency in the virtual hal in a fixed value (single element) or random
|
||||
* values (two elements representing the bound values)
|
||||
* The latency simulates the delay from the time framework requesting HAL to authetication to
|
||||
* the time when HAL is ready to perform authentication operations.
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in array falls in any of
|
||||
* the following conditions
|
||||
* 1. the array contains no element
|
||||
* 2. the array contains more than two elements
|
||||
* 3. the array contains any negative value
|
||||
* The accompanying error message gives more detail
|
||||
*
|
||||
* @param latencyMs[] value(s) are in milli-seconds
|
||||
*/
|
||||
void setOperationAuthenticateLatency(in int[] latencyMs);
|
||||
|
||||
/**
|
||||
* setOperationAuthenticateDuration
|
||||
*
|
||||
* Set authentication duration covering the HAL authetication from start to end, including
|
||||
* fingerprint capturing, and matching, acquired info reporting. In case a sequence of acquired
|
||||
* info code are specified via setOperationAuthenticateAcquired(), the reporting is evenly
|
||||
* distributed over the duration.
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
|
||||
*
|
||||
* @param duration value is in milli-seconds
|
||||
*/
|
||||
void setOperationAuthenticateDuration(in int durationMs);
|
||||
|
||||
/**
|
||||
* setOperationAuthenticateError
|
||||
*
|
||||
* Force authentication to error out for non-zero error
|
||||
* Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid error codes
|
||||
*
|
||||
* @param error if error < 1000
|
||||
* non-vendor error
|
||||
* else
|
||||
* vendor error
|
||||
*/
|
||||
void setOperationAuthenticateError(in int error);
|
||||
|
||||
/**
|
||||
* setOperationAuthenticateAcquired
|
||||
*
|
||||
* Set one of more acquired info codes for the virtual hal to report during authentication
|
||||
* Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid acquired
|
||||
* info codes
|
||||
*
|
||||
* @param acquired[], one or more acquired info codes
|
||||
*/
|
||||
void setOperationAuthenticateAcquired(in int[] acquired);
|
||||
|
||||
/**
|
||||
* setOperationEnrollError
|
||||
*
|
||||
* Force enrollment operation to error out for non-zero error
|
||||
* Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid error codes
|
||||
*
|
||||
* @param error if error < 1000
|
||||
* non-vendor error
|
||||
* else
|
||||
* vendor error
|
||||
*/
|
||||
void setOperationEnrollError(in int error);
|
||||
|
||||
/**
|
||||
* setOperationEnrollLatency
|
||||
*
|
||||
* Set enrollment latency in the virtual hal in a fixed value (single element) or random
|
||||
* values (two elements representing the bound values)
|
||||
* The latency simulates the delay from the time framework requesting HAL to enroll to the
|
||||
* time when HAL is ready to perform enrollment operations.
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in array falls in any of
|
||||
* the following conditions
|
||||
* 1. the array contains no element
|
||||
* 2. the array contains more than two elements
|
||||
* 3. the array contains any negative value
|
||||
* The accompanying error message gives more detail
|
||||
*
|
||||
* @param latencyMs[] value(s) are in milli-seconds
|
||||
*/
|
||||
void setOperationEnrollLatency(in int[] latencyMs);
|
||||
|
||||
/**
|
||||
* setOperationDetectInteractionLatency
|
||||
*
|
||||
* Set detect interaction latency in the virtual hal in a fixed value (single element) or random
|
||||
* values (two elements representing the bound values)
|
||||
* The latency simulates the delay from the time framework requesting HAL to detect interaction
|
||||
* to the time when HAL is ready to perform detect interaction operations.
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in array falls in any of
|
||||
* the following conditions
|
||||
* 1. the array contains no element
|
||||
* 2. the array contains more than two elements
|
||||
* 3. the array contains any negative value
|
||||
* The accompanying error message gives more detail
|
||||
*
|
||||
* @param latencyMs[] value(s) are in milli-seconds
|
||||
*/
|
||||
void setOperationDetectInteractionLatency(in int[] latencyMs);
|
||||
|
||||
/**
|
||||
* setOperationDetectInteractionError
|
||||
*
|
||||
* Force detect interaction operation to error out for non-zero error
|
||||
* Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid error codes
|
||||
*
|
||||
* @param error if error < 1000
|
||||
* non-vendor error
|
||||
* else
|
||||
* vendor error
|
||||
*/
|
||||
void setOperationDetectInteractionError(in int error);
|
||||
|
||||
/**
|
||||
* setOperationDetectInteractionDuration
|
||||
*
|
||||
* Set detect interaction duration covering the HAL authetication from start to end, including
|
||||
* fingerprint detect and acquired info reporting. In case a sequence of acquired info code are
|
||||
* specified via setOperationDetectInteractionAcquired(), the reporting is evenly distributed
|
||||
* over the duration.
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
|
||||
*
|
||||
* @param duration value is in milli-seconds
|
||||
*/
|
||||
void setOperationDetectInteractionDuration(in int durationMs);
|
||||
|
||||
/**
|
||||
* setOperationDetectInteractionAcquired
|
||||
*
|
||||
* Set one of more acquired info codes for the virtual hal to report during detect interaction
|
||||
* Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid acquired
|
||||
* info codes
|
||||
*
|
||||
* @param acquired[], one or more acquired info codes
|
||||
*/
|
||||
void setOperationDetectInteractionAcquired(in int[] acquired);
|
||||
|
||||
/**
|
||||
* setLockout
|
||||
*
|
||||
* Whether to force to lockout on authentcation operation. If true, the virtual hal will report
|
||||
* permanent lockout in processing authentication requrest, regardless of whether
|
||||
* setLockoutEnable(true) is called or not.
|
||||
*
|
||||
* @param lockout, set to true if lockout is desired
|
||||
*/
|
||||
void setLockout(in boolean lockout);
|
||||
|
||||
/**
|
||||
* setLockoutEnable
|
||||
*
|
||||
* Whether to enable authentication-fail-based lockout tracking or not. The lock tracking
|
||||
* includes both timed-based (aka temporary) lockout and permanent lockout.
|
||||
*
|
||||
* @param enable, set true to enable the lockout tracking
|
||||
*/
|
||||
void setLockoutEnable(in boolean enable);
|
||||
|
||||
/**
|
||||
* setLockoutTimedThreshold
|
||||
*
|
||||
* Set the number of consecutive authentication failures that triggers the timed-based lock to
|
||||
* occur
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
|
||||
*
|
||||
* @param threshold, the number of consecutive failures
|
||||
*/
|
||||
void setLockoutTimedThreshold(in int threshold);
|
||||
|
||||
/**
|
||||
* setLockoutTimedDuration
|
||||
*
|
||||
* Set the duration to expire timed-based lock during which there is no authentication failure
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
|
||||
*
|
||||
* @param duration, in milli-seconds
|
||||
*/
|
||||
void setLockoutTimedDuration(in int durationMs);
|
||||
|
||||
/**
|
||||
* setLockoutPermanentThreshold
|
||||
*
|
||||
* Set the number of consecutive authentication failures that triggers the permanent lock to
|
||||
* occur
|
||||
*
|
||||
* This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
|
||||
*
|
||||
* @param threshold, the number of consecutive failures
|
||||
*/
|
||||
void setLockoutPermanentThreshold(in int threshold);
|
||||
|
||||
/**
|
||||
* The following functions are used to configure Fingerprint Virtual HAL sensor properties
|
||||
* refer to SensorProps.aidl and CommonProps.aidl for details of each property
|
||||
*/
|
||||
void setType(in FingerprintSensorType type);
|
||||
void setSensorId(in int id);
|
||||
void setSensorStrength(in SensorStrength strength);
|
||||
void setMaxEnrollmentPerUser(in int max);
|
||||
void setSensorLocation(in SensorLocation loc);
|
||||
void setNavigationGuesture(in boolean v);
|
||||
void setDetectInteraction(in boolean v);
|
||||
void setDisplayTouch(in boolean v);
|
||||
void setControlIllumination(in boolean v);
|
||||
}
|
|
@ -21,6 +21,7 @@ cc_binary {
|
|||
"Fingerprint.cpp",
|
||||
"Session.cpp",
|
||||
"FingerprintConfig.cpp",
|
||||
"VirtualHal.cpp",
|
||||
"main.cpp",
|
||||
],
|
||||
stl: "c++_static",
|
||||
|
@ -31,7 +32,7 @@ cc_binary {
|
|||
static_libs: [
|
||||
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
|
||||
"libbase",
|
||||
"android.hardware.biometrics.fingerprint-V4-ndk",
|
||||
"android.hardware.biometrics.fingerprint-V5-ndk",
|
||||
"android.hardware.biometrics.common-V4-ndk",
|
||||
"android.hardware.biometrics.common.thread",
|
||||
"android.hardware.biometrics.common.util",
|
||||
|
@ -61,7 +62,7 @@ cc_test {
|
|||
],
|
||||
static_libs: [
|
||||
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
|
||||
"android.hardware.biometrics.fingerprint-V4-ndk",
|
||||
"android.hardware.biometrics.fingerprint-V5-ndk",
|
||||
"android.hardware.biometrics.common-V4-ndk",
|
||||
"android.hardware.keymaster-V4-ndk",
|
||||
"android.hardware.biometrics.common.util",
|
||||
|
@ -89,7 +90,7 @@ cc_test {
|
|||
],
|
||||
static_libs: [
|
||||
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
|
||||
"android.hardware.biometrics.fingerprint-V4-ndk",
|
||||
"android.hardware.biometrics.fingerprint-V5-ndk",
|
||||
"android.hardware.biometrics.common-V4-ndk",
|
||||
"android.hardware.keymaster-V4-ndk",
|
||||
"android.hardware.biometrics.common.util",
|
||||
|
@ -115,7 +116,7 @@ cc_test {
|
|||
],
|
||||
static_libs: [
|
||||
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
|
||||
"android.hardware.biometrics.fingerprint-V4-ndk",
|
||||
"android.hardware.biometrics.fingerprint-V5-ndk",
|
||||
"android.hardware.biometrics.common-V4-ndk",
|
||||
"android.hardware.keymaster-V4-ndk",
|
||||
"android.hardware.biometrics.common.util",
|
||||
|
@ -143,7 +144,7 @@ cc_test {
|
|||
],
|
||||
static_libs: [
|
||||
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
|
||||
"android.hardware.biometrics.fingerprint-V4-ndk",
|
||||
"android.hardware.biometrics.fingerprint-V5-ndk",
|
||||
"android.hardware.biometrics.common-V4-ndk",
|
||||
"android.hardware.keymaster-V4-ndk",
|
||||
"android.hardware.biometrics.common.util",
|
||||
|
@ -155,6 +156,44 @@ cc_test {
|
|||
require_root: true,
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "android.hardware.biometrics.fingerprint.VirtualHalTest",
|
||||
local_include_dirs: ["include"],
|
||||
srcs: [
|
||||
"tests/VirtualHalTest.cpp",
|
||||
"Session.cpp",
|
||||
"VirtualHal.cpp",
|
||||
"FakeFingerprintEngineRear.cpp",
|
||||
"FakeFingerprintEngineUdfps.cpp",
|
||||
"FakeFingerprintEngineSide.cpp",
|
||||
"FakeFingerprintEngine.cpp",
|
||||
"FakeLockoutTracker.cpp",
|
||||
"Fingerprint.cpp",
|
||||
"FingerprintConfig.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
static_libs: [
|
||||
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
|
||||
"android.hardware.biometrics.fingerprint-V5-ndk",
|
||||
"android.hardware.biometrics.common-V4-ndk",
|
||||
"android.hardware.keymaster-V4-ndk",
|
||||
"android.hardware.biometrics.common.util",
|
||||
"android.hardware.biometrics.common.thread",
|
||||
"android.hardware.biometrics.common.config",
|
||||
],
|
||||
product_variables: {
|
||||
debuggable: {
|
||||
cflags: ["-DFPS_DEBUGGABLE"],
|
||||
},
|
||||
},
|
||||
vendor: true,
|
||||
test_suites: ["general-tests"],
|
||||
require_root: true,
|
||||
}
|
||||
|
||||
sysprop_library {
|
||||
name: "android.hardware.biometrics.fingerprint.VirtualProps",
|
||||
srcs: ["fingerprint.sysprop"],
|
||||
|
|
|
@ -171,7 +171,7 @@ void Fingerprint::resetConfigToDefault() {
|
|||
}
|
||||
|
||||
void Fingerprint::clearConfigSysprop() {
|
||||
LOG(INFO) << __func__ << ": clear all systprop configuration";
|
||||
LOG(INFO) << __func__ << ": clear all sysprop configuration";
|
||||
#define RESET_CONFIG_O(__NAME__) \
|
||||
if (FingerprintHalProperties::__NAME__()) FingerprintHalProperties::__NAME__(std::nullopt)
|
||||
#define RESET_CONFIG_V(__NAME__) \
|
||||
|
@ -209,4 +209,19 @@ void Fingerprint::clearConfigSysprop() {
|
|||
RESET_CONFIG_O(lockout_permanent_threshold);
|
||||
}
|
||||
|
||||
const char* Fingerprint::type2String(FingerprintSensorType type) {
|
||||
switch (type) {
|
||||
case FingerprintSensorType::REAR:
|
||||
return "rear";
|
||||
case FingerprintSensorType::POWER_BUTTON:
|
||||
return "side";
|
||||
case FingerprintSensorType::UNDER_DISPLAY_OPTICAL:
|
||||
return "udfps";
|
||||
case FingerprintSensorType::UNDER_DISPLAY_ULTRASONIC:
|
||||
return "udfps";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
||||
|
|
275
biometrics/fingerprint/aidl/default/VirtualHal.cpp
Normal file
275
biometrics/fingerprint/aidl/default/VirtualHal.cpp
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "VirtualHal.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "util/CancellationSignal.h"
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "FingerprintVirtualHalAidl"
|
||||
|
||||
namespace aidl::android::hardware::biometrics::fingerprint {
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setEnrollments(const std::vector<int32_t>& enrollments) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().setopt<OptIntVec>("enrollments", intVec2OptIntVec(enrollments));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setEnrollmentHit(int32_t enrollment_hit) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<std::int32_t>("enrollment_hit", enrollment_hit);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setAuthenticatorId(int64_t in_id) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int64_t>("authenticator_id", in_id);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setChallenge(int64_t in_challenge) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int64_t>("challenge", in_challenge);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateFails(bool in_fail) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("operation_authenticate_fails", in_fail);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateLatency(
|
||||
const std::vector<int32_t>& in_latency) {
|
||||
ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
|
||||
if (!status.isOk()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_latency",
|
||||
intVec2OptIntVec(in_latency));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateDuration(int32_t in_duration) {
|
||||
if (in_duration < 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("operation_authenticate_duration", in_duration);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateError(int32_t in_error) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("operation_authenticate_error", in_error);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateAcquired(
|
||||
const std::vector<int32_t>& in_acquired) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_acquired",
|
||||
intVec2OptIntVec(in_acquired));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationEnrollError(int32_t in_error) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("operation_enroll_error", in_error);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationEnrollLatency(const std::vector<int32_t>& in_latency) {
|
||||
ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
|
||||
if (!status.isOk()) {
|
||||
return status;
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().setopt<OptIntVec>("operation_enroll_latency", intVec2OptIntVec(in_latency));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionLatency(
|
||||
const std::vector<int32_t>& in_latency) {
|
||||
ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
|
||||
if (!status.isOk()) {
|
||||
return status;
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interact_latency",
|
||||
intVec2OptIntVec(in_latency));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionError(int32_t in_error) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("operation_detect_interaction_error", in_error);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionDuration(int32_t in_duration) {
|
||||
if (in_duration < 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("operation_detect_interaction_duration", in_duration);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionAcquired(
|
||||
const std::vector<int32_t>& in_acquired) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_acquired",
|
||||
intVec2OptIntVec(in_acquired));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setLockout(bool in_lockout) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("lockout", in_lockout);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setLockoutEnable(bool in_enable) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("lockout_enable", in_enable);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setLockoutTimedThreshold(int32_t in_threshold) {
|
||||
if (in_threshold < 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("lockout_timed_threshold", in_threshold);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setLockoutTimedDuration(int32_t in_duration) {
|
||||
if (in_duration < 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("lockout_timed_duration", in_duration);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setLockoutPermanentThreshold(int32_t in_threshold) {
|
||||
if (in_threshold < 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
|
||||
}
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("lockout_permanent_threshold", in_threshold);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setType(
|
||||
::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<std::string>("type", Fingerprint::type2String(in_type));
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setSensorId(int32_t in_id) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("sensor_id", in_id);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setSensorStrength(SensorStrength in_strength) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("sensor_strength", (int32_t)in_strength);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setMaxEnrollmentPerUser(int32_t in_max) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<int32_t>("max_enrollments", in_max);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setSensorLocation(const SensorLocation& in_loc) {
|
||||
std::string str = std::to_string(in_loc.sensorLocationX) + ":" +
|
||||
std::to_string(in_loc.sensorLocationY) + ":" +
|
||||
std::to_string(in_loc.sensorRadius);
|
||||
;
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<std::string>("sensor_location", str);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setNavigationGuesture(bool in_v) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("navigation_guesture", in_v);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setDetectInteraction(bool in_v) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("detect_interaction", in_v);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setDisplayTouch(bool in_v) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("display_touch", in_v);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::setControlIllumination(bool in_v) {
|
||||
Fingerprint::cfg().sourcedFromAidl();
|
||||
Fingerprint::cfg().set<bool>("control_illumination", in_v);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
OptIntVec VirtualHal::intVec2OptIntVec(const std::vector<int32_t>& in_vec) {
|
||||
OptIntVec optIntVec;
|
||||
std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
|
||||
[](int value) { return std::optional<int>(value); });
|
||||
return optIntVec;
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus VirtualHal::sanityCheckLatency(const std::vector<int32_t>& in_latency) {
|
||||
if (in_latency.size() == 0 || in_latency.size() > 2) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER,
|
||||
"Error: input input array must contain 1 or 2 elements"));
|
||||
}
|
||||
|
||||
for (auto x : in_latency) {
|
||||
if (x < 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IVirtualHal::STATUS_INVALID_PARAMETER,
|
||||
"Error: input data must not be negative"));
|
||||
}
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
|
@ -1,7 +1,7 @@
|
|||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.biometrics.fingerprint</name>
|
||||
<version>4</version>
|
||||
<version>5</version>
|
||||
<fqname>IFingerprint/virtual</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
|
@ -40,6 +40,7 @@ class Fingerprint : public BnFingerprint {
|
|||
std::shared_ptr<ISession>* out) override;
|
||||
binder_status_t dump(int fd, const char** args, uint32_t numArgs);
|
||||
binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc);
|
||||
bool connected() { return mEngine != nullptr; }
|
||||
|
||||
static FingerprintConfig& cfg() {
|
||||
static FingerprintConfig* cfg = nullptr;
|
||||
|
@ -49,9 +50,10 @@ class Fingerprint : public BnFingerprint {
|
|||
}
|
||||
return *cfg;
|
||||
}
|
||||
void resetConfigToDefault();
|
||||
static const char* type2String(FingerprintSensorType type);
|
||||
|
||||
private:
|
||||
void resetConfigToDefault();
|
||||
void onHelp(int);
|
||||
void onSimFingerDown();
|
||||
void clearConfigSysprop();
|
||||
|
|
73
biometrics/fingerprint/aidl/default/include/VirtualHal.h
Normal file
73
biometrics/fingerprint/aidl/default/include/VirtualHal.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/biometrics/fingerprint/BnVirtualHal.h>
|
||||
|
||||
#include "Fingerprint.h"
|
||||
|
||||
namespace aidl::android::hardware::biometrics::fingerprint {
|
||||
|
||||
class VirtualHal : public BnVirtualHal {
|
||||
public:
|
||||
VirtualHal(Fingerprint* fp) : mFp(fp) {}
|
||||
|
||||
::ndk::ScopedAStatus setEnrollments(const std::vector<int32_t>& in_id) override;
|
||||
::ndk::ScopedAStatus setEnrollmentHit(int32_t in_hit_id) override;
|
||||
::ndk::ScopedAStatus setAuthenticatorId(int64_t in_id) override;
|
||||
::ndk::ScopedAStatus setChallenge(int64_t in_challenge) override;
|
||||
::ndk::ScopedAStatus setOperationAuthenticateFails(bool in_fail) override;
|
||||
::ndk::ScopedAStatus setOperationAuthenticateLatency(
|
||||
const std::vector<int32_t>& in_latency) override;
|
||||
::ndk::ScopedAStatus setOperationAuthenticateDuration(int32_t in_duration) override;
|
||||
::ndk::ScopedAStatus setOperationAuthenticateError(int32_t in_error) override;
|
||||
::ndk::ScopedAStatus setOperationAuthenticateAcquired(
|
||||
const std::vector<int32_t>& in_acquired) override;
|
||||
::ndk::ScopedAStatus setOperationEnrollError(int32_t in_error) override;
|
||||
::ndk::ScopedAStatus setOperationEnrollLatency(const std::vector<int32_t>& in_latency) override;
|
||||
::ndk::ScopedAStatus setOperationDetectInteractionLatency(
|
||||
const std::vector<int32_t>& in_latency) override;
|
||||
::ndk::ScopedAStatus setOperationDetectInteractionError(int32_t in_error) override;
|
||||
::ndk::ScopedAStatus setOperationDetectInteractionDuration(int32_t in_duration) override;
|
||||
::ndk::ScopedAStatus setOperationDetectInteractionAcquired(
|
||||
const std::vector<int32_t>& in_acquired) override;
|
||||
::ndk::ScopedAStatus setLockout(bool in_lockout) override;
|
||||
::ndk::ScopedAStatus setLockoutEnable(bool in_enable) override;
|
||||
::ndk::ScopedAStatus setLockoutTimedThreshold(int32_t in_threshold) override;
|
||||
::ndk::ScopedAStatus setLockoutTimedDuration(int32_t in_duration) override;
|
||||
::ndk::ScopedAStatus setLockoutPermanentThreshold(int32_t in_threshold) override;
|
||||
::ndk::ScopedAStatus setType(
|
||||
::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type)
|
||||
override;
|
||||
::ndk::ScopedAStatus setSensorId(int32_t in_id) override;
|
||||
::ndk::ScopedAStatus setSensorStrength(SensorStrength in_strength) override;
|
||||
::ndk::ScopedAStatus setMaxEnrollmentPerUser(int32_t in_max) override;
|
||||
::ndk::ScopedAStatus setSensorLocation(
|
||||
const ::aidl::android::hardware::biometrics::fingerprint::SensorLocation& in_loc)
|
||||
override;
|
||||
::ndk::ScopedAStatus setNavigationGuesture(bool in_v) override;
|
||||
::ndk::ScopedAStatus setDetectInteraction(bool in_v) override;
|
||||
::ndk::ScopedAStatus setDisplayTouch(bool in_v) override;
|
||||
::ndk::ScopedAStatus setControlIllumination(bool in_v) override;
|
||||
|
||||
private:
|
||||
OptIntVec intVec2OptIntVec(const std::vector<int32_t>& intVec);
|
||||
::ndk::ScopedAStatus sanityCheckLatency(const std::vector<int32_t>& in_latency);
|
||||
Fingerprint* mFp;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
|
@ -15,23 +15,34 @@
|
|||
*/
|
||||
|
||||
#include "Fingerprint.h"
|
||||
#include "VirtualHal.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
using aidl::android::hardware::biometrics::fingerprint::Fingerprint;
|
||||
using aidl::android::hardware::biometrics::fingerprint::VirtualHal;
|
||||
|
||||
int main() {
|
||||
LOG(INFO) << "Fingerprint HAL started";
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<Fingerprint> hal = ndk::SharedRefBase::make<Fingerprint>();
|
||||
auto binder = hal->asBinder();
|
||||
|
||||
std::shared_ptr<VirtualHal> hal_ext = ndk::SharedRefBase::make<VirtualHal>(hal.get());
|
||||
auto binder_ext = hal_ext->asBinder();
|
||||
|
||||
if (hal->connected()) {
|
||||
CHECK(STATUS_OK == AIBinder_setExtension(binder.get(), binder_ext.get()));
|
||||
const std::string instance = std::string(Fingerprint::descriptor) + "/virtual";
|
||||
binder_status_t status =
|
||||
AServiceManager_registerLazyService(hal->asBinder().get(), instance.c_str());
|
||||
AServiceManager_registerLazyService(binder.get(), instance.c_str());
|
||||
CHECK_EQ(status, STATUS_OK);
|
||||
AServiceManager_forceLazyServicesPersist(true);
|
||||
} else {
|
||||
LOG(ERROR) << "Fingerprint HAL is not connected";
|
||||
}
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
return EXIT_FAILURE; // should not reach
|
||||
|
|
232
biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
Normal file
232
biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android/binder_process.h>
|
||||
#include <fingerprint.sysprop.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "Fingerprint.h"
|
||||
#include "VirtualHal.h"
|
||||
|
||||
using namespace ::android::fingerprint::virt;
|
||||
using namespace ::aidl::android::hardware::biometrics::fingerprint;
|
||||
|
||||
namespace aidl::android::hardware::biometrics::fingerprint {
|
||||
|
||||
class VirtualHalTest : public ::testing::Test {
|
||||
public:
|
||||
static const int32_t STATUS_FAILED_TO_SET_PARAMETER = 2;
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
mHal = ndk::SharedRefBase::make<Fingerprint>();
|
||||
mVhal = ndk::SharedRefBase::make<VirtualHal>(mHal.get());
|
||||
ASSERT_TRUE(mVhal != nullptr);
|
||||
mHal->resetConfigToDefault();
|
||||
}
|
||||
|
||||
void TearDown() override { mHal->resetConfigToDefault(); }
|
||||
|
||||
std::shared_ptr<VirtualHal> mVhal;
|
||||
|
||||
ndk::ScopedAStatus validateNonNegativeInputOfInt32(const char* name,
|
||||
ndk::ScopedAStatus (VirtualHal::*f)(int32_t),
|
||||
const std::vector<int32_t>& in_good);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Fingerprint> mHal;
|
||||
};
|
||||
|
||||
ndk::ScopedAStatus VirtualHalTest::validateNonNegativeInputOfInt32(
|
||||
const char* name, ndk::ScopedAStatus (VirtualHal::*f)(int32_t),
|
||||
const std::vector<int32_t>& in_params_good) {
|
||||
ndk::ScopedAStatus status;
|
||||
for (auto& param : in_params_good) {
|
||||
status = (*mVhal.*f)(param);
|
||||
if (!status.isOk()) return status;
|
||||
if (Fingerprint::cfg().get<int32_t>(name) != param) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER,
|
||||
"Error: fail to set non-negative parameter"));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t old_param = Fingerprint::cfg().get<int32_t>(name);
|
||||
status = (*mVhal.*f)(-1);
|
||||
if (status.isOk()) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER, "Error: should return NOK"));
|
||||
}
|
||||
if (status.getServiceSpecificError() != IVirtualHal::STATUS_INVALID_PARAMETER) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER,
|
||||
"Error: unexpected return error code"));
|
||||
}
|
||||
if (Fingerprint::cfg().get<int32_t>(name) != old_param) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER,
|
||||
"Error: unexpected parameter change on failed attempt"));
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, init) {
|
||||
mVhal->setLockout(false);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<bool>("lockout") == false);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<std::string>("type") == "rear");
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<std::int32_t>("sensor_strength") == 2);
|
||||
std::int64_t id = Fingerprint::cfg().get<std::int64_t>("authenticator_id");
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<std::int64_t>("authenticator_id") == 0);
|
||||
ASSERT_TRUE(Fingerprint::cfg().getopt<OptIntVec>("enrollments") == OptIntVec());
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, enrollment_hit_int32) {
|
||||
mVhal->setEnrollmentHit(11);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<int32_t>("enrollment_hit") == 11);
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, authenticator_id_int64) {
|
||||
mVhal->setAuthenticatorId(12345678900);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<int64_t>("authenticator_id") == 12345678900);
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, opeationAuthenticateFails_bool) {
|
||||
mVhal->setOperationAuthenticateFails(true);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<bool>("operation_authenticate_fails"));
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, operationAuthenticateAcquired_int32_vector) {
|
||||
std::vector<int32_t> ac{1, 2, 3, 4, 5, 6, 7};
|
||||
mVhal->setOperationAuthenticateAcquired(ac);
|
||||
OptIntVec ac_get = Fingerprint::cfg().getopt<OptIntVec>("operation_authenticate_acquired");
|
||||
ASSERT_TRUE(ac_get.size() == ac.size());
|
||||
for (int i = 0; i < ac.size(); i++) {
|
||||
ASSERT_TRUE(ac[i] == ac_get[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, type) {
|
||||
struct {
|
||||
FingerprintSensorType type;
|
||||
const char* typeStr;
|
||||
} typeMap[] = {{FingerprintSensorType::REAR, "rear"},
|
||||
{FingerprintSensorType::POWER_BUTTON, "side"},
|
||||
{FingerprintSensorType::UNDER_DISPLAY_OPTICAL, "udfps"},
|
||||
{FingerprintSensorType::UNDER_DISPLAY_ULTRASONIC, "udfps"},
|
||||
{FingerprintSensorType::UNKNOWN, "unknown"}};
|
||||
for (auto const& x : typeMap) {
|
||||
mVhal->setType(x.type);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<std::string>("type") == x.typeStr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, sensorStrength) {
|
||||
SensorStrength strengths[] = {SensorStrength::CONVENIENCE, SensorStrength::WEAK,
|
||||
SensorStrength::STRONG};
|
||||
|
||||
for (auto const& strength : strengths) {
|
||||
mVhal->setSensorStrength(strength);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<int32_t>("sensor_strength") == (int32_t)(strength));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, sensorLocation) {
|
||||
SensorLocation loc = {.sensorLocationX = 1, .sensorLocationY = 2, .sensorRadius = 3};
|
||||
mVhal->setSensorLocation(loc);
|
||||
ASSERT_TRUE(Fingerprint::cfg().get<std::string>("sensor_location") == "1:2:3");
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setLatency) {
|
||||
ndk::ScopedAStatus status;
|
||||
std::vector<int32_t> in_lats[] = {{1}, {2, 3}, {5, 4}};
|
||||
for (auto const& in_lat : in_lats) {
|
||||
status = mVhal->setOperationAuthenticateLatency(in_lat);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
OptIntVec out_lat = Fingerprint::cfg().getopt<OptIntVec>("operation_authenticate_latency");
|
||||
ASSERT_TRUE(in_lat.size() == out_lat.size());
|
||||
for (int i = 0; i < in_lat.size(); i++) {
|
||||
ASSERT_TRUE(in_lat[i] == out_lat[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int32_t> bad_in_lats[] = {{}, {1, 2, 3}, {1, -3}};
|
||||
for (auto const& in_lat : bad_in_lats) {
|
||||
status = mVhal->setOperationAuthenticateLatency(in_lat);
|
||||
ASSERT_TRUE(!status.isOk());
|
||||
ASSERT_TRUE(status.getServiceSpecificError() == IVirtualHal::STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setOperationAuthenticateDuration) {
|
||||
ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
|
||||
"operation_authenticate_duration", &IVirtualHal::setOperationAuthenticateDuration,
|
||||
{0, 33});
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setOperationDetectInteractionDuration) {
|
||||
ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
|
||||
"operation_detect_interaction_duration",
|
||||
&IVirtualHal::setOperationDetectInteractionDuration, {0, 34});
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setLockoutTimedDuration) {
|
||||
ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
|
||||
"lockout_timed_duration", &IVirtualHal::setLockoutTimedDuration, {0, 35});
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setLockoutTimedThreshold) {
|
||||
ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
|
||||
"lockout_timed_threshold", &IVirtualHal::setLockoutTimedThreshold, {0, 36});
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setLockoutPermanentThreshold) {
|
||||
ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
|
||||
"lockout_permanent_threshold", &IVirtualHal::setLockoutPermanentThreshold, {0, 37});
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
TEST_F(VirtualHalTest, setOthers) {
|
||||
// Verify that there is no CHECK() failures
|
||||
mVhal->setEnrollments({7, 6, 5});
|
||||
mVhal->setChallenge(111222333444555666);
|
||||
mVhal->setOperationAuthenticateError(4);
|
||||
mVhal->setOperationEnrollError(5);
|
||||
mVhal->setOperationEnrollLatency({4, 5});
|
||||
mVhal->setOperationDetectInteractionError(6);
|
||||
mVhal->setOperationDetectInteractionAcquired({4, 3, 2});
|
||||
mVhal->setLockout(false);
|
||||
mVhal->setLockoutEnable(false);
|
||||
mVhal->setSensorId(5);
|
||||
mVhal->setMaxEnrollmentPerUser(6);
|
||||
mVhal->setNavigationGuesture(false);
|
||||
mVhal->setDetectInteraction(false);
|
||||
mVhal->setDisplayTouch(false);
|
||||
mVhal->setControlIllumination(false);
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::fingerprint
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
|
@ -116,7 +116,7 @@
|
|||
</hal>
|
||||
<hal format="aidl" updatable-via-apex="true">
|
||||
<name>android.hardware.biometrics.fingerprint</name>
|
||||
<version>3-4</version>
|
||||
<version>3-5</version>
|
||||
<interface>
|
||||
<name>IFingerprint</name>
|
||||
<instance>default</instance>
|
||||
|
|
Loading…
Reference in a new issue