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 Kilbournstatic bool processHasCapability(int capability) { 7073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(!cap_valid(capability), "invalid linux capability: %d", capability); 7173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct __user_cap_header_struct cap_header_data; 7273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct __user_cap_data_struct cap_data_data[2]; 7373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn cap_user_header_t caphdr = &cap_header_data; 7473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn cap_user_data_t capdata = cap_data_data; 7573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn caphdr->pid = 0; 7673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn caphdr->version = _LINUX_CAPABILITY_VERSION_3; 7773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(capget(caphdr, capdata) != 0, 7873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn "Could not get process capabilities. errno=%d", errno); 7973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int idx = CAP_TO_INDEX(capability); 8073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return capdata[idx].effective & CAP_TO_MASK(capability); 8173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 8273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 8373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournclass EvdevDeviceNode : public InputDeviceNode { 8473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournpublic: 8573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn static EvdevDeviceNode* openDeviceNode(const std::string& path); 8673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 8773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual ~EvdevDeviceNode() { 8873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("closing %s (fd=%d)", mPath.c_str(), mFd); 8973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mFd >= 0) { 9073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mFd); 9173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 9273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 9373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 9473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual int getFd() const { return mFd; } 9573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getPath() const override { return mPath; } 9673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getName() const override { return mName; } 9773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getLocation() const override { return mLocation; } 9873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual const std::string& getUniqueId() const override { return mUniqueId; } 9973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 10073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getBusType() const override { return mBusType; } 10173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getVendorId() const override { return mVendorId; } 10273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getProductId() const override { return mProductId; } 10373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual uint16_t getVersion() const override { return mVersion; } 10473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 10573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual bool hasKey(int32_t key) const override; 1063186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasKeyInRange(int32_t start, int32_t end) const override; 1073186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasRelativeAxis(int32_t axis) const override; 1083186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasAbsoluteAxis(int32_t axis) const override; 1093186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasSwitch(int32_t sw) const override; 1103186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual bool hasForceFeedback(int32_t ff) const override; 11173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual bool hasInputProperty(int property) const override; 11273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 11373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual int32_t getKeyState(int32_t key) const override; 11473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual int32_t getSwitchState(int32_t sw) const override; 1153186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual const AbsoluteAxisInfo* getAbsoluteAxisInfo(int32_t axis) const override; 11673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual status_t getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const override; 11773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 11873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual void vibrate(nsecs_t duration) override; 1193186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn virtual void cancelVibrate() override; 12073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 12173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn virtual void disableDriverKeyRepeat() override; 12273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 12373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournprivate: 12473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn EvdevDeviceNode(const std::string& path, int fd) : 12573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFd(fd), mPath(path) {} 12673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 12773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t queryProperties(); 12873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn void queryAxisInfo(); 12973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 13073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int mFd; 13173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mPath; 13273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 13373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mName; 13473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mLocation; 13573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string mUniqueId; 13673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 13773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mBusType; 13873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mVendorId; 13973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mProductId; 14073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint16_t mVersion; 14173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 14273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mKeyBitmask[KEY_CNT / 8]; 14373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mAbsBitmask[ABS_CNT / 8]; 14473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mRelBitmask[REL_CNT / 8]; 14573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mSwBitmask[SW_CNT / 8]; 14673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mLedBitmask[LED_CNT / 8]; 14773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mFfBitmask[FF_CNT / 8]; 14873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t mPropBitmask[INPUT_PROP_CNT / 8]; 14973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 15073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::unordered_map<uint32_t, std::unique_ptr<AbsoluteAxisInfo>> mAbsInfo; 15173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 15273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn bool mFfEffectPlaying = false; 15373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int16_t mFfEffectId = -1; 15473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn}; 15573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 15673475a4eb2cebf06f965c58e015d06c333e71e61Tim KilbournEvdevDeviceNode* EvdevDeviceNode::openDeviceNode(const std::string& path) { 15773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)); 15873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (fd < 0) { 15973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open evdev device %s. err=%d", path.c_str(), errno); 16073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 16173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 16273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 16373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Tell the kernel that we want to use the monotonic clock for reporting 16473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // timestamps associated with input events. This is important because the 16573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // input system uses the timestamps extensively and assumes they were 16673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // recorded using the monotonic clock. 16773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 16873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // The EVIOCSCLOCKID ioctl was introduced in Linux 3.4. 16973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int clockId = CLOCK_MONOTONIC; 17073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(fd, EVIOCSCLOCKID, &clockId)) < 0) { 17173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not set input clock id to CLOCK_MONOTONIC. errno=%d", errno); 17273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 17373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 17473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto node = new EvdevDeviceNode(path, fd); 17573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t ret = node->queryProperties(); 17673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (ret != OK) { 17773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open evdev device %s: failed to read properties. errno=%d", 17873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn path.c_str(), ret); 17973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn delete node; 18073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 18173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 18273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return node; 18373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 18473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 18573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t EvdevDeviceNode::queryProperties() { 18673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn char buffer[80]; 18773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 18873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGNAME(sizeof(buffer) - 1), buffer)) < 1) { 18973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("could not get device name for %s.", mPath.c_str()); 19073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 19173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn buffer[sizeof(buffer) - 1] = '\0'; 19273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mName = buffer; 19373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 19473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 19573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int driverVersion; 19673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGVERSION, &driverVersion))) { 19773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not get driver version for %s. err=%d", mPath.c_str(), errno); 19873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 19973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 20073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 20173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_id inputId; 20273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGID, &inputId))) { 20373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not get device input id for %s. err=%d", mPath.c_str(), errno); 20473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 20573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 20673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mBusType = inputId.bustype; 20773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mVendorId = inputId.vendor; 20873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mProductId = inputId.product; 20973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mVersion = inputId.version; 21073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 21173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPHYS(sizeof(buffer) - 1), buffer)) < 1) { 21273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("could not get location for %s.", mPath.c_str()); 21373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 21473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn buffer[sizeof(buffer) - 1] = '\0'; 21573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mLocation = buffer; 21673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 21773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 21873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGUNIQ(sizeof(buffer) - 1), buffer)) < 1) { 21973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("could not get unique id for %s.", mPath.c_str()); 22073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 22173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn buffer[sizeof(buffer) - 1] = '\0'; 22273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mUniqueId = buffer; 22373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 22473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 22573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("add device %s", mPath.c_str()); 22673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV(" bus: %04x\n" 22773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " vendor: %04x\n" 22873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " product: %04x\n" 22973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " version: %04x\n", 23073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mBusType, mVendorId, mProductId, mVersion); 23173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV(" name: \"%s\"\n" 23273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " location: \"%s\"\n" 23373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " unique_id: \"%s\"\n" 23473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " descriptor: (TODO)\n" 23573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn " driver: v%d.%d.%d", 23673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mName.c_str(), mLocation.c_str(), mUniqueId.c_str(), 23773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn driverVersion >> 16, (driverVersion >> 8) & 0xff, (driverVersion >> 16) & 0xff); 23873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 23973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_KEY, sizeof(mKeyBitmask)), mKeyBitmask)); 24073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_ABS, sizeof(mAbsBitmask)), mAbsBitmask)); 24173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_REL, sizeof(mRelBitmask)), mRelBitmask)); 24273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_SW, sizeof(mSwBitmask)), mSwBitmask)); 24373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_LED, sizeof(mLedBitmask)), mLedBitmask)); 24473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_FF, sizeof(mFfBitmask)), mFfBitmask)); 24573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPROP(sizeof(mPropBitmask)), mPropBitmask)); 24673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 24773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn queryAxisInfo(); 24873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 24973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 25073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 25173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 25273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid EvdevDeviceNode::queryAxisInfo() { 25373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (int32_t axis = 0; axis < ABS_MAX; ++axis) { 25473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(axis, mAbsBitmask)) { 25573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_absinfo info; 25673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGABS(axis), &info))) { 25773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", 25873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn axis, mPath.c_str(), mFd, errno); 25973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 26073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 26173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 26273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mAbsInfo[axis] = std::unique_ptr<AbsoluteAxisInfo>(new AbsoluteAxisInfo{ 26373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .minValue = info.minimum, 26473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .maxValue = info.maximum, 26573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .flat = info.flat, 26673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .fuzz = info.fuzz, 26773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn .resolution = info.resolution 26873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn }); 26973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 27073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 27173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 27273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 27373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool EvdevDeviceNode::hasKey(int32_t key) const { 27473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (key >= 0 && key <= KEY_MAX) { 27573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(key, mKeyBitmask); 27673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 27773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return false; 27873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 27973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 2803186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasKeyInRange(int32_t startKey, int32_t endKey) const { 281dbc8c16841483f665feeb9df362551b8e9e65263Tim Kilbourn return testBitInRange(mKeyBitmask, startKey, endKey); 2823186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 2833186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 28473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool EvdevDeviceNode::hasRelativeAxis(int axis) const { 28573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (axis >= 0 && axis <= REL_MAX) { 28673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(axis, mRelBitmask); 28773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 28873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return false; 28973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 29073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 2913186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasAbsoluteAxis(int axis) const { 2923186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn if (axis >= 0 && axis <= ABS_MAX) { 2933186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return getAbsoluteAxisInfo(axis) != nullptr; 2943186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn } 2953186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return false; 2963186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 2973186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 29873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournconst AbsoluteAxisInfo* EvdevDeviceNode::getAbsoluteAxisInfo(int32_t axis) const { 29973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (axis < 0 || axis > ABS_MAX) { 30073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 30173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 30273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 30373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn const auto absInfo = mAbsInfo.find(axis); 30473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (absInfo != mAbsInfo.end()) { 30573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return absInfo->second.get(); 30673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 30773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 30873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 30973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 3103186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasSwitch(int32_t sw) const { 3113186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn if (sw >= 0 && sw <= SW_MAX) { 3123186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return testBit(sw, mSwBitmask); 3133186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn } 3143186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return false; 3153186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 3163186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 3173186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournbool EvdevDeviceNode::hasForceFeedback(int32_t ff) const { 3183186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn if (ff >= 0 && ff <= FF_MAX) { 3193186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return testBit(ff, mFfBitmask); 3203186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn } 3213186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn return false; 3223186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn} 3233186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbourn 32473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool EvdevDeviceNode::hasInputProperty(int property) const { 32573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (property >= 0 && property <= INPUT_PROP_MAX) { 32673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(property, mPropBitmask); 32773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 32873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return false; 32973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 33073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 33173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournint32_t EvdevDeviceNode::getKeyState(int32_t key) const { 33273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (key >= 0 && key <= KEY_MAX) { 33373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(key, mKeyBitmask)) { 33473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t keyState[sizeofBitArray(KEY_CNT)]; 33573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn memset(keyState, 0, sizeof(keyState)); 33673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGKEY(sizeof(keyState)), keyState)) >= 0) { 33773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(key, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; 33873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 33973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 34073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 34173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return AKEY_STATE_UNKNOWN; 34273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 34373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 34473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournint32_t EvdevDeviceNode::getSwitchState(int32_t sw) const { 34573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (sw >= 0 && sw <= SW_MAX) { 34673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(sw, mSwBitmask)) { 34773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint8_t swState[sizeofBitArray(SW_CNT)]; 34873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn memset(swState, 0, sizeof(swState)); 34973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGSW(sizeof(swState)), swState)) >= 0) { 35073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return testBit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; 35173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 35273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 35373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 35473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return AKEY_STATE_UNKNOWN; 35573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 35673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 35773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t EvdevDeviceNode::getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const { 35873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn *outValue = 0; 35973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 36073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (axis >= 0 && axis <= ABS_MAX) { 36173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (testBit(axis, mAbsBitmask)) { 36273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_absinfo info; 36373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGABS(axis), &info))) { 36473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", 36573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn axis, mPath.c_str(), mFd, errno); 36673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 36773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 36873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 36973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn *outValue = info.value; 37073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 37173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 37273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 37373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -1; 37473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 37573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 37673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid EvdevDeviceNode::vibrate(nsecs_t duration) { 37773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ff_effect effect{}; 37873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.type = FF_RUMBLE; 37973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.id = mFfEffectId; 38073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.u.rumble.strong_magnitude = 0xc000; 38173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.u.rumble.weak_magnitude = 0xc000; 38273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.replay.length = (duration + 999'999LL) / 1'000'000LL; 38373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn effect.replay.delay = 0; 38473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCSFF, &effect))) { 38573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not upload force feedback effect to device %s due to error %d.", 38673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 38773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return; 38873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 38973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFfEffectId = effect.id; 39073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 39173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_event ev{}; 39273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.type = EV_FF; 39373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.code = mFfEffectId; 39473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.value = 1; 39573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t written = TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(ev))); 39673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (written != sizeof(ev)) { 39773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not start force feedback effect on device %s due to error %d.", 39873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 39973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return; 40073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 40173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFfEffectPlaying = true; 40273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 40373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 4043186e7bf4805b317769470137ffcf1f7eb0215e0Tim Kilbournvoid EvdevDeviceNode::cancelVibrate() { 40573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mFfEffectPlaying) { 40673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mFfEffectPlaying = false; 40773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 40873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_event ev{}; 40973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.type = EV_FF; 41073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.code = mFfEffectId; 41173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ev.value = 0; 41273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t written = TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(ev))); 41373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (written != sizeof(ev)) { 41473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not stop force feedback effect on device %s due to error %d.", 41573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 41673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return; 41773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 41873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 41973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 42073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 42173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid EvdevDeviceNode::disableDriverKeyRepeat() { 42273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn unsigned int repeatRate[] = {0, 0}; 42373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCSREP, repeatRate))) { 42473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Unable to disable kernel key repeat for %s due to error %d.", 42573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mPath.c_str(), errno); 42673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 42773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 42873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 429c929d2509530b0262681c8e6619609f44bfceea4Tim KilbournInputHub::InputHub(const std::shared_ptr<InputCallbackInterface>& cb) : 43073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback(cb) { 43173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Determine the type of suspend blocking we can do on this device. There 43273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // are 3 options, in decreasing order of preference: 43373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 1) EPOLLWAKEUP: introduced in Linux kernel 3.5, this flag can be set on 43473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // an epoll event to indicate that a wake lock should be held from the 43573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // time an fd has data until the next epoll_wait (or the epoll fd is 43673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // closed). 43773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 2) EVIOCSSUSPENDBLOCK: introduced into the Android kernel's evdev 43873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // driver, this ioctl blocks suspend while the event queue for the fd is 43973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // not empty. This was never accepted into the mainline kernel, and it was 44073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // replaced by EPOLLWAKEUP. 44173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 3) explicit wake locks: use acquire_wake_lock to manage suspend 44273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // blocking explicitly in the InputHub code. 44373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // 44473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // (1) can be checked by simply observing the Linux kernel version. (2) 44573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // requires an fd from an evdev node, which cannot be done in the InputHub 44673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // constructor. So we assume (3) unless (1) is true, and we can verify 44773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // whether (2) is true once we have an evdev fd (and we're not in (1)). 44873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int major, minor; 44973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn getLinuxRelease(&major, &minor); 45073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (major > 3 || (major == 3 && minor >= 5)) { 45173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Using EPOLLWAKEUP to block suspend while processing input events."); 45273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWakeupMechanism = WakeMechanism::EPOLL_WAKEUP; 45373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mNeedToCheckSuspendBlockIoctl = false; 45473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 45573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 45673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 45773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 45873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 45973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // epoll_create argument is ignored, but it must be > 0. 46073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mEpollFd = epoll_create(1); 46173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 46273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 46373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mINotifyFd = inotify_init(); 46473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(mINotifyFd < 0, "Could not create inotify instance. errno=%d", errno); 46573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 46673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct epoll_event eventItem; 46773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn memset(&eventItem, 0, sizeof(eventItem)); 46873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events = EPOLLIN; 46973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mWakeupMechanism == WakeMechanism::EPOLL_WAKEUP) { 47073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events |= EPOLLWAKEUP; 47173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 47273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.data.u32 = mINotifyFd; 47373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem); 47473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno); 47573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 47673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int wakeFds[2]; 47773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn result = pipe(wakeFds); 47873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 47973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 48073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWakeEventFd = eventfd(0, EFD_NONBLOCK); 48173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(mWakeEventFd == -1, "Could not create wake event fd. errno=%d", errno); 48273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 48373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.data.u32 = mWakeEventFd; 48473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, &eventItem); 48573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance. errno=%d", errno); 48673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 48773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 48873475a4eb2cebf06f965c58e015d06c333e71e61Tim KilbournInputHub::~InputHub() { 48973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mEpollFd); 49073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mINotifyFd); 49173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(mWakeEventFd); 49273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 49373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 49473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn release_wake_lock(WAKE_LOCK_ID); 49573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 49673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 49773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 49873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::registerDevicePath(const std::string& path) { 49973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("registering device path %s", path.c_str()); 50073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int wd = inotify_add_watch(mINotifyFd, path.c_str(), IN_DELETE | IN_CREATE); 50173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (wd < 0) { 50273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("Could not add %s to INotify watch. errno=%d", path.c_str(), errno); 50373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 50473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 50573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWatchedPaths[wd] = path; 50673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn scanDir(path); 50773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 50873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 50973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 51073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::unregisterDevicePath(const std::string& path) { 51173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int wd = -1; 51273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto pair : mWatchedPaths) { 51373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pair.second == path) { 51473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn wd = pair.first; 51573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 51673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 51773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 51873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 51973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (wd == -1) { 52073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return BAD_VALUE; 52173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 52273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWatchedPaths.erase(wd); 52373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (inotify_rm_watch(mINotifyFd, wd) != 0) { 52473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 52573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 52673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 52773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 52873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 52973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::poll() { 53073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn bool deviceChange = false; 53173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 53273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 53373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Mind the wake lock dance! 53473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // If we're relying on wake locks, we hold a wake lock at all times 53573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // except during epoll_wait(). This works due to some subtle 53673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // choreography. When a device driver has pending (unread) events, it 53773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // acquires a kernel wake lock. However, once the last pending event 53873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // has been read, the device driver will release the kernel wake lock. 53973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // To prevent the system from going to sleep when this happens, the 54073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // InputHub holds onto its own user wake lock while the client is 54173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // processing events. Thus the system can only sleep if there are no 54273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // events pending or currently being processed. 54373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn release_wake_lock(WAKE_LOCK_ID); 54473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 54573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 54673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct epoll_event pendingEventItems[EPOLL_MAX_EVENTS]; 54773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int pollResult = epoll_wait(mEpollFd, pendingEventItems, EPOLL_MAX_EVENTS, NO_TIMEOUT); 54873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 54973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (manageWakeLocks()) { 55073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 55173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 55273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 55373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pollResult == 0) { 55473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("epoll_wait should not return 0 with no timeout"); 55573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return UNKNOWN_ERROR; 55673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 55773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pollResult < 0) { 55873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // An error occurred. Return even if it's EINTR, and let the caller 55973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // restart the poll. 56073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("epoll_wait returned with errno=%d", errno); 56173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 56273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 56373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 56473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // pollResult > 0: there are events to process 56573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 56673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::vector<int> removedDeviceFds; 56773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int inputFd = -1; 56873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::shared_ptr<InputDeviceNode> deviceNode; 56973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (int i = 0; i < pollResult; ++i) { 57073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn const struct epoll_event& eventItem = pendingEventItems[i]; 57173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 57273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int dataFd = static_cast<int>(eventItem.data.u32); 57373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (dataFd == mINotifyFd) { 57473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (eventItem.events & EPOLLIN) { 57573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn deviceChange = true; 57673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 57773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); 57873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 57973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 58073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 58173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 58273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (dataFd == mWakeEventFd) { 58373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (eventItem.events & EPOLLIN) { 58473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("awoken after wake()"); 58573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint64_t u; 58673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t nRead = TEMP_FAILURE_RETRY(read(mWakeEventFd, &u, sizeof(uint64_t))); 58773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (nRead != sizeof(uint64_t)) { 58873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not read event fd; waking anyway."); 58973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 59073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 59173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Received unexpected epoll event 0x%08x for wake event.", 59273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events); 59373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 59473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 59573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 59673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 59773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // Update the fd and device node when the fd changes. When several 59873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // events are read back-to-back with the same fd, this saves many reads 59973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // from the hash table. 60073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (inputFd != dataFd) { 60173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn inputFd = dataFd; 60273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn deviceNode = mDeviceNodes[inputFd]; 60373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 60473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceNode == nullptr) { 60573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not find device node for fd %d", inputFd); 60673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 60773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 60873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (eventItem.events & EPOLLIN) { 60973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct input_event ievs[INPUT_MAX_EVENTS]; 61073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (;;) { 61173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t readSize = TEMP_FAILURE_RETRY(read(inputFd, ievs, sizeof(ievs))); 61273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { 61373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not get event, removed? (fd: %d, size: %d errno: %d)", 61473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn inputFd, readSize, errno); 61573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 61673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn removedDeviceFds.push_back(inputFd); 61773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 61873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else if (readSize < 0) { 61973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (errno != EAGAIN && errno != EINTR) { 62073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not get event. errno=%d", errno); 62173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 62273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 62373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else if (readSize % sizeof(input_event) != 0) { 62473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not get event. wrong size=%d", readSize); 62573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn break; 62673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 62773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t count = static_cast<size_t>(readSize) / sizeof(struct input_event); 62873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (size_t i = 0; i < count; ++i) { 62973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto& iev = ievs[i]; 63073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto when = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); 63173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn InputEvent inputEvent = { when, iev.type, iev.code, iev.value }; 63273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onInputEvent(deviceNode, inputEvent, now); 63373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 63473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 63573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 63673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else if (eventItem.events & EPOLLHUP) { 63773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Removing device fd %d due to epoll hangup event.", inputFd); 63873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn removedDeviceFds.push_back(inputFd); 63973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 64073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Received unexpected epoll event 0x%08x for device fd %d", 64173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events, inputFd); 64273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 64473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 64573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (removedDeviceFds.size()) { 64673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto deviceFd : removedDeviceFds) { 64773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto deviceNode = mDeviceNodes[deviceFd]; 64873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceNode != nullptr) { 64973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t ret = closeNodeByFd(deviceFd); 65073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (ret != OK) { 65173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not close device with fd %d. errno=%d", deviceFd, ret); 65273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 65373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceRemoved(deviceNode); 65473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 65573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 65673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 65773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 65873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 65973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceChange) { 66073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn readNotify(); 66173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 66273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 66373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 66473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 66573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 66673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::wake() { 66773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("wake() called"); 66873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 66973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn uint64_t u = 1; 67073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &u, sizeof(uint64_t))); 67173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 67273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (nWrite != sizeof(uint64_t) && errno != EAGAIN) { 67373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not write wake signal, errno=%d", errno); 67473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 67573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 67673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 67773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 67873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 67973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournvoid InputHub::dump(String8& dump) { 68073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // TODO 68173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 68273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 68373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::readNotify() { 68473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn char event_buf[512]; 68573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct inotify_event* event; 68673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 68773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ssize_t res = TEMP_FAILURE_RETRY(read(mINotifyFd, event_buf, sizeof(event_buf))); 68873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (res < static_cast<int>(sizeof(*event))) { 68973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not get inotify event, %s\n", strerror(errno)); 69073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 69173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 69273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 69373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn size_t event_pos = 0; 69473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 69573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn while (res >= static_cast<int>(sizeof(*event))) { 69673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn event = reinterpret_cast<struct inotify_event*>(event_buf + event_pos); 69773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (event->len) { 69873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string path = mWatchedPaths[event->wd]; 69973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn path.append("/").append(event->name); 70073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("inotify event for path %s", path.c_str()); 70173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 70273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (event->mask & IN_CREATE) { 703c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn auto deviceNode = openNode(path); 704c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn if (deviceNode == nullptr) { 70573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open device node %s. err=%d", path.c_str(), res); 70673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 70773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceAdded(deviceNode); 70873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 70973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 71073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto deviceNode = findNodeByPath(path); 71173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (deviceNode != nullptr) { 712c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn status_t ret = closeNode(deviceNode.get()); 71373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (ret != OK) { 71473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not close device %s. errno=%d", path.c_str(), ret); 71573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 71673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceRemoved(deviceNode); 71773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 71873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 71973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("could not find device node for %s", path.c_str()); 72073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 72173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 72273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 72373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn int event_size = sizeof(*event) + event->len; 72473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn res -= event_size; 72573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn event_pos += event_size; 72673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 72773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 72873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 72973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 73073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 73173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::scanDir(const std::string& path) { 73273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto dir = ::opendir(path.c_str()); 73373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (dir == nullptr) { 73473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open device path %s to scan for devices. err=%d", path.c_str(), errno); 73573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return -errno; 73673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 73773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 73873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn while (auto dirent = readdir(dir)) { 73973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (strcmp(dirent->d_name, ".") == 0 || 74073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn strcmp(dirent->d_name, "..") == 0) { 74173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn continue; 74273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 74373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn std::string filename = path + "/" + dirent->d_name; 744c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn auto node = openNode(filename); 745c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn if (node == nullptr) { 74673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("could not open device node %s", filename.c_str()); 74773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 74873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mInputCallback->onDeviceAdded(node); 74973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 75073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 75173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::closedir(dir); 75273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return OK; 75373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 75473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 755c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbournstd::shared_ptr<InputDeviceNode> InputHub::openNode(const std::string& path) { 75673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("opening %s...", path.c_str()); 75773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto evdevNode = std::shared_ptr<EvdevDeviceNode>(EvdevDeviceNode::openDeviceNode(path)); 75873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (evdevNode == nullptr) { 759c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn return nullptr; 76073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 76173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 76273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn auto fd = evdevNode->getFd(); 76373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGV("opened %s with fd %d", path.c_str(), fd); 764c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn mDeviceNodes[fd] = evdevNode; 76573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn struct epoll_event eventItem{}; 76673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events = EPOLLIN; 76773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mWakeupMechanism == WakeMechanism::EPOLL_WAKEUP) { 76873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.events |= EPOLLWAKEUP; 76973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 77073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn eventItem.data.u32 = fd; 77173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) { 77273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGE("Could not add device fd to epoll instance. errno=%d", errno); 773c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn return nullptr; 77473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 77573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 77673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (mNeedToCheckSuspendBlockIoctl) { 77773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#ifndef EVIOCSSUSPENDBLOCK 77873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels 77973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // will use an epoll flag instead, so as long as we want to support this 78073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // feature, we need to be prepared to define the ioctl ourselves. 78173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int) 78273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn#endif 78373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (TEMP_FAILURE_RETRY(ioctl(fd, EVIOCSSUSPENDBLOCK, 1))) { 78473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // no wake mechanism, continue using explicit wake locks 78573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Using explicit wakelocks to block suspend while processing input events."); 78673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } else { 78773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mWakeupMechanism = WakeMechanism::LEGACY_EVDEV_SUSPENDBLOCK_IOCTL; 78873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn // release any held wakelocks since we won't need them anymore 78973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn release_wake_lock(WAKE_LOCK_ID); 79073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGI("Using EVIOCSSUSPENDBLOCK to block suspend while processing input events."); 79173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 79273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mNeedToCheckSuspendBlockIoctl = false; 79373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 79473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 795c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn return evdevNode; 79673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 79773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 798c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbournstatus_t InputHub::closeNode(const InputDeviceNode* node) { 79973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto pair : mDeviceNodes) { 800c929d2509530b0262681c8e6619609f44bfceea4Tim Kilbourn if (pair.second.get() == node) { 80173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return closeNodeByFd(pair.first); 80273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 80373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 80473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return BAD_VALUE; 80573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 80673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 80773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstatus_t InputHub::closeNodeByFd(int fd) { 80873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn status_t ret = OK; 80973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL)) { 81073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ALOGW("Could not remove device fd from epoll instance. errno=%d", errno); 81173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ret = -errno; 81273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 81373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn mDeviceNodes.erase(fd); 81473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn ::close(fd); 81573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return ret; 81673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 81773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 81873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournstd::shared_ptr<InputDeviceNode> InputHub::findNodeByPath(const std::string& path) { 81973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn for (auto pair : mDeviceNodes) { 82073475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn if (pair.second->getPath() == path) return pair.second; 82173475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn } 82273475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return nullptr; 82373475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 82473475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 82573475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbournbool InputHub::manageWakeLocks() const { 82673475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn return mWakeupMechanism != WakeMechanism::EPOLL_WAKEUP; 82773475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} 82873475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn 82973475a4eb2cebf06f965c58e015d06c333e71e61Tim Kilbourn} // namespace android 830