Add TouchVideoDevice
TouchVideoDevice will represent a video device that reports heatmaps.
The heatmaps are strength of the signal at each point of the
touchscreen, taken at a particular time.
The only purpose of TouchVideoDevice is to read TouchVideoFrames.
Test: this is a partial cherry-pick of a standalone binary that was used
to pull heatmaps. Integration tested by observing the action of
InputClassifier HAL.
Bug: 111480215
Change-Id: Iba1b38114b156d4debb5966b803f3df6cdb1b91c
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index a3ecebc..904580f 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1003,14 +1003,18 @@
} while (nWrite == -1 && errno == EINTR);
if (nWrite != 1 && errno != EAGAIN) {
- ALOGW("Could not write wake signal, errno=%d", errno);
+ ALOGW("Could not write wake signal: %s", strerror(errno));
}
}
void EventHub::scanDevicesLocked() {
- status_t res = scanDirLocked(DEVICE_PATH);
- if(res < 0) {
- ALOGE("scan dir failed for %s\n", DEVICE_PATH);
+ status_t result = scanDirLocked(DEVICE_PATH);
+ if(result < 0) {
+ ALOGE("scan dir failed for %s", DEVICE_PATH);
+ }
+ result = scanVideoDirLocked(VIDEO_DEVICE_PATH);
+ if (result != OK) {
+ ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH);
}
if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
createVirtualKeyboardLocked();
@@ -1396,6 +1400,17 @@
toString(usingClockIoctl));
}
+void EventHub::openVideoDeviceLocked(const std::string& devicePath) {
+ std::unique_ptr<TouchVideoDevice> videoDevice = TouchVideoDevice::create(devicePath);
+ if (!videoDevice) {
+ ALOGE("Could not create touch video device for %s. Ignoring", devicePath.c_str());
+ return;
+ }
+ ALOGI("Adding video device %s to list of unattached video devices",
+ videoDevice->getName().c_str());
+ mUnattachedVideoDevices.push_back(std::move(videoDevice));
+}
+
bool EventHub::isDeviceEnabled(int32_t deviceId) {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
@@ -1575,24 +1590,31 @@
return NAME_NOT_FOUND;
}
-status_t EventHub::closeDeviceByPathLocked(const char *devicePath) {
+void EventHub::closeDeviceByPathLocked(const char *devicePath) {
Device* device = getDeviceByPathLocked(devicePath);
if (device) {
closeDeviceLocked(device);
- return 0;
+ return;
}
ALOGV("Remove device: %s not found, device may already have been removed.", devicePath);
- return -1;
+}
+
+void EventHub::closeVideoDeviceByPathLocked(const std::string& devicePath) {
+ mUnattachedVideoDevices.erase(std::remove_if(mUnattachedVideoDevices.begin(),
+ mUnattachedVideoDevices.end(), [&devicePath](
+ const std::unique_ptr<TouchVideoDevice>& videoDevice) {
+ return videoDevice->getPath() == devicePath; }), mUnattachedVideoDevices.end());
}
void EventHub::closeAllDevicesLocked() {
+ mUnattachedVideoDevices.clear();
while (mDevices.size() > 0) {
closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1));
}
}
void EventHub::closeDeviceLocked(Device* device) {
- ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
+ ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x",
device->path.c_str(), device->identifier.name.c_str(), device->id,
device->fd, device->classes);
@@ -1670,7 +1692,12 @@
else if (event->wd == mVideoWd) {
if (isV4lTouchNode(event->name)) {
std::string filename = StringPrintf("%s/%s", VIDEO_DEVICE_PATH, event->name);
- ALOGV("Received an inotify event for a video device %s", filename.c_str());
+ if (event->mask & IN_CREATE) {
+ openVideoDeviceLocked(filename);
+ } else {
+ ALOGI("Removing video device '%s' due to inotify event", filename.c_str());
+ closeVideoDeviceByPathLocked(filename);
+ }
}
}
else {
@@ -1708,6 +1735,30 @@
return 0;
}
+/**
+ * Look for all dirname/v4l-touch* devices, and open them.
+ */
+status_t EventHub::scanVideoDirLocked(const std::string& dirname)
+{
+ DIR* dir;
+ struct dirent* de;
+ dir = opendir(dirname.c_str());
+ if(!dir) {
+ ALOGE("Could not open video directory %s", dirname.c_str());
+ return BAD_VALUE;
+ }
+
+ while((de = readdir(dir))) {
+ const char* name = de->d_name;
+ if (isV4lTouchNode(name)) {
+ ALOGI("Found touch video device %s", name);
+ openVideoDeviceLocked(dirname + "/" + name);
+ }
+ }
+ closedir(dir);
+ return OK;
+}
+
void EventHub::requestReopenDevices() {
ALOGV("requestReopenDevices() called");
@@ -1754,6 +1805,14 @@
dump += StringPrintf(INDENT3 "HaveKeyboardLayoutOverlay: %s\n",
toString(device->overlayKeyMap != nullptr));
}
+
+ dump += INDENT "Unattached video devices:\n";
+ for (const std::unique_ptr<TouchVideoDevice>& videoDevice : mUnattachedVideoDevices) {
+ dump += INDENT2 + videoDevice->dump() + "\n";
+ }
+ if (mUnattachedVideoDevices.empty()) {
+ dump += INDENT2 "<none>\n";
+ }
} // release lock
}