blob: 8c4834557498f6642f7d3550308cc3fea4162ef6 [file] [log] [blame]
Tim Kilbourn73475a42015-02-13 10:35:20 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputHub"
Tim Kilbourn3186e7b2015-04-16 15:32:08 -070018//#define LOG_NDEBUG 0
19
20// Enables debug output for hasKeyInRange
21#define DEBUG_KEY_RANGE 0
Tim Kilbourn73475a42015-02-13 10:35:20 -080022
23#include <dirent.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <string.h>
27#include <sys/capability.h>
28#include <sys/epoll.h>
29#include <sys/eventfd.h>
30#include <sys/inotify.h>
31#include <sys/ioctl.h>
32#include <sys/stat.h>
33#include <sys/types.h>
34#include <sys/utsname.h>
35#include <unistd.h>
36
37#include <vector>
38
39#include "InputHub.h"
Tim Kilbourn3186e7b2015-04-16 15:32:08 -070040#include "InputHub-internal.h"
Tim Kilbourn73475a42015-02-13 10:35:20 -080041
42#include <android/input.h>
43#include <hardware_legacy/power.h>
44#include <linux/input.h>
45
46#include <utils/Log.h>
47
48namespace android {
49
50static const char WAKE_LOCK_ID[] = "KeyEvents";
51static const int NO_TIMEOUT = -1;
52static const int EPOLL_MAX_EVENTS = 16;
53static const int INPUT_MAX_EVENTS = 128;
54
55static constexpr bool testBit(int bit, const uint8_t arr[]) {
56 return arr[bit / 8] & (1 << (bit % 8));
57}
58
59static constexpr size_t sizeofBitArray(size_t bits) {
60 return (bits + 7) / 8;
61}
62
Tim Kilbourn3186e7b2015-04-16 15:32:08 -070063namespace internal {
64
65#if DEBUG_KEY_RANGE
66static const char* bitstrings[16] = {
67 "0000", "0001", "0010", "0011",
68 "0100", "0101", "0110", "0111",
69 "1000", "1001", "1010", "1011",
70 "1100", "1101", "1110", "1111",
71};
72#endif
73
74bool testBitInRange(const uint8_t arr[], size_t start, size_t end) {
75#if DEBUG_KEY_RANGE
76 ALOGD("testBitInRange(%d, %d)", start, end);
77#endif
78 // Invalid range! This is nonsense; just say no.
79 if (end <= start) return false;
80
81 // Find byte array indices. The end is not included in the range, nor is
82 // endIndex. Round up for endIndex.
83 size_t startIndex = start / 8;
84 size_t endIndex = (end + 7) / 8;
85#if DEBUG_KEY_RANGE
86 ALOGD("startIndex=%d, endIndex=%d", startIndex, endIndex);
87#endif
88 for (size_t i = startIndex; i < endIndex; ++i) {
89 uint8_t bits = arr[i];
90 uint8_t mask = 0xff;
91#if DEBUG_KEY_RANGE
92 ALOGD("block %04d: %s%s", i, bitstrings[bits >> 4], bitstrings[bits & 0x0f]);
93#endif
94 if (bits) {
95 // Mask off bits before our start bit
96 if (i == startIndex) {
97 mask &= 0xff << (start % 8);
98 }
99 // Mask off bits after our end bit
100 if (i == endIndex - 1 && (end % 8)) {
101 mask &= 0xff >> (8 - (end % 8));
102 }
103#if DEBUG_KEY_RANGE
104 ALOGD("mask: %s%s", bitstrings[mask >> 4], bitstrings[mask & 0x0f]);
105#endif
106 // Test the index against the mask
107 if (bits & mask) return true;
108 }
109 }
110 return false;
111}
112} // namespace internal
113
Tim Kilbourn73475a42015-02-13 10:35:20 -0800114static void getLinuxRelease(int* major, int* minor) {
115 struct utsname info;
116 if (uname(&info) || sscanf(info.release, "%d.%d", major, minor) <= 0) {
117 *major = 0, *minor = 0;
118 ALOGE("Could not get linux version: %s", strerror(errno));
119 }
120}
121
122static bool processHasCapability(int capability) {
123 LOG_ALWAYS_FATAL_IF(!cap_valid(capability), "invalid linux capability: %d", capability);
124 struct __user_cap_header_struct cap_header_data;
125 struct __user_cap_data_struct cap_data_data[2];
126 cap_user_header_t caphdr = &cap_header_data;
127 cap_user_data_t capdata = cap_data_data;
128 caphdr->pid = 0;
129 caphdr->version = _LINUX_CAPABILITY_VERSION_3;
130 LOG_ALWAYS_FATAL_IF(capget(caphdr, capdata) != 0,
131 "Could not get process capabilities. errno=%d", errno);
Tim Kilbourn73475a42015-02-13 10:35:20 -0800132 int idx = CAP_TO_INDEX(capability);
133 return capdata[idx].effective & CAP_TO_MASK(capability);
134}
135
136class EvdevDeviceNode : public InputDeviceNode {
137public:
138 static EvdevDeviceNode* openDeviceNode(const std::string& path);
139
140 virtual ~EvdevDeviceNode() {
141 ALOGV("closing %s (fd=%d)", mPath.c_str(), mFd);
142 if (mFd >= 0) {
143 ::close(mFd);
144 }
145 }
146
147 virtual int getFd() const { return mFd; }
148 virtual const std::string& getPath() const override { return mPath; }
149 virtual const std::string& getName() const override { return mName; }
150 virtual const std::string& getLocation() const override { return mLocation; }
151 virtual const std::string& getUniqueId() const override { return mUniqueId; }
152
153 virtual uint16_t getBusType() const override { return mBusType; }
154 virtual uint16_t getVendorId() const override { return mVendorId; }
155 virtual uint16_t getProductId() const override { return mProductId; }
156 virtual uint16_t getVersion() const override { return mVersion; }
157
158 virtual bool hasKey(int32_t key) const override;
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700159 virtual bool hasKeyInRange(int32_t start, int32_t end) const override;
160 virtual bool hasRelativeAxis(int32_t axis) const override;
161 virtual bool hasAbsoluteAxis(int32_t axis) const override;
162 virtual bool hasSwitch(int32_t sw) const override;
163 virtual bool hasForceFeedback(int32_t ff) const override;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800164 virtual bool hasInputProperty(int property) const override;
165
166 virtual int32_t getKeyState(int32_t key) const override;
167 virtual int32_t getSwitchState(int32_t sw) const override;
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700168 virtual const AbsoluteAxisInfo* getAbsoluteAxisInfo(int32_t axis) const override;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800169 virtual status_t getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const override;
170
171 virtual void vibrate(nsecs_t duration) override;
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700172 virtual void cancelVibrate() override;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800173
174 virtual void disableDriverKeyRepeat() override;
175
176private:
177 EvdevDeviceNode(const std::string& path, int fd) :
178 mFd(fd), mPath(path) {}
179
180 status_t queryProperties();
181 void queryAxisInfo();
182
183 int mFd;
184 std::string mPath;
185
186 std::string mName;
187 std::string mLocation;
188 std::string mUniqueId;
189
190 uint16_t mBusType;
191 uint16_t mVendorId;
192 uint16_t mProductId;
193 uint16_t mVersion;
194
195 uint8_t mKeyBitmask[KEY_CNT / 8];
196 uint8_t mAbsBitmask[ABS_CNT / 8];
197 uint8_t mRelBitmask[REL_CNT / 8];
198 uint8_t mSwBitmask[SW_CNT / 8];
199 uint8_t mLedBitmask[LED_CNT / 8];
200 uint8_t mFfBitmask[FF_CNT / 8];
201 uint8_t mPropBitmask[INPUT_PROP_CNT / 8];
202
203 std::unordered_map<uint32_t, std::unique_ptr<AbsoluteAxisInfo>> mAbsInfo;
204
205 bool mFfEffectPlaying = false;
206 int16_t mFfEffectId = -1;
207};
208
209EvdevDeviceNode* EvdevDeviceNode::openDeviceNode(const std::string& path) {
210 auto fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC));
211 if (fd < 0) {
212 ALOGE("could not open evdev device %s. err=%d", path.c_str(), errno);
213 return nullptr;
214 }
215
216 // Tell the kernel that we want to use the monotonic clock for reporting
217 // timestamps associated with input events. This is important because the
218 // input system uses the timestamps extensively and assumes they were
219 // recorded using the monotonic clock.
220 //
221 // The EVIOCSCLOCKID ioctl was introduced in Linux 3.4.
222 int clockId = CLOCK_MONOTONIC;
223 if (TEMP_FAILURE_RETRY(ioctl(fd, EVIOCSCLOCKID, &clockId)) < 0) {
224 ALOGW("Could not set input clock id to CLOCK_MONOTONIC. errno=%d", errno);
225 }
226
227 auto node = new EvdevDeviceNode(path, fd);
228 status_t ret = node->queryProperties();
229 if (ret != OK) {
230 ALOGE("could not open evdev device %s: failed to read properties. errno=%d",
231 path.c_str(), ret);
232 delete node;
233 return nullptr;
234 }
235 return node;
236}
237
238status_t EvdevDeviceNode::queryProperties() {
239 char buffer[80];
240
241 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGNAME(sizeof(buffer) - 1), buffer)) < 1) {
242 ALOGV("could not get device name for %s.", mPath.c_str());
243 } else {
244 buffer[sizeof(buffer) - 1] = '\0';
245 mName = buffer;
246 }
247
248 int driverVersion;
249 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGVERSION, &driverVersion))) {
250 ALOGE("could not get driver version for %s. err=%d", mPath.c_str(), errno);
251 return -errno;
252 }
253
254 struct input_id inputId;
255 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGID, &inputId))) {
256 ALOGE("could not get device input id for %s. err=%d", mPath.c_str(), errno);
257 return -errno;
258 }
259 mBusType = inputId.bustype;
260 mVendorId = inputId.vendor;
261 mProductId = inputId.product;
262 mVersion = inputId.version;
263
264 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPHYS(sizeof(buffer) - 1), buffer)) < 1) {
265 ALOGV("could not get location for %s.", mPath.c_str());
266 } else {
267 buffer[sizeof(buffer) - 1] = '\0';
268 mLocation = buffer;
269 }
270
271 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGUNIQ(sizeof(buffer) - 1), buffer)) < 1) {
272 ALOGV("could not get unique id for %s.", mPath.c_str());
273 } else {
274 buffer[sizeof(buffer) - 1] = '\0';
275 mUniqueId = buffer;
276 }
277
278 ALOGV("add device %s", mPath.c_str());
279 ALOGV(" bus: %04x\n"
280 " vendor: %04x\n"
281 " product: %04x\n"
282 " version: %04x\n",
283 mBusType, mVendorId, mProductId, mVersion);
284 ALOGV(" name: \"%s\"\n"
285 " location: \"%s\"\n"
286 " unique_id: \"%s\"\n"
287 " descriptor: (TODO)\n"
288 " driver: v%d.%d.%d",
289 mName.c_str(), mLocation.c_str(), mUniqueId.c_str(),
290 driverVersion >> 16, (driverVersion >> 8) & 0xff, (driverVersion >> 16) & 0xff);
291
292 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_KEY, sizeof(mKeyBitmask)), mKeyBitmask));
293 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_ABS, sizeof(mAbsBitmask)), mAbsBitmask));
294 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_REL, sizeof(mRelBitmask)), mRelBitmask));
295 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_SW, sizeof(mSwBitmask)), mSwBitmask));
296 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_LED, sizeof(mLedBitmask)), mLedBitmask));
297 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_FF, sizeof(mFfBitmask)), mFfBitmask));
298 TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPROP(sizeof(mPropBitmask)), mPropBitmask));
299
300 queryAxisInfo();
301
302 return OK;
303}
304
305void EvdevDeviceNode::queryAxisInfo() {
306 for (int32_t axis = 0; axis < ABS_MAX; ++axis) {
307 if (testBit(axis, mAbsBitmask)) {
308 struct input_absinfo info;
309 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGABS(axis), &info))) {
310 ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
311 axis, mPath.c_str(), mFd, errno);
312 continue;
313 }
314
315 mAbsInfo[axis] = std::unique_ptr<AbsoluteAxisInfo>(new AbsoluteAxisInfo{
316 .minValue = info.minimum,
317 .maxValue = info.maximum,
318 .flat = info.flat,
319 .fuzz = info.fuzz,
320 .resolution = info.resolution
321 });
322 }
323 }
324}
325
326bool EvdevDeviceNode::hasKey(int32_t key) const {
327 if (key >= 0 && key <= KEY_MAX) {
328 return testBit(key, mKeyBitmask);
329 }
330 return false;
331}
332
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700333bool EvdevDeviceNode::hasKeyInRange(int32_t startKey, int32_t endKey) const {
334 return internal::testBitInRange(mKeyBitmask, startKey, endKey);
335}
336
Tim Kilbourn73475a42015-02-13 10:35:20 -0800337bool EvdevDeviceNode::hasRelativeAxis(int axis) const {
338 if (axis >= 0 && axis <= REL_MAX) {
339 return testBit(axis, mRelBitmask);
340 }
341 return false;
342}
343
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700344bool EvdevDeviceNode::hasAbsoluteAxis(int axis) const {
345 if (axis >= 0 && axis <= ABS_MAX) {
346 return getAbsoluteAxisInfo(axis) != nullptr;
347 }
348 return false;
349}
350
Tim Kilbourn73475a42015-02-13 10:35:20 -0800351const AbsoluteAxisInfo* EvdevDeviceNode::getAbsoluteAxisInfo(int32_t axis) const {
352 if (axis < 0 || axis > ABS_MAX) {
353 return nullptr;
354 }
355
356 const auto absInfo = mAbsInfo.find(axis);
357 if (absInfo != mAbsInfo.end()) {
358 return absInfo->second.get();
359 }
360 return nullptr;
361}
362
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700363bool EvdevDeviceNode::hasSwitch(int32_t sw) const {
364 if (sw >= 0 && sw <= SW_MAX) {
365 return testBit(sw, mSwBitmask);
366 }
367 return false;
368}
369
370bool EvdevDeviceNode::hasForceFeedback(int32_t ff) const {
371 if (ff >= 0 && ff <= FF_MAX) {
372 return testBit(ff, mFfBitmask);
373 }
374 return false;
375}
376
Tim Kilbourn73475a42015-02-13 10:35:20 -0800377bool EvdevDeviceNode::hasInputProperty(int property) const {
378 if (property >= 0 && property <= INPUT_PROP_MAX) {
379 return testBit(property, mPropBitmask);
380 }
381 return false;
382}
383
384int32_t EvdevDeviceNode::getKeyState(int32_t key) const {
385 if (key >= 0 && key <= KEY_MAX) {
386 if (testBit(key, mKeyBitmask)) {
387 uint8_t keyState[sizeofBitArray(KEY_CNT)];
388 memset(keyState, 0, sizeof(keyState));
389 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGKEY(sizeof(keyState)), keyState)) >= 0) {
390 return testBit(key, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
391 }
392 }
393 }
394 return AKEY_STATE_UNKNOWN;
395}
396
397int32_t EvdevDeviceNode::getSwitchState(int32_t sw) const {
398 if (sw >= 0 && sw <= SW_MAX) {
399 if (testBit(sw, mSwBitmask)) {
400 uint8_t swState[sizeofBitArray(SW_CNT)];
401 memset(swState, 0, sizeof(swState));
402 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGSW(sizeof(swState)), swState)) >= 0) {
403 return testBit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
404 }
405 }
406 }
407 return AKEY_STATE_UNKNOWN;
408}
409
410status_t EvdevDeviceNode::getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const {
411 *outValue = 0;
412
413 if (axis >= 0 && axis <= ABS_MAX) {
414 if (testBit(axis, mAbsBitmask)) {
415 struct input_absinfo info;
416 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGABS(axis), &info))) {
417 ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
418 axis, mPath.c_str(), mFd, errno);
419 return -errno;
420 }
421
422 *outValue = info.value;
423 return OK;
424 }
425 }
426 return -1;
427}
428
429void EvdevDeviceNode::vibrate(nsecs_t duration) {
430 ff_effect effect{};
431 effect.type = FF_RUMBLE;
432 effect.id = mFfEffectId;
433 effect.u.rumble.strong_magnitude = 0xc000;
434 effect.u.rumble.weak_magnitude = 0xc000;
435 effect.replay.length = (duration + 999'999LL) / 1'000'000LL;
436 effect.replay.delay = 0;
437 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCSFF, &effect))) {
438 ALOGW("Could not upload force feedback effect to device %s due to error %d.",
439 mPath.c_str(), errno);
440 return;
441 }
442 mFfEffectId = effect.id;
443
444 struct input_event ev{};
445 ev.type = EV_FF;
446 ev.code = mFfEffectId;
447 ev.value = 1;
448 size_t written = TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(ev)));
449 if (written != sizeof(ev)) {
450 ALOGW("Could not start force feedback effect on device %s due to error %d.",
451 mPath.c_str(), errno);
452 return;
453 }
454 mFfEffectPlaying = true;
455}
456
Tim Kilbourn3186e7b2015-04-16 15:32:08 -0700457void EvdevDeviceNode::cancelVibrate() {
Tim Kilbourn73475a42015-02-13 10:35:20 -0800458 if (mFfEffectPlaying) {
459 mFfEffectPlaying = false;
460
461 struct input_event ev{};
462 ev.type = EV_FF;
463 ev.code = mFfEffectId;
464 ev.value = 0;
465 size_t written = TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(ev)));
466 if (written != sizeof(ev)) {
467 ALOGW("Could not stop force feedback effect on device %s due to error %d.",
468 mPath.c_str(), errno);
469 return;
470 }
471 }
472}
473
474void EvdevDeviceNode::disableDriverKeyRepeat() {
475 unsigned int repeatRate[] = {0, 0};
476 if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCSREP, repeatRate))) {
477 ALOGW("Unable to disable kernel key repeat for %s due to error %d.",
478 mPath.c_str(), errno);
479 }
480}
481
Tim Kilbournc929d252015-04-29 13:50:17 -0700482InputHub::InputHub(const std::shared_ptr<InputCallbackInterface>& cb) :
Tim Kilbourn73475a42015-02-13 10:35:20 -0800483 mInputCallback(cb) {
484 // Determine the type of suspend blocking we can do on this device. There
485 // are 3 options, in decreasing order of preference:
486 // 1) EPOLLWAKEUP: introduced in Linux kernel 3.5, this flag can be set on
487 // an epoll event to indicate that a wake lock should be held from the
488 // time an fd has data until the next epoll_wait (or the epoll fd is
489 // closed).
490 // 2) EVIOCSSUSPENDBLOCK: introduced into the Android kernel's evdev
491 // driver, this ioctl blocks suspend while the event queue for the fd is
492 // not empty. This was never accepted into the mainline kernel, and it was
493 // replaced by EPOLLWAKEUP.
494 // 3) explicit wake locks: use acquire_wake_lock to manage suspend
495 // blocking explicitly in the InputHub code.
496 //
497 // (1) can be checked by simply observing the Linux kernel version. (2)
498 // requires an fd from an evdev node, which cannot be done in the InputHub
499 // constructor. So we assume (3) unless (1) is true, and we can verify
500 // whether (2) is true once we have an evdev fd (and we're not in (1)).
501 int major, minor;
502 getLinuxRelease(&major, &minor);
503 if (major > 3 || (major == 3 && minor >= 5)) {
504 ALOGI("Using EPOLLWAKEUP to block suspend while processing input events.");
505 mWakeupMechanism = WakeMechanism::EPOLL_WAKEUP;
506 mNeedToCheckSuspendBlockIoctl = false;
507 }
508 if (manageWakeLocks()) {
509 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
510 }
511
512 // epoll_create argument is ignored, but it must be > 0.
513 mEpollFd = epoll_create(1);
514 LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
515
516 mINotifyFd = inotify_init();
517 LOG_ALWAYS_FATAL_IF(mINotifyFd < 0, "Could not create inotify instance. errno=%d", errno);
518
519 struct epoll_event eventItem;
520 memset(&eventItem, 0, sizeof(eventItem));
521 eventItem.events = EPOLLIN;
522 if (mWakeupMechanism == WakeMechanism::EPOLL_WAKEUP) {
523 eventItem.events |= EPOLLWAKEUP;
524 }
525 eventItem.data.u32 = mINotifyFd;
526 int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
527 LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno);
528
529 int wakeFds[2];
530 result = pipe(wakeFds);
531 LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno);
532
533 mWakeEventFd = eventfd(0, EFD_NONBLOCK);
534 LOG_ALWAYS_FATAL_IF(mWakeEventFd == -1, "Could not create wake event fd. errno=%d", errno);
535
536 eventItem.data.u32 = mWakeEventFd;
537 result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, &eventItem);
538 LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance. errno=%d", errno);
539}
540
541InputHub::~InputHub() {
542 ::close(mEpollFd);
543 ::close(mINotifyFd);
544 ::close(mWakeEventFd);
545
546 if (manageWakeLocks()) {
547 release_wake_lock(WAKE_LOCK_ID);
548 }
549}
550
551status_t InputHub::registerDevicePath(const std::string& path) {
552 ALOGV("registering device path %s", path.c_str());
553 int wd = inotify_add_watch(mINotifyFd, path.c_str(), IN_DELETE | IN_CREATE);
554 if (wd < 0) {
555 ALOGE("Could not add %s to INotify watch. errno=%d", path.c_str(), errno);
556 return -errno;
557 }
558 mWatchedPaths[wd] = path;
559 scanDir(path);
560 return OK;
561}
562
563status_t InputHub::unregisterDevicePath(const std::string& path) {
564 int wd = -1;
565 for (auto pair : mWatchedPaths) {
566 if (pair.second == path) {
567 wd = pair.first;
568 break;
569 }
570 }
571
572 if (wd == -1) {
573 return BAD_VALUE;
574 }
575 mWatchedPaths.erase(wd);
576 if (inotify_rm_watch(mINotifyFd, wd) != 0) {
577 return -errno;
578 }
579 return OK;
580}
581
582status_t InputHub::poll() {
583 bool deviceChange = false;
584
585 if (manageWakeLocks()) {
586 // Mind the wake lock dance!
587 // If we're relying on wake locks, we hold a wake lock at all times
588 // except during epoll_wait(). This works due to some subtle
589 // choreography. When a device driver has pending (unread) events, it
590 // acquires a kernel wake lock. However, once the last pending event
591 // has been read, the device driver will release the kernel wake lock.
592 // To prevent the system from going to sleep when this happens, the
593 // InputHub holds onto its own user wake lock while the client is
594 // processing events. Thus the system can only sleep if there are no
595 // events pending or currently being processed.
596 release_wake_lock(WAKE_LOCK_ID);
597 }
598
599 struct epoll_event pendingEventItems[EPOLL_MAX_EVENTS];
600 int pollResult = epoll_wait(mEpollFd, pendingEventItems, EPOLL_MAX_EVENTS, NO_TIMEOUT);
601
602 if (manageWakeLocks()) {
603 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
604 }
605
606 if (pollResult == 0) {
607 ALOGW("epoll_wait should not return 0 with no timeout");
608 return UNKNOWN_ERROR;
609 }
610 if (pollResult < 0) {
611 // An error occurred. Return even if it's EINTR, and let the caller
612 // restart the poll.
613 ALOGE("epoll_wait returned with errno=%d", errno);
614 return -errno;
615 }
616
617 // pollResult > 0: there are events to process
618 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
619 std::vector<int> removedDeviceFds;
620 int inputFd = -1;
621 std::shared_ptr<InputDeviceNode> deviceNode;
622 for (int i = 0; i < pollResult; ++i) {
623 const struct epoll_event& eventItem = pendingEventItems[i];
624
625 int dataFd = static_cast<int>(eventItem.data.u32);
626 if (dataFd == mINotifyFd) {
627 if (eventItem.events & EPOLLIN) {
628 deviceChange = true;
629 } else {
630 ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
631 }
632 continue;
633 }
634
635 if (dataFd == mWakeEventFd) {
636 if (eventItem.events & EPOLLIN) {
637 ALOGV("awoken after wake()");
638 uint64_t u;
639 ssize_t nRead = TEMP_FAILURE_RETRY(read(mWakeEventFd, &u, sizeof(uint64_t)));
640 if (nRead != sizeof(uint64_t)) {
641 ALOGW("Could not read event fd; waking anyway.");
642 }
643 } else {
644 ALOGW("Received unexpected epoll event 0x%08x for wake event.",
645 eventItem.events);
646 }
647 continue;
648 }
649
650 // Update the fd and device node when the fd changes. When several
651 // events are read back-to-back with the same fd, this saves many reads
652 // from the hash table.
653 if (inputFd != dataFd) {
654 inputFd = dataFd;
655 deviceNode = mDeviceNodes[inputFd];
656 }
657 if (deviceNode == nullptr) {
658 ALOGE("could not find device node for fd %d", inputFd);
659 continue;
660 }
661 if (eventItem.events & EPOLLIN) {
662 struct input_event ievs[INPUT_MAX_EVENTS];
663 for (;;) {
664 ssize_t readSize = TEMP_FAILURE_RETRY(read(inputFd, ievs, sizeof(ievs)));
665 if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
666 ALOGW("could not get event, removed? (fd: %d, size: %d errno: %d)",
667 inputFd, readSize, errno);
668
669 removedDeviceFds.push_back(inputFd);
670 break;
671 } else if (readSize < 0) {
672 if (errno != EAGAIN && errno != EINTR) {
673 ALOGW("could not get event. errno=%d", errno);
674 }
675 break;
676 } else if (readSize % sizeof(input_event) != 0) {
677 ALOGE("could not get event. wrong size=%d", readSize);
678 break;
679 } else {
680 size_t count = static_cast<size_t>(readSize) / sizeof(struct input_event);
681 for (size_t i = 0; i < count; ++i) {
682 auto& iev = ievs[i];
683 auto when = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
684 InputEvent inputEvent = { when, iev.type, iev.code, iev.value };
685 mInputCallback->onInputEvent(deviceNode, inputEvent, now);
686 }
687 }
688 }
689 } else if (eventItem.events & EPOLLHUP) {
690 ALOGI("Removing device fd %d due to epoll hangup event.", inputFd);
691 removedDeviceFds.push_back(inputFd);
692 } else {
693 ALOGW("Received unexpected epoll event 0x%08x for device fd %d",
694 eventItem.events, inputFd);
695 }
696 }
697
698 if (removedDeviceFds.size()) {
699 for (auto deviceFd : removedDeviceFds) {
700 auto deviceNode = mDeviceNodes[deviceFd];
701 if (deviceNode != nullptr) {
702 status_t ret = closeNodeByFd(deviceFd);
703 if (ret != OK) {
704 ALOGW("Could not close device with fd %d. errno=%d", deviceFd, ret);
705 } else {
706 mInputCallback->onDeviceRemoved(deviceNode);
707 }
708 }
709 }
710 }
711
712 if (deviceChange) {
713 readNotify();
714 }
715
716 return OK;
717}
718
719status_t InputHub::wake() {
720 ALOGV("wake() called");
721
722 uint64_t u = 1;
723 ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &u, sizeof(uint64_t)));
724
725 if (nWrite != sizeof(uint64_t) && errno != EAGAIN) {
726 ALOGW("Could not write wake signal, errno=%d", errno);
727 return -errno;
728 }
729 return OK;
730}
731
732void InputHub::dump(String8& dump) {
733 // TODO
734}
735
736status_t InputHub::readNotify() {
737 char event_buf[512];
738 struct inotify_event* event;
739
740 ssize_t res = TEMP_FAILURE_RETRY(read(mINotifyFd, event_buf, sizeof(event_buf)));
741 if (res < static_cast<int>(sizeof(*event))) {
742 ALOGW("could not get inotify event, %s\n", strerror(errno));
743 return -errno;
744 }
745
746 size_t event_pos = 0;
747 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
748 while (res >= static_cast<int>(sizeof(*event))) {
749 event = reinterpret_cast<struct inotify_event*>(event_buf + event_pos);
750 if (event->len) {
751 std::string path = mWatchedPaths[event->wd];
752 path.append("/").append(event->name);
753 ALOGV("inotify event for path %s", path.c_str());
754
755 if (event->mask & IN_CREATE) {
Tim Kilbournc929d252015-04-29 13:50:17 -0700756 auto deviceNode = openNode(path);
757 if (deviceNode == nullptr) {
Tim Kilbourn73475a42015-02-13 10:35:20 -0800758 ALOGE("could not open device node %s. err=%d", path.c_str(), res);
759 } else {
760 mInputCallback->onDeviceAdded(deviceNode);
761 }
762 } else {
763 auto deviceNode = findNodeByPath(path);
764 if (deviceNode != nullptr) {
Tim Kilbournc929d252015-04-29 13:50:17 -0700765 status_t ret = closeNode(deviceNode.get());
Tim Kilbourn73475a42015-02-13 10:35:20 -0800766 if (ret != OK) {
767 ALOGW("Could not close device %s. errno=%d", path.c_str(), ret);
768 } else {
769 mInputCallback->onDeviceRemoved(deviceNode);
770 }
771 } else {
772 ALOGW("could not find device node for %s", path.c_str());
773 }
774 }
775 }
776 int event_size = sizeof(*event) + event->len;
777 res -= event_size;
778 event_pos += event_size;
779 }
780
781 return OK;
782}
783
784status_t InputHub::scanDir(const std::string& path) {
785 auto dir = ::opendir(path.c_str());
786 if (dir == nullptr) {
787 ALOGE("could not open device path %s to scan for devices. err=%d", path.c_str(), errno);
788 return -errno;
789 }
790
791 while (auto dirent = readdir(dir)) {
792 if (strcmp(dirent->d_name, ".") == 0 ||
793 strcmp(dirent->d_name, "..") == 0) {
794 continue;
795 }
796 std::string filename = path + "/" + dirent->d_name;
Tim Kilbournc929d252015-04-29 13:50:17 -0700797 auto node = openNode(filename);
798 if (node == nullptr) {
Tim Kilbourn73475a42015-02-13 10:35:20 -0800799 ALOGE("could not open device node %s", filename.c_str());
800 } else {
801 mInputCallback->onDeviceAdded(node);
802 }
803 }
804 ::closedir(dir);
805 return OK;
806}
807
Tim Kilbournc929d252015-04-29 13:50:17 -0700808std::shared_ptr<InputDeviceNode> InputHub::openNode(const std::string& path) {
Tim Kilbourn73475a42015-02-13 10:35:20 -0800809 ALOGV("opening %s...", path.c_str());
810 auto evdevNode = std::shared_ptr<EvdevDeviceNode>(EvdevDeviceNode::openDeviceNode(path));
811 if (evdevNode == nullptr) {
Tim Kilbournc929d252015-04-29 13:50:17 -0700812 return nullptr;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800813 }
814
815 auto fd = evdevNode->getFd();
816 ALOGV("opened %s with fd %d", path.c_str(), fd);
Tim Kilbournc929d252015-04-29 13:50:17 -0700817 mDeviceNodes[fd] = evdevNode;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800818 struct epoll_event eventItem{};
819 eventItem.events = EPOLLIN;
820 if (mWakeupMechanism == WakeMechanism::EPOLL_WAKEUP) {
821 eventItem.events |= EPOLLWAKEUP;
822 }
823 eventItem.data.u32 = fd;
824 if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
825 ALOGE("Could not add device fd to epoll instance. errno=%d", errno);
Tim Kilbournc929d252015-04-29 13:50:17 -0700826 return nullptr;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800827 }
828
829 if (mNeedToCheckSuspendBlockIoctl) {
830#ifndef EVIOCSSUSPENDBLOCK
831 // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels
832 // will use an epoll flag instead, so as long as we want to support this
833 // feature, we need to be prepared to define the ioctl ourselves.
834#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int)
835#endif
836 if (TEMP_FAILURE_RETRY(ioctl(fd, EVIOCSSUSPENDBLOCK, 1))) {
837 // no wake mechanism, continue using explicit wake locks
838 ALOGI("Using explicit wakelocks to block suspend while processing input events.");
839 } else {
840 mWakeupMechanism = WakeMechanism::LEGACY_EVDEV_SUSPENDBLOCK_IOCTL;
841 // release any held wakelocks since we won't need them anymore
842 release_wake_lock(WAKE_LOCK_ID);
843 ALOGI("Using EVIOCSSUSPENDBLOCK to block suspend while processing input events.");
844 }
845 mNeedToCheckSuspendBlockIoctl = false;
846 }
847
Tim Kilbournc929d252015-04-29 13:50:17 -0700848 return evdevNode;
Tim Kilbourn73475a42015-02-13 10:35:20 -0800849}
850
Tim Kilbournc929d252015-04-29 13:50:17 -0700851status_t InputHub::closeNode(const InputDeviceNode* node) {
Tim Kilbourn73475a42015-02-13 10:35:20 -0800852 for (auto pair : mDeviceNodes) {
Tim Kilbournc929d252015-04-29 13:50:17 -0700853 if (pair.second.get() == node) {
Tim Kilbourn73475a42015-02-13 10:35:20 -0800854 return closeNodeByFd(pair.first);
855 }
856 }
857 return BAD_VALUE;
858}
859
860status_t InputHub::closeNodeByFd(int fd) {
861 status_t ret = OK;
862 if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL)) {
863 ALOGW("Could not remove device fd from epoll instance. errno=%d", errno);
864 ret = -errno;
865 }
866 mDeviceNodes.erase(fd);
867 ::close(fd);
868 return ret;
869}
870
871std::shared_ptr<InputDeviceNode> InputHub::findNodeByPath(const std::string& path) {
872 for (auto pair : mDeviceNodes) {
873 if (pair.second->getPath() == path) return pair.second;
874 }
875 return nullptr;
876}
877
878bool InputHub::manageWakeLocks() const {
879 return mWakeupMechanism != WakeMechanism::EPOLL_WAKEUP;
880}
881
882} // namespace android