From b3156205e12de5ac3fa523a3894b9c2b26b4dc4a Mon Sep 17 00:00:00 2001 From: Tim Zimmermann Date: Mon, 29 Nov 2021 20:51:07 +0100 Subject: [PATCH] fingerprint: implement gestures Change-Id: I66dfe09e569fcaea295649cce69350f4d4003eb4 --- hidl/fingerprint/Android.mk | 4 + hidl/fingerprint/BiometricsFingerprint.cpp | 93 +++++++++++++++++++ hidl/fingerprint/BiometricsFingerprint.h | 8 ++ ...metrics.fingerprint@2.3-service.samsung.rc | 2 +- 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/hidl/fingerprint/Android.mk b/hidl/fingerprint/Android.mk index db4650a3..2f0d1e3a 100644 --- a/hidl/fingerprint/Android.mk +++ b/hidl/fingerprint/Android.mk @@ -44,6 +44,10 @@ ifeq ($(TARGET_SEC_FP_CALL_CANCEL_ON_ENROLL_COMPLETION),true) LOCAL_CFLAGS += -DCALL_CANCEL_ON_ENROLL_COMPLETION endif +ifeq ($(TARGET_SEC_FP_HAS_FINGERPRINT_GESTURES),true) + LOCAL_CFLAGS += -DHAS_FINGERPRINT_GESTURES +endif + LOCAL_MODULE := android.hardware.biometrics.fingerprint@2.3-service.samsung LOCAL_INIT_RC := android.hardware.biometrics.fingerprint@2.3-service.samsung.rc LOCAL_VINTF_FRAGMENTS := android.hardware.biometrics.fingerprint@2.3-service.samsung.xml diff --git a/hidl/fingerprint/BiometricsFingerprint.cpp b/hidl/fingerprint/BiometricsFingerprint.cpp index b112cd12..256a36bd 100644 --- a/hidl/fingerprint/BiometricsFingerprint.cpp +++ b/hidl/fingerprint/BiometricsFingerprint.cpp @@ -28,6 +28,10 @@ #include #include +#ifdef HAS_FINGERPRINT_GESTURES +#include +#endif + namespace android { namespace hardware { namespace biometrics { @@ -49,6 +53,42 @@ BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) { mIsUdfps = !!in; 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 } BiometricsFingerprint::~BiometricsFingerprint() { @@ -310,6 +350,10 @@ void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) { } } 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); @@ -387,6 +431,55 @@ void BiometricsFingerprint::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); diff --git a/hidl/fingerprint/BiometricsFingerprint.h b/hidl/fingerprint/BiometricsFingerprint.h index 9abb3b33..9e2e3ce1 100644 --- a/hidl/fingerprint/BiometricsFingerprint.h +++ b/hidl/fingerprint/BiometricsFingerprint.h @@ -20,6 +20,10 @@ #include #include +#ifdef HAS_FINGERPRINT_GESTURES +#include +#endif + #include #include #include @@ -79,6 +83,7 @@ struct BiometricsFingerprint : public IBiometricsFingerprint { int waitForSensor(std::chrono::milliseconds pollWait, std::chrono::milliseconds timeOut); static void notify( const fingerprint_msg_t* msg); /* Static callback for legacy HAL implementation */ + void handleEvent(int eventCode); static Return ErrorFilter(int32_t error); static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode); static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode); @@ -87,6 +92,9 @@ struct BiometricsFingerprint : public IBiometricsFingerprint { std::mutex mClientCallbackMutex; sp mClientCallback; bool mIsUdfps; +#ifdef HAS_FINGERPRINT_GESTURES + int uinputFd; +#endif int (*ss_fingerprint_close)(); int (*ss_fingerprint_open)(const char* id); diff --git a/hidl/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.samsung.rc b/hidl/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.samsung.rc index a011f8a2..dafed7ca 100644 --- a/hidl/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.samsung.rc +++ b/hidl/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.samsung.rc @@ -4,5 +4,5 @@ service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2. # /data is mounted. class late_start user system - group system input + group system input uhid writepid /dev/cpuset/system-background/tasks