|
|
|
@ -13,7 +13,7 @@ |
|
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
|
* limitations under the License. |
|
|
|
|
*/ |
|
|
|
|
#define LOG_TAG "vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125" |
|
|
|
|
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service-samsung.sm7125" |
|
|
|
|
|
|
|
|
|
#include <android-base/logging.h> |
|
|
|
|
|
|
|
|
@ -23,30 +23,28 @@ |
|
|
|
|
#include <hardware/hardware.h> |
|
|
|
|
#include "BiometricsFingerprint.h" |
|
|
|
|
#include <android-base/properties.h> |
|
|
|
|
#include <fstream> |
|
|
|
|
#include <dlfcn.h> |
|
|
|
|
#include <fstream> |
|
|
|
|
#include <inttypes.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#include <thread> |
|
|
|
|
|
|
|
|
|
#define SEH_FINGER_STATE 22 |
|
|
|
|
#define SEH_PARAM_PRESSED 2 |
|
|
|
|
#define SEH_PARAM_RELEASED 1 |
|
|
|
|
#define SEH_AOSP_FQNAME "android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint" |
|
|
|
|
#ifdef HAS_FINGERPRINT_GESTURES |
|
|
|
|
#include <fcntl.h> |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#define TSP_CMD_PATH "/sys/class/sec/tsp/cmd" |
|
|
|
|
#define HBM_PATH "/sys/class/lcd/panel/mask_brightness" |
|
|
|
|
|
|
|
|
|
namespace vendor { |
|
|
|
|
namespace samsung { |
|
|
|
|
namespace android { |
|
|
|
|
namespace hardware { |
|
|
|
|
namespace biometrics { |
|
|
|
|
namespace fingerprint { |
|
|
|
|
namespace V3_0 { |
|
|
|
|
namespace V2_3 { |
|
|
|
|
namespace implementation { |
|
|
|
|
|
|
|
|
|
using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus; |
|
|
|
|
|
|
|
|
|
ISehBiometricsFingerprint* SehBiometricsFingerprint::sInstance = nullptr; |
|
|
|
|
BiometricsFingerprint* BiometricsFingerprint::sInstance = nullptr; |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
static void set(const std::string& path, const T& value) { |
|
|
|
@ -58,16 +56,7 @@ std::string getBootloader() { |
|
|
|
|
return android::base::GetProperty("ro.boot.bootloader", ""); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
static T get(const std::string& path, const T& def) { |
|
|
|
|
std::ifstream file(path); |
|
|
|
|
T result; |
|
|
|
|
|
|
|
|
|
file >> result; |
|
|
|
|
return file.fail() ? def : result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SehBiometricsFingerprint::SehBiometricsFingerprint() : mClientCallback(nullptr) { |
|
|
|
|
BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) { |
|
|
|
|
sInstance = this; // keep track of the most recent instance
|
|
|
|
|
if (!openHal()) { |
|
|
|
|
LOG(ERROR) << "Can't open HAL module"; |
|
|
|
@ -86,55 +75,75 @@ SehBiometricsFingerprint::SehBiometricsFingerprint() : mClientCallback(nullptr) |
|
|
|
|
if (in) |
|
|
|
|
in.close(); |
|
|
|
|
|
|
|
|
|
#ifdef HAS_FINGERPRINT_GESTURES |
|
|
|
|
request(FINGERPRINT_REQUEST_NAVIGATION_MODE_START, 1); |
|
|
|
|
|
|
|
|
|
uinputFd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); |
|
|
|
|
if (uinputFd < 0) { |
|
|
|
|
LOG(ERROR) << "Unable to open uinput node"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int err = ioctl(uinputFd, UI_SET_EVBIT, EV_KEY) | |
|
|
|
|
ioctl(uinputFd, UI_SET_KEYBIT, KEY_UP) | |
|
|
|
|
ioctl(uinputFd, UI_SET_KEYBIT, KEY_DOWN); |
|
|
|
|
if (err != 0) { |
|
|
|
|
LOG(ERROR) << "Unable to enable key events"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct uinput_user_dev uidev; |
|
|
|
|
sprintf(uidev.name, "uinput-sec-fp"); |
|
|
|
|
uidev.id.bustype = BUS_VIRTUAL; |
|
|
|
|
|
|
|
|
|
err = write(uinputFd, &uidev, sizeof(uidev)); |
|
|
|
|
if (err < 0) { |
|
|
|
|
LOG(ERROR) << "Write user device to uinput node failed"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = ioctl(uinputFd, UI_DEV_CREATE); |
|
|
|
|
if (err < 0) { |
|
|
|
|
LOG(ERROR) << "Unable to create uinput device"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(INFO) << "Successfully registered uinput-sec-fp for fingerprint gestures"; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
set(TSP_CMD_PATH, "fod_enable,1,1,0"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SehBiometricsFingerprint::~SehBiometricsFingerprint() { |
|
|
|
|
BiometricsFingerprint::~BiometricsFingerprint() { |
|
|
|
|
if (ss_fingerprint_close() != 0) { |
|
|
|
|
LOG(ERROR) << "Can't close HAL module"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<bool> SehBiometricsFingerprint::isUdfps(uint32_t) { |
|
|
|
|
Return<bool> BiometricsFingerprint::isUdfps(uint32_t) { |
|
|
|
|
return mIsUdfps; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SehBiometricsFingerprint::requestResult(int, const hidl_vec<int8_t>&) { |
|
|
|
|
// Ignore all results
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static hidl_vec<int8_t> stringToVec(const std::string& str) { |
|
|
|
|
auto vec = hidl_vec<int8_t>(); |
|
|
|
|
vec.resize(str.size() + 1); |
|
|
|
|
for (size_t i = 0; i < str.size(); ++i) { |
|
|
|
|
vec[i] = (int8_t) str[i]; |
|
|
|
|
} |
|
|
|
|
vec[str.size()] = '\0'; |
|
|
|
|
return vec; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<void> SehBiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) { |
|
|
|
|
Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) { |
|
|
|
|
std::thread([this]() { |
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(35)); |
|
|
|
|
set(HBM_PATH, "331"); |
|
|
|
|
}).detach(); |
|
|
|
|
|
|
|
|
|
sehRequest(SEH_FINGER_STATE, SEH_PARAM_PRESSED, |
|
|
|
|
stringToVec(SEH_AOSP_FQNAME), SehBiometricsFingerprint::requestResult); |
|
|
|
|
request(SEM_REQUEST_TOUCH_EVENT, FINGERPRINT_REQUEST_SESSION_OPEN); |
|
|
|
|
|
|
|
|
|
return Void(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<void> SehBiometricsFingerprint::onFingerUp() { |
|
|
|
|
sehRequest(SEH_FINGER_STATE, SEH_PARAM_RELEASED, |
|
|
|
|
stringToVec(SEH_AOSP_FQNAME), SehBiometricsFingerprint::requestResult); |
|
|
|
|
Return<void> BiometricsFingerprint::onFingerUp() { |
|
|
|
|
request(SEM_REQUEST_TOUCH_EVENT, FINGERPRINT_REQUEST_RESUME); |
|
|
|
|
|
|
|
|
|
set(HBM_PATH, "0"); |
|
|
|
|
|
|
|
|
|
return Void(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::ErrorFilter(int32_t error) { |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) { |
|
|
|
|
switch (error) { |
|
|
|
|
case 0: |
|
|
|
|
return RequestStatus::SYS_OK; |
|
|
|
@ -168,7 +177,7 @@ Return<RequestStatus> SehBiometricsFingerprint::ErrorFilter(int32_t error) { |
|
|
|
|
|
|
|
|
|
// Translate from errors returned by traditional HAL (see fingerprint.h) to
|
|
|
|
|
// HIDL-compliant FingerprintError.
|
|
|
|
|
FingerprintError SehBiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) { |
|
|
|
|
FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) { |
|
|
|
|
*vendorCode = 0; |
|
|
|
|
switch (error) { |
|
|
|
|
case FINGERPRINT_ERROR_HW_UNAVAILABLE: |
|
|
|
@ -198,7 +207,7 @@ FingerprintError SehBiometricsFingerprint::VendorErrorFilter(int32_t error, int3 |
|
|
|
|
|
|
|
|
|
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
|
|
|
|
|
// to HIDL-compliant FingerprintAcquiredInfo.
|
|
|
|
|
FingerprintAcquiredInfo SehBiometricsFingerprint::VendorAcquiredFilter(int32_t info, |
|
|
|
|
FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(int32_t info, |
|
|
|
|
int32_t* vendorCode) { |
|
|
|
|
*vendorCode = 0; |
|
|
|
|
switch (info) { |
|
|
|
@ -225,7 +234,7 @@ FingerprintAcquiredInfo SehBiometricsFingerprint::VendorAcquiredFilter(int32_t i |
|
|
|
|
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<uint64_t> SehBiometricsFingerprint::setNotify( |
|
|
|
|
Return<uint64_t> BiometricsFingerprint::setNotify( |
|
|
|
|
const sp<IBiometricsFingerprintClientCallback>& clientCallback) { |
|
|
|
|
std::lock_guard<std::mutex> lock(mClientCallbackMutex); |
|
|
|
|
mClientCallback = clientCallback; |
|
|
|
@ -236,30 +245,45 @@ Return<uint64_t> SehBiometricsFingerprint::setNotify( |
|
|
|
|
return reinterpret_cast<uint64_t>(this); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<uint64_t> SehBiometricsFingerprint::preEnroll() { |
|
|
|
|
Return<uint64_t> BiometricsFingerprint::preEnroll() { |
|
|
|
|
return ss_fingerprint_pre_enroll(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat, |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat, |
|
|
|
|
uint32_t gid, uint32_t timeoutSec) { |
|
|
|
|
const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(hat.data()); |
|
|
|
|
|
|
|
|
|
#ifdef REQUEST_FORCE_CALIBRATE |
|
|
|
|
request(SEM_REQUEST_FORCE_CBGE, 1); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::postEnroll() { |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::postEnroll() { |
|
|
|
|
return ErrorFilter(ss_fingerprint_post_enroll()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<uint64_t> SehBiometricsFingerprint::getAuthenticatorId() { |
|
|
|
|
Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() { |
|
|
|
|
return ss_fingerprint_get_auth_id(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::cancel() { |
|
|
|
|
return ErrorFilter(ss_fingerprint_cancel()); |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::cancel() { |
|
|
|
|
int32_t ret = ss_fingerprint_cancel(); |
|
|
|
|
|
|
|
|
|
#ifdef CALL_NOTIFY_ON_CANCEL |
|
|
|
|
if (ret == 0) { |
|
|
|
|
fingerprint_msg_t msg{}; |
|
|
|
|
msg.type = FINGERPRINT_ERROR; |
|
|
|
|
msg.data.error = FINGERPRINT_ERROR_CANCELED; |
|
|
|
|
notify(&msg); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return ErrorFilter(ret); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::enumerate() { |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::enumerate() { |
|
|
|
|
if (ss_fingerprint_enumerate != nullptr) { |
|
|
|
|
return ErrorFilter(ss_fingerprint_enumerate()); |
|
|
|
|
} |
|
|
|
@ -267,62 +291,36 @@ Return<RequestStatus> SehBiometricsFingerprint::enumerate() { |
|
|
|
|
return RequestStatus::SYS_UNKNOWN; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { |
|
|
|
|
return ErrorFilter(ss_fingerprint_remove(gid, fid)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::setActiveGroup(uint32_t gid, |
|
|
|
|
const hidl_string&) { |
|
|
|
|
std::string storePath = "/data/vendor/biometrics/fp/User_" + std::to_string(gid); |
|
|
|
|
LOG(ERROR) << "setActiveGroup " << gid << " " << storePath; |
|
|
|
|
return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<RequestStatus> SehBiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) { |
|
|
|
|
return ErrorFilter(ss_fingerprint_authenticate(operationId, gid)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Return<void> SehBiometricsFingerprint::sehRequest(int32_t cmd_id, |
|
|
|
|
int32_t inParam, const hidl_vec<int8_t>& inputBuf, sehRequest_cb _hidl_cb) { |
|
|
|
|
size_t inputSize = 0; |
|
|
|
|
for (; inputBuf[inputSize] != '\0'; ++inputSize); |
|
|
|
|
|
|
|
|
|
int8_t input[inputSize + 1]; |
|
|
|
|
|
|
|
|
|
// HACK: SehBiometrics 3.0 doesn't have the len parameter like the older 2.1 HAL has. Set it to 10 for now
|
|
|
|
|
int8_t output[10]; |
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < inputSize; ++i) { |
|
|
|
|
input[i] = inputBuf[i]; |
|
|
|
|
} |
|
|
|
|
input[inputSize] = '\0'; |
|
|
|
|
for (size_t i = 0; i < static_cast<size_t>(10); ++i) { |
|
|
|
|
output[i] = '\0'; |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid, |
|
|
|
|
const hidl_string& storePath) { |
|
|
|
|
if (storePath.size() >= PATH_MAX || storePath.size() <= 0) { |
|
|
|
|
LOG(ERROR) << "Bad path length: " << storePath.size(); |
|
|
|
|
return RequestStatus::SYS_EINVAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(ERROR) << "request(cmd_id=" << cmd_id |
|
|
|
|
<< ", len=" << 10 |
|
|
|
|
<< ", inParam=" << inParam |
|
|
|
|
<< ", inputBuf=" << input |
|
|
|
|
<< ")"; |
|
|
|
|
|
|
|
|
|
int ret = ss_fingerprint_request(cmd_id, input, 0, 10 == 0 ? nullptr : output, 10, inParam); |
|
|
|
|
if (access(storePath.c_str(), W_OK)) { |
|
|
|
|
return RequestStatus::SYS_EINVAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto outBuf = hidl_vec<int8_t>(); |
|
|
|
|
outBuf.setToExternal(output, 10); |
|
|
|
|
return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_hidl_cb(ret, outBuf); |
|
|
|
|
return Void(); |
|
|
|
|
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) { |
|
|
|
|
return ErrorFilter(ss_fingerprint_authenticate(operationId, gid)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ISehBiometricsFingerprint* SehBiometricsFingerprint::getInstance() { |
|
|
|
|
IBiometricsFingerprint* BiometricsFingerprint::getInstance() { |
|
|
|
|
if (!sInstance) { |
|
|
|
|
sInstance = new SehBiometricsFingerprint(); |
|
|
|
|
sInstance = new BiometricsFingerprint(); |
|
|
|
|
} |
|
|
|
|
return sInstance; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool SehBiometricsFingerprint::openHal() { |
|
|
|
|
bool BiometricsFingerprint::openHal() { |
|
|
|
|
void* handle = dlopen("libbauthserver.so", RTLD_NOW); |
|
|
|
|
if (handle) { |
|
|
|
|
int err; |
|
|
|
@ -360,7 +358,7 @@ bool SehBiometricsFingerprint::openHal() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((err = ss_set_notify_callback(SehBiometricsFingerprint::notify)) != 0) { |
|
|
|
|
if ((err = ss_set_notify_callback(BiometricsFingerprint::notify)) != 0) { |
|
|
|
|
LOG(ERROR) << "Can't register fingerprint module callback, error: " << err; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -371,9 +369,9 @@ bool SehBiometricsFingerprint::openHal() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SehBiometricsFingerprint::notify(const fingerprint_msg_t* msg) { |
|
|
|
|
SehBiometricsFingerprint* thisPtr = |
|
|
|
|
static_cast<SehBiometricsFingerprint*>(SehBiometricsFingerprint::getInstance()); |
|
|
|
|
void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) { |
|
|
|
|
BiometricsFingerprint* thisPtr = |
|
|
|
|
static_cast<BiometricsFingerprint*>(BiometricsFingerprint::getInstance()); |
|
|
|
|
std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex); |
|
|
|
|
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) { |
|
|
|
|
LOG(ERROR) << "Receiving callbacks before the client callback is registered."; |
|
|
|
@ -391,6 +389,10 @@ void SehBiometricsFingerprint::notify(const fingerprint_msg_t* msg) { |
|
|
|
|
getInstance()->onFingerUp(); |
|
|
|
|
} break; |
|
|
|
|
case FINGERPRINT_ACQUIRED: { |
|
|
|
|
if (msg->data.acquired.acquired_info > SEM_FINGERPRINT_EVENT_BASE) { |
|
|
|
|
thisPtr->handleEvent(msg->data.acquired.acquired_info); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
int32_t vendorCode = 0; |
|
|
|
|
FingerprintAcquiredInfo result = |
|
|
|
|
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); |
|
|
|
@ -400,20 +402,23 @@ void SehBiometricsFingerprint::notify(const fingerprint_msg_t* msg) { |
|
|
|
|
} |
|
|
|
|
} break; |
|
|
|
|
case FINGERPRINT_TEMPLATE_ENROLLING: |
|
|
|
|
#ifdef USES_PERCENTAGE_SAMPLES |
|
|
|
|
const_cast<fingerprint_msg_t*>(msg)->data.enroll.samples_remaining = |
|
|
|
|
100 - msg->data.enroll.samples_remaining; |
|
|
|
|
#endif |
|
|
|
|
if(msg->data.enroll.samples_remaining == 0) { |
|
|
|
|
set(HBM_PATH, "0"); |
|
|
|
|
#ifdef CALL_CANCEL_ON_ENROLL_COMPLETION |
|
|
|
|
thisPtr->ss_fingerprint_cancel(); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid |
|
|
|
|
<< ", gid=" << msg->data.enroll.finger.gid |
|
|
|
|
<< ", rem=" << msg->data.enroll.samples_remaining << ")"; |
|
|
|
|
if (thisPtr->mClientCallback |
|
|
|
|
if (!thisPtr->mClientCallback |
|
|
|
|
->onEnrollResult(devId, msg->data.enroll.finger.fid, |
|
|
|
|
msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining) |
|
|
|
|
.isOk()) { |
|
|
|
|
fingerprint_msg_t* newMsg = (fingerprint_msg_t*)msg; |
|
|
|
|
newMsg->data.enroll.samples_remaining = 100 - msg->data.enroll.samples_remaining; |
|
|
|
|
msg = newMsg; |
|
|
|
|
} else { |
|
|
|
|
LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback"; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
@ -467,10 +472,84 @@ void SehBiometricsFingerprint::notify(const fingerprint_msg_t* msg) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BiometricsFingerprint::handleEvent(int eventCode) { |
|
|
|
|
switch (eventCode) { |
|
|
|
|
#ifdef HAS_FINGERPRINT_GESTURES |
|
|
|
|
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN: |
|
|
|
|
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP: |
|
|
|
|
struct input_event event {}; |
|
|
|
|
int keycode = eventCode == SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP ? |
|
|
|
|
KEY_UP : KEY_DOWN; |
|
|
|
|
|
|
|
|
|
// Report the key
|
|
|
|
|
event.type = EV_KEY; |
|
|
|
|
event.code = keycode; |
|
|
|
|
event.value = 1; |
|
|
|
|
if (write(uinputFd, &event, sizeof(event)) < 0) { |
|
|
|
|
LOG(ERROR) << "Write EV_KEY to uinput node failed"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Force a flush with an EV_SYN
|
|
|
|
|
event.type = EV_SYN; |
|
|
|
|
event.code = SYN_REPORT; |
|
|
|
|
event.value = 0; |
|
|
|
|
if (write(uinputFd, &event, sizeof(event)) < 0) { |
|
|
|
|
LOG(ERROR) << "Write EV_SYN to uinput node failed"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Report the key
|
|
|
|
|
event.type = EV_KEY; |
|
|
|
|
event.code = keycode; |
|
|
|
|
event.value = 0; |
|
|
|
|
if (write(uinputFd, &event, sizeof(event)) < 0) { |
|
|
|
|
LOG(ERROR) << "Write EV_KEY to uinput node failed"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Force a flush with an EV_SYN
|
|
|
|
|
event.type = EV_SYN; |
|
|
|
|
event.code = SYN_REPORT; |
|
|
|
|
event.value = 0; |
|
|
|
|
if (write(uinputFd, &event, sizeof(event)) < 0) { |
|
|
|
|
LOG(ERROR) << "Write EV_SYN to uinput node failed"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int BiometricsFingerprint::request(int cmd, int param) { |
|
|
|
|
// TO-DO: input, output handling not implemented
|
|
|
|
|
int result = ss_fingerprint_request(cmd, nullptr, 0, nullptr, 0, param); |
|
|
|
|
LOG(INFO) << "request(cmd=" << cmd << ", param=" << param << ", result=" << result << ")"; |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int BiometricsFingerprint::waitForSensor(std::chrono::milliseconds pollWait, |
|
|
|
|
std::chrono::milliseconds timeOut) { |
|
|
|
|
int sensorStatus = SEM_SENSOR_STATUS_WORKING; |
|
|
|
|
std::chrono::milliseconds timeWaited = 0ms; |
|
|
|
|
while (sensorStatus != SEM_SENSOR_STATUS_OK) { |
|
|
|
|
if (sensorStatus == SEM_SENSOR_STATUS_CALIBRATION_ERROR |
|
|
|
|
|| sensorStatus == SEM_SENSOR_STATUS_ERROR){ |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (timeWaited >= timeOut) { |
|
|
|
|
return -2; |
|
|
|
|
} |
|
|
|
|
sensorStatus = request(FINGERPRINT_REQUEST_GET_SENSOR_STATUS, 0); |
|
|
|
|
std::this_thread::sleep_for(pollWait); |
|
|
|
|
timeWaited += pollWait; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace implementation
|
|
|
|
|
} // namespace V3_0
|
|
|
|
|
} // namespace V2_3
|
|
|
|
|
} // namespace fingerprint
|
|
|
|
|
} // namespace biometrics
|
|
|
|
|
} // namespace hardware
|
|
|
|
|
} // namespace samsung
|
|
|
|
|
} // namespace vendor
|
|
|
|
|
} // namespace android
|
|
|
|
|