Merge changes from topic "vpa16" into main
* changes:
Plumb vpa16 checking through to cmd gpu vkprofiles
Adjust vkprofiles tool to work with landed vulkan-headers
Add VPA16 profile and regenerate
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h
index 3470be4..71c215f 100644
--- a/include/input/PrintTools.h
+++ b/include/input/PrintTools.h
@@ -19,13 +19,18 @@
#include <bitset>
#include <map>
#include <optional>
-#include <set>
+#include <ranges>
#include <sstream>
#include <string>
#include <vector>
namespace android {
+namespace internal {
+template <typename T>
+concept Container = std::ranges::range<T>;
+}
+
template <size_t N>
std::string bitsetToString(const std::bitset<N>& bitset) {
if (bitset.none()) {
@@ -72,10 +77,12 @@
/**
* Convert a set of integral types to string.
*/
-template <typename T>
-std::string dumpSet(const std::set<T>& v, std::string (*toString)(const T&) = constToString) {
+template <internal::Container T>
+std::string dumpContainer(
+ const T& container,
+ std::string (*toString)(const std::ranges::range_value_t<T>&) = constToString) {
std::string out;
- for (const T& entry : v) {
+ for (const auto& entry : container) {
out += out.empty() ? "{" : ", ";
out += toString(entry);
}
diff --git a/libs/input/InputConsumerNoResampling.cpp b/libs/input/InputConsumerNoResampling.cpp
index cd85821..6087461 100644
--- a/libs/input/InputConsumerNoResampling.cpp
+++ b/libs/input/InputConsumerNoResampling.cpp
@@ -18,6 +18,7 @@
#define ATRACE_TAG ATRACE_TAG_INPUT
#include <inttypes.h>
+#include <set>
#include <android-base/logging.h>
#include <android-base/properties.h>
diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp
index b2680a2..3de639f 100644
--- a/services/inputflinger/NotifyArgs.cpp
+++ b/services/inputflinger/NotifyArgs.cpp
@@ -206,4 +206,9 @@
return std::visit(toStringVisitor, args);
}
+std::ostream& operator<<(std::ostream& out, const NotifyArgs& args) {
+ out << toString(args);
+ return out;
+}
+
} // namespace android
diff --git a/services/inputflinger/PreferStylusOverTouchBlocker.cpp b/services/inputflinger/PreferStylusOverTouchBlocker.cpp
index d9d0450..6864947 100644
--- a/services/inputflinger/PreferStylusOverTouchBlocker.cpp
+++ b/services/inputflinger/PreferStylusOverTouchBlocker.cpp
@@ -216,10 +216,10 @@
std::string PreferStylusOverTouchBlocker::dump() const {
std::string out;
- out += "mActiveStyli: " + dumpSet(mActiveStyli) + "\n";
+ out += "mActiveStyli: " + dumpContainer(mActiveStyli) + "\n";
out += "mLastTouchEvents: " + dumpMap(mLastTouchEvents, constToString, dumpArgs) + "\n";
- out += "mDevicesWithMixedToolType: " + dumpSet(mDevicesWithMixedToolType) + "\n";
- out += "mCanceledDevices: " + dumpSet(mCanceledDevices) + "\n";
+ out += "mDevicesWithMixedToolType: " + dumpContainer(mDevicesWithMixedToolType) + "\n";
+ out += "mCanceledDevices: " + dumpContainer(mCanceledDevices) + "\n";
return out;
}
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index 0e9ec91..29de635 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -727,7 +727,7 @@
if (!std::includes(oldSuppressedIds.begin(), oldSuppressedIds.end(),
mSuppressedPointerIds.begin(), mSuppressedPointerIds.end())) {
ALOGI("Palm detected, removing pointer ids %s after %" PRId64 "ms from %s",
- dumpSet(mSuppressedPointerIds).c_str(), ns2ms(args.eventTime - args.downTime),
+ dumpContainer(mSuppressedPointerIds).c_str(), ns2ms(args.eventTime - args.downTime),
args.dump().c_str());
}
@@ -748,7 +748,7 @@
out += "mSlotState:\n";
out += addLinePrefix(mSlotState.dump(), " ");
out += "mSuppressedPointerIds: ";
- out += dumpSet(mSuppressedPointerIds) + "\n";
+ out += dumpContainer(mSuppressedPointerIds) + "\n";
std::stringstream state;
state << *mSharedPalmState;
out += "mSharedPalmState: " + state.str() + "\n";
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 493e480..098019f 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -5801,8 +5801,8 @@
}
std::set<DeviceId> deviceIds = touchedWindow->getTouchingDeviceIds();
if (deviceIds.size() != 1) {
- LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
- << " for window: " << touchedWindow->dump();
+ LOG(INFO) << "Can't transfer touch. Currently touching devices: "
+ << dumpContainer(deviceIds) << " for window: " << touchedWindow->dump();
return false;
}
const DeviceId deviceId = *deviceIds.begin();
diff --git a/services/inputflinger/include/NotifyArgs.h b/services/inputflinger/include/NotifyArgs.h
index 14487fe..c513bfc 100644
--- a/services/inputflinger/include/NotifyArgs.h
+++ b/services/inputflinger/include/NotifyArgs.h
@@ -225,4 +225,6 @@
const char* toString(const NotifyArgs& args);
+std::ostream& operator<<(std::ostream& out, const NotifyArgs& args);
+
} // namespace android
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 5cfda03..8deff6b 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -302,6 +302,8 @@
ConfigurationChanges changes) {
std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
+ std::optional<ui::LogicalDisplayId> previousDisplayId = getAssociatedDisplayId();
+
mConfig = config;
// Full configuration should happen the first time configure is called and
@@ -350,6 +352,8 @@
}
if (changes.any() && resetNeeded) {
+ // Touches should be aborted using the previous display id, so that the stream is consistent
+ out += abortTouches(when, when, /*policyFlags=*/0, previousDisplayId);
out += reset(when);
// Send reset, unless this is the first time the device has been configured,
@@ -1657,6 +1661,10 @@
mParameters.hasAssociatedDisplay;
}
+ui::LogicalDisplayId TouchInputMapper::resolveDisplayId() const {
+ return getAssociatedDisplayId().value_or(ui::LogicalDisplayId::INVALID);
+};
+
void TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) {
if (mDeviceMode == DeviceMode::DIRECT && hasExternalStylus()) {
// If any of the external buttons are already pressed by the touch device, ignore them.
@@ -1928,8 +1936,9 @@
keyEventFlags, keyCode, scanCode, metaState, downTime);
}
-std::list<NotifyArgs> TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readTime,
- uint32_t policyFlags) {
+std::list<NotifyArgs> TouchInputMapper::abortTouches(
+ nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
+ std::optional<ui::LogicalDisplayId> currentGestureDisplayId) {
std::list<NotifyArgs> out;
if (mCurrentMotionAborted) {
// Current motion event was already aborted.
@@ -1940,6 +1949,7 @@
int32_t metaState = getContext()->getGlobalMetaState();
int32_t buttonState = mCurrentCookedState.buttonState;
out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ currentGestureDisplayId.value_or(resolveDisplayId()),
AMOTION_EVENT_ACTION_CANCEL, 0, AMOTION_EVENT_FLAG_CANCELED,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mCurrentCookedState.cookedPointerData.pointerProperties,
@@ -1994,14 +2004,15 @@
if (!currentIdBits.isEmpty()) {
// No pointer id changes so this is a move event.
// The listener takes care of batching moves so we don't have to deal with that here.
- out.push_back(
- dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE,
- 0, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mCurrentCookedState.cookedPointerData.pointerProperties,
- mCurrentCookedState.cookedPointerData.pointerCoords,
- mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits,
- -1, mOrientedXPrecision, mOrientedYPrecision, mDownTime,
- MotionClassification::NONE));
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
+ AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ mCurrentCookedState.cookedPointerData.pointerProperties,
+ mCurrentCookedState.cookedPointerData.pointerCoords,
+ mCurrentCookedState.cookedPointerData.idToIndex,
+ currentIdBits, -1, mOrientedXPrecision,
+ mOrientedYPrecision, mDownTime,
+ MotionClassification::NONE));
}
} else {
// There may be pointers going up and pointers going down and pointers moving
@@ -2031,7 +2042,7 @@
if (isCanceled) {
ALOGI("Canceling pointer %d for the palm event was detected.", upId);
}
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_POINTER_UP, 0,
isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState,
buttonState, 0,
@@ -2050,7 +2061,7 @@
// events, they do not generally handle them except when presented in a move event.
if (moveNeeded && !moveIdBits.isEmpty()) {
ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, 0,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
@@ -2071,7 +2082,7 @@
}
out.push_back(
- dispatchMotion(when, readTime, policyFlags, mSource,
+ dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState,
0, mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
@@ -2090,7 +2101,7 @@
(mCurrentCookedState.cookedPointerData.hoveringIdBits.isEmpty() ||
!mCurrentCookedState.cookedPointerData.touchingIdBits.isEmpty())) {
int32_t metaState = getContext()->getGlobalMetaState();
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState,
mLastCookedState.buttonState, 0,
mLastCookedState.cookedPointerData.pointerProperties,
@@ -2111,7 +2122,7 @@
!mCurrentCookedState.cookedPointerData.hoveringIdBits.isEmpty()) {
int32_t metaState = getContext()->getGlobalMetaState();
if (!mSentHoverEnter) {
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
mCurrentCookedState.cookedPointerData.pointerProperties,
@@ -2123,7 +2134,7 @@
mSentHoverEnter = true;
}
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
mCurrentCookedState.cookedPointerData.pointerProperties,
@@ -2146,7 +2157,7 @@
while (!releasedButtons.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit());
buttonState &= ~actionButton;
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
metaState, buttonState, 0,
mLastCookedState.cookedPointerData.pointerProperties,
@@ -2168,7 +2179,7 @@
while (!pressedButtons.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit());
buttonState |= actionButton;
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0, metaState,
buttonState, 0,
mCurrentCookedState.cookedPointerData.pointerProperties,
@@ -2192,7 +2203,7 @@
while (!releasedButtons.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit());
buttonState &= ~actionButton;
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
metaState, buttonState, 0,
mPointerGesture.lastGestureProperties,
@@ -2216,7 +2227,7 @@
while (!pressedButtons.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit());
buttonState |= actionButton;
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0, metaState,
buttonState, 0, mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords,
@@ -2564,7 +2575,7 @@
if (!dispatchedGestureIdBits.isEmpty()) {
if (cancelPreviousGesture) {
const uint32_t cancelFlags = flags | AMOTION_EVENT_FLAG_CANCELED;
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_CANCEL, 0, cancelFlags, metaState,
buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.lastGestureProperties,
@@ -2591,8 +2602,9 @@
}
const uint32_t id = upGestureIdBits.clearFirstMarkedBit();
out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
- AMOTION_EVENT_ACTION_POINTER_UP, 0, flags, metaState,
- buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ resolveDisplayId(), AMOTION_EVENT_ACTION_POINTER_UP, 0,
+ flags, metaState, buttonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords,
mPointerGesture.lastGestureIdToIndex,
@@ -2606,13 +2618,14 @@
// Send motion events for all pointers that moved.
if (moveNeeded) {
- out.push_back(
- dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0,
- flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mPointerGesture.currentGestureProperties,
- mPointerGesture.currentGestureCoords,
- mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, -1,
- 0, 0, mPointerGesture.downTime, classification));
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
+ AMOTION_EVENT_ACTION_MOVE, 0, flags, metaState, buttonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ mPointerGesture.currentGestureProperties,
+ mPointerGesture.currentGestureCoords,
+ mPointerGesture.currentGestureIdToIndex,
+ dispatchedGestureIdBits, -1, 0, 0, mPointerGesture.downTime,
+ classification));
}
// Send motion events for all pointers that went down.
@@ -2627,7 +2640,7 @@
mPointerGesture.downTime = when;
}
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, flags, metaState,
buttonState, 0, mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords,
@@ -2645,7 +2658,7 @@
// Send motion events for hover.
if (mPointerGesture.currentGestureMode == PointerGesture::Mode::HOVER) {
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, flags, metaState,
buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.currentGestureProperties,
@@ -2704,7 +2717,7 @@
if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
int32_t metaState = getContext()->getGlobalMetaState();
int32_t buttonState = mCurrentRawState.buttonState;
- out.push_back(dispatchMotion(when, readTime, policyFlags, mSource,
+ out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(),
AMOTION_EVENT_ACTION_CANCEL, 0, AMOTION_EVENT_FLAG_CANCELED,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.lastGestureProperties,
@@ -3498,8 +3511,7 @@
hovering = false;
}
- return dispatchPointerSimple(when, readTime, policyFlags, down, hovering,
- getAssociatedDisplayId().value_or(ui::LogicalDisplayId::INVALID));
+ return dispatchPointerSimple(when, readTime, policyFlags, down, hovering, resolveDisplayId());
}
std::list<NotifyArgs> TouchInputMapper::abortPointerMouse(nsecs_t when, nsecs_t readTime,
@@ -3662,9 +3674,10 @@
}
NotifyMotionArgs TouchInputMapper::dispatchMotion(
- nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
- int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
+ nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source,
+ ui::LogicalDisplayId displayId, int32_t action, int32_t actionButton, int32_t flags,
+ int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ const PropertiesArray& properties, const CoordsArray& coords,
const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
float yPrecision, nsecs_t downTime, MotionClassification classification) const {
std::vector<PointerCoords> pointerCoords;
@@ -3714,9 +3727,6 @@
}
}
- const ui::LogicalDisplayId displayId =
- getAssociatedDisplayId().value_or(ui::LogicalDisplayId::INVALID);
-
float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
if (mDeviceMode == DeviceMode::POINTER) {
@@ -3739,7 +3749,7 @@
std::list<NotifyArgs> TouchInputMapper::cancelTouch(nsecs_t when, nsecs_t readTime) {
std::list<NotifyArgs> out;
out += abortPointerUsage(when, readTime, /*policyFlags=*/0);
- out += abortTouches(when, readTime, /* policyFlags=*/0);
+ out += abortTouches(when, readTime, /* policyFlags=*/0, std::nullopt);
return out;
}
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 96fc61b..4ef0be8 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -238,7 +238,7 @@
// DeviceType::TOUCH_SCREEN, and will otherwise use DeviceType::POINTER by default.
// This can be overridden by IDC files, using the `touch.deviceType` config.
DeviceType deviceType;
- bool hasAssociatedDisplay;
+ bool hasAssociatedDisplay = false;
bool associatedDisplayIsExternal;
bool orientationAware;
@@ -779,8 +779,9 @@
nsecs_t readTime);
const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
void cookPointerData();
- [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
- uint32_t policyFlags);
+ [[nodiscard]] std::list<NotifyArgs> abortTouches(
+ nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
+ std::optional<ui::LogicalDisplayId> gestureDisplayId);
[[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags,
@@ -836,15 +837,18 @@
// method will take care of setting the index and transmuting the action to DOWN or UP
// it is the first / last pointer to go down / up.
[[nodiscard]] NotifyMotionArgs dispatchMotion(
- nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
- int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
+ nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source,
+ ui::LogicalDisplayId displayId, int32_t action, int32_t actionButton, int32_t flags,
+ int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ const PropertiesArray& properties, const CoordsArray& coords,
const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
float yPrecision, nsecs_t downTime, MotionClassification classification) const;
// Returns if this touch device is a touch screen with an associated display.
bool isTouchScreen();
+ ui::LogicalDisplayId resolveDisplayId() const;
+
bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index a8e4736..d9a75a5 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -8441,41 +8441,6 @@
WithToolType(ToolType::STYLUS))));
}
-// --- MultiTouchInputMapperTest_ExternalDevice ---
-
-class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
-protected:
- void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
-};
-
-/**
- * Expect fallback to internal viewport if device is external and external viewport is not present.
- */
-TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
- prepareAxes(POSITION);
- addConfigurationProperty("touch.deviceType", "touchScreen");
- prepareDisplay(ui::ROTATION_0);
- MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
-
- ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
-
- NotifyMotionArgs motionArgs;
-
- // Expect the event to be sent to the internal viewport,
- // because an external viewport is not present.
- processPosition(mapper, 100, 100);
- processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(ui::LogicalDisplayId::DEFAULT, motionArgs.displayId);
-
- // Expect the event to be sent to the external viewport if it is present.
- prepareSecondaryDisplay(ViewportType::EXTERNAL);
- processPosition(mapper, 100, 100);
- processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
-}
-
// TODO(b/281840344): Remove the test when the old touchpad stack is removed. It is currently
// unclear what the behavior of the touchpad logic in TouchInputMapper should do after the
// PointerChoreographer refactor.
diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp
index 1cfaaa8..d8c5eac 100644
--- a/services/inputflinger/tests/LatencyTracker_test.cpp
+++ b/services/inputflinger/tests/LatencyTracker_test.cpp
@@ -80,8 +80,9 @@
<< "Received timeline with productId=" << received.productId
<< " instead of expected productId=" << expected.productId;
LOG_IF(ERROR, expected.sources != received.sources)
- << "Received timeline with sources=" << dumpSet(received.sources, ftl::enum_string)
- << " instead of expected sources=" << dumpSet(expected.sources, ftl::enum_string);
+ << "Received timeline with sources="
+ << dumpContainer(received.sources, ftl::enum_string)
+ << " instead of expected sources=" << dumpContainer(expected.sources, ftl::enum_string);
LOG_IF(ERROR, expected.inputEventActionType != received.inputEventActionType)
<< "Received timeline with inputEventActionType="
<< ftl::enum_string(received.inputEventActionType)
diff --git a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
index b7cb348..cc3d123 100644
--- a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
+++ b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
@@ -37,17 +37,30 @@
using testing::SetArgPointee;
using testing::VariantWith;
-static constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
-static constexpr int32_t DISPLAY_WIDTH = 480;
-static constexpr int32_t DISPLAY_HEIGHT = 800;
-static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
-static constexpr int32_t SLOT_COUNT = 5;
+namespace {
-static constexpr int32_t ACTION_POINTER_0_UP =
+constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
+constexpr ui::LogicalDisplayId SECOND_DISPLAY_ID = ui::LogicalDisplayId{DISPLAY_ID.val() + 1};
+constexpr int32_t DISPLAY_WIDTH = 480;
+constexpr int32_t DISPLAY_HEIGHT = 800;
+constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
+constexpr int32_t SLOT_COUNT = 5;
+
+constexpr int32_t ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
+constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL;
+constexpr int32_t ACTION_POINTER_0_UP =
AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
-static constexpr int32_t ACTION_POINTER_1_DOWN =
+constexpr int32_t ACTION_POINTER_1_DOWN =
AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+template <typename... Args>
+void assertNotifyArgs(const std::list<NotifyArgs>& args, Args... matchers) {
+ ASSERT_THAT(args, ElementsAre(matchers...))
+ << "Got instead: " << dumpContainer(args, streamableToString);
+}
+
+} // namespace
+
/**
* Unit tests for MultiTouchInputMapper.
*/
@@ -84,6 +97,17 @@
EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, _)).WillRepeatedly(Return(false));
EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_DIRECT))
.WillRepeatedly(Return(true));
+ // The following EXPECT_CALL lines are not load-bearing, but without them gtest prints
+ // warnings about "uninteresting mocked call", which are distracting when developing the
+ // tests because this text is interleaved with logs of interest.
+ EXPECT_CALL(mMockEventHub, getVirtualKeyDefinitions(EVENTHUB_ID, _))
+ .WillRepeatedly(Return());
+ EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, _))
+ .WillRepeatedly(testing::Return(false));
+ EXPECT_CALL(mMockEventHub, getVideoFrames(EVENTHUB_ID))
+ .WillRepeatedly(testing::Return(std::vector<TouchVideoFrame>{}));
+ EXPECT_CALL(mMockInputReaderContext, getExternalStylusDevices(_)).WillRepeatedly(Return());
+ EXPECT_CALL(mMockInputReaderContext, getGlobalMetaState()).WillRepeatedly(Return(0));
// Axes that the device has
setupAxis(ABS_MT_SLOT, /*valid=*/true, /*min=*/0, /*max=*/SLOT_COUNT - 1, /*resolution=*/0);
@@ -151,24 +175,97 @@
});
}
- std::list<NotifyArgs> processPosition(int32_t x, int32_t y) {
+ [[nodiscard]] std::list<NotifyArgs> processPosition(int32_t x, int32_t y) {
std::list<NotifyArgs> args;
args += process(EV_ABS, ABS_MT_POSITION_X, x);
args += process(EV_ABS, ABS_MT_POSITION_Y, y);
return args;
}
- std::list<NotifyArgs> processId(int32_t id) { return process(EV_ABS, ABS_MT_TRACKING_ID, id); }
+ [[nodiscard]] std::list<NotifyArgs> processId(int32_t id) {
+ return process(EV_ABS, ABS_MT_TRACKING_ID, id);
+ }
- std::list<NotifyArgs> processKey(int32_t code, int32_t value) {
+ [[nodiscard]] std::list<NotifyArgs> processKey(int32_t code, int32_t value) {
return process(EV_KEY, code, value);
}
- std::list<NotifyArgs> processSlot(int32_t slot) { return process(EV_ABS, ABS_MT_SLOT, slot); }
+ [[nodiscard]] std::list<NotifyArgs> processSlot(int32_t slot) {
+ return process(EV_ABS, ABS_MT_SLOT, slot);
+ }
- std::list<NotifyArgs> processSync() { return process(EV_SYN, SYN_REPORT, 0); }
+ [[nodiscard]] std::list<NotifyArgs> processSync() { return process(EV_SYN, SYN_REPORT, 0); }
};
+/**
+ * While a gesture is active, change the display that the device is associated with. Make sure that
+ * the CANCEL event that's generated has the display id of the original DOWN event, rather than the
+ * new display id.
+ */
+TEST_F(MultiTouchInputMapperUnitTest, ChangeAssociatedDisplayIdWhenTouchIsActive) {
+ std::list<NotifyArgs> args;
+
+ // Add a second viewport that later will be associated with our device.
+ DisplayViewport secondViewport =
+ createViewport(SECOND_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
+ /*isActive=*/true, "local:1", NO_PORT, ViewportType::EXTERNAL);
+ mFakePolicy->addDisplayViewport(secondViewport);
+ std::optional<DisplayViewport> firstViewport =
+ mFakePolicy->getDisplayViewportByUniqueId("local:0");
+
+ // InputReaderConfiguration contains information about how devices are associated with displays.
+ // The mapper receives this information. However, it doesn't actually parse it - that's done by
+ // InputDevice. The mapper asks InputDevice about the associated viewport, so that's what we
+ // need to mock here to simulate association. This abstraction is confusing and should be
+ // refactored.
+
+ // Start with the first viewport
+ ON_CALL((*mDevice), getAssociatedViewport).WillByDefault(Return(firstViewport));
+ args += mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration,
+ InputReaderConfiguration::Change::DISPLAY_INFO);
+
+ int32_t x1 = 100, y1 = 125;
+ args += processKey(BTN_TOUCH, 1);
+ args += processPosition(x1, y1);
+ args += processId(1);
+ args += processSync();
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(ACTION_DOWN), WithDisplayId(DISPLAY_ID)))));
+ args.clear();
+
+ // Now associate with the second viewport, and reconfigure.
+ ON_CALL((*mDevice), getAssociatedViewport).WillByDefault(Return(secondViewport));
+ args += mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration,
+ InputReaderConfiguration::Change::DISPLAY_INFO);
+ assertNotifyArgs(args,
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(DISPLAY_ID))),
+ VariantWith<NotifyDeviceResetArgs>(WithDeviceId(DEVICE_ID)));
+
+ // The remainder of the gesture is ignored
+ // Move.
+ x1 += 10;
+ y1 += 15;
+ args = processPosition(x1, y1);
+ args += processSync();
+ // Up
+ args += processKey(BTN_TOUCH, 0);
+ args += processId(-1);
+ args += processSync();
+
+ ASSERT_THAT(args, IsEmpty());
+
+ // New touch is delivered with the new display id.
+ args += processId(2);
+ args += processKey(BTN_TOUCH, 1);
+ args += processPosition(x1 + 20, y1 + 40);
+ args += processSync();
+ assertNotifyArgs(args,
+ VariantWith<NotifyMotionArgs>(AllOf(WithMotionAction(ACTION_DOWN),
+ WithDisplayId(SECOND_DISPLAY_ID))));
+}
+
// This test simulates a multi-finger gesture with unexpected reset in between. This might happen
// due to buffer overflow and device with report a SYN_DROPPED. In this case we expect mapper to be
// reset, MT slot state to be re-populated and the gesture should be cancelled and restarted.
@@ -178,7 +275,7 @@
// Two fingers down at once.
constexpr int32_t FIRST_TRACKING_ID = 1, SECOND_TRACKING_ID = 2;
int32_t x1 = 100, y1 = 125, x2 = 200, y2 = 225;
- processKey(BTN_TOUCH, 1);
+ args += processKey(BTN_TOUCH, 1);
args += processPosition(x1, y1);
args += processId(FIRST_TRACKING_ID);
args += processSlot(1);
@@ -186,7 +283,7 @@
args += processId(SECOND_TRACKING_ID);
ASSERT_THAT(args, IsEmpty());
- args = processSync();
+ args += processSync();
ASSERT_THAT(args,
ElementsAre(VariantWith<NotifyMotionArgs>(
WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
@@ -259,8 +356,8 @@
ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_POINTER_0_UP))));
// Second finger up.
- processKey(BTN_TOUCH, 0);
- args = processSlot(1);
+ args = processKey(BTN_TOUCH, 0);
+ args += processSlot(1);
args += processId(-1);
ASSERT_THAT(args, IsEmpty());
@@ -270,6 +367,58 @@
VariantWith<NotifyMotionArgs>(WithMotionAction(AMOTION_EVENT_ACTION_UP))));
}
+class ExternalMultiTouchInputMapperTest : public MultiTouchInputMapperUnitTest {
+protected:
+ void SetUp() override { MultiTouchInputMapperUnitTest::SetUp(/*bus=*/0, /*isExternal=*/true); }
+};
+
+/**
+ * Expect fallback to internal viewport if device is external and external viewport is not present.
+ */
+TEST_F(ExternalMultiTouchInputMapperTest, Viewports_Fallback) {
+ std::list<NotifyArgs> args;
+
+ // Expect the event to be sent to the internal viewport,
+ // because an external viewport is not present.
+ args += processKey(BTN_TOUCH, 1);
+ args += processId(1);
+ args += processPosition(100, 200);
+ args += processSync();
+
+ assertNotifyArgs(args,
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(ACTION_DOWN), WithDisplayId(DISPLAY_ID))));
+
+ // Expect the event to be sent to the external viewport if it is present.
+ DisplayViewport externalViewport =
+ createViewport(SECOND_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
+ /*isActive=*/true, "local:1", NO_PORT, ViewportType::EXTERNAL);
+ mFakePolicy->addDisplayViewport(externalViewport);
+ std::optional<DisplayViewport> internalViewport =
+ mFakePolicy->getDisplayViewportByUniqueId("local:0");
+ mReaderConfiguration.setDisplayViewports({*internalViewport, externalViewport});
+ args = mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration,
+ InputReaderConfiguration::Change::DISPLAY_INFO);
+
+ assertNotifyArgs(args,
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(DISPLAY_ID))),
+ VariantWith<NotifyDeviceResetArgs>(WithDeviceId(DEVICE_ID)));
+ // Lift up the old pointer.
+ args = processKey(BTN_TOUCH, 0);
+ args += processId(-1);
+ args += processSync();
+
+ // Send new pointer
+ args += processKey(BTN_TOUCH, 1);
+ args += processId(2);
+ args += processPosition(111, 211);
+ args += processSync();
+ assertNotifyArgs(args,
+ VariantWith<NotifyMotionArgs>(AllOf(WithMotionAction(ACTION_DOWN),
+ WithDisplayId(SECOND_DISPLAY_ID))));
+}
+
class MultiTouchInputMapperPointerModeUnitTest : public MultiTouchInputMapperUnitTest {
protected:
void SetUp() override {
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index 7fb8895..65bc278 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -505,8 +505,8 @@
}
if (mPointerIds != actualPointerIds) {
- *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got "
- << dumpSet(actualPointerIds);
+ *os << "expected pointer ids " << dumpContainer(mPointerIds) << ", but got "
+ << dumpContainer(actualPointerIds);
return false;
}
return true;
@@ -519,14 +519,16 @@
}
if (mPointerIds != actualPointerIds) {
- *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got "
- << dumpSet(actualPointerIds);
+ *os << "expected pointer ids " << dumpContainer(mPointerIds) << ", but got "
+ << dumpContainer(actualPointerIds);
return false;
}
return true;
}
- void DescribeTo(std::ostream* os) const { *os << "with pointer ids " << dumpSet(mPointerIds); }
+ void DescribeTo(std::ostream* os) const {
+ *os << "with pointer ids " << dumpContainer(mPointerIds);
+ }
void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer ids"; }