• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ConfigureRel(uint16_t rel_type)171 int EvdevInjector::ConfigureRel(uint16_t rel_type) {
172   ALOGV("ConfigureRel 0x%" PRIX16 "", rel_type);
173   if (rel_type < 0 || rel_type >= REL_CNT) {
174     ALOGE("EV_REL type 0x%" PRIX16 " out of range [0,0x%X)", rel_type, REL_CNT);
175     return Error(ERROR_REL_RANGE);
176   }
177   if (const int status = RequireState(State::CONFIGURING)) {
178     return status;
179   }
180   if (const int status = EnableEventType(EV_REL)) {
181     return status;
182   }
183   if (const int status = uinput_->IoctlSetInt(UI_SET_RELBIT, rel_type)) {
184     ALOGE("failed to enable EV_REL 0x%" PRIX16 "", rel_type);
185     return Error(status);
186   }
187   return 0;
188 }
189 
ConfigureEnd()190 int EvdevInjector::ConfigureEnd() {
191   ALOGV("ConfigureEnd:");
192   ALOGV("  name=\"%s\"", uidev_.name);
193   ALOGV("  id.bustype=0x%04" PRIX16, uidev_.id.bustype);
194   ALOGV("  id.vendor=0x%04" PRIX16, uidev_.id.vendor);
195   ALOGV("  id.product=0x%04" PRIX16, uidev_.id.product);
196   ALOGV("  id.version=0x%04" PRIX16, uidev_.id.version);
197   ALOGV("  ff_effects_max=%" PRIu32, uidev_.ff_effects_max);
198   for (int i = 0; i < ABS_CNT; ++i) {
199     if (uidev_.absmin[i]) {
200       ALOGV("  absmin[%d]=%" PRId32, i, uidev_.absmin[i]);
201     }
202     if (uidev_.absmax[i]) {
203       ALOGV("  absmax[%d]=%" PRId32, i, uidev_.absmax[i]);
204     }
205     if (uidev_.absfuzz[i]) {
206       ALOGV("  absfuzz[%d]=%" PRId32, i, uidev_.absfuzz[i]);
207     }
208     if (uidev_.absflat[i]) {
209       ALOGV("  absflat[%d]=%" PRId32, i, uidev_.absflat[i]);
210     }
211   }
212 
213   if (const int status = RequireState(State::CONFIGURING)) {
214     return status;
215   }
216   // Write out device settings.
217   if (const int status = uinput_->Write(&uidev_, sizeof uidev_)) {
218     ALOGE("failed to write device settings");
219     return Error(status);
220   }
221   // Create device node.
222   if (const int status = uinput_->IoctlVoid(UI_DEV_CREATE)) {
223     ALOGE("failed to create device node");
224     return Error(status);
225   }
226   state_ = State::READY;
227   return 0;
228 }
229 
Send(uint16_t type,uint16_t code,int32_t value)230 int EvdevInjector::Send(uint16_t type, uint16_t code, int32_t value) {
231   ALOGV("Send(0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32 ")", type, code, value);
232   if (const int status = RequireState(State::READY)) {
233     return status;
234   }
235   struct input_event event;
236   memset(&event, 0, sizeof(event));
237   event.type = type;
238   event.code = code;
239   event.value = value;
240   if (const int status = uinput_->Write(&event, sizeof(event))) {
241     ALOGE("failed to write event 0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32,
242           type, code, value);
243     return Error(status);
244   }
245   return 0;
246 }
247 
SendSynReport()248 int EvdevInjector::SendSynReport() { return Send(EV_SYN, SYN_REPORT, 0); }
249 
SendKey(uint16_t code,int32_t value)250 int EvdevInjector::SendKey(uint16_t code, int32_t value) {
251   return Send(EV_KEY, code, value);
252 }
253 
SendAbs(uint16_t code,int32_t value)254 int EvdevInjector::SendAbs(uint16_t code, int32_t value) {
255   return Send(EV_ABS, code, value);
256 }
257 
SendRel(uint16_t code,int32_t value)258 int EvdevInjector::SendRel(uint16_t code, int32_t value) {
259   return Send(EV_REL, code, value);
260 }
261 
SendMultiTouchSlot(int32_t slot)262 int EvdevInjector::SendMultiTouchSlot(int32_t slot) {
263   if (latest_slot_ != slot) {
264     if (const int status = SendAbs(ABS_MT_SLOT, slot)) {
265       return status;
266     }
267     latest_slot_ = slot;
268   }
269   return 0;
270 }
271 
SendMultiTouchXY(int32_t slot,int32_t id,int32_t x,int32_t y)272 int EvdevInjector::SendMultiTouchXY(int32_t slot, int32_t id, int32_t x,
273                                     int32_t y) {
274   if (const int status = SendMultiTouchSlot(slot)) {
275     return status;
276   }
277   if (const int status = SendAbs(ABS_MT_TRACKING_ID, id)) {
278     return status;
279   }
280   if (const int status = SendAbs(ABS_MT_POSITION_X, x)) {
281     return status;
282   }
283   if (const int status = SendAbs(ABS_MT_POSITION_Y, y)) {
284     return status;
285   }
286   return 0;
287 }
288 
SendMultiTouchLift(int32_t slot)289 int EvdevInjector::SendMultiTouchLift(int32_t slot) {
290   if (const int status = SendMultiTouchSlot(slot)) {
291     return status;
292   }
293   if (const int status = SendAbs(ABS_MT_TRACKING_ID, -1)) {
294     return status;
295   }
296   return 0;
297 }
298 
Error(int code)299 int EvdevInjector::Error(int code) {
300   if (!error_) {
301     error_ = code;
302   }
303   return code;
304 }
305 
RequireState(State required_state)306 int EvdevInjector::RequireState(State required_state) {
307   if (error_) {
308     return error_;
309   }
310   if (state_ != required_state) {
311     ALOGE("in state %d but require state %d", static_cast<int>(state_),
312           static_cast<int>(required_state));
313     return Error(ERROR_SEQUENCING);
314   }
315   return 0;
316 }
317 
EnableEventType(uint16_t type)318 int EvdevInjector::EnableEventType(uint16_t type) {
319   if (const int status = RequireState(State::CONFIGURING)) {
320     return status;
321   }
322   if (enabled_event_types_.count(type) > 0) {
323     return 0;
324   }
325   if (const int status = uinput_->IoctlSetInt(UI_SET_EVBIT, type)) {
326     ALOGE("failed to enable event type 0x%X", type);
327     return Error(status);
328   }
329   enabled_event_types_.insert(type);
330   return 0;
331 }
332 
dumpInternal(String8 & result)333 void EvdevInjector::dumpInternal(String8& result) {
334   result.appendFormat("injector_state = %d\n", static_cast<int>(state_));
335   result.appendFormat("injector_error = %d\n", error_);
336 }
337 
338 }  // namespace dvr
339 }  // namespace android
340