TouchEvent (3/n) Enhancing InputDispatcher to support TouchModeEvent
This CL provides the infrastructure to dispatch TouchModeEvent via
InputDispatcher. Remaining logic like permission check, Java integration, etc will be added in next incoming CLs.
Note:
InputDispatcher::requestTouchModeChange instantiate and enqueue TouchModeEvent.
InputDispatcher::dispatchTouchModeChangeLocked notifies all windows
about the touch mode update.
Test: atest inputflinger_tests
Bug: 193718270
Change-Id: I3cfeec0e9bc33737f15d6822242f7eb5e381a119
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 1478a3c..81c64e2 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -826,6 +826,14 @@
break;
}
+ case EventEntry::Type::TOUCH_MODE_CHANGED: {
+ const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
+ dispatchTouchModeChangeLocked(currentTime, typedEntry);
+ done = true;
+ dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
+ break;
+ }
+
case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
const auto typedEntry =
std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
@@ -1006,6 +1014,7 @@
LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
break;
}
+ case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR:
@@ -1140,6 +1149,7 @@
break;
}
case EventEntry::Type::FOCUS:
+ case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
@@ -1384,6 +1394,43 @@
dropReason = DropReason::NOT_DROPPED;
}
+void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
+ const std::shared_ptr<TouchModeEntry>& entry) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ getWindowHandlesLocked(mFocusedDisplayId);
+ if (windowHandles.empty()) {
+ return;
+ }
+ const std::vector<InputTarget> inputTargets =
+ getInputTargetsFromWindowHandlesLocked(windowHandles);
+ if (inputTargets.empty()) {
+ return;
+ }
+ entry->dispatchInProgress = true;
+ dispatchEventLocked(currentTime, entry, inputTargets);
+}
+
+std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
+ const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
+ std::vector<InputTarget> inputTargets;
+ for (const sp<WindowInfoHandle>& handle : windowHandles) {
+ // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
+ const sp<IBinder>& token = handle->getToken();
+ if (token == nullptr) {
+ continue;
+ }
+ std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
+ if (channel == nullptr) {
+ continue; // Window has gone away
+ }
+ InputTarget target;
+ target.inputChannel = channel;
+ target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
+ inputTargets.push_back(target);
+ }
+ return inputTargets;
+}
+
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Preprocessing.
@@ -1746,6 +1793,7 @@
}
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::FOCUS:
+ case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR:
@@ -2732,6 +2780,10 @@
eventType = USER_ACTIVITY_EVENT_BUTTON;
break;
}
+ case EventEntry::Type::TOUCH_MODE_CHANGED: {
+ break;
+ }
+
case EventEntry::Type::FOCUS:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
@@ -2960,6 +3012,7 @@
break;
}
case EventEntry::Type::FOCUS:
+ case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::DRAG: {
break;
@@ -3178,6 +3231,16 @@
break;
}
+ case EventEntry::Type::TOUCH_MODE_CHANGED: {
+ const TouchModeEntry& touchModeEntry =
+ static_cast<const TouchModeEntry&>(eventEntry);
+ status = connection->inputPublisher
+ .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
+ touchModeEntry.inTouchMode);
+
+ break;
+ }
+
case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
const auto& captureEntry =
static_cast<const PointerCaptureChangedEntry&>(eventEntry);
@@ -3512,6 +3575,7 @@
break;
}
case EventEntry::Type::FOCUS:
+ case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::DRAG: {
LOG_ALWAYS_FATAL("Canceling %s events is not supported",
@@ -3575,6 +3639,7 @@
case EventEntry::Type::KEY:
case EventEntry::Type::FOCUS:
+ case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
@@ -4774,6 +4839,7 @@
void InputDispatcher::setInTouchMode(bool inTouchMode) {
std::scoped_lock lock(mLock);
mInTouchMode = inTouchMode;
+ // TODO(b/193718270): Fire TouchModeEvent here.
}
void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {