Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78eb975e authored by Usama Arif's avatar Usama Arif Committed by Siarhei Vishniakou
Browse files

Check if /dev/input exists before accessing the path



It is possible that development platforms don't have any input devices,
hence /dev/input directory won't be created. Hence check if /dev/input exists
before adding inotify watch and scanDirLocked for /dev/input.
inotify_add_watch is also added for /dev/input when it is created. for e.g.
during EventHubTest.

Test: atest inputflinger_tests (on a development board with no input
devices)
Signed-off-by: default avatarUsama Arif <usama.arif@arm.com>
Change-Id: I8675921280e351dd8885becce79a7cb4a9936c10
Merged-In: I8675921280e351dd8885becce79a7cb4a9936c10
(cherry picked from commit b27c8e63)
parent f3d34a71
Loading
Loading
Loading
Loading
+56 −19
Original line number Diff line number Diff line
@@ -63,9 +63,9 @@ using namespace android::flag_operators;

namespace android {

static const char* DEVICE_PATH = "/dev/input";
static const char* DEVICE_INPUT_PATH = "/dev/input";
// v4l2 devices go directly into /dev
static const char* VIDEO_DEVICE_PATH = "/dev";
static const char* DEVICE_PATH = "/dev";

static constexpr size_t OBFUSCATED_LENGTH = 8;

@@ -685,15 +685,23 @@ EventHub::EventHub(void)
    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));

    mINotifyFd = inotify_init();
    mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
    LOG_ALWAYS_FATAL_IF(mInputWd < 0, "Could not register INotify for %s: %s", DEVICE_PATH,
                        strerror(errno));
    if (isV4lScanningEnabled()) {
        mVideoWd = inotify_add_watch(mINotifyFd, VIDEO_DEVICE_PATH, IN_DELETE | IN_CREATE);
        LOG_ALWAYS_FATAL_IF(mVideoWd < 0, "Could not register INotify for %s: %s",
                            VIDEO_DEVICE_PATH, strerror(errno));

    std::error_code errorCode;
    bool isDeviceInotifyAdded = false;
    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
        addDeviceInputInotify();
    } else {
        addDeviceInotify();
        isDeviceInotifyAdded = true;
        if (errorCode) {
            ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
                  errorCode.message().c_str());
        }
    }

    if (isV4lScanningEnabled() && !isDeviceInotifyAdded) {
        addDeviceInotify();
    } else {
        mVideoWd = -1;
        ALOGI("Video device scanning disabled");
    }

@@ -733,6 +741,23 @@ EventHub::~EventHub(void) {
    ::close(mWakeWritePipeFd);
}

/**
 * On devices that don't have any input devices (like some development boards), the /dev/input
 * directory will be absent. However, the user may still plug in an input device at a later time.
 * Add watch for contents of /dev/input only when /dev/input appears.
 */
void EventHub::addDeviceInputInotify() {
    mDeviceInputWd = inotify_add_watch(mINotifyFd, DEVICE_INPUT_PATH, IN_DELETE | IN_CREATE);
    LOG_ALWAYS_FATAL_IF(mDeviceInputWd < 0, "Could not register INotify for %s: %s",
                        DEVICE_INPUT_PATH, strerror(errno));
}

void EventHub::addDeviceInotify() {
    mDeviceWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
    LOG_ALWAYS_FATAL_IF(mDeviceWd < 0, "Could not register INotify for %s: %s", DEVICE_PATH,
                        strerror(errno));
}

InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
    std::scoped_lock _l(mLock);
    Device* device = getDeviceLocked(deviceId);
@@ -1739,14 +1764,24 @@ void EventHub::wake() {
}

void EventHub::scanDevicesLocked() {
    status_t result = scanDirLocked(DEVICE_PATH);
    status_t result;
    std::error_code errorCode;

    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
        result = scanDirLocked(DEVICE_INPUT_PATH);
        if (result < 0) {
        ALOGE("scan dir failed for %s", DEVICE_PATH);
            ALOGE("scan dir failed for %s", DEVICE_INPUT_PATH);
        }
    } else {
        if (errorCode) {
            ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
                  errorCode.message().c_str());
        }
    }
    if (isV4lScanningEnabled()) {
        result = scanVideoDirLocked(VIDEO_DEVICE_PATH);
        result = scanVideoDirLocked(DEVICE_PATH);
        if (result != OK) {
            ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH);
            ALOGE("scan video dir failed for %s", DEVICE_PATH);
        }
    }
    if (mDevices.find(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) == mDevices.end()) {
@@ -2357,23 +2392,25 @@ status_t EventHub::readNotifyLocked() {
    while (res >= (int)sizeof(*event)) {
        event = (struct inotify_event*)(event_buf + event_pos);
        if (event->len) {
            if (event->wd == mInputWd) {
                std::string filename = std::string(DEVICE_PATH) + "/" + event->name;
            if (event->wd == mDeviceInputWd) {
                std::string filename = std::string(DEVICE_INPUT_PATH) + "/" + event->name;
                if (event->mask & IN_CREATE) {
                    openDeviceLocked(filename);
                } else {
                    ALOGI("Removing device '%s' due to inotify event\n", filename.c_str());
                    closeDeviceByPathLocked(filename);
                }
            } else if (event->wd == mVideoWd) {
            } else if (event->wd == mDeviceWd) {
                if (isV4lTouchNode(event->name)) {
                    std::string filename = std::string(VIDEO_DEVICE_PATH) + "/" + event->name;
                    std::string filename = std::string(DEVICE_PATH) + "/" + event->name;
                    if (event->mask & IN_CREATE) {
                        openVideoDeviceLocked(filename);
                    } else {
                        ALOGI("Removing video device '%s' due to inotify event", filename.c_str());
                        closeVideoDeviceByPathLocked(filename);
                    }
                } else if (strcmp(event->name, "input") == 0 && event->mask & IN_CREATE) {
                    addDeviceInputInotify();
                }
            } else {
                LOG_ALWAYS_FATAL("Unexpected inotify event, wd = %i", event->wd);
+5 −2
Original line number Diff line number Diff line
@@ -663,6 +663,9 @@ private:
    const std::unordered_map<int32_t, RawLightInfo>& getLightInfoLocked(int32_t deviceId) const
            REQUIRES(mLock);

    void addDeviceInputInotify();
    void addDeviceInotify();

    // Protect all internal state.
    mutable std::mutex mLock;

@@ -702,8 +705,8 @@ private:
    int mWakeReadPipeFd;
    int mWakeWritePipeFd;

    int mInputWd;
    int mVideoWd;
    int mDeviceInputWd;
    int mDeviceWd = -1;

    // Maximum number of signalled FDs to handle at a time.
    static const int EPOLL_MAX_EVENTS = 16;