Revert "Track hovering pointers explicitly"
Revert "Remove duplicate ACTION_HOVER_MOVE"
Revert submission 20414906-refactor hovering pointers
Reason for revert: Part of DM+Platinum monitor efforts likely Likely causing b/261731836. This won't be submitted if proven otherwise.
Reverted Changes:
I3665d8e68:Remove duplicate ACTION_HOVER_MOVE
I047926e53:Track hovering pointers explicitly
Change-Id: I64b682558071661d79dca953d449251f79ee7004
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h
index a20544b..e24344b 100644
--- a/include/input/PrintTools.h
+++ b/include/input/PrintTools.h
@@ -16,7 +16,6 @@
#pragma once
-#include <bitset>
#include <map>
#include <optional>
#include <set>
@@ -24,11 +23,6 @@
namespace android {
-template <size_t N>
-std::string bitsetToString(const std::bitset<N>& bitset) {
- return bitset.to_string();
-}
-
template <typename T>
inline std::string constToString(const T& v) {
return std::to_string(v);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 4d3e6de..4aac377 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -554,65 +554,6 @@
return std::nullopt;
}
-/**
- * Compare the old touch state to the new touch state, and generate the corresponding touched
- * windows (== input targets).
- * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
- * If the pointer just entered the new window, produce HOVER_ENTER.
- * For pointers remaining in the window, produce HOVER_MOVE.
- */
-std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
- const TouchState& newTouchState,
- const MotionEntry& entry) {
- std::vector<TouchedWindow> out;
- const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
- if (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER &&
- maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE &&
- maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
- // Not a hover event - don't need to do anything
- return out;
- }
-
- // We should consider all hovering pointers here. But for now, just use the first one
- const int32_t pointerId = entry.pointerProperties[0].id;
-
- std::set<sp<WindowInfoHandle>> oldWindows;
- if (oldState != nullptr) {
- oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId);
- }
-
- std::set<sp<WindowInfoHandle>> newWindows =
- newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId);
-
- // If the pointer is no longer in the new window set, send HOVER_EXIT.
- for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
- if (newWindows.find(oldWindow) == newWindows.end()) {
- TouchedWindow touchedWindow;
- touchedWindow.windowHandle = oldWindow;
- touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_HOVER_EXIT;
- touchedWindow.pointerIds.markBit(pointerId);
- out.push_back(touchedWindow);
- }
- }
-
- for (const sp<WindowInfoHandle>& newWindow : newWindows) {
- TouchedWindow touchedWindow;
- touchedWindow.windowHandle = newWindow;
- if (oldWindows.find(newWindow) == oldWindows.end()) {
- // Any windows that have this pointer now, and didn't have it before, should get
- // HOVER_ENTER
- touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_HOVER_ENTER;
- } else {
- // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
- LOG_ALWAYS_FATAL_IF(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE);
- touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_IS;
- }
- touchedWindow.pointerIds.markBit(pointerId);
- out.push_back(touchedWindow);
- }
- return out;
-}
-
} // namespace
// --- InputDispatcher ---
@@ -2142,6 +2083,8 @@
// Update the touch state as needed based on the properties of the touch event.
outInjectionResult = InputEventInjectionResult::PENDING;
+ sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
+ sp<WindowInfoHandle> newTouchedWindowHandle;
// Copy current touch state into tempTouchState.
// This state will be used to update mTouchStatesByDisplay at the end of this function.
@@ -2174,7 +2117,7 @@
outInjectionResult = InputEventInjectionResult::FAILED;
return touchedWindows; // wrong device
}
- tempTouchState.clearWindowsWithoutPointers();
+ tempTouchState.reset();
tempTouchState.deviceId = entry.deviceId;
tempTouchState.source = entry.source;
isSplit = false;
@@ -2187,21 +2130,14 @@
return touchedWindows; // wrong device
}
- if (isHoverAction) {
- // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
- // all of the existing hovering pointers and recompute.
- tempTouchState.clearHoveringPointers();
- }
-
if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
/* Case 1: New splittable pointer going down, or need target for hover or scroll. */
const auto [x, y] = resolveTouchedPosition(entry);
const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
const bool isStylus = isPointerFromStylus(entry, pointerIndex);
- sp<WindowInfoHandle> newTouchedWindowHandle =
- findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus,
- isDown /*addOutsideTargets*/);
+ newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
+ isStylus, isDown /*addOutsideTargets*/);
// Handle the case where we did not find a window.
if (newTouchedWindowHandle == nullptr) {
@@ -2236,6 +2172,15 @@
isSplit = !isFromMouse;
}
+ // Update hover state.
+ if (newTouchedWindowHandle != nullptr) {
+ if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
+ newHoverWindowHandle = nullptr;
+ } else if (isHoverAction) {
+ newHoverWindowHandle = newTouchedWindowHandle;
+ }
+ }
+
std::vector<sp<WindowInfoHandle>> newTouchedWindows =
findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
if (newTouchedWindowHandle != nullptr) {
@@ -2255,18 +2200,6 @@
continue;
}
- if (isHoverAction) {
- const int32_t pointerId = entry.pointerProperties[0].id;
- if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
- // Pointer left. Remove it
- tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
- } else {
- // The "windowHandle" is the target of this hovering pointer.
- tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId,
- pointerId);
- }
- }
-
// Set target flags.
ftl::Flags<InputTarget::Flags> targetFlags = InputTarget::Flags::DISPATCH_AS_IS;
@@ -2286,9 +2219,7 @@
// Update the temporary touch state.
BitSet32 pointerIds;
- if (!isHoverAction) {
- pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
- }
+ pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds,
entry.eventTime);
@@ -2324,7 +2255,7 @@
const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
sp<WindowInfoHandle> oldTouchedWindowHandle =
tempTouchState.getFirstForegroundWindowHandle();
- sp<WindowInfoHandle> newTouchedWindowHandle =
+ newTouchedWindowHandle =
findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
// Verify targeted injection.
@@ -2395,11 +2326,36 @@
}
// Update dispatching for hover enter and exit.
- {
- std::vector<TouchedWindow> hoveringWindows =
- getHoveringWindowsLocked(oldState, tempTouchState, entry);
- touchedWindows.insert(touchedWindows.end(), hoveringWindows.begin(), hoveringWindows.end());
+ if (newHoverWindowHandle != mLastHoverWindowHandle) {
+ // Let the previous window know that the hover sequence is over, unless we already did
+ // it when dispatching it as is to newTouchedWindowHandle.
+ if (mLastHoverWindowHandle != nullptr &&
+ (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
+ mLastHoverWindowHandle != newTouchedWindowHandle)) {
+ if (DEBUG_HOVER) {
+ ALOGD("Sending hover exit event to window %s.",
+ mLastHoverWindowHandle->getName().c_str());
+ }
+ tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
+ InputTarget::Flags::DISPATCH_AS_HOVER_EXIT,
+ BitSet32(0));
+ }
+
+ // Let the new window know that the hover sequence is starting, unless we already did it
+ // when dispatching it as is to newTouchedWindowHandle.
+ if (newHoverWindowHandle != nullptr &&
+ (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
+ newHoverWindowHandle != newTouchedWindowHandle)) {
+ if (DEBUG_HOVER) {
+ ALOGD("Sending hover enter event to window %s.",
+ newHoverWindowHandle->getName().c_str());
+ }
+ tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
+ InputTarget::Flags::DISPATCH_AS_HOVER_ENTER,
+ BitSet32(0));
+ }
}
+
// Ensure that we have at least one foreground window or at least one window that cannot be a
// foreground target. If we only have windows that are not receiving foreground touches (e.g. we
// only have windows getting ACTION_OUTSIDE), then drop the event, because there is no window
@@ -2489,13 +2445,10 @@
}
}
- // Success! Output targets for everything except hovers.
- if (!isHoverAction) {
- touchedWindows.insert(touchedWindows.end(), tempTouchState.windows.begin(),
- tempTouchState.windows.end());
- }
-
+ // Success! Output targets.
+ touchedWindows = tempTouchState.windows;
outInjectionResult = InputEventInjectionResult::SUCCEEDED;
+
// Drop the outside or hover touch windows since we will not care about them
// in the next iteration.
tempTouchState.filterNonAsIsTouchWindows();
@@ -2516,16 +2469,14 @@
"Conflicting pointer actions: Hover received while pointer was down.");
*outConflictingPointerActions = true;
}
+ tempTouchState.reset();
if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
tempTouchState.deviceId = entry.deviceId;
tempTouchState.source = entry.source;
}
- } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
- // Pointer went up.
- tempTouchState.removeTouchedPointer(entry.pointerProperties[0].id);
- tempTouchState.clearWindowsWithoutPointers();
- } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
+ } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
+ maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
// All pointers up or canceled.
tempTouchState.reset();
} else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
@@ -2564,6 +2515,9 @@
mTouchStatesByDisplay.erase(displayId);
}
+ // Update hover state.
+ mLastHoverWindowHandle = newHoverWindowHandle;
+
return touchedWindows;
}
@@ -4855,6 +4809,14 @@
updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ if (mLastHoverWindowHandle) {
+ const WindowInfo* lastHoverWindowInfo = mLastHoverWindowHandle->getInfo();
+ if (lastHoverWindowInfo->displayId == displayId &&
+ std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
+ windowHandles.end()) {
+ mLastHoverWindowHandle = nullptr;
+ }
+ }
std::optional<FocusResolver::FocusChanges> changes =
mFocusResolver.setInputWindows(displayId, windowHandles);
@@ -5302,6 +5264,7 @@
mAnrTracker.clear();
mTouchStatesByDisplay.clear();
+ mLastHoverWindowHandle.clear();
mReplacedKeys.clear();
}
@@ -6491,6 +6454,7 @@
synthesizeCancelationEventsForAllConnectionsLocked(options);
mTouchStatesByDisplay.clear();
+ mLastHoverWindowHandle.clear();
}
// Wake up poll loop since there might be work to do.
mLooper->wake();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 3c7ddfa..5efb39e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -530,6 +530,9 @@
// prevent unneeded wakeups.
AnrTracker mAnrTracker GUARDED_BY(mLock);
+ // Contains the last window which received a hover event.
+ sp<android::gui::WindowInfoHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
+
void cancelEventsForAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
// If a focused application changes, we should stop counting down the "no focused window" time,
// because we will have no way of knowing when the previous application actually added a window.
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index f120fc9..c21af9e 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -31,30 +31,10 @@
*this = TouchState();
}
-void TouchState::removeTouchedPointer(int32_t pointerId) {
- for (TouchedWindow& touchedWindow : windows) {
- touchedWindow.pointerIds.clearBit(pointerId);
- }
-}
-
-void TouchState::clearHoveringPointers() {
- for (TouchedWindow& touchedWindow : windows) {
- touchedWindow.clearHoveringPointers();
- }
-}
-
-void TouchState::clearWindowsWithoutPointers() {
- std::erase_if(windows, [](const TouchedWindow& w) {
- return w.pointerIds.isEmpty() && !w.hasHoveringPointers();
- });
-}
-
void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
ftl::Flags<InputTarget::Flags> targetFlags, BitSet32 pointerIds,
std::optional<nsecs_t> eventTime) {
for (TouchedWindow& touchedWindow : windows) {
- // We do not compare windows by token here because two windows that share the same token
- // may have a different transform
if (touchedWindow.windowHandle == windowHandle) {
touchedWindow.targetFlags |= targetFlags;
if (targetFlags.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT)) {
@@ -79,21 +59,6 @@
windows.push_back(touchedWindow);
}
-void TouchState::addHoveringPointerToWindow(const sp<WindowInfoHandle>& windowHandle,
- int32_t hoveringDeviceId, int32_t hoveringPointerId) {
- for (TouchedWindow& touchedWindow : windows) {
- if (touchedWindow.windowHandle == windowHandle) {
- touchedWindow.addHoveringPointer(hoveringDeviceId, hoveringPointerId);
- return;
- }
- }
-
- TouchedWindow touchedWindow;
- touchedWindow.windowHandle = windowHandle;
- touchedWindow.addHoveringPointer(hoveringDeviceId, hoveringPointerId);
- windows.push_back(touchedWindow);
-}
-
void TouchState::removeWindowByToken(const sp<IBinder>& token) {
for (size_t i = 0; i < windows.size(); i++) {
if (windows[i].windowHandle->getToken() == token) {
@@ -180,26 +145,6 @@
[](const TouchedWindow& window) { return !window.pointerIds.isEmpty(); });
}
-std::set<sp<WindowInfoHandle>> TouchState::getWindowsWithHoveringPointer(int32_t hoveringDeviceId,
- int32_t pointerId) const {
- std::set<sp<WindowInfoHandle>> out;
- for (const TouchedWindow& window : windows) {
- if (window.hasHoveringPointer(hoveringDeviceId, pointerId)) {
- out.insert(window.windowHandle);
- }
- }
- return out;
-}
-
-void TouchState::removeHoveringPointer(int32_t hoveringDeviceId, int32_t hoveringPointerId) {
- for (TouchedWindow& window : windows) {
- window.removeHoveringPointer(hoveringDeviceId, hoveringPointerId);
- }
- std::erase_if(windows, [](const TouchedWindow& w) {
- return w.pointerIds.isEmpty() && !w.hasHoveringPointers();
- });
-}
-
std::string TouchState::dump() const {
std::string out;
out += StringPrintf("deviceId=%d, source=%s\n", deviceId,
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index b75e6ef..77c1cdf 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -16,7 +16,6 @@
#pragma once
-#include <set>
#include "TouchedWindow.h"
namespace android {
@@ -40,16 +39,9 @@
TouchState& operator=(const TouchState&) = default;
void reset();
- void clearWindowsWithoutPointers();
-
- void removeTouchedPointer(int32_t pointerId);
void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
ftl::Flags<InputTarget::Flags> targetFlags, BitSet32 pointerIds,
std::optional<nsecs_t> eventTime = std::nullopt);
- void addHoveringPointerToWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
- int32_t deviceId, int32_t hoveringPointerId);
- void removeHoveringPointer(int32_t deviceId, int32_t hoveringPointerId);
- void clearHoveringPointers();
void removeWindowByToken(const sp<IBinder>& token);
void filterNonAsIsTouchWindows();
@@ -64,9 +56,6 @@
sp<android::gui::WindowInfoHandle> getWallpaperWindow() const;
// Whether any of the windows are currently being touched
bool isDown() const;
-
- std::set<sp<android::gui::WindowInfoHandle>> getWindowsWithHoveringPointer(
- int32_t deviceId, int32_t pointerId) const;
std::string dump() const;
};
diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp
index 3704edd..af74598 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.cpp
+++ b/services/inputflinger/dispatcher/TouchedWindow.cpp
@@ -25,49 +25,11 @@
namespace inputdispatcher {
-bool TouchedWindow::hasHoveringPointers() const {
- return !mHoveringPointerIdsByDevice.empty();
-}
-
-void TouchedWindow::clearHoveringPointers() {
- mHoveringPointerIdsByDevice.clear();
-}
-
-bool TouchedWindow::hasHoveringPointer(int32_t deviceId, int32_t pointerId) const {
- auto it = mHoveringPointerIdsByDevice.find(deviceId);
- if (it == mHoveringPointerIdsByDevice.end()) {
- return false;
- }
- return it->second.test(pointerId);
-}
-
-void TouchedWindow::addHoveringPointer(int32_t deviceId, int32_t pointerId) {
- const auto [it, _] = mHoveringPointerIdsByDevice.insert({deviceId, {}});
- it->second.set(pointerId);
-}
-
-void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
- const auto it = mHoveringPointerIdsByDevice.find(deviceId);
- if (it == mHoveringPointerIdsByDevice.end()) {
- return;
- }
- it->second.set(pointerId, false);
-
- if (it->second.none()) {
- mHoveringPointerIdsByDevice.erase(deviceId);
- }
-}
-
std::string TouchedWindow::dump() const {
- std::string out;
- std::string hoveringPointers =
- dumpMap(mHoveringPointerIdsByDevice, constToString, bitsetToString);
- out += StringPrintf("name='%s', pointerIds=0x%0x, targetFlags=%s, firstDownTimeInTarget=%s, "
- "mHoveringPointerIdsByDevice=%s\n",
+ return StringPrintf("name='%s', pointerIds=0x%0x, "
+ "targetFlags=%s, firstDownTimeInTarget=%s\n",
windowHandle->getName().c_str(), pointerIds.value,
- targetFlags.string().c_str(), toString(firstDownTimeInTarget).c_str(),
- hoveringPointers.c_str());
- return out;
+ targetFlags.string().c_str(), toString(firstDownTimeInTarget).c_str());
}
} // namespace inputdispatcher
diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h
index add6b61..dd08323 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.h
+++ b/services/inputflinger/dispatcher/TouchedWindow.h
@@ -17,9 +17,7 @@
#pragma once
#include <gui/WindowInfo.h>
-#include <input/Input.h>
#include <utils/BitSet.h>
-#include <bitset>
#include "InputTarget.h"
namespace android {
@@ -35,17 +33,7 @@
// Time at which the first action down occurred on this window.
// NOTE: This is not initialized in case of HOVER entry/exit and DISPATCH_AS_OUTSIDE scenario.
std::optional<nsecs_t> firstDownTimeInTarget;
-
- bool hasHoveringPointers() const;
-
- bool hasHoveringPointer(int32_t deviceId, int32_t pointerId) const;
- void addHoveringPointer(int32_t deviceId, int32_t pointerId);
- void removeHoveringPointer(int32_t deviceId, int32_t pointerId);
- void clearHoveringPointers();
std::string dump() const;
-
-private:
- std::map<int32_t /*deviceId*/, std::bitset<MAX_POINTERS>> mHoveringPointerIdsByDevice;
};
} // namespace inputdispatcher
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 9881cd4..41c174a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2135,6 +2135,7 @@
.y(400))
.build()));
windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
+ windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));
// Move cursor into left window
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -2147,6 +2148,7 @@
.build()));
windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
+ windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));
// Inject a series of mouse events for a mouse click
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -2204,6 +2206,7 @@
.build()));
windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
+ windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));
// No more events
windowLeft->assertNoEvents();
@@ -2265,6 +2268,7 @@
.y(400))
.build()));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
+
// Inject a series of mouse events for a mouse click
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
@@ -2322,38 +2326,8 @@
}
/**
- * Hover over a window, and then remove that window. Make sure that HOVER_EXIT for that event
- * is generated.
- */
-TEST_F(InputDispatcherTest, HoverExitIsSentToRemovedWindow) {
- std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
- sp<FakeWindowHandle> window =
- sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
- window->setFrame(Rect(0, 0, 1200, 800));
-
- mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
-
- mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
-
- ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
- injectMotionEvent(mDispatcher,
- MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
- AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
- .build()));
- window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
-
- // Remove the window, but keep the channel.
- mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
- window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
-}
-
-/**
* Inject a mouse hover event followed by a tap from touchscreen.
- * The tap causes a HOVER_EXIT event to be generated because the current event
- * stream's source has been switched.
+ * In the current implementation, the tap does not cause a HOVER_EXIT event.
*/
TEST_F(InputDispatcherTest, MouseHoverAndTouchTap) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
@@ -2373,16 +2347,15 @@
ASSERT_NO_FATAL_FAILURE(
window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
WithSource(AINPUT_SOURCE_MOUSE))));
+ ASSERT_NO_FATAL_FAILURE(
+ window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithSource(AINPUT_SOURCE_MOUSE))));
// Tap on the window
motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
ADISPLAY_ID_DEFAULT, {{10, 10}});
mDispatcher->notifyMotion(&motionArgs);
ASSERT_NO_FATAL_FAILURE(
- window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
- WithSource(AINPUT_SOURCE_MOUSE))));
-
- ASSERT_NO_FATAL_FAILURE(
window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithSource(AINPUT_SOURCE_TOUCHSCREEN))));
@@ -2420,6 +2393,7 @@
.y(600))
.build()));
windowDefaultDisplay->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
+ windowDefaultDisplay->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE));
// Remove all windows in secondary display and check that no event happens on window in
// primary display.