Merge changes from topic "revert-31063667-ZXNTVOTPQF" into main
* changes:
Revert "[8/n InputDispatcher refactor] move input connections to a subclass"
Revert "[9/n Dispatcher refactor] Move computeTouchOcclusionInfo..."
Revert "[10/n Dispatcher refactor] Move obscuring related method..."
Revert "[11/n Dispatcher refactor] Move isTouchTrusted to WindowInfo"
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 266e691..fcd784d 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -918,21 +918,6 @@
return inputTarget;
}
-std::string dumpWindowForTouchOcclusion(const WindowInfo& info, bool isTouchedWindow) {
- return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
- "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
- "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
- "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
- isTouchedWindow ? "[TOUCHED] " : "", info.packageName.c_str(),
- info.ownerUid.toString().c_str(), info.id,
- toString(info.touchOcclusionMode).c_str(), info.alpha, info.frame.left,
- info.frame.top, info.frame.right, info.frame.bottom,
- dumpRegion(info.touchableRegion).c_str(), info.name.c_str(),
- info.inputConfig.string().c_str(), toString(info.token != nullptr),
- info.applicationInfo.name.c_str(),
- binderToString(info.applicationInfo.token).c_str());
-}
-
} // namespace
// --- InputDispatcher ---
@@ -943,17 +928,16 @@
InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)
: mPolicy(policy),
- mLooper(sp<Looper>::make(false)),
mPendingEvent(nullptr),
mLastDropReason(DropReason::NOT_DROPPED),
mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL),
- mConnectionManager(mLooper),
mNextUnblockedEvent(nullptr),
mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
mDispatchEnabled(false),
mDispatchFrozen(false),
mInputFilterEnabled(false),
+ mMaximumObscuringOpacityForTouch(1.0f),
mFocusedDisplayId(ui::LogicalDisplayId::DEFAULT),
mWindowTokenWithPointerCapture(nullptr),
mAwaitedApplicationDisplayId(ui::LogicalDisplayId::INVALID),
@@ -964,6 +948,7 @@
: std::move(std::unique_ptr<InputEventTimelineProcessor>(
new LatencyAggregator()))),
mLatencyTracker(*mInputEventTimelineProcessor) {
+ mLooper = sp<Looper>::make(false);
mReporter = createInputReporter();
mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
@@ -986,6 +971,11 @@
releasePendingEventLocked();
drainInboundQueueLocked();
mCommandQueue.clear();
+
+ while (!mConnectionsByToken.empty()) {
+ std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
+ removeInputChannelLocked(connection, /*notify=*/false);
+ }
}
status_t InputDispatcher::start() {
@@ -1102,8 +1092,7 @@
}
// If we reached here, we have an unresponsive connection.
- std::shared_ptr<Connection> connection =
- mConnectionManager.getConnection(mAnrTracker.firstToken());
+ std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
if (connection == nullptr) {
ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
return nextAnrCheck;
@@ -1355,7 +1344,7 @@
motionEntry.deviceId, mTouchStatesByDisplay);
for (const auto& windowHandle : touchedSpies) {
const std::shared_ptr<Connection> connection =
- mConnectionManager.getConnection(windowHandle->getToken());
+ getConnectionLocked(windowHandle->getToken());
if (connection != nullptr && connection->responsive) {
// This spy window could take more input. Drop all events preceding this
// event, so that the spy window can get a chance to receive the stream.
@@ -1738,8 +1727,7 @@
void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
std::shared_ptr<const FocusEntry> entry) {
- std::shared_ptr<Connection> connection =
- mConnectionManager.getConnection(entry->connectionToken);
+ std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken);
if (connection == nullptr) {
return; // Connection has gone away
}
@@ -1807,7 +1795,7 @@
}
}
- auto connection = mConnectionManager.getConnection(token);
+ auto connection = getConnectionLocked(token);
if (connection == nullptr) {
// Window has gone away, clean up Pointer Capture state.
mWindowTokenWithPointerCapture = nullptr;
@@ -1846,7 +1834,7 @@
if (token == nullptr) {
continue;
}
- std::shared_ptr<Connection> connection = mConnectionManager.getConnection(token);
+ std::shared_ptr<Connection> connection = getConnectionLocked(token);
if (connection == nullptr) {
continue; // Connection has gone away
}
@@ -1970,8 +1958,7 @@
InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
// Add monitor channels from event's or focused display.
- ui::LogicalDisplayId displayId = getTargetDisplayId(*entry);
- addGlobalMonitoringTargetsLocked(inputTargets, displayId);
+ addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
if (mTracer) {
ensureEventTraced(*entry);
@@ -2113,8 +2100,7 @@
}
// Add monitor channels from event's or focused display.
- ui::LogicalDisplayId displayId = getTargetDisplayId(*entry);
- addGlobalMonitoringTargetsLocked(inputTargets, displayId);
+ addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
if (mTracer) {
ensureEventTraced(*entry);
@@ -2141,8 +2127,7 @@
void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
std::shared_ptr<const DragEntry> entry) {
- std::shared_ptr<Connection> connection =
- mConnectionManager.getConnection(entry->connectionToken);
+ std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken);
if (connection == nullptr) {
return; // Connection has gone away
}
@@ -2386,6 +2371,26 @@
return focusedWindowHandle;
}
+/**
+ * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
+ * that are currently unresponsive.
+ */
+std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
+ const std::vector<Monitor>& monitors) const {
+ std::vector<Monitor> responsiveMonitors;
+ std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
+ [](const Monitor& monitor) REQUIRES(mLock) {
+ std::shared_ptr<Connection> connection = monitor.connection;
+ if (!connection->responsive) {
+ ALOGW("Unresponsive monitor %s will not get the new gesture",
+ connection->getInputChannelName().c_str());
+ return false;
+ }
+ return true;
+ });
+ return responsiveMonitors;
+}
+
base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) {
ATRACE_CALL();
@@ -2505,9 +2510,9 @@
if (isSplit) {
targetFlags |= InputTarget::Flags::SPLIT;
}
- if (mWindowInfos.isWindowObscuredAtPoint(windowHandle, x, y)) {
+ if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
- } else if (mWindowInfos.isWindowObscured(windowHandle)) {
+ } else if (isWindowObscuredLocked(windowHandle)) {
targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
}
@@ -2538,8 +2543,7 @@
if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
windowHandle->getInfo()->inputConfig.test(
gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
- sp<WindowInfoHandle> wallpaper =
- mWindowInfos.findWallpaperWindowBelow(windowHandle);
+ sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
if (wallpaper != nullptr) {
ftl::Flags<InputTarget::Flags> wallpaperFlags =
InputTarget::Flags::WINDOW_IS_OBSCURED |
@@ -2652,9 +2656,9 @@
if (isSplit) {
targetFlags |= InputTarget::Flags::SPLIT;
}
- if (mWindowInfos.isWindowObscuredAtPoint(newTouchedWindowHandle, x, y)) {
+ if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
- } else if (mWindowInfos.isWindowObscured(newTouchedWindowHandle)) {
+ } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
}
@@ -2937,8 +2941,7 @@
const WindowInfo* windowInfo = windowHandle->getInfo();
if (it == inputTargets.end()) {
- std::shared_ptr<Connection> connection =
- mConnectionManager.getConnection(windowHandle->getToken());
+ std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken());
if (connection == nullptr) {
ALOGW("Not creating InputTarget for %s, no input channel",
windowHandle->getName().c_str());
@@ -2992,8 +2995,7 @@
const WindowInfo* windowInfo = windowHandle->getInfo();
if (it == inputTargets.end()) {
- std::shared_ptr<Connection> connection =
- mConnectionManager.getConnection(windowHandle->getToken());
+ std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken());
if (connection == nullptr) {
ALOGW("Not creating InputTarget for %s, no input channel",
windowHandle->getName().c_str());
@@ -3028,31 +3030,18 @@
void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
ui::LogicalDisplayId displayId) {
- ui::Transform displayTransform = mWindowInfos.getDisplayTransform(displayId);
- mConnectionManager
- .forEachGlobalMonitorConnection(displayId,
- [&](const std::shared_ptr<Connection>& connection) {
- if (!connection->responsive) {
- ALOGW("Ignoring unrsponsive monitor: %s",
- connection->getInputChannelName()
- .c_str());
- return;
- }
+ auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
+ if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
- InputTarget target{connection};
- // target.firstDownTimeInTarget is not set for
- // global monitors. It is only required in split
- // touch and global monitoring works as intended
- // even without setting firstDownTimeInTarget. Since
- // global monitors don't have windows, use the
- // display transform as the raw transform.
- base::ScopedLockAssertion assumeLocked(mLock);
- target.rawTransform =
- mWindowInfos.getDisplayTransform(displayId);
- target.setDefaultPointerTransform(
- target.rawTransform);
- inputTargets.push_back(target);
- });
+ for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
+ InputTarget target{monitor.connection};
+ // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
+ // touch and global monitoring works as intended even without setting firstDownTimeInTarget.
+ // Since global monitors don't have windows, use the display transform as the raw transform.
+ target.rawTransform = mWindowInfos.getDisplayTransform(displayId);
+ target.setDefaultPointerTransform(target.rawTransform);
+ inputTargets.push_back(target);
+ }
}
/**
@@ -3108,12 +3097,12 @@
*
* If neither of those is true, then it means the touch can be allowed.
*/
-InputDispatcher::DispatcherWindowInfo::TouchOcclusionInfo
-InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo(
+InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
const WindowInfo* windowInfo = windowHandle->getInfo();
ui::LogicalDisplayId displayId = windowInfo->displayId;
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
TouchOcclusionInfo info;
info.hasBlockingOcclusion = false;
info.obscuringOpacity = 0;
@@ -3125,11 +3114,12 @@
}
const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) &&
- windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId)) &&
+ windowOccludesTouchAt(*otherInfo, displayId, x, y,
+ mWindowInfos.getDisplayTransform(displayId)) &&
!haveSameApplicationToken(windowInfo, otherInfo)) {
if (DEBUG_TOUCH_OCCLUSION) {
info.debugInfo.push_back(
- dumpWindowForTouchOcclusion(*otherInfo, /*isTouchedWindow=*/false));
+ dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
}
// canBeObscuredBy() has returned true above, which means this window is untrusted, so
// we perform the checks below to see if the touch can be propagated or not based on the
@@ -3157,14 +3147,28 @@
}
}
if (DEBUG_TOUCH_OCCLUSION) {
- info.debugInfo.push_back(
- dumpWindowForTouchOcclusion(*windowInfo, /*isTouchedWindow=*/true));
+ info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
}
return info;
}
-bool InputDispatcher::DispatcherWindowInfo::isTouchTrusted(
- const TouchOcclusionInfo& occlusionInfo) const {
+std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
+ bool isTouchedWindow) const {
+ return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
+ "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
+ "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
+ "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
+ isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
+ info->ownerUid.toString().c_str(), info->id,
+ toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
+ info->frame.top, info->frame.right, info->frame.bottom,
+ dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
+ info->inputConfig.string().c_str(), toString(info->token != nullptr),
+ info->applicationInfo.name.c_str(),
+ binderToString(info->applicationInfo.token).c_str());
+}
+
+bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
if (occlusionInfo.hasBlockingOcclusion) {
ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
occlusionInfo.obscuringUid.toString().c_str());
@@ -3180,27 +3184,29 @@
return true;
}
-bool InputDispatcher::DispatcherWindowInfo::isWindowObscuredAtPoint(
- const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
+bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
+ float x, float y) const {
ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
break; // All future windows are below us. Exit early.
}
const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) &&
- windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId))) {
+ windowOccludesTouchAt(*otherInfo, displayId, x, y,
+ mWindowInfos.getDisplayTransform(displayId))) {
return true;
}
}
return false;
}
-bool InputDispatcher::DispatcherWindowInfo::isWindowObscured(
- const sp<WindowInfoHandle>& windowHandle) const {
+bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
- const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
+ mWindowInfos.getWindowHandlesForDisplay(displayId);
const WindowInfo* windowInfo = windowHandle->getInfo();
for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
@@ -3994,7 +4000,7 @@
int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
std::scoped_lock _l(mLock);
- std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken);
+ std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
if (connection == nullptr) {
ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
connectionToken.get(), events);
@@ -4102,12 +4108,12 @@
void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
const CancelationOptions& options) {
- mConnectionManager.forEachGlobalMonitorConnection(
- [&](const std::shared_ptr<Connection>& connection) {
- base::ScopedLockAssertion assumeLocked(mLock);
- synthesizeCancelationEventsForConnectionLocked(connection, options,
- /*window=*/nullptr);
- });
+ for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
+ for (const Monitor& monitor : monitors) {
+ synthesizeCancelationEventsForConnectionLocked(monitor.connection, options,
+ /*window=*/nullptr);
+ }
+ }
}
void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
@@ -4125,7 +4131,7 @@
}
std::shared_ptr<Connection> resolvedConnection =
- connection ? connection : mConnectionManager.getConnection(windowHandle->getToken());
+ connection ? connection : getConnectionLocked(windowHandle->getToken());
if (!resolvedConnection) {
LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName();
return;
@@ -5270,9 +5276,8 @@
return dump;
}
-bool InputDispatcher::canWindowReceiveMotionLocked(
- const sp<android::gui::WindowInfoHandle>& window,
- const android::inputdispatcher::MotionEntry& motionEntry) const {
+bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
+ const MotionEntry& motionEntry) const {
const WindowInfo& info = *window->getInfo();
// Skip spy window targets that are not valid for targeted injection.
@@ -5291,7 +5296,7 @@
return false;
}
- std::shared_ptr<Connection> connection = mConnectionManager.getConnection(window->getToken());
+ std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
if (connection == nullptr) {
ALOGW("Not sending touch to %s because there's no corresponding connection",
window->getName().c_str());
@@ -5305,9 +5310,8 @@
// Drop events that can't be trusted due to occlusion
const auto [x, y] = resolveTouchedPosition(motionEntry);
- DispatcherWindowInfo::TouchOcclusionInfo occlusionInfo =
- mWindowInfos.computeTouchOcclusionInfo(window, x, y);
- if (!mWindowInfos.isTouchTrusted(occlusionInfo)) {
+ TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
+ if (!isTouchTrustedLocked(occlusionInfo)) {
if (DEBUG_TOUCH_OCCLUSION) {
ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
for (const auto& log : occlusionInfo.debugInfo) {
@@ -5355,7 +5359,7 @@
std::vector<sp<WindowInfoHandle>> newHandles;
for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
const WindowInfo* info = handle->getInfo();
- if (mConnectionManager.getConnection(handle->getToken()) == nullptr) {
+ if (getConnectionLocked(handle->getToken()) == nullptr) {
const bool noInputChannel =
info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
const bool canReceiveInput =
@@ -5751,8 +5755,13 @@
}
void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
+ if (opacity < 0 || opacity > 1) {
+ LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
+ return;
+ }
+
std::scoped_lock lock(mLock);
- mWindowInfos.setMaximumObscuringOpacityForTouch(opacity);
+ mMaximumObscuringOpacityForTouch = opacity;
}
std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
@@ -5856,8 +5865,8 @@
// Synthesize cancel for old window and down for new window.
ScopedSyntheticEventTracer traceContext(mTracer);
- std::shared_ptr<Connection> fromConnection = mConnectionManager.getConnection(fromToken);
- std::shared_ptr<Connection> toConnection = mConnectionManager.getConnection(toToken);
+ std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
+ std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
if (fromConnection != nullptr && toConnection != nullptr) {
fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
@@ -6032,9 +6041,17 @@
dump += addLinePrefix(mWindowInfos.dumpDisplayAndWindowInfo(), INDENT);
- const nsecs_t currentTime = now();
+ if (!mGlobalMonitorsByDisplay.empty()) {
+ for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
+ dump += StringPrintf(INDENT "Global monitors on display %s:\n",
+ displayId.toString().c_str());
+ dumpMonitors(dump, monitors);
+ }
+ } else {
+ dump += INDENT "Global Monitors: <none>\n";
+ }
- dump += addLinePrefix(mConnectionManager.dump(currentTime), INDENT);
+ const nsecs_t currentTime = now();
// Dump recently dispatched or dropped events from oldest to newest.
if (!mRecentQueue.empty()) {
@@ -6077,6 +6094,37 @@
dump += INDENT "CommandQueue: <empty>\n";
}
+ if (!mConnectionsByToken.empty()) {
+ dump += INDENT "Connections:\n";
+ for (const auto& [token, connection] : mConnectionsByToken) {
+ dump += StringPrintf(INDENT2 "%i: channelName='%s', "
+ "status=%s, monitor=%s, responsive=%s\n",
+ connection->inputPublisher.getChannel().getFd(),
+ connection->getInputChannelName().c_str(),
+ ftl::enum_string(connection->status).c_str(),
+ toString(connection->monitor), toString(connection->responsive));
+
+ if (!connection->outboundQueue.empty()) {
+ dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
+ connection->outboundQueue.size());
+ dump += dumpQueue(connection->outboundQueue, currentTime);
+ }
+
+ if (!connection->waitQueue.empty()) {
+ dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
+ connection->waitQueue.size());
+ dump += dumpQueue(connection->waitQueue, currentTime);
+ }
+ std::string inputStateDump = streamableToString(connection->inputState);
+ if (!inputStateDump.empty()) {
+ dump += INDENT3 "InputState: ";
+ dump += inputStateDump + "\n";
+ }
+ }
+ } else {
+ dump += INDENT "Connections: <none>\n";
+ }
+
if (!mTouchModePerDisplay.empty()) {
dump += INDENT "TouchModePerDisplay:\n";
for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
@@ -6097,6 +6145,16 @@
dump += mTracer == nullptr ? "Disabled" : "Enabled";
}
+void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
+ const size_t numMonitors = monitors.size();
+ for (size_t i = 0; i < numMonitors; i++) {
+ const Monitor& monitor = monitors[i];
+ const std::shared_ptr<Connection>& connection = monitor.connection;
+ dump += StringPrintf(INDENT2 "%zu: '%s', ", i, connection->getInputChannelName().c_str());
+ dump += "\n";
+ }
+}
+
class LooperEventCallback : public LooperCallback {
public:
LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
@@ -6123,8 +6181,14 @@
std::scoped_lock _l(mLock);
const sp<IBinder>& token = serverChannel->getConnectionToken();
const int fd = serverChannel->getFd();
+ std::shared_ptr<Connection> connection =
+ std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
+ mIdGenerator);
- mConnectionManager.createConnection(std::move(serverChannel), mIdGenerator);
+ auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection);
+ if (!inserted) {
+ ALOGE("Created a new connection, but the token %p is already known", token.get());
+ }
std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
this, std::placeholders::_1, token);
@@ -6157,11 +6221,19 @@
const sp<IBinder>& token = serverChannel->getConnectionToken();
const int fd = serverChannel->getFd();
+ std::shared_ptr<Connection> connection =
+ std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/true,
+ mIdGenerator);
+
+ auto [_, inserted] = mConnectionsByToken.emplace(token, connection);
+ if (!inserted) {
+ ALOGE("Created a new connection, but the token %p is already known", token.get());
+ }
+
std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
this, std::placeholders::_1, token);
- mConnectionManager.createGlobalInputMonitor(displayId, std::move(serverChannel),
- mIdGenerator, pid);
+ mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
nullptr);
@@ -6175,14 +6247,14 @@
status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
{ // acquire lock
std::scoped_lock _l(mLock);
- std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken);
+ std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
if (connection == nullptr) {
// Connection can be removed via socket hang up or an explicit call to
// 'removeInputChannel'
return BAD_VALUE;
}
- status_t status = mConnectionManager.removeInputChannel(connection);
+ status_t status = removeInputChannelLocked(connection, /*notify=*/false);
if (status) {
return status;
}
@@ -6198,14 +6270,19 @@
bool notify) {
LOG_ALWAYS_FATAL_IF(connection == nullptr);
abortBrokenDispatchCycleLocked(connection, notify);
+ removeConnectionLocked(connection);
- mAnrTracker.eraseToken(connection->getToken());
- mConnectionManager.removeInputChannel(connection);
+ if (connection->monitor) {
+ removeMonitorChannelLocked(connection->getToken());
+ }
+ mLooper->removeFd(connection->inputPublisher.getChannel().getFd());
+
+ connection->status = Connection::Status::ZOMBIE;
return OK;
}
-void InputDispatcher::ConnectionManager::removeMonitorChannel(const sp<IBinder>& connectionToken) {
+void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
auto& [displayId, monitors] = *it;
std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
@@ -6226,8 +6303,7 @@
}
status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
- const std::shared_ptr<Connection> requestingConnection =
- mConnectionManager.getConnection(token);
+ const std::shared_ptr<Connection> requestingConnection = getConnectionLocked(token);
if (!requestingConnection) {
LOG(WARNING)
<< "Attempted to pilfer pointers from an un-registered channel or invalid token";
@@ -6334,8 +6410,7 @@
} // release lock
}
-std::optional<gui::Pid> InputDispatcher::ConnectionManager::findMonitorPidByToken(
- const sp<IBinder>& token) const {
+std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
for (const Monitor& monitor : monitors) {
if (monitor.connection->getToken() == token) {
@@ -6346,7 +6421,7 @@
return std::nullopt;
}
-std::shared_ptr<Connection> InputDispatcher::ConnectionManager::getConnection(
+std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
const sp<IBinder>& inputConnectionToken) const {
if (inputConnectionToken == nullptr) {
return nullptr;
@@ -6361,8 +6436,16 @@
return nullptr;
}
-void InputDispatcher::ConnectionManager::removeConnection(
- const std::shared_ptr<Connection>& connection) {
+std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
+ std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
+ if (connection == nullptr) {
+ return "<nullptr>";
+ }
+ return connection->getInputChannelName();
+}
+
+void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
+ mAnrTracker.eraseToken(connection->getToken());
mConnectionsByToken.erase(connection->getToken());
}
@@ -6590,7 +6673,7 @@
if (connection.monitor) {
ALOGW("Monitor %s is unresponsive: %s", connection.getInputChannelName().c_str(),
reason.c_str());
- pid = mConnectionManager.findMonitorPidByToken(connectionToken);
+ pid = findMonitorPidByTokenLocked(connectionToken);
} else {
// The connection is a window
ALOGW("Window %s is unresponsive: %s", connection.getInputChannelName().c_str(),
@@ -6610,7 +6693,7 @@
const sp<IBinder>& connectionToken = connection.getToken();
std::optional<gui::Pid> pid;
if (connection.monitor) {
- pid = mConnectionManager.findMonitorPidByToken(connectionToken);
+ pid = findMonitorPidByTokenLocked(connectionToken);
} else {
// The connection is a window
const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken);
@@ -7060,7 +7143,7 @@
if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
(windowHandle->getInfo()->inputConfig.test(
WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
- mWindowInfos.isWindowObscured(windowHandle))) {
+ isWindowObscuredLocked(windowHandle))) {
ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
"display %s.",
ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
@@ -7113,7 +7196,7 @@
const sp<WindowInfoHandle> oldWallpaper =
oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
const sp<WindowInfoHandle> newWallpaper =
- newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(newWindowHandle) : nullptr;
+ newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
if (oldWallpaper == newWallpaper) {
return;
}
@@ -7150,7 +7233,7 @@
const sp<WindowInfoHandle> oldWallpaper =
oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
const sp<WindowInfoHandle> newWallpaper =
- newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(toWindowHandle) : nullptr;
+ newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
if (oldWallpaper == newWallpaper) {
return;
}
@@ -7171,10 +7254,10 @@
state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
deviceId, pointers, downTimeInTarget);
std::shared_ptr<Connection> wallpaperConnection =
- mConnectionManager.getConnection(newWallpaper->getToken());
+ getConnectionLocked(newWallpaper->getToken());
if (wallpaperConnection != nullptr) {
std::shared_ptr<Connection> toConnection =
- mConnectionManager.getConnection(toWindowHandle->getToken());
+ getConnectionLocked(toWindowHandle->getToken());
toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
wallpaperFlags, traceTracker);
@@ -7182,10 +7265,10 @@
}
}
-sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWallpaperWindowBelow(
+sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
const sp<WindowInfoHandle>& windowHandle) const {
const std::vector<sp<WindowInfoHandle>>& windowHandles =
- getWindowHandlesForDisplay(windowHandle->getInfo()->displayId);
+ mWindowInfos.getWindowHandlesForDisplay(windowHandle->getInfo()->displayId);
bool foundWindow = false;
for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (!foundWindow && otherHandle != windowHandle) {
@@ -7238,130 +7321,4 @@
}
}
-InputDispatcher::ConnectionManager::ConnectionManager(sp<android::Looper> looper)
- : mLooper(looper) {}
-
-InputDispatcher::ConnectionManager::~ConnectionManager() {
- while (!mConnectionsByToken.empty()) {
- std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
- removeInputChannel(connection);
- }
-}
-
-void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
- std::function<void(const std::shared_ptr<Connection>&)> f) const {
- for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
- for (const Monitor& monitor : monitors) {
- f(monitor.connection);
- }
- }
-}
-
-void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
- ui::LogicalDisplayId displayId,
- std::function<void(const std::shared_ptr<Connection>&)> f) const {
- auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
- if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
-
- for (const Monitor& monitor : monitorsIt->second) {
- f(monitor.connection);
- }
-}
-
-void InputDispatcher::ConnectionManager::createGlobalInputMonitor(
- ui::LogicalDisplayId displayId, std::unique_ptr<InputChannel>&& inputChannel,
- const android::IdGenerator& idGenerator, gui::Pid pid) {
- std::shared_ptr<Connection> connection =
- std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/true, idGenerator);
- sp<IBinder> token = connection->getToken();
- auto [_, inserted] = mConnectionsByToken.emplace(token, connection);
- if (!inserted) {
- ALOGE("Created a new connection, but the token %p is already known", token.get());
- }
- mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
-}
-
-void InputDispatcher::ConnectionManager::createConnection(
- std::unique_ptr<InputChannel>&& inputChannel, const android::IdGenerator& idGenerator) {
- std::shared_ptr<Connection> connection =
- std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/false, idGenerator);
- sp<IBinder> token = connection->getToken();
- auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection);
- if (!inserted) {
- ALOGE("Created a new connection, but the token %p is already known", token.get());
- }
-}
-
-status_t InputDispatcher::ConnectionManager::removeInputChannel(
- const std::shared_ptr<Connection>& connection) {
- removeConnection(connection);
-
- if (connection->monitor) {
- removeMonitorChannel(connection->getToken());
- }
-
- mLooper->removeFd(connection->inputPublisher.getChannel().getFd());
-
- connection->status = Connection::Status::ZOMBIE;
- return OK;
-}
-
-std::string InputDispatcher::ConnectionManager::dump(nsecs_t currentTime) const {
- std::string dump;
- if (!mGlobalMonitorsByDisplay.empty()) {
- for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
- dump += StringPrintf("Global monitors on display %s:\n", displayId.toString().c_str());
- const size_t numMonitors = monitors.size();
- for (size_t i = 0; i < numMonitors; i++) {
- const Monitor& monitor = monitors[i];
- const std::shared_ptr<Connection>& connection = monitor.connection;
- dump += StringPrintf(INDENT "%zu: '%s', ", i,
- connection->getInputChannelName().c_str());
- dump += "\n";
- }
- }
- } else {
- dump += "Global Monitors: <none>\n";
- }
-
- if (!mConnectionsByToken.empty()) {
- dump += "Connections:\n";
- for (const auto& [token, connection] : mConnectionsByToken) {
- dump += StringPrintf(INDENT "%i: channelName='%s', "
- "status=%s, monitor=%s, responsive=%s\n",
- connection->inputPublisher.getChannel().getFd(),
- connection->getInputChannelName().c_str(),
- ftl::enum_string(connection->status).c_str(),
- toString(connection->monitor), toString(connection->responsive));
-
- if (!connection->outboundQueue.empty()) {
- dump += StringPrintf(INDENT2 "OutboundQueue: length=%zu\n",
- connection->outboundQueue.size());
- dump += dumpQueue(connection->outboundQueue, currentTime);
- }
-
- if (!connection->waitQueue.empty()) {
- dump += StringPrintf(INDENT2 "WaitQueue: length=%zu\n",
- connection->waitQueue.size());
- dump += dumpQueue(connection->waitQueue, currentTime);
- }
- std::string inputStateDump = streamableToString(connection->inputState);
- if (!inputStateDump.empty()) {
- dump += INDENT2 "InputState: ";
- dump += inputStateDump + "\n";
- }
- }
- } else {
- dump += "Connections: <none>\n";
- }
- return dump;
-}
-
-void InputDispatcher::DispatcherWindowInfo::setMaximumObscuringOpacityForTouch(float opacity) {
- if (opacity < 0 || opacity > 1) {
- LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
- }
- mMaximumObscuringOpacityForTouch = opacity;
-}
-
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 13fec2a..bca1c67 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -224,133 +224,6 @@
/** Stores the latest user-activity poke event times per user activity types. */
std::array<nsecs_t, USER_ACTIVITY_EVENT_LAST + 1> mLastUserActivityTimes GUARDED_BY(mLock);
- template <typename T>
- struct StrongPointerHash {
- std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
- };
-
- class ConnectionManager {
- public:
- ConnectionManager(sp<Looper> lopper);
- ~ConnectionManager();
-
- std::shared_ptr<Connection> getConnection(const sp<IBinder>& inputConnectionToken) const;
- std::string getConnectionName(const sp<IBinder>& connectionToken) const;
-
- // Find a monitor pid by the provided token.
- std::optional<gui::Pid> findMonitorPidByToken(const sp<IBinder>& token) const;
- void forEachGlobalMonitorConnection(
- std::function<void(const std::shared_ptr<Connection>&)> f) const;
- void forEachGlobalMonitorConnection(
- ui::LogicalDisplayId displayId,
- std::function<void(const std::shared_ptr<Connection>&)> f) const;
-
- void createGlobalInputMonitor(ui::LogicalDisplayId displayId,
- std::unique_ptr<InputChannel>&& inputChannel,
- const IdGenerator& idGenerator, gui::Pid pid);
-
- status_t removeInputChannel(const std::shared_ptr<Connection>& connection);
- void removeConnection(const std::shared_ptr<Connection>& connection);
-
- void createConnection(std::unique_ptr<InputChannel>&& inputChannel,
- const IdGenerator& idGenerator);
-
- std::string dump(nsecs_t currentTime) const;
-
- private:
- sp<Looper> mLooper;
-
- // All registered connections mapped by input channel token.
- std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>>
- mConnectionsByToken;
-
- // Input channels that will receive a copy of all input events sent to the provided display.
- std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay;
-
- void removeMonitorChannel(const sp<IBinder>& connectionToken);
- };
-
- ConnectionManager mConnectionManager GUARDED_BY(mLock);
-
- class DispatcherWindowInfo {
- public:
- struct TouchOcclusionInfo {
- bool hasBlockingOcclusion;
- float obscuringOpacity;
- std::string obscuringPackage;
- gui::Uid obscuringUid = gui::Uid::INVALID;
- std::vector<std::string> debugInfo;
- };
-
- void setWindowHandlesForDisplay(
- ui::LogicalDisplayId displayId,
- std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles);
-
- void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos);
-
- void removeDisplay(ui::LogicalDisplayId displayId);
-
- void setMaximumObscuringOpacityForTouch(float opacity);
-
- // Get a reference to window handles by display, return an empty vector if not found.
- const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay(
- ui::LogicalDisplayId displayId) const;
-
- void forEachWindowHandle(
- std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const;
-
- void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const;
-
- // Get the transform for display, returns Identity-transform if display is missing.
- ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const;
-
- // Get the raw transform to use for motion events going to the given window.
- ui::Transform getRawTransform(const android::gui::WindowInfo&) const;
-
- // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where
- // display-id is not provided lookup is done for all displays.
- sp<android::gui::WindowInfoHandle> findWindowHandle(
- const sp<IBinder>& windowHandleToken,
- std::optional<ui::LogicalDisplayId> displayId = {}) const;
-
- bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const;
-
- // Returns the touched window at the given location, excluding the ignoreWindow if provided.
- sp<android::gui::WindowInfoHandle> findTouchedWindowAt(
- ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
- const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;
-
- std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
- ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
- const;
-
- TouchOcclusionInfo computeTouchOcclusionInfo(
- const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const;
-
- bool isWindowObscured(const sp<android::gui::WindowInfoHandle>& windowHandle) const;
-
- bool isWindowObscuredAtPoint(const sp<android::gui::WindowInfoHandle>& windowHandle,
- float x, float y) const;
-
- sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
- const sp<android::gui::WindowInfoHandle>& windowHandle) const;
-
- bool isTouchTrusted(const TouchOcclusionInfo& occlusionInfo) const;
-
- std::string dumpDisplayAndWindowInfo() const;
-
- private:
- std::unordered_map<ui::LogicalDisplayId /*displayId*/,
- std::vector<sp<android::gui::WindowInfoHandle>>>
- mWindowHandlesByDisplay;
- std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo>
- mDisplayInfos;
- float mMaximumObscuringOpacityForTouch{1.0f};
- };
-
- DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);
-
// With each iteration, InputDispatcher nominally processes one queued event,
// a timeout, or a response from an input consumer.
// This method should only be called on the input dispatcher's own thread.
@@ -387,8 +260,31 @@
const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay,
ui::LogicalDisplayId displayId);
+ std::shared_ptr<Connection> getConnectionLocked(const sp<IBinder>& inputConnectionToken) const
+ REQUIRES(mLock);
+
+ std::string getConnectionNameLocked(const sp<IBinder>& connectionToken) const REQUIRES(mLock);
+
+ void removeConnectionLocked(const std::shared_ptr<Connection>& connection) REQUIRES(mLock);
+
status_t pilferPointersLocked(const sp<IBinder>& token) REQUIRES(mLock);
+ template <typename T>
+ struct StrongPointerHash {
+ std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
+ };
+
+ // All registered connections mapped by input channel token.
+ std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>>
+ mConnectionsByToken GUARDED_BY(mLock);
+
+ // Find a monitor pid by the provided token.
+ std::optional<gui::Pid> findMonitorPidByTokenLocked(const sp<IBinder>& token) REQUIRES(mLock);
+
+ // Input channels that will receive a copy of all input events sent to the provided display.
+ std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay
+ GUARDED_BY(mLock);
+
const HmacKeyManager mHmacKeyManager;
const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry,
const DispatchEntry& dispatchEntry) const;
@@ -448,6 +344,7 @@
bool mDispatchEnabled GUARDED_BY(mLock);
bool mDispatchFrozen GUARDED_BY(mLock);
bool mInputFilterEnabled GUARDED_BY(mLock);
+ float mMaximumObscuringOpacityForTouch GUARDED_BY(mLock);
// This map is not really needed, but it helps a lot with debugging (dumpsys input).
// In the java layer, touch mode states are spread across multiple DisplayContent objects,
@@ -465,6 +362,61 @@
};
sp<gui::WindowInfosListener> mWindowInfoListener;
+ class DispatcherWindowInfo {
+ public:
+ void setWindowHandlesForDisplay(
+ ui::LogicalDisplayId displayId,
+ std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles);
+
+ void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos);
+
+ void removeDisplay(ui::LogicalDisplayId displayId);
+
+ // Get a reference to window handles by display, return an empty vector if not found.
+ const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay(
+ ui::LogicalDisplayId displayId) const;
+
+ void forEachWindowHandle(
+ std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const;
+
+ void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const;
+
+ // Get the transform for display, returns Identity-transform if display is missing.
+ ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const;
+
+ // Get the raw transform to use for motion events going to the given window.
+ ui::Transform getRawTransform(const android::gui::WindowInfo&) const;
+
+ // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where
+ // display-id is not provided lookup is done for all displays.
+ sp<android::gui::WindowInfoHandle> findWindowHandle(
+ const sp<IBinder>& windowHandleToken,
+ std::optional<ui::LogicalDisplayId> displayId = {}) const;
+
+ bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const;
+
+ // Returns the touched window at the given location, excluding the ignoreWindow if provided.
+ sp<android::gui::WindowInfoHandle> findTouchedWindowAt(
+ ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
+ const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;
+
+ std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
+ ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
+ const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
+ const;
+
+ std::string dumpDisplayAndWindowInfo() const;
+
+ private:
+ std::unordered_map<ui::LogicalDisplayId /*displayId*/,
+ std::vector<sp<android::gui::WindowInfoHandle>>>
+ mWindowHandlesByDisplay;
+ std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo>
+ mDisplayInfos;
+ };
+
+ DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);
+
void setInputWindowsLocked(
const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
ui::LogicalDisplayId displayId) REQUIRES(mLock);
@@ -630,6 +582,8 @@
nsecs_t& nextWakeupTime) REQUIRES(mLock);
base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock);
+ std::vector<Monitor> selectResponsiveMonitorsLocked(
+ const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock);
void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
InputTarget::DispatchMode dispatchMode,
@@ -650,6 +604,24 @@
void addDragEventLocked(const MotionEntry& entry) REQUIRES(mLock);
void finishDragAndDrop(ui::LogicalDisplayId displayId, float x, float y) REQUIRES(mLock);
+ struct TouchOcclusionInfo {
+ bool hasBlockingOcclusion;
+ float obscuringOpacity;
+ std::string obscuringPackage;
+ gui::Uid obscuringUid = gui::Uid::INVALID;
+ std::vector<std::string> debugInfo;
+ };
+
+ TouchOcclusionInfo computeTouchOcclusionInfoLocked(
+ const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const
+ REQUIRES(mLock);
+ bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock);
+ bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+ float x, float y) const REQUIRES(mLock);
+ bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
+ REQUIRES(mLock);
+ std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info,
+ bool isTouchWindow) const;
std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
const sp<android::gui::WindowInfoHandle>& windowHandle);
@@ -717,9 +689,12 @@
// Dump state.
void dumpDispatchStateLocked(std::string& dump) const REQUIRES(mLock);
+ void dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const;
void logDispatchStateLocked() const REQUIRES(mLock);
std::string dumpPointerCaptureStateLocked() const REQUIRES(mLock);
+ // Registration.
+ void removeMonitorChannelLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock);
status_t removeInputChannelLocked(const std::shared_ptr<Connection>& connection, bool notify)
REQUIRES(mLock);
@@ -802,6 +777,9 @@
const std::unique_ptr<trace::EventTrackerInterface>& traceTracker)
REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
+ const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
+
/** Stores the value of the input flag for per device input latency metrics. */
const bool mPerDeviceInputLatencyMetricsFlag =
com::android::input::flags::enable_per_device_input_latency_metrics();