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 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 23 int EvdevInjector::UInput::Close() { 24 errno = 0; 25 fd_.reset(); 26 return errno; 27 } 28 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 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 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 59 void EvdevInjector::Close() { 60 uinput_->Close(); 61 state_ = State::CLOSED; 62 } 63 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 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 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 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 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 167 int EvdevInjector::ConfigureAbsSlots(int slots) { 168 return ConfigureAbs(ABS_MT_SLOT, 0, slots, 0, 0); 169 } 170 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 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 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 248 int EvdevInjector::SendSynReport() { return Send(EV_SYN, SYN_REPORT, 0); } 249 250 int EvdevInjector::SendKey(uint16_t code, int32_t value) { 251 return Send(EV_KEY, code, value); 252 } 253 254 int EvdevInjector::SendAbs(uint16_t code, int32_t value) { 255 return Send(EV_ABS, code, value); 256 } 257 258 int EvdevInjector::SendRel(uint16_t code, int32_t value) { 259 return Send(EV_REL, code, value); 260 } 261 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 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 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 299 int EvdevInjector::Error(int code) { 300 if (!error_) { 301 error_ = code; 302 } 303 return code; 304 } 305 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 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 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