-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUdfpsHandler.cpp
135 lines (111 loc) · 3.41 KB
/
UdfpsHandler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* Copyright (C) 2022 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "UdfpsHandler.xiaomi_kona"
#include "UdfpsHandler.h"
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <fcntl.h>
#include <poll.h>
#include <thread>
#include <unistd.h>
#define COMMAND_NIT 10
#define PARAM_NIT_FOD 1
#define PARAM_NIT_NONE 0
#define FOD_STATUS_ON 1
#define FOD_STATUS_OFF -1
#define TOUCH_DEV_PATH "/dev/xiaomi-touch"
#define TOUCH_FOD_ENABLE 10
#define TOUCH_MAGIC 0x5400
#define TOUCH_IOC_SETMODE TOUCH_MAGIC + 0
static const char* kFodUiPaths[] = {
"/sys/devices/platform/soc/soc:qcom,dsi-display-primary/fod_ui",
"/sys/devices/platform/soc/soc:qcom,dsi-display/fod_ui",
};
static bool readBool(int fd) {
char c;
int rc;
rc = lseek(fd, 0, SEEK_SET);
if (rc) {
LOG(ERROR) << "failed to seek fd, err: " << rc;
return false;
}
rc = read(fd, &c, sizeof(char));
if (rc != 1) {
LOG(ERROR) << "failed to read bool from fd, err: " << rc;
return false;
}
return c != '0';
}
class XiaomiKonaUdfpsHandler : public UdfpsHandler {
public:
void init(fingerprint_device_t *device) {
mDevice = device;
touch_fd_ = android::base::unique_fd(open(TOUCH_DEV_PATH, O_RDWR));
std::thread([this]() {
int fd;
for (auto& path : kFodUiPaths) {
fd = open(path, O_RDONLY);
if (fd >= 0) {
break;
}
}
if (fd < 0) {
LOG(ERROR) << "failed to open fd, err: " << fd;
return;
}
struct pollfd fodUiPoll = {
.fd = fd,
.events = POLLERR | POLLPRI,
.revents = 0,
};
while (true) {
int rc = poll(&fodUiPoll, 1, -1);
if (rc < 0) {
LOG(ERROR) << "failed to poll fd, err: " << rc;
continue;
}
mDevice->extCmd(mDevice, COMMAND_NIT,
readBool(fd) ? PARAM_NIT_FOD : PARAM_NIT_NONE);
}
}).detach();
}
void onFingerDown(uint32_t /*x*/, uint32_t /*y*/, float /*minor*/, float /*major*/) {
// nothing
}
void onFingerUp() {
// nothing
}
void onAcquired(int32_t result, int32_t vendorCode) {
if (result == FINGERPRINT_ACQUIRED_GOOD) {
int arg[2] = {TOUCH_FOD_ENABLE, FOD_STATUS_OFF};
ioctl(touch_fd_.get(), TOUCH_IOC_SETMODE, &arg);
} else if (vendorCode == 21 || vendorCode == 23) {
/*
* vendorCode = 21 waiting for fingerprint authentication
* vendorCode = 23 waiting for fingerprint enroll
*/
int arg[2] = {TOUCH_FOD_ENABLE, FOD_STATUS_ON};
ioctl(touch_fd_.get(), TOUCH_IOC_SETMODE, &arg);
}
}
void cancel() {
int arg[2] = {TOUCH_FOD_ENABLE, FOD_STATUS_OFF};
ioctl(touch_fd_.get(), TOUCH_IOC_SETMODE, &arg);
}
private:
fingerprint_device_t *mDevice;
android::base::unique_fd touch_fd_;
};
static UdfpsHandler* create() {
return new XiaomiKonaUdfpsHandler();
}
static void destroy(UdfpsHandler* handler) {
delete handler;
}
extern "C" UdfpsHandlerFactory UDFPS_HANDLER_FACTORY = {
.create = create,
.destroy = destroy,
};