1 #include "EvdevInjector.h"
2
3 #include <errno.h>
4 #include <inttypes.h>
5 #include <linux/input.h>
6 #include <log/log.h>
7 #include <string.h>
8 #include <sys/fcntl.h>
9 #include <unistd.h>
10
11 namespace android {
12 namespace dvr {
13
Open()14 int EvdevInjector::UInput::Open() {
15 errno = 0;
16 fd_.reset(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
17 if (fd_.get() < 0) {
18 ALOGE("couldn't open uinput (r=%d errno=%d)", fd_.get(), errno);
19 }
20 return errno;
21 }
22
Close()23 int EvdevInjector::UInput::Close() {
24 errno = 0;
25 fd_.reset();
26 return errno;
27 }
28
Write(const void * buf,size_t count)29 int EvdevInjector::UInput::Write(const void* buf, size_t count) {
30 ALOGV("UInput::Write(%zu, %02X...)", count, *static_cast<const char*>(buf));
31 errno = 0;
32 ssize_t r = write(fd_.get(), buf, count);
33 if (r != static_cast<ssize_t>(count)) {
34 ALOGE("write(%zu) failed (r=%zd errno=%d)", count, r, errno);
35 }
36 return errno;
37 }
38
IoctlSetInt(int request,int value)39 int EvdevInjector::UInput::IoctlSetInt(int request, int value) {
40 ALOGV("UInput::IoctlSetInt(0x%X, 0x%X)", request, value);
41 errno = 0;
42 if (const int status = ioctl(fd_.get(), request, value)) {
43 ALOGE("ioctl(%d, 0x%X, 0x%X) failed (r=%d errno=%d)", fd_.get(), request,
44 value, status, errno);
45 }
46 return errno;
47 }
48
IoctlVoid(int request)49 int EvdevInjector::UInput::IoctlVoid(int request) {
50 ALOGV("UInput::IoctlVoid(0x%X)", request);
51 errno = 0;
52 if (const int status = ioctl(fd_.get(), request)) {
53 ALOGE("ioctl(%d, 0x%X) failed (r=%d errno=%d)", fd_.get(), request, status,
54 errno);
55 }
56 return errno;
57 }
58
Close()59 void EvdevInjector::Close() {
60 uinput_->Close();
61 state_ = State::CLOSED;
62 }
63
ConfigureBegin(const char * device_name,int16_t bustype,int16_t vendor,int16_t product,int16_t version)64 int EvdevInjector::ConfigureBegin(const char* device_name, int16_t bustype,
65 int16_t vendor, int16_t product,
66 int16_t version) {
67 ALOGV("ConfigureBegin %s 0x%04" PRIX16 " 0x%04" PRIX16 " 0x%04" PRIX16
68 " 0x%04" PRIX16 "",
69 device_name, bustype, vendor, product, version);
70 if (!device_name || strlen(device_name) >= UINPUT_MAX_NAME_SIZE) {
71 return Error(ERROR_DEVICE_NAME);
72 }
73 if (const int status = RequireState(State::NEW)) {
74 return status;
75 }
76 if (!uinput_) {
77 owned_uinput_.reset(new EvdevInjector::UInput());
78 uinput_ = owned_uinput_.get();
79 }
80 if (const int status = uinput_->Open()) {
81 // Without uinput we're dead in the water.
82 state_ = State::CLOSED;
83 return Error(status);
84 }
85 state_ = State::CONFIGURING;
86 // Initialize device setting structure.
87 memset(&uidev_, 0, sizeof(uidev_));
88 strncpy(uidev_.name, device_name, UINPUT_MAX_NAME_SIZE);
89 uidev_.id.bustype = bustype;
90 uidev_.id.vendor = vendor;
91 uidev_.id.product = product;
92 uidev_.id.version = version;
93 return 0;
94 }
95
ConfigureInputProperty(int property)96 int EvdevInjector::ConfigureInputProperty(int property) {
97 ALOGV("ConfigureInputProperty %d", property);
98 if (property < 0 || property >= INPUT_PROP_CNT) {
99 ALOGE("property 0x%X out of range [0,0x%X)", property, INPUT_PROP_CNT);
100 return Error(ERROR_PROPERTY_RANGE);
101 }
102 if (const int status = RequireState(State::CONFIGURING)) {
103 return status;
104 }
105 if (const int status = uinput_->IoctlSetInt(UI_SET_PROPBIT, property)) {
106 ALOGE("failed to set property %d", property);
107 return Error(status);
108 }
109 return 0;
110 }
111
ConfigureKey(uint16_t key)112 int EvdevInjector::ConfigureKey(uint16_t key) {
113 ALOGV("ConfigureKey 0x%02" PRIX16 "", key);
114 if (key < 0 || key >= KEY_CNT) {
115 ALOGE("key 0x%X out of range [0,0x%X)", key, KEY_CNT);
116 return Error(ERROR_KEY_RANGE);
117 }
118 if (const int status = RequireState(State::CONFIGURING)) {
119 return status;
120 }
121 if (const int status = EnableEventType(EV_KEY)) {
122 return status;
123 }
124 if (const int status = uinput_->IoctlSetInt(UI_SET_KEYBIT, key)) {
125 ALOGE("failed to enable EV_KEY 0x%02" PRIX16 "", key);
126 return Error(status);
127 }
128 return 0;
129 }
130
ConfigureAbs(uint16_t abs_type,int32_t min,int32_t max,int32_t fuzz,int32_t flat)131 int EvdevInjector::ConfigureAbs(uint16_t abs_type, int32_t min, int32_t max,
132 int32_t fuzz, int32_t flat) {
133 ALOGV("ConfigureAbs 0x%" PRIX16 " %" PRId32 " %" PRId32 " %" PRId32
134 " %" PRId32 "",
135 abs_type, min, max, fuzz, flat);
136 if (abs_type < 0 || abs_type >= ABS_CNT) {
137 ALOGE("EV_ABS type 0x%" PRIX16 " out of range [0,0x%X)", abs_type, ABS_CNT);
138 return Error(ERROR_ABS_RANGE);
139 }
140 if (const int status = RequireState(State::CONFIGURING)) {
141 return status;
142 }
143 if (const int status = EnableEventType(EV_ABS)) {
144 return status;
145 }
146 if (const int status = uinput_->IoctlSetInt(UI_SET_ABSBIT, abs_type)) {
147 ALOGE("failed to enable EV_ABS 0x%" PRIX16 "", abs_type);
148 return Error(status);
149 }
150 uidev_.absmin[abs_type] = min;
151 uidev_.absmax[abs_type] = max;
152 uidev_.absfuzz[abs_type] = fuzz;
153 uidev_.absflat[abs_type] = flat;
154 return 0;
155 }
156
ConfigureMultiTouchXY(int x0,int y0,int x1,int y1)157 int EvdevInjector::ConfigureMultiTouchXY(int x0, int y0, int x1, int y1) {
158 if (const int status = ConfigureAbs(ABS_MT_POSITION_X, x0, x1, 0, 0)) {
159 return status;
160 }
161 if (const int status = ConfigureAbs(ABS_MT_POSITION_Y, y0, y1, 0, 0)) {
162 return status;
163 }
164 return 0;
165 }
166
ConfigureAbsSlots(int slots)167 int EvdevInjector::ConfigureAbsSlots(int slots) {
168 return ConfigureAbs(ABS_MT_SLOT, 0, slots, 0, 0);
169 }
170
ConfigureEnd()171 int EvdevInjector::ConfigureEnd() {
172 ALOGV("ConfigureEnd:");
173 ALOGV(" name=\"%s\"", uidev_.name);
174 ALOGV(" id.bustype=0x%04" PRIX16, uidev_.id.bustype);
175 ALOGV(" id.vendor=0x%04" PRIX16, uidev_.id.vendor);
176 ALOGV(" id.product=0x%04" PRIX16, uidev_.id.product);
177 ALOGV(" id.version=0x%04" PRIX16, uidev_.id.version);
178 ALOGV(" ff_effects_max=%" PRIu32, uidev_.ff_effects_max);
179 for (int i = 0; i < ABS_CNT; ++i) {
180 if (uidev_.absmin[i]) {
181 ALOGV(" absmin[%d]=%" PRId32, i, uidev_.absmin[i]);
182 }
183 if (uidev_.absmax[i]) {
184 ALOGV(" absmax[%d]=%" PRId32, i, uidev_.absmax[i]);
185 }
186 if (uidev_.absfuzz[i]) {
187 ALOGV(" absfuzz[%d]=%" PRId32, i, uidev_.absfuzz[i]);
188 }
189 if (uidev_.absflat[i]) {
190 ALOGV(" absflat[%d]=%" PRId32, i, uidev_.absflat[i]);
191 }
192 }
193
194 if (const int status = RequireState(State::CONFIGURING)) {
195 return status;
196 }
197 // Write out device settings.
198 if (const int status = uinput_->Write(&uidev_, sizeof uidev_)) {
199 ALOGE("failed to write device settings");
200 return Error(status);
201 }
202 // Create device node.
203 if (const int status = uinput_->IoctlVoid(UI_DEV_CREATE)) {
204 ALOGE("failed to create device node");
205 return Error(status);
206 }
207 state_ = State::READY;
208 return 0;
209 }
210
Send(uint16_t type,uint16_t code,int32_t value)211 int EvdevInjector::Send(uint16_t type, uint16_t code, int32_t value) {
212 ALOGV("Send(0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32 ")", type, code, value);
213 if (const int status = RequireState(State::READY)) {
214 return status;
215 }
216 struct input_event event;
217 memset(&event, 0, sizeof(event));
218 event.type = type;
219 event.code = code;
220 event.value = value;
221 if (const int status = uinput_->Write(&event, sizeof(event))) {
222 ALOGE("failed to write event 0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32,
223 type, code, value);
224 return Error(status);
225 }
226 return 0;
227 }
228
SendSynReport()229 int EvdevInjector::SendSynReport() { return Send(EV_SYN, SYN_REPORT, 0); }
230
SendKey(uint16_t code,int32_t value)231 int EvdevInjector::SendKey(uint16_t code, int32_t value) {
232 return Send(EV_KEY, code, value);
233 }
234
SendAbs(uint16_t code,int32_t value)235 int EvdevInjector::SendAbs(uint16_t code, int32_t value) {
236 return Send(EV_ABS, code, value);
237 }
238
SendMultiTouchSlot(int32_t slot)239 int EvdevInjector::SendMultiTouchSlot(int32_t slot) {
240 if (latest_slot_ != slot) {
241 if (const int status = SendAbs(ABS_MT_SLOT, slot)) {
242 return status;
243 }
244 latest_slot_ = slot;
245 }
246 return 0;
247 }
248
SendMultiTouchXY(int32_t slot,int32_t id,int32_t x,int32_t y)249 int EvdevInjector::SendMultiTouchXY(int32_t slot, int32_t id, int32_t x,
250 int32_t y) {
251 if (const int status = SendMultiTouchSlot(slot)) {
252 return status;
253 }
254 if (const int status = SendAbs(ABS_MT_TRACKING_ID, id)) {
255 return status;
256 }
257 if (const int status = SendAbs(ABS_MT_POSITION_X, x)) {
258 return status;
259 }
260 if (const int status = SendAbs(ABS_MT_POSITION_Y, y)) {
261 return status;
262 }
263 return 0;
264 }
265
SendMultiTouchLift(int32_t slot)266 int EvdevInjector::SendMultiTouchLift(int32_t slot) {
267 if (const int status = SendMultiTouchSlot(slot)) {
268 return status;
269 }
270 if (const int status = SendAbs(ABS_MT_TRACKING_ID, -1)) {
271 return status;
272 }
273 return 0;
274 }
275
Error(int code)276 int EvdevInjector::Error(int code) {
277 if (!error_) {
278 error_ = code;
279 }
280 return code;
281 }
282
RequireState(State required_state)283 int EvdevInjector::RequireState(State required_state) {
284 if (error_) {
285 return error_;
286 }
287 if (state_ != required_state) {
288 ALOGE("in state %d but require state %d", static_cast<int>(state_),
289 static_cast<int>(required_state));
290 return Error(ERROR_SEQUENCING);
291 }
292 return 0;
293 }
294
EnableEventType(uint16_t type)295 int EvdevInjector::EnableEventType(uint16_t type) {
296 if (const int status = RequireState(State::CONFIGURING)) {
297 return status;
298 }
299 if (enabled_event_types_.count(type) > 0) {
300 return 0;
301 }
302 if (const int status = uinput_->IoctlSetInt(UI_SET_EVBIT, type)) {
303 ALOGE("failed to enable event type 0x%X", type);
304 return Error(status);
305 }
306 enabled_event_types_.insert(type);
307 return 0;
308 }
309
dumpInternal(String8 & result)310 void EvdevInjector::dumpInternal(String8& result) {
311 result.appendFormat("injector_state = %d\n", static_cast<int>(state_));
312 result.appendFormat("injector_error = %d\n", error_);
313 }
314
315 } // namespace dvr
316 } // namespace android
317