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::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 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 229 int EvdevInjector::SendSynReport() { return Send(EV_SYN, SYN_REPORT, 0); } 230 231 int EvdevInjector::SendKey(uint16_t code, int32_t value) { 232 return Send(EV_KEY, code, value); 233 } 234 235 int EvdevInjector::SendAbs(uint16_t code, int32_t value) { 236 return Send(EV_ABS, code, value); 237 } 238 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 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 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 276 int EvdevInjector::Error(int code) { 277 if (!error_) { 278 error_ = code; 279 } 280 return code; 281 } 282 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 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 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