173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn/* 273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * Copyright (C) 2015 The Android Open Source Project 373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * 473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * Licensed under the Apache License, Version 2.0 (the "License"); 573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * you may not use this file except in compliance with the License. 673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * You may obtain a copy of the License at 773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * 873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * http://www.apache.org/licenses/LICENSE-2.0 973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * 1073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * Unless required by applicable law or agreed to in writing, software 1173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * distributed under the License is distributed on an "AS IS" BASIS, 1273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * See the License for the specific language governing permissions and 1473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn * limitations under the License. 1573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn */ 1673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 1773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#define LOG_TAG "InputHub" 183186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn//#define LOG_NDEBUG 0 193186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 20dbc8c16841483f665feeb9df362551b8e9e65263Tim Kilbourn#include "InputHub.h" 2173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 2273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <dirent.h> 2373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <errno.h> 2473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <fcntl.h> 2573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <string.h> 2673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/capability.h> 2773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/epoll.h> 2873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/eventfd.h> 2973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/inotify.h> 3073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/ioctl.h> 3173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/stat.h> 3273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/types.h> 3373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <sys/utsname.h> 3473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <unistd.h> 3573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 3673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <vector> 3773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 3873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <android/input.h> 3973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <hardware_legacy/power.h> 4073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <linux/input.h> 4173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 4273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#include <utils/Log.h> 4373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 44dbc8c16841483f665feeb9df362551b8e9e65263Tim Kilbourn#include "BitUtils.h" 45dbc8c16841483f665feeb9df362551b8e9e65263Tim Kilbourn 4673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournnamespace android { 4773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 4873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic const char WAKE_LOCK_ID[] = "KeyEvents"; 4973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic const int NO_TIMEOUT = -1; 5073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic const int EPOLL_MAX_EVENTS = 16; 5173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic const int INPUT_MAX_EVENTS = 128; 5273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 5373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic constexpr bool testBit(int bit, const uint8_t arr[]) { 5473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return arr[bit / 8] & (1 << (bit % 8)); 5573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 5673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 5773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic constexpr size_t sizeofBitArray(size_t bits) { 5873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return (bits + 7) / 8; 5973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 6073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 6173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatic void getLinuxRelease(int* major, int* minor) { 6273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct utsname info; 6373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (uname(&info) || sscanf(info.release, "%d.%d", major, minor) <= 0) { 6473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn *major = 0, *minor = 0; 6573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("Could not get linux version: %s", strerror(errno)); 6673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 6773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 6873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 6973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournclass EvdevDeviceNode : public InputDeviceNode { 7073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournpublic: 7173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn static EvdevDeviceNode* openDeviceNode(const std::string& path); 7273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 7373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual ~EvdevDeviceNode() { 7473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("closing %s (fd=%d)", mPath.c_str(), mFd); 7573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mFd >= 0) { 7673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mFd); 7773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 7873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 7973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 8073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual int getFd() const { return mFd; } 8173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getPath() const override { return mPath; } 8273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getName() const override { return mName; } 8373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getLocation() const override { return mLocation; } 8473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getUniqueId() const override { return mUniqueId; } 8573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 8673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getBusType() const override { return mBusType; } 8773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getVendorId() const override { return mVendorId; } 8873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getProductId() const override { return mProductId; } 8973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getVersion() const override { return mVersion; } 9073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 9173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual bool hasKey(int32_t key) const override; 923186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasKeyInRange(int32_t start, int32_t end) const override; 933186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasRelativeAxis(int32_t axis) const override; 943186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasAbsoluteAxis(int32_t axis) const override; 953186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasSwitch(int32_t sw) const override; 963186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasForceFeedback(int32_t ff) const override; 9773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual bool hasInputProperty(int property) const override; 9873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 9973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual int32_t getKeyState(int32_t key) const override; 10073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual int32_t getSwitchState(int32_t sw) const override; 1013186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual const AbsoluteAxisInfo* getAbsoluteAxisInfo(int32_t axis) const override; 10273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual status_t getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const override; 10373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 10473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual void vibrate(nsecs_t duration) override; 1053186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual void cancelVibrate() override; 10673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 10773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual void disableDriverKeyRepeat() override; 10873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 10973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournprivate: 11073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn EvdevDeviceNode(const std::string& path, int fd) : 11173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFd(fd), mPath(path) {} 11273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 11373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t queryProperties(); 11473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn void queryAxisInfo(); 11573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 11673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int mFd; 11773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mPath; 11873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 11973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mName; 12073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mLocation; 12173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mUniqueId; 12273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 12373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mBusType; 12473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mVendorId; 12573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mProductId; 12673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mVersion; 12773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 12873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mKeyBitmask[KEY_CNT / 8]; 12973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mAbsBitmask[ABS_CNT / 8]; 13073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mRelBitmask[REL_CNT / 8]; 13173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mSwBitmask[SW_CNT / 8]; 13273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mLedBitmask[LED_CNT / 8]; 13373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mFfBitmask[FF_CNT / 8]; 13473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mPropBitmask[INPUT_PROP_CNT / 8]; 13573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 13673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::unordered_map<uint32_t, std::unique_ptr<AbsoluteAxisInfo>> mAbsInfo; 13773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 13873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn bool mFfEffectPlaying = false; 13973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int16_t mFfEffectId = -1; 14073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn}; 14173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 14273475a4eb2cebf06f965c58e015d06c333e71e61Tim KilbournEvdevDeviceNode* EvdevDeviceNode::openDeviceNode(const std::string& path) { 14373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)); 14473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (fd < 0) { 14573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open evdev device %s. err=%d", path.c_str(), errno); 14673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 14773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 14873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 14973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Tell the kernel that we want to use the monotonic clock for reporting 15073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // timestamps associated with input events. This is important because the 15173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // input system uses the timestamps extensively and assumes they were 15273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // recorded using the monotonic clock. 15373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 15473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // The EVIOCSCLOCKID ioctl was introduced in Linux 3.4. 15573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int clockId = CLOCK_MONOTONIC; 15673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(fd, EVIOCSCLOCKID, &clockId)) < 0) { 15773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not set input clock id to CLOCK_MONOTONIC. errno=%d", errno); 15873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 15973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 16073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto node = new EvdevDeviceNode(path, fd); 16173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t ret = node->queryProperties(); 16273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (ret != OK) { 16373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open evdev device %s: failed to read properties. errno=%d", 16473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn path.c_str(), ret); 16573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn delete node; 16673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 16773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 16873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return node; 16973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 17073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 17173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t EvdevDeviceNode::queryProperties() { 17273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn char buffer[80]; 17373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 17473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGNAME(sizeof(buffer) - 1), buffer)) < 1) { 17573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("could not get device name for %s.", mPath.c_str()); 17673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 17773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn buffer[sizeof(buffer) - 1] = '\0'; 17873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mName = buffer; 17973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 18073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 18173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int driverVersion; 18273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGVERSION, &driverVersion))) { 18373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not get driver version for %s. err=%d", mPath.c_str(), errno); 18473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 18573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 18673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 18773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_id inputId; 18873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGID, &inputId))) { 18973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not get device input id for %s. err=%d", mPath.c_str(), errno); 19073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 19173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 19273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mBusType = inputId.bustype; 19373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mVendorId = inputId.vendor; 19473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mProductId = inputId.product; 19573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mVersion = inputId.version; 19673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 19773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPHYS(sizeof(buffer) - 1), buffer)) < 1) { 19873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("could not get location for %s.", mPath.c_str()); 19973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 20073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn buffer[sizeof(buffer) - 1] = '\0'; 20173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mLocation = buffer; 20273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 20373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 20473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGUNIQ(sizeof(buffer) - 1), buffer)) < 1) { 20573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("could not get unique id for %s.", mPath.c_str()); 20673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 20773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn buffer[sizeof(buffer) - 1] = '\0'; 20873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mUniqueId = buffer; 20973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 21073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 21173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("add device %s", mPath.c_str()); 21273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV(" bus: %04x\n" 21373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " vendor: %04x\n" 21473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " product: %04x\n" 21573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " version: %04x\n", 21673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mBusType, mVendorId, mProductId, mVersion); 21773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV(" name: \"%s\"\n" 21873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " location: \"%s\"\n" 21973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " unique_id: \"%s\"\n" 22073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " descriptor: (TODO)\n" 22173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " driver: v%d.%d.%d", 22273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mName.c_str(), mLocation.c_str(), mUniqueId.c_str(), 22373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn driverVersion >> 16, (driverVersion >> 8) & 0xff, (driverVersion >> 16) & 0xff); 22473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 22573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_KEY, sizeof(mKeyBitmask)), mKeyBitmask)); 22673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_ABS, sizeof(mAbsBitmask)), mAbsBitmask)); 22773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_REL, sizeof(mRelBitmask)), mRelBitmask)); 22873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_SW, sizeof(mSwBitmask)), mSwBitmask)); 22973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_LED, sizeof(mLedBitmask)), mLedBitmask)); 23073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_FF, sizeof(mFfBitmask)), mFfBitmask)); 23173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPROP(sizeof(mPropBitmask)), mPropBitmask)); 23273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 23373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn queryAxisInfo(); 23473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 23573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 23673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 23773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 23873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid EvdevDeviceNode::queryAxisInfo() { 23973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (int32_t axis = 0; axis < ABS_MAX; ++axis) { 24073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(axis, mAbsBitmask)) { 24173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_absinfo info; 24273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGABS(axis), &info))) { 24373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", 24473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn axis, mPath.c_str(), mFd, errno); 24573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 24673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 24773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 24873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mAbsInfo[axis] = std::unique_ptr<AbsoluteAxisInfo>(new AbsoluteAxisInfo{ 24973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .minValue = info.minimum, 25073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .maxValue = info.maximum, 25173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .flat = info.flat, 25273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .fuzz = info.fuzz, 25373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .resolution = info.resolution 25473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn }); 25573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 25673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 25773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 25873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 25973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool EvdevDeviceNode::hasKey(int32_t key) const { 26073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (key >= 0 && key <= KEY_MAX) { 26173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(key, mKeyBitmask); 26273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 26373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return false; 26473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 26573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 2663186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasKeyInRange(int32_t startKey, int32_t endKey) const { 267dbc8c16841483f665feeb9df362551b8e9e65263Tim Kilbourn return testBitInRange(mKeyBitmask, startKey, endKey); 2683186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 2693186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 27073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool EvdevDeviceNode::hasRelativeAxis(int axis) const { 27173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (axis >= 0 && axis <= REL_MAX) { 27273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(axis, mRelBitmask); 27373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 27473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return false; 27573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 27673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 2773186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasAbsoluteAxis(int axis) const { 2783186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn if (axis >= 0 && axis <= ABS_MAX) { 2793186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return getAbsoluteAxisInfo(axis) != nullptr; 2803186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn } 2813186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return false; 2823186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 2833186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 28473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournconst AbsoluteAxisInfo* EvdevDeviceNode::getAbsoluteAxisInfo(int32_t axis) const { 28573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (axis < 0 || axis > ABS_MAX) { 28673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 28773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 28873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 28973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn const auto absInfo = mAbsInfo.find(axis); 29073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (absInfo != mAbsInfo.end()) { 29173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return absInfo->second.get(); 29273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 29373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 29473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 29573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 2963186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasSwitch(int32_t sw) const { 2973186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn if (sw >= 0 && sw <= SW_MAX) { 2983186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return testBit(sw, mSwBitmask); 2993186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn } 3003186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return false; 3013186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 3023186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 3033186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasForceFeedback(int32_t ff) const { 3043186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn if (ff >= 0 && ff <= FF_MAX) { 3053186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return testBit(ff, mFfBitmask); 3063186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn } 3073186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return false; 3083186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 3093186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 31073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool EvdevDeviceNode::hasInputProperty(int property) const { 31173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (property >= 0 && property <= INPUT_PROP_MAX) { 31273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(property, mPropBitmask); 31373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 31473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return false; 31573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 31673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 31773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournint32_t EvdevDeviceNode::getKeyState(int32_t key) const { 31873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (key >= 0 && key <= KEY_MAX) { 31973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(key, mKeyBitmask)) { 32073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t keyState[sizeofBitArray(KEY_CNT)]; 32173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn memset(keyState, 0, sizeof(keyState)); 32273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGKEY(sizeof(keyState)), keyState)) >= 0) { 32373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(key, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; 32473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 32573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 32673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 32773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return AKEY_STATE_UNKNOWN; 32873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 32973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 33073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournint32_t EvdevDeviceNode::getSwitchState(int32_t sw) const { 33173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (sw >= 0 && sw <= SW_MAX) { 33273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(sw, mSwBitmask)) { 33373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t swState[sizeofBitArray(SW_CNT)]; 33473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn memset(swState, 0, sizeof(swState)); 33573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGSW(sizeof(swState)), swState)) >= 0) { 33673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; 33773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 33873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 33973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 34073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return AKEY_STATE_UNKNOWN; 34173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 34273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 34373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t EvdevDeviceNode::getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const { 34473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn *outValue = 0; 34573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 34673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (axis >= 0 && axis <= ABS_MAX) { 34773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(axis, mAbsBitmask)) { 34873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_absinfo info; 34973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGABS(axis), &info))) { 35073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", 35173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn axis, mPath.c_str(), mFd, errno); 35273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 35373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 35473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 35573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn *outValue = info.value; 35673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 35773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 35873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 35973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -1; 36073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 36173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 36273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid EvdevDeviceNode::vibrate(nsecs_t duration) { 36373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ff_effect effect{}; 36473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.type = FF_RUMBLE; 36573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.id = mFfEffectId; 36673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.u.rumble.strong_magnitude = 0xc000; 36773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.u.rumble.weak_magnitude = 0xc000; 36873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.replay.length = (duration + 999'999LL) / 1'000'000LL; 36973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.replay.delay = 0; 37073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCSFF, &effect))) { 37173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not upload force feedback effect to device %s due to error %d.", 37273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 37373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return; 37473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 37573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFfEffectId = effect.id; 37673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 37773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_event ev{}; 37873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.type = EV_FF; 37973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.code = mFfEffectId; 38073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.value = 1; 38173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t written = TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(ev))); 38273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (written != sizeof(ev)) { 38373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not start force feedback effect on device %s due to error %d.", 38473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 38573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return; 38673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 38773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFfEffectPlaying = true; 38873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 38973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 3903186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournvoid EvdevDeviceNode::cancelVibrate() { 39173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mFfEffectPlaying) { 39273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFfEffectPlaying = false; 39373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 39473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_event ev{}; 39573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.type = EV_FF; 39673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.code = mFfEffectId; 39773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.value = 0; 39873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t written = TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(ev))); 39973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (written != sizeof(ev)) { 40073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not stop force feedback effect on device %s due to error %d.", 40173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 40273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return; 40373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 40473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 40573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 40673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 40773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid EvdevDeviceNode::disableDriverKeyRepeat() { 40873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn unsigned int repeatRate[] = {0, 0}; 40973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCSREP, repeatRate))) { 41073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Unable to disable kernel key repeat for %s due to error %d.", 41173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 41273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 41373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 41473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 415c929d2509530b0262681c8e6619609f44bfceea4Tim KilbournInputHub::InputHub(const std::shared_ptr<InputCallbackInterface>& cb) : 41673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback(cb) { 41773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Determine the type of suspend blocking we can do on this device. There 41873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // are 3 options, in decreasing order of preference: 41973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 1) EPOLLWAKEUP: introduced in Linux kernel 3.5, this flag can be set on 42073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // an epoll event to indicate that a wake lock should be held from the 42173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // time an fd has data until the next epoll_wait (or the epoll fd is 42273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // closed). 42373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 2) EVIOCSSUSPENDBLOCK: introduced into the Android kernel's evdev 42473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // driver, this ioctl blocks suspend while the event queue for the fd is 42573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // not empty. This was never accepted into the mainline kernel, and it was 42673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // replaced by EPOLLWAKEUP. 42773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 3) explicit wake locks: use acquire_wake_lock to manage suspend 42873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // blocking explicitly in the InputHub code. 42973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 43073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // (1) can be checked by simply observing the Linux kernel version. (2) 43173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // requires an fd from an evdev node, which cannot be done in the InputHub 43273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // constructor. So we assume (3) unless (1) is true, and we can verify 43373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // whether (2) is true once we have an evdev fd (and we're not in (1)). 43473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int major, minor; 43573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn getLinuxRelease(&major, &minor); 43673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (major > 3 || (major == 3 && minor >= 5)) { 43773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Using EPOLLWAKEUP to block suspend while processing input events."); 43873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWakeupMechanism = WakeMechanism::EPOLL_WAKEUP; 43973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mNeedToCheckSuspendBlockIoctl = false; 44073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 44173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 44273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 44373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 44473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 44573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // epoll_create argument is ignored, but it must be > 0. 44673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mEpollFd = epoll_create(1); 44773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 44873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 44973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mINotifyFd = inotify_init(); 45073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(mINotifyFd < 0, "Could not create inotify instance. errno=%d", errno); 45173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 45273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct epoll_event eventItem; 45373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn memset(&eventItem, 0, sizeof(eventItem)); 45473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events = EPOLLIN; 45573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mWakeupMechanism == WakeMechanism::EPOLL_WAKEUP) { 45673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events |= EPOLLWAKEUP; 45773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 45873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.data.u32 = mINotifyFd; 45973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem); 46073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno); 46173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 46273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int wakeFds[2]; 46373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn result = pipe(wakeFds); 46473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 46573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 46673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWakeEventFd = eventfd(0, EFD_NONBLOCK); 46773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(mWakeEventFd == -1, "Could not create wake event fd. errno=%d", errno); 46873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 46973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.data.u32 = mWakeEventFd; 47073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, &eventItem); 47173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance. errno=%d", errno); 47273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 47373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 47473475a4eb2cebf06f965c58e015d06c333e71e61Tim KilbournInputHub::~InputHub() { 47573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mEpollFd); 47673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mINotifyFd); 47773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mWakeEventFd); 47873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 47973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 48073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn release_wake_lock(WAKE_LOCK_ID); 48173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 48273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 48373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 48473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::registerDevicePath(const std::string& path) { 48573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("registering device path %s", path.c_str()); 48673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int wd = inotify_add_watch(mINotifyFd, path.c_str(), IN_DELETE | IN_CREATE); 48773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (wd < 0) { 48873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("Could not add %s to INotify watch. errno=%d", path.c_str(), errno); 48973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 49073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 49173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWatchedPaths[wd] = path; 49273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn scanDir(path); 49373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 49473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 49573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 49673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::unregisterDevicePath(const std::string& path) { 49773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int wd = -1; 49873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto pair : mWatchedPaths) { 49973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pair.second == path) { 50073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn wd = pair.first; 50173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 50273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 50373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 50473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 50573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (wd == -1) { 50673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return BAD_VALUE; 50773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 50873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWatchedPaths.erase(wd); 50973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (inotify_rm_watch(mINotifyFd, wd) != 0) { 51073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 51173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 51273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 51373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 51473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 51573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::poll() { 51673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn bool deviceChange = false; 51773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 51873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 51973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Mind the wake lock dance! 52073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // If we're relying on wake locks, we hold a wake lock at all times 52173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // except during epoll_wait(). This works due to some subtle 52273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // choreography. When a device driver has pending (unread) events, it 52373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // acquires a kernel wake lock. However, once the last pending event 52473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // has been read, the device driver will release the kernel wake lock. 52573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // To prevent the system from going to sleep when this happens, the 52673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // InputHub holds onto its own user wake lock while the client is 52773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // processing events. Thus the system can only sleep if there are no 52873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // events pending or currently being processed. 52973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn release_wake_lock(WAKE_LOCK_ID); 53073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 53173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 53273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct epoll_event pendingEventItems[EPOLL_MAX_EVENTS]; 53373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int pollResult = epoll_wait(mEpollFd, pendingEventItems, EPOLL_MAX_EVENTS, NO_TIMEOUT); 53473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 53573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 53673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 53773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 53873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 53973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pollResult == 0) { 54073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("epoll_wait should not return 0 with no timeout"); 54173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return UNKNOWN_ERROR; 54273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 54373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pollResult < 0) { 54473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // An error occurred. Return even if it's EINTR, and let the caller 54573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // restart the poll. 54673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("epoll_wait returned with errno=%d", errno); 54773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 54873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 54973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 55073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // pollResult > 0: there are events to process 55173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 55273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::vector<int> removedDeviceFds; 55373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int inputFd = -1; 55473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::shared_ptr<InputDeviceNode> deviceNode; 55573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (int i = 0; i < pollResult; ++i) { 55673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn const struct epoll_event& eventItem = pendingEventItems[i]; 55773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 55873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int dataFd = static_cast<int>(eventItem.data.u32); 55973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (dataFd == mINotifyFd) { 56073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (eventItem.events & EPOLLIN) { 56173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn deviceChange = true; 56273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 56373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); 56473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 56573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 56673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 56773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 56873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (dataFd == mWakeEventFd) { 56973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (eventItem.events & EPOLLIN) { 57073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("awoken after wake()"); 57173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint64_t u; 57273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t nRead = TEMP_FAILURE_RETRY(read(mWakeEventFd, &u, sizeof(uint64_t))); 57373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (nRead != sizeof(uint64_t)) { 57473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not read event fd; waking anyway."); 57573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 57673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 57773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Received unexpected epoll event 0x%08x for wake event.", 57873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events); 57973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 58073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 58173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 58273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 58373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Update the fd and device node when the fd changes. When several 58473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // events are read back-to-back with the same fd, this saves many reads 58573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // from the hash table. 58673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (inputFd != dataFd) { 58773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn inputFd = dataFd; 58873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn deviceNode = mDeviceNodes[inputFd]; 58973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 59073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceNode == nullptr) { 59173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not find device node for fd %d", inputFd); 59273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 59373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 59473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (eventItem.events & EPOLLIN) { 59573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_event ievs[INPUT_MAX_EVENTS]; 59673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (;;) { 59773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t readSize = TEMP_FAILURE_RETRY(read(inputFd, ievs, sizeof(ievs))); 59873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { 599682d4f45e3d38f22d01968b666bd8b1055d049caGreg Kaiser ALOGW("could not get event, removed? (fd: %d, size: %zd errno: %d)", 60073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn inputFd, readSize, errno); 60173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 60273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn removedDeviceFds.push_back(inputFd); 60373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 60473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else if (readSize < 0) { 60573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (errno != EAGAIN && errno != EINTR) { 60673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not get event. errno=%d", errno); 60773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 60873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 60973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else if (readSize % sizeof(input_event) != 0) { 610682d4f45e3d38f22d01968b666bd8b1055d049caGreg Kaiser ALOGE("could not get event. wrong size=%zd", readSize); 61173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 61273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 61373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t count = static_cast<size_t>(readSize) / sizeof(struct input_event); 61473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (size_t i = 0; i < count; ++i) { 61573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto& iev = ievs[i]; 61673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto when = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); 61773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn InputEvent inputEvent = { when, iev.type, iev.code, iev.value }; 61873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onInputEvent(deviceNode, inputEvent, now); 61973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 62073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 62173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 62273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else if (eventItem.events & EPOLLHUP) { 62373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Removing device fd %d due to epoll hangup event.", inputFd); 62473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn removedDeviceFds.push_back(inputFd); 62573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 62673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Received unexpected epoll event 0x%08x for device fd %d", 62773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events, inputFd); 62873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 62973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 63073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 63173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (removedDeviceFds.size()) { 63273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto deviceFd : removedDeviceFds) { 63373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto deviceNode = mDeviceNodes[deviceFd]; 63473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceNode != nullptr) { 63573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t ret = closeNodeByFd(deviceFd); 63673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (ret != OK) { 63773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not close device with fd %d. errno=%d", deviceFd, ret); 63873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 63973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceRemoved(deviceNode); 64073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 64573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceChange) { 64673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn readNotify(); 64773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 64973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 65073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 65173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 65273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::wake() { 65373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("wake() called"); 65473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 65573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint64_t u = 1; 65673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &u, sizeof(uint64_t))); 65773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 65873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (nWrite != sizeof(uint64_t) && errno != EAGAIN) { 65973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not write wake signal, errno=%d", errno); 66073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 66173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 66273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 66373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 66473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 66573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid InputHub::dump(String8& dump) { 66673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // TODO 66773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 66873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 66973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::readNotify() { 67073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn char event_buf[512]; 67173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct inotify_event* event; 67273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 67373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t res = TEMP_FAILURE_RETRY(read(mINotifyFd, event_buf, sizeof(event_buf))); 67473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (res < static_cast<int>(sizeof(*event))) { 67573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not get inotify event, %s\n", strerror(errno)); 67673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 67773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 67873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 67973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t event_pos = 0; 68073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn while (res >= static_cast<int>(sizeof(*event))) { 68173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn event = reinterpret_cast<struct inotify_event*>(event_buf + event_pos); 68273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (event->len) { 68373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string path = mWatchedPaths[event->wd]; 68473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn path.append("/").append(event->name); 68573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("inotify event for path %s", path.c_str()); 68673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 68773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (event->mask & IN_CREATE) { 688c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn auto deviceNode = openNode(path); 689c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn if (deviceNode == nullptr) { 690682d4f45e3d38f22d01968b666bd8b1055d049caGreg Kaiser ALOGE("could not open device node %s. err=%zd", path.c_str(), res); 69173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 69273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceAdded(deviceNode); 69373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 69473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 69573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto deviceNode = findNodeByPath(path); 69673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceNode != nullptr) { 697c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn status_t ret = closeNode(deviceNode.get()); 69873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (ret != OK) { 69973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not close device %s. errno=%d", path.c_str(), ret); 70073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 70173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceRemoved(deviceNode); 70273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 70373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 70473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not find device node for %s", path.c_str()); 70573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 70673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 70773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 70873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int event_size = sizeof(*event) + event->len; 70973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn res -= event_size; 71073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn event_pos += event_size; 71173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 71273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 71373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 71473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 71573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 71673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::scanDir(const std::string& path) { 71773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto dir = ::opendir(path.c_str()); 71873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (dir == nullptr) { 71973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open device path %s to scan for devices. err=%d", path.c_str(), errno); 72073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 72173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 72273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 72373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn while (auto dirent = readdir(dir)) { 72473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (strcmp(dirent->d_name, ".") == 0 || 72573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn strcmp(dirent->d_name, "..") == 0) { 72673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 72773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 72873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string filename = path + "/" + dirent->d_name; 729c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn auto node = openNode(filename); 730c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn if (node == nullptr) { 73173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open device node %s", filename.c_str()); 73273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 73373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceAdded(node); 73473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 73573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 73673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::closedir(dir); 73773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 73873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 73973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 740c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbournstd::shared_ptr<InputDeviceNode> InputHub::openNode(const std::string& path) { 74173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("opening %s...", path.c_str()); 74273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto evdevNode = std::shared_ptr<EvdevDeviceNode>(EvdevDeviceNode::openDeviceNode(path)); 74373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (evdevNode == nullptr) { 744c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn return nullptr; 74573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 74673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 74773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto fd = evdevNode->getFd(); 74873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("opened %s with fd %d", path.c_str(), fd); 749c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn mDeviceNodes[fd] = evdevNode; 75073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct epoll_event eventItem{}; 75173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events = EPOLLIN; 75273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mWakeupMechanism == WakeMechanism::EPOLL_WAKEUP) { 75373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events |= EPOLLWAKEUP; 75473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 75573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.data.u32 = fd; 75673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) { 75773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("Could not add device fd to epoll instance. errno=%d", errno); 758c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn return nullptr; 75973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 76073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 76173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mNeedToCheckSuspendBlockIoctl) { 76273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#ifndef EVIOCSSUSPENDBLOCK 76373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels 76473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // will use an epoll flag instead, so as long as we want to support this 76573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // feature, we need to be prepared to define the ioctl ourselves. 76673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int) 76773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#endif 76873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(fd, EVIOCSSUSPENDBLOCK, 1))) { 76973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // no wake mechanism, continue using explicit wake locks 77073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Using explicit wakelocks to block suspend while processing input events."); 77173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 77273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWakeupMechanism = WakeMechanism::LEGACY_EVDEV_SUSPENDBLOCK_IOCTL; 77373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // release any held wakelocks since we won't need them anymore 77473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn release_wake_lock(WAKE_LOCK_ID); 77573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Using EVIOCSSUSPENDBLOCK to block suspend while processing input events."); 77673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 77773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mNeedToCheckSuspendBlockIoctl = false; 77873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 77973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 780c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn return evdevNode; 78173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 78273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 783c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbournstatus_t InputHub::closeNode(const InputDeviceNode* node) { 78473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto pair : mDeviceNodes) { 785c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn if (pair.second.get() == node) { 78673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return closeNodeByFd(pair.first); 78773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 78873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 78973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return BAD_VALUE; 79073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 79173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 79273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::closeNodeByFd(int fd) { 79373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t ret = OK; 79473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL)) { 79573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not remove device fd from epoll instance. errno=%d", errno); 79673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ret = -errno; 79773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 79873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mDeviceNodes.erase(fd); 79973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(fd); 80073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return ret; 80173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 80273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 80373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstd::shared_ptr<InputDeviceNode> InputHub::findNodeByPath(const std::string& path) { 80473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto pair : mDeviceNodes) { 80573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pair.second->getPath() == path) return pair.second; 80673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 80773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 80873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 80973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 81073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool InputHub::manageWakeLocks() const { 81173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return mWakeupMechanism != WakeMechanism::EPOLL_WAKEUP; 81273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 81373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 81473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} // namespace android 815