Merge changes from topic "read heatmap"
* changes:
Consume video frames
Add video device to epoll in EventHub
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index b2d2f14..18c3ded 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -220,7 +220,6 @@
// --- EventHub ---
-const int EventHub::EPOLL_SIZE_HINT;
const int EventHub::EPOLL_MAX_EVENTS;
EventHub::EventHub(void) :
@@ -762,13 +761,27 @@
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 @@
}
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);
@@ -994,6 +1028,16 @@
return event - buffer;
}
+std::vector<TouchVideoFrame> EventHub::getVideoFrames(int32_t deviceId) {
+ AutoMutex _l(mLock);
+
+ Device* device = getDeviceLocked(deviceId);
+ if (!device || !device->videoDevice) {
+ return {};
+ }
+ return device->videoDevice->consumeFrames();
+}
+
void EventHub::wake() {
ALOGV("wake() called");
@@ -1044,6 +1088,7 @@
};
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 +1117,21 @@
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 +1140,23 @@
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 +1414,7 @@
}
// 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 +1492,9 @@
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 +1705,7 @@
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 +1736,7 @@
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/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 73fcb11..3d5f1d9 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -6483,11 +6483,13 @@
}
}
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ const int32_t deviceId = getDeviceId();
+ std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId);
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId,
source, mViewport.displayId, policyFlags,
action, actionButton, flags, metaState, buttonState, edgeFlags,
deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
- xPrecision, yPrecision, downTime, /* videoFrames */ {});
+ xPrecision, yPrecision, downTime, std::move(frames));
getListener()->notifyMotion(&args);
}
diff --git a/services/inputflinger/include/EventHub.h b/services/inputflinger/include/EventHub.h
index ae70169..295aca8 100644
--- a/services/inputflinger/include/EventHub.h
+++ b/services/inputflinger/include/EventHub.h
@@ -211,6 +211,7 @@
* Returns the number of events obtained, or 0 if the timeout expired.
*/
virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) = 0;
+ virtual std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) = 0;
/*
* Query current input state.
@@ -303,6 +304,7 @@
const int32_t* keyCodes, uint8_t* outFlags) const;
virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize);
+ virtual std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId);
virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const;
virtual bool hasLed(int32_t deviceId, int32_t led) const;
@@ -381,7 +383,7 @@
}
};
- 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 +402,9 @@
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 +414,10 @@
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 +478,6 @@
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;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index b5d2090..d39d8dc 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -692,6 +692,10 @@
return 1;
}
+ virtual std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) {
+ return {};
+ }
+
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const {
Device* device = getDevice(deviceId);
if (device) {