Merge "InputDispatcher: Ensure synthesized events are associated with windows" into main
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 229d699..aeab1f8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -804,6 +804,20 @@
}
}
+std::pair<bool /*cancelPointers*/, bool /*cancelNonPointers*/> expandCancellationMode(
+ CancelationOptions::Mode mode) {
+ switch (mode) {
+ case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
+ return {true, true};
+ case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
+ return {true, false};
+ case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
+ return {false, true};
+ case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS:
+ return {false, true};
+ }
+}
+
} // namespace
// --- InputDispatcher ---
@@ -2078,7 +2092,9 @@
if (connection->status == Connection::Status::NORMAL) {
CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
"application not responding");
- synthesizeCancelationEventsForConnectionLocked(connection, options);
+ synthesizeCancelationEventsForConnectionLocked(connection, options,
+ getWindowHandleLocked(
+ connection->getToken()));
}
}
@@ -3328,7 +3344,13 @@
void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
std::shared_ptr<const EventEntry> eventEntry,
const InputTarget& inputTarget) {
- // TODO(b/210460522): Verify all targets excluding global monitors are associated with a window.
+ const bool isKeyOrMotion = eventEntry->type == EventEntry::Type::KEY ||
+ eventEntry->type == EventEntry::Type::MOTION;
+ if (isKeyOrMotion && !inputTarget.windowHandle && !connection->monitor) {
+ LOG(FATAL) << "All InputTargets for non-monitors must be associated with a window; target: "
+ << inputTarget << " connection: " << connection->getInputChannelName()
+ << " entry: " << eventEntry->getDescription();
+ }
// This is a new event.
// Enqueue a new dispatch entry onto the outbound queue for this connection.
std::unique_ptr<DispatchEntry> dispatchEntry =
@@ -3977,22 +3999,78 @@
void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
const CancelationOptions& options) {
- for (const auto& [token, connection] : mConnectionsByToken) {
- synthesizeCancelationEventsForConnectionLocked(connection, options);
+ // Cancel windows (i.e. non-monitors).
+ // A channel must have at least one window to receive any input. If a window was removed, the
+ // event streams directed to the window will already have been canceled during window removal.
+ // So there is no need to generate cancellations for connections without any windows.
+ const auto [cancelPointers, cancelNonPointers] = expandCancellationMode(options.mode);
+ // Generate cancellations for touched windows first. This is to avoid generating cancellations
+ // through a non-touched window if there are more than one window for an input channel.
+ if (cancelPointers) {
+ for (const auto& [displayId, touchState] : mTouchStatesByDisplay) {
+ if (options.displayId.has_value() && options.displayId != displayId) {
+ continue;
+ }
+ for (const auto& touchedWindow : touchState.windows) {
+ synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
+ }
+ }
}
+ // Follow up by generating cancellations for all windows, because we don't explicitly track
+ // the windows that have an ongoing focus event stream.
+ if (cancelNonPointers) {
+ for (const auto& [_, handles] : mWindowHandlesByDisplay) {
+ for (const auto& windowHandle : handles) {
+ synthesizeCancelationEventsForWindowLocked(windowHandle, options);
+ }
+ }
+ }
+
+ // Cancel monitors.
+ synthesizeCancelationEventsForMonitorsLocked(options);
}
void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
const CancelationOptions& options) {
for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
for (const Monitor& monitor : monitors) {
- synthesizeCancelationEventsForConnectionLocked(monitor.connection, options);
+ synthesizeCancelationEventsForConnectionLocked(monitor.connection, options,
+ /*window=*/nullptr);
}
}
}
+void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
+ const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options,
+ const std::shared_ptr<Connection>& connection) {
+ if (windowHandle == nullptr) {
+ LOG(FATAL) << __func__ << ": Window handle must not be null";
+ }
+ if (connection) {
+ // The connection can be optionally provided to avoid multiple lookups.
+ if (windowHandle->getToken() != connection->getToken()) {
+ LOG(FATAL) << __func__
+ << ": Wrong connection provided for window: " << windowHandle->getName();
+ }
+ }
+
+ std::shared_ptr<Connection> resolvedConnection =
+ connection ? connection : getConnectionLocked(windowHandle->getToken());
+ if (!resolvedConnection) {
+ LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName();
+ return;
+ }
+ synthesizeCancelationEventsForConnectionLocked(resolvedConnection, options, windowHandle);
+}
+
void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
- const std::shared_ptr<Connection>& connection, const CancelationOptions& options) {
+ const std::shared_ptr<Connection>& connection, const CancelationOptions& options,
+ const sp<WindowInfoHandle>& window) {
+ if (!connection->monitor && window == nullptr) {
+ LOG(FATAL) << __func__
+ << ": Cannot send event to non-monitor channel without a window - channel: "
+ << connection->getInputChannelName();
+ }
if (connection->status != Connection::Status::NORMAL) {
return;
}
@@ -4029,10 +4107,7 @@
switch (cancelationEventEntry->type) {
case EventEntry::Type::KEY: {
const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
- const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
- ? std::make_optional(keyEntry.displayId)
- : std::nullopt;
- if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
+ if (window) {
addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
/*targetFlags=*/{}, keyEntry.downTime, targets);
} else {
@@ -4043,11 +4118,7 @@
}
case EventEntry::Type::MOTION: {
const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
- const std::optional<int32_t> targetDisplay =
- motionEntry.displayId != ADISPLAY_ID_NONE
- ? std::make_optional(motionEntry.displayId)
- : std::nullopt;
- if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
+ if (window) {
std::bitset<MAX_POINTER_ID + 1> pointerIds;
for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
pointerIndex++) {
@@ -4175,17 +4246,6 @@
}
}
-void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
- const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
- if (windowHandle != nullptr) {
- std::shared_ptr<Connection> wallpaperConnection =
- getConnectionLocked(windowHandle->getToken());
- if (wallpaperConnection != nullptr) {
- synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
- }
- }
-}
-
std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
nsecs_t splitDownTime) {
@@ -5216,19 +5276,16 @@
if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
<< " in display %" << displayId;
- std::shared_ptr<Connection> touchedConnection =
- getConnectionLocked(touchedWindow.windowHandle->getToken());
- if (touchedConnection != nullptr) {
- CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
- "touched window was removed");
- synthesizeCancelationEventsForConnectionLocked(touchedConnection, options);
- // Since we are about to drop the touch, cancel the events for the wallpaper as
- // well.
- if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
- touchedWindow.windowHandle->getInfo()->inputConfig.test(
- gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
- sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
- synthesizeCancelationEventsForWindowLocked(wallpaper, options);
+ CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
+ "touched window was removed");
+ synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
+ // Since we are about to drop the touch, cancel the events for the wallpaper as
+ // well.
+ if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
+ touchedWindow.windowHandle->getInfo()->inputConfig.test(
+ gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
+ if (const auto& ww = state.getWallpaperWindow(); ww) {
+ synthesizeCancelationEventsForWindowLocked(ww, options);
}
}
state.windows.erase(state.windows.begin() + i);
@@ -5515,9 +5572,10 @@
}
const int32_t deviceId = *deviceIds.begin();
- sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
- if (toWindowHandle == nullptr) {
- ALOGW("Cannot transfer touch because to window not found.");
+ const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
+ const sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
+ if (!toWindowHandle) {
+ ALOGW("Cannot transfer touch because the transfer target window was not found.");
return false;
}
@@ -5530,7 +5588,6 @@
// Erase old window.
ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
- sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
state->removeWindowByToken(fromToken);
// Add new window.
@@ -5562,7 +5619,7 @@
fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
"transferring touch from this window to another window");
- synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
+ synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection);
synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
newTargetFlags);
@@ -6044,12 +6101,10 @@
std::string canceledWindows;
for (const TouchedWindow& w : state.windows) {
- const std::shared_ptr<Connection> connection =
- getConnectionLocked(w.windowHandle->getToken());
- if (connection != nullptr && connection->getToken() != token) {
- synthesizeCancelationEventsForConnectionLocked(connection, options);
+ if (w.windowHandle->getToken() != token) {
+ synthesizeCancelationEventsForWindowLocked(w.windowHandle, options);
canceledWindows += canceledWindows.empty() ? "[" : ", ";
- canceledWindows += connection->getInputChannelName();
+ canceledWindows += w.windowHandle->getName();
}
}
canceledWindows += canceledWindows.empty() ? "[]" : "]";
@@ -6463,7 +6518,7 @@
"or is no longer a foreground target, "
"canceling previously dispatched fallback key");
options.keyCode = *fallbackKeyCode;
- synthesizeCancelationEventsForConnectionLocked(connection, options);
+ synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection);
}
}
connection->inputState.removeFallbackKey(originalKeyCode);
@@ -6545,7 +6600,7 @@
CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
"canceling fallback, policy no longer desires it");
options.keyCode = *fallbackKeyCode;
- synthesizeCancelationEventsForConnectionLocked(connection, options);
+ synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection);
}
fallback = false;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 90a5250..f2fd0ca 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -615,18 +615,21 @@
REQUIRES(mLock);
void synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions& options)
REQUIRES(mLock);
- void synthesizeCancelationEventsForConnectionLocked(
- const std::shared_ptr<Connection>& connection, const CancelationOptions& options)
+ void synthesizeCancelationEventsForWindowLocked(const sp<gui::WindowInfoHandle>&,
+ const CancelationOptions&,
+ const std::shared_ptr<Connection>& = nullptr)
REQUIRES(mLock);
+ // This is a convenience function used to generate cancellation for a connection without having
+ // to check whether it's a monitor or a window. For non-monitors, the window handle must not be
+ // null. Always prefer the "-ForWindow" method above when explicitly dealing with windows.
+ void synthesizeCancelationEventsForConnectionLocked(
+ const std::shared_ptr<Connection>& connection, const CancelationOptions& options,
+ const sp<gui::WindowInfoHandle>& window) REQUIRES(mLock);
void synthesizePointerDownEventsForConnectionLocked(
const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
ftl::Flags<InputTarget::Flags> targetFlags) REQUIRES(mLock);
- void synthesizeCancelationEventsForWindowLocked(
- const sp<android::gui::WindowInfoHandle>& windowHandle,
- const CancelationOptions& options) REQUIRES(mLock);
-
// Splitting motion events across windows. When splitting motion event for a target,
// splitDownTime refers to the time of first 'down' event on that particular target
std::unique_ptr<MotionEntry> splitMotionEvent(const MotionEntry& originalMotionEntry,
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 8dd98e1..01bc2f3 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -5779,27 +5779,27 @@
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
// Window should receive motion event.
- firstWindowInPrimary->consumeMotionDown(SECOND_DISPLAY_ID);
+ firstWindowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
// Transfer touch focus
ASSERT_TRUE(mDispatcher->transferTouch(secondWindowInSecondary->getToken(), SECOND_DISPLAY_ID));
// The first window gets cancel.
- firstWindowInPrimary->consumeMotionCancel(SECOND_DISPLAY_ID);
- secondWindowInPrimary->consumeMotionDown(SECOND_DISPLAY_ID);
+ firstWindowInSecondary->consumeMotionCancel(SECOND_DISPLAY_ID);
+ secondWindowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(*mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
SECOND_DISPLAY_ID, {150, 50}))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
- firstWindowInPrimary->assertNoEvents();
- secondWindowInPrimary->consumeMotionMove(SECOND_DISPLAY_ID);
+ firstWindowInSecondary->assertNoEvents();
+ secondWindowInSecondary->consumeMotionMove(SECOND_DISPLAY_ID);
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionUp(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID, {150, 50}))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
- firstWindowInPrimary->assertNoEvents();
- secondWindowInPrimary->consumeMotionUp(SECOND_DISPLAY_ID);
+ firstWindowInSecondary->assertNoEvents();
+ secondWindowInSecondary->consumeMotionUp(SECOND_DISPLAY_ID);
}
TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
@@ -8290,13 +8290,13 @@
}
}
- void touchAndAssertPositions(int32_t action, const std::vector<PointF>& touchedPoints,
+ void touchAndAssertPositions(sp<FakeWindowHandle> touchedWindow, int32_t action,
+ const std::vector<PointF>& touchedPoints,
std::vector<PointF> expectedPoints) {
mDispatcher->notifyMotion(generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN,
ADISPLAY_ID_DEFAULT, touchedPoints));
- // Always consume from window1 since it's the window that has the InputReceiver
- consumeMotionEvent(mWindow1, action, expectedPoints);
+ consumeMotionEvent(touchedWindow, action, expectedPoints);
}
};
@@ -8304,15 +8304,15 @@
// Touch Window 1
PointF touchedPoint = {10, 10};
PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
// Release touch on Window 1
- touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
// Touch Window 2
touchedPoint = {150, 150};
expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow2, AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
}
TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentTransform) {
@@ -8323,21 +8323,21 @@
// Touch Window 1
PointF touchedPoint = {10, 10};
PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
// Release touch on Window 1
- touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
// Touch Window 2
touchedPoint = {150, 150};
expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
- touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow2, AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow2, AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
// Update the transform so rotation is set
mWindow2->setWindowTransform(0, -1, 1, 0);
mDispatcher->onWindowInfosChanged({{*mWindow1->getInfo(), *mWindow2->getInfo()}, {}, 0, 0});
expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
+ touchAndAssertPositions(mWindow2, AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
}
TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentTransform) {
@@ -8347,22 +8347,25 @@
// Touch Window 1
std::vector<PointF> touchedPoints = {PointF{10, 10}};
std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
// Touch Window 2
+ // Since this is part of the same touch gesture that has already been dispatched to Window 1,
+ // the touch stream from Window 2 will be merged with the stream in Window 1. The merged stream
+ // will continue to be dispatched through Window 1.
touchedPoints.push_back(PointF{150, 150});
expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
- touchAndAssertPositions(POINTER_1_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_DOWN, touchedPoints, expectedPoints);
// Release Window 2
- touchAndAssertPositions(POINTER_1_UP, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_UP, touchedPoints, expectedPoints);
expectedPoints.pop_back();
// Update the transform so rotation is set for Window 2
mWindow2->setWindowTransform(0, -1, 1, 0);
mDispatcher->onWindowInfosChanged({{*mWindow1->getInfo(), *mWindow2->getInfo()}, {}, 0, 0});
expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
- touchAndAssertPositions(POINTER_1_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_DOWN, touchedPoints, expectedPoints);
}
TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentTransform) {
@@ -8372,37 +8375,37 @@
// Touch Window 1
std::vector<PointF> touchedPoints = {PointF{10, 10}};
std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
// Touch Window 2
touchedPoints.push_back(PointF{150, 150});
expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
- touchAndAssertPositions(POINTER_1_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_DOWN, touchedPoints, expectedPoints);
// Move both windows
touchedPoints = {{20, 20}, {175, 175}};
expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
- touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
// Release Window 2
- touchAndAssertPositions(POINTER_1_UP, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_UP, touchedPoints, expectedPoints);
expectedPoints.pop_back();
// Touch Window 2
mWindow2->setWindowTransform(0, -1, 1, 0);
mDispatcher->onWindowInfosChanged({{*mWindow1->getInfo(), *mWindow2->getInfo()}, {}, 0, 0});
expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
- touchAndAssertPositions(POINTER_1_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_DOWN, touchedPoints, expectedPoints);
// Move both windows
touchedPoints = {{20, 20}, {175, 175}};
expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
- touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
}
TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
@@ -8412,20 +8415,20 @@
// Touch Window 1
std::vector<PointF> touchedPoints = {PointF{10, 10}};
std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
- touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
// Touch Window 2
touchedPoints.push_back(PointF{150, 150});
expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
- touchAndAssertPositions(POINTER_1_DOWN, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, POINTER_1_DOWN, touchedPoints, expectedPoints);
// Move both windows
touchedPoints = {{20, 20}, {175, 175}};
expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
- touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
+ touchAndAssertPositions(mWindow1, AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
}
/**
@@ -8469,7 +8472,7 @@
.pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(150))
.build());
consumeMotionEvent(mWindow1, ACTION_HOVER_EXIT, {{50, 50}});
- consumeMotionEvent(mWindow1, ACTION_HOVER_ENTER,
+ consumeMotionEvent(mWindow2, ACTION_HOVER_ENTER,
{getPointInWindow(mWindow2->getInfo(), PointF{150, 150})});
}
@@ -9608,7 +9611,7 @@
TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAllWindowsFocusable) {
setFocusedWindow(mMirror);
- // window gets focused
+ // window gets focused because it is above the mirror
mWindow->consumeFocusEvent(true);
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(*mDispatcher))
<< "Inject key event should return InputEventInjectionResult::SUCCEEDED";
@@ -9681,10 +9684,10 @@
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(*mDispatcher))
<< "Inject key event should return InputEventInjectionResult::SUCCEEDED";
- mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
+ mMirror->consumeKeyDown(ADISPLAY_ID_NONE);
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(*mDispatcher))
<< "Inject key event should return InputEventInjectionResult::SUCCEEDED";
- mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
+ mMirror->consumeKeyUp(ADISPLAY_ID_NONE);
// Both windows are removed
mDispatcher->onWindowInfosChanged({{}, {}, 0, 0});