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