summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Siarhei Vishniakou <svv@google.com> 2018-11-02 17:19:19 -0700
committer Siarhei Vishniakou <svv@google.com> 2019-01-02 13:49:31 -0800
commit12598681b0f189ed8116d7194b3806d7771b39ba (patch)
tree55f82fe078e7a7299d132347bb638afdf1a01b3b
parent49a99b9ff288a105de660cd43ce73e0ce2e7d2f2 (diff)
Add video device to epoll in EventHub
The video device is already being watched, and we now need to start actually reading the video frames. This is done similarly to the input devices. The video device fd is added to epoll. Whenever an epoll detects new data, the frames will be added to video device's internal queue. In the subsequent commits we will consume these frames and report them to the InputClassifier HAL. Note here that registering for epoll is a bit complex. It is important to only have the video device in epoll if the input device is in epoll. There are several situations possible here: 1) Video device is found during directory traversal of /dev 2) Video device is found through inotify 3) Video device is added after matching input device 4) Video device is added before matching input device 5) Video device is added while input device is disabled 6) As long as input device is enabled, and has a video device, the video device should be part of epoll. That means input device.enable() should add the video device to epoll. Therefore, the decision here was made to registerVideoDevice inside registerDevice (=registerInputDevice), which should account for most cases. For the other corner cases, handle adding video device to epoll separately. Test: video device is being read, because InputClassifier receives video frames and classifies them. Bug: 111480215 Change-Id: I340b44a9b17182444b8a3308e3ab322ae1ad444c
-rw-r--r--services/inputflinger/EventHub.cpp75
-rw-r--r--services/inputflinger/include/EventHub.h11
2 files changed, 77 insertions, 9 deletions
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index b2d2f14bf3..aa241a00e9 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -220,7 +220,6 @@ bool EventHub::Device::hasValidFd() {
// --- EventHub ---
-const int EventHub::EPOLL_SIZE_HINT;
const int EventHub::EPOLL_MAX_EVENTS;
EventHub::EventHub(void) :
@@ -762,13 +761,27 @@ EventHub::Device* EventHub::getDeviceByPathLocked(const char* devicePath) const
return nullptr;
}
+/**
+ * The file descriptor could be either input device, or a video device (associated with a
+ * specific input device). Check both cases here, and return the device that this event
+ * belongs to. Caller can compare the fd's once more to determine event type.
+ * Looks through all input devices, and only attached video devices. Unattached video
+ * devices are ignored.
+ */
EventHub::Device* EventHub::getDeviceByFdLocked(int fd) const {
for (size_t i = 0; i < mDevices.size(); i++) {
Device* device = mDevices.valueAt(i);
if (device->fd == fd) {
+ // This is an input device event
+ return device;
+ }
+ if (device->videoDevice && device->videoDevice->getFd() == fd) {
+ // This is a video device event
return device;
}
}
+ // We do not check mUnattachedVideoDevices here because they should not participate in epoll,
+ // and therefore should never be looked up by fd.
return nullptr;
}
@@ -874,12 +887,33 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
}
Device* device = getDeviceByFdLocked(eventItem.data.fd);
- if (device == nullptr) {
- ALOGW("Received unexpected epoll event 0x%08x for unknown device fd %d.",
+ if (!device) {
+ ALOGE("Received unexpected epoll event 0x%08x for unknown fd %d.",
eventItem.events, eventItem.data.fd);
+ ALOG_ASSERT(!DEBUG);
continue;
}
-
+ if (device->videoDevice && eventItem.data.fd == device->videoDevice->getFd()) {
+ if (eventItem.events & EPOLLIN) {
+ size_t numFrames = device->videoDevice->readAndQueueFrames();
+ if (numFrames == 0) {
+ ALOGE("Received epoll event for video device %s, but could not read frame",
+ device->videoDevice->getName().c_str());
+ }
+ } else if (eventItem.events & EPOLLHUP) {
+ // TODO(b/121395353) - consider adding EPOLLRDHUP
+ ALOGI("Removing video device %s due to epoll hang-up event.",
+ device->videoDevice->getName().c_str());
+ unregisterVideoDeviceFromEpollLocked(*device->videoDevice);
+ device->videoDevice = nullptr;
+ } else {
+ ALOGW("Received unexpected epoll event 0x%08x for device %s.",
+ eventItem.events, device->videoDevice->getName().c_str());
+ ALOG_ASSERT(!DEBUG);
+ }
+ continue;
+ }
+ // This must be an input event
if (eventItem.events & EPOLLIN) {
int32_t readSize = read(device->fd, readBuffer,
sizeof(struct input_event) * capacity);
@@ -1044,6 +1078,7 @@ static const int32_t GAMEPAD_KEYCODES[] = {
};
status_t EventHub::registerFdForEpoll(int fd) {
+ // TODO(b/121395353) - consider adding EPOLLRDHUP
struct epoll_event eventItem = {};
eventItem.events = EPOLLIN | EPOLLWAKEUP;
eventItem.data.fd = fd;
@@ -1072,10 +1107,21 @@ status_t EventHub::registerDeviceForEpollLocked(Device* device) {
status_t result = registerFdForEpoll(device->fd);
if (result != OK) {
ALOGE("Could not add input device fd to epoll for device %" PRId32, device->id);
+ return result;
+ }
+ if (device->videoDevice) {
+ registerVideoDeviceForEpollLocked(*device->videoDevice);
}
return result;
}
+void EventHub::registerVideoDeviceForEpollLocked(const TouchVideoDevice& videoDevice) {
+ status_t result = registerFdForEpoll(videoDevice.getFd());
+ if (result != OK) {
+ ALOGE("Could not add video device %s to epoll", videoDevice.getName().c_str());
+ }
+}
+
status_t EventHub::unregisterDeviceFromEpollLocked(Device* device) {
if (device->hasValidFd()) {
status_t result = unregisterFdFromEpoll(device->fd);
@@ -1084,10 +1130,23 @@ status_t EventHub::unregisterDeviceFromEpollLocked(Device* device) {
return result;
}
}
+ if (device->videoDevice) {
+ unregisterVideoDeviceFromEpollLocked(*device->videoDevice);
+ }
return OK;
}
-status_t EventHub::openDeviceLocked(const char *devicePath) {
+void EventHub::unregisterVideoDeviceFromEpollLocked(const TouchVideoDevice& videoDevice) {
+ if (videoDevice.hasValidFd()) {
+ status_t result = unregisterFdFromEpoll(videoDevice.getFd());
+ if (result != OK) {
+ ALOGW("Could not remove video device fd from epoll for device: %s",
+ videoDevice.getName().c_str());
+ }
+ }
+}
+
+status_t EventHub::openDeviceLocked(const char* devicePath) {
char buffer[80];
ALOGV("Opening device: %s", devicePath);
@@ -1345,6 +1404,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
}
// Find a matching video device by comparing device names
+ // This should be done before registerDeviceForEpollLocked, so that both fds are added to epoll
for (std::unique_ptr<TouchVideoDevice>& videoDevice : mUnattachedVideoDevices) {
if (device->identifier.name == videoDevice->getName()) {
device->videoDevice = std::move(videoDevice);
@@ -1422,6 +1482,9 @@ void EventHub::openVideoDeviceLocked(const std::string& devicePath) {
Device* device = mDevices.valueAt(i);
if (videoDevice->getName() == device->identifier.name) {
device->videoDevice = std::move(videoDevice);
+ if (device->enabled) {
+ registerVideoDeviceForEpollLocked(*device->videoDevice);
+ }
return;
}
}
@@ -1632,6 +1695,7 @@ void EventHub::closeVideoDeviceByPathLocked(const std::string& devicePath) {
for (size_t i = 0; i < mDevices.size(); i++) {
Device* device = mDevices.valueAt(i);
if (device->videoDevice && device->videoDevice->getPath() == devicePath) {
+ unregisterVideoDeviceFromEpollLocked(*device->videoDevice);
device->videoDevice = nullptr;
return;
}
@@ -1662,6 +1726,7 @@ void EventHub::closeDeviceLocked(Device* device) {
unregisterDeviceFromEpollLocked(device);
if (device->videoDevice) {
+ // This must be done after the video device is removed from epoll
mUnattachedVideoDevices.push_back(std::move(device->videoDevice));
}
diff --git a/services/inputflinger/include/EventHub.h b/services/inputflinger/include/EventHub.h
index ae70169a09..dd64132f3e 100644
--- a/services/inputflinger/include/EventHub.h
+++ b/services/inputflinger/include/EventHub.h
@@ -381,7 +381,7 @@ private:
}
};
- status_t openDeviceLocked(const char *devicePath);
+ status_t openDeviceLocked(const char* devicePath);
void openVideoDeviceLocked(const std::string& devicePath);
void createVirtualKeyboardLocked();
void addDeviceLocked(Device* device);
@@ -400,7 +400,9 @@ private:
status_t registerFdForEpoll(int fd);
status_t unregisterFdFromEpoll(int fd);
status_t registerDeviceForEpollLocked(Device* device);
+ void registerVideoDeviceForEpollLocked(const TouchVideoDevice& videoDevice);
status_t unregisterDeviceFromEpollLocked(Device* device);
+ void unregisterVideoDeviceFromEpollLocked(const TouchVideoDevice& videoDevice);
status_t scanDirLocked(const char *dirname);
status_t scanVideoDirLocked(const std::string& dirname);
@@ -410,6 +412,10 @@ private:
Device* getDeviceByDescriptorLocked(const std::string& descriptor) const;
Device* getDeviceLocked(int32_t deviceId) const;
Device* getDeviceByPathLocked(const char* devicePath) const;
+ /**
+ * Look through all available fd's (both for input devices and for video devices),
+ * and return the device pointer.
+ */
Device* getDeviceByFdLocked(int fd) const;
bool hasKeycodeLocked(Device* device, int keycode) const;
@@ -470,9 +476,6 @@ private:
int mInputWd;
int mVideoWd;
- // Epoll FD list size hint.
- static const int EPOLL_SIZE_HINT = 8;
-
// Maximum number of signalled FDs to handle at a time.
static const int EPOLL_MAX_EVENTS = 16;