Use Transform in InputDispatcher
Modified InputDispatcher to use the Transform object instead of offset
and scale values.
Bug: 158476194
Test: /data/nativetest64/inputflinger_tests/inputflinger_tests
Test: /data/nativetest64/libinput_tests/libinput_tests
Change-Id: I31242fa6af92b02158ccb0d292c208a4a21c9e43
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index fdbb1d1..26a1644 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -240,17 +240,13 @@
volatile int32_t DispatchEntry::sNextSeqAtomic;
-DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset,
- float yOffset, float globalScaleFactor, float windowXScale,
- float windowYScale)
+DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, ui::Transform transform,
+ float globalScaleFactor)
: seq(nextSeq()),
eventEntry(eventEntry),
targetFlags(targetFlags),
- xOffset(xOffset),
- yOffset(yOffset),
+ transform(transform),
globalScaleFactor(globalScaleFactor),
- windowXScale(windowXScale),
- windowYScale(windowYScale),
deliveryTime(0),
resolvedAction(0),
resolvedFlags(0) {
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 6b7697d..5dfcdd1 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -193,11 +193,8 @@
EventEntry* eventEntry; // the event to dispatch
int32_t targetFlags;
- float xOffset;
- float yOffset;
+ ui::Transform transform;
float globalScaleFactor;
- float windowXScale = 1.0f;
- float windowYScale = 1.0f;
// Both deliveryTime and timeoutTime are only populated when the entry is sent to the app,
// and will be undefined before that.
nsecs_t deliveryTime; // time when the event was actually delivered
@@ -209,8 +206,8 @@
int32_t resolvedAction;
int32_t resolvedFlags;
- DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset, float yOffset,
- float globalScaleFactor, float windowXScale, float windowYScale);
+ DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, ui::Transform transform,
+ float globalScaleFactor);
~DispatchEntry();
inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 3bdbcce..a4538bb 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -271,12 +271,11 @@
static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
EventEntry* eventEntry,
int32_t inputTargetFlags) {
- if (inputTarget.useDefaultPointerInfo()) {
- const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
+ if (inputTarget.useDefaultPointerTransform()) {
+ const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
return std::make_unique<DispatchEntry>(eventEntry, // increments ref
- inputTargetFlags, pointerInfo.xOffset,
- pointerInfo.yOffset, inputTarget.globalScaleFactor,
- pointerInfo.windowXScale, pointerInfo.windowYScale);
+ inputTargetFlags, transform,
+ inputTarget.globalScaleFactor);
}
ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
@@ -286,28 +285,24 @@
// Use the first pointer information to normalize all other pointers. This could be any pointer
// as long as all other pointers are normalized to the same value and the final DispatchEntry
- // uses the offset and scale for the normalized pointer.
- const PointerInfo& firstPointerInfo =
- inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
+ // uses the transform for the normalized pointer.
+ const ui::Transform& firstPointerTransform =
+ inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
+ ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
// Iterate through all pointers in the event to normalize against the first.
for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
uint32_t pointerId = uint32_t(pointerProperties.id);
- const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
-
- // The scale factor is the ratio of the current pointers scale to the normalized scale.
- float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
- float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
+ const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
- // First apply the current pointers offset to set the window at 0,0
- pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
- // Next scale the coordinates.
- pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
- // Lastly, offset the coordinates so they're in the normalized pointer's frame.
- pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
- -firstPointerInfo.yOffset);
+ // First, apply the current pointer's transform to update the coordinates into
+ // window space.
+ pointerCoords[pointerIndex].transform(currTransform);
+ // Next, apply the inverse transform of the normalized coordinates so the
+ // current coordinates are transformed into the normalized coordinate space.
+ pointerCoords[pointerIndex].transform(inverseFirstTransform);
}
MotionEntry* combinedMotionEntry =
@@ -329,10 +324,8 @@
std::unique_ptr<DispatchEntry> dispatchEntry =
std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
- inputTargetFlags, firstPointerInfo.xOffset,
- firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
- firstPointerInfo.windowXScale,
- firstPointerInfo.windowYScale);
+ inputTargetFlags, firstPointerTransform,
+ inputTarget.globalScaleFactor);
combinedMotionEntry->release();
return dispatchEntry;
}
@@ -2044,8 +2037,7 @@
ALOG_ASSERT(it->flags == targetFlags);
ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
- it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
- windowInfo->windowXScale, windowInfo->windowYScale);
+ it->addPointers(pointerIds, windowInfo->transform);
}
void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
@@ -2068,7 +2060,9 @@
InputTarget target;
target.inputChannel = monitor.inputChannel;
target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
- target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
+ ui::Transform t;
+ t.set(xOffset, yOffset);
+ target.setDefaultPointerTransform(t);
inputTargets.push_back(target);
}
@@ -2587,15 +2581,9 @@
const PointerCoords* usingCoords = motionEntry->pointerCoords;
// Set the X and Y offset and X and Y scale depending on the input source.
- float xOffset = 0.0f, yOffset = 0.0f;
- float xScale = 1.0f, yScale = 1.0f;
if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
float globalScaleFactor = dispatchEntry->globalScaleFactor;
- xScale = dispatchEntry->windowXScale;
- yScale = dispatchEntry->windowYScale;
- xOffset = dispatchEntry->xOffset * xScale;
- yOffset = dispatchEntry->yOffset * yScale;
if (globalScaleFactor != 1.0f) {
for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
scaledCoords[i] = motionEntry->pointerCoords[i];
@@ -2630,8 +2618,12 @@
dispatchEntry->resolvedFlags,
motionEntry->edgeFlags, motionEntry->metaState,
motionEntry->buttonState,
- motionEntry->classification, xScale, yScale,
- xOffset, yOffset, motionEntry->xPrecision,
+ motionEntry->classification,
+ dispatchEntry->transform.dsdx(),
+ dispatchEntry->transform.dsdy(),
+ dispatchEntry->transform.tx(),
+ dispatchEntry->transform.ty(),
+ motionEntry->xPrecision,
motionEntry->yPrecision,
motionEntry->xCursorPosition,
motionEntry->yCursorPosition,
@@ -2909,8 +2901,7 @@
getWindowHandleLocked(connection->inputChannel->getConnectionToken());
if (windowHandle != nullptr) {
const InputWindowInfo* windowInfo = windowHandle->getInfo();
- target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
- windowInfo->windowXScale, windowInfo->windowYScale);
+ target.setDefaultPointerTransform(windowInfo->transform);
target.globalScaleFactor = windowInfo->globalScaleFactor;
}
target.inputChannel = connection->inputChannel;
@@ -2975,8 +2966,7 @@
getWindowHandleLocked(connection->inputChannel->getConnectionToken());
if (windowHandle != nullptr) {
const InputWindowInfo* windowInfo = windowHandle->getInfo();
- target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
- windowInfo->windowXScale, windowInfo->windowYScale);
+ target.setDefaultPointerTransform(windowInfo->transform);
target.globalScaleFactor = windowInfo->globalScaleFactor;
}
target.inputChannel = connection->inputChannel;
@@ -4219,7 +4209,7 @@
"hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
"flags=%s, type=0x%08x, "
"frame=[%d,%d][%d,%d], globalScale=%f, "
- "windowScale=(%f,%f), touchableRegion=",
+ "touchableRegion=",
i, windowInfo->name.c_str(), windowInfo->displayId,
windowInfo->portalToDisplayId,
toString(windowInfo->paused),
@@ -4232,8 +4222,7 @@
static_cast<int32_t>(windowInfo->type),
windowInfo->frameLeft, windowInfo->frameTop,
windowInfo->frameRight, windowInfo->frameBottom,
- windowInfo->globalScaleFactor, windowInfo->windowXScale,
- windowInfo->windowYScale);
+ windowInfo->globalScaleFactor);
dumpRegion(dump, windowInfo->touchableRegion);
dump += StringPrintf(", inputFeatures=%s",
windowInfo->inputFeatures.string().c_str());
@@ -4241,6 +4230,7 @@
"ms\n",
windowInfo->ownerPid, windowInfo->ownerUid,
millis(windowInfo->dispatchingTimeout));
+ windowInfo->transform.dump(dump, INDENT4 "transform=");
}
} else {
dump += INDENT2 "Windows: <none>\n";
diff --git a/services/inputflinger/dispatcher/InputTarget.cpp b/services/inputflinger/dispatcher/InputTarget.cpp
index 0588374..f6958d4 100644
--- a/services/inputflinger/dispatcher/InputTarget.cpp
+++ b/services/inputflinger/dispatcher/InputTarget.cpp
@@ -42,12 +42,11 @@
return StringPrintf("%" PRId32, dispatchMode);
}
-void InputTarget::addPointers(BitSet32 newPointerIds, float xOffset, float yOffset,
- float windowXScale, float windowYScale) {
+void InputTarget::addPointers(BitSet32 newPointerIds, const ui::Transform& transform) {
// The pointerIds can be empty, but still a valid InputTarget. This can happen for Monitors
// and non splittable windows since we will just use all the pointers from the input event.
if (newPointerIds.isEmpty()) {
- setDefaultPointerInfo(xOffset, yOffset, windowXScale, windowYScale);
+ setDefaultPointerTransform(transform);
return;
}
@@ -57,47 +56,39 @@
pointerIds |= newPointerIds;
while (!newPointerIds.isEmpty()) {
int32_t pointerId = newPointerIds.clearFirstMarkedBit();
- pointerInfos[pointerId].xOffset = xOffset;
- pointerInfos[pointerId].yOffset = yOffset;
- pointerInfos[pointerId].windowXScale = windowXScale;
- pointerInfos[pointerId].windowYScale = windowYScale;
+ pointerTransforms[pointerId] = transform;
}
}
-void InputTarget::setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
- float windowYScale) {
+void InputTarget::setDefaultPointerTransform(const ui::Transform& transform) {
pointerIds.clear();
- pointerInfos[0].xOffset = xOffset;
- pointerInfos[0].yOffset = yOffset;
- pointerInfos[0].windowXScale = windowXScale;
- pointerInfos[0].windowYScale = windowYScale;
+ pointerTransforms[0] = transform;
}
-bool InputTarget::useDefaultPointerInfo() const {
+bool InputTarget::useDefaultPointerTransform() const {
return pointerIds.isEmpty();
}
-const PointerInfo& InputTarget::getDefaultPointerInfo() const {
- return pointerInfos[0];
+const ui::Transform& InputTarget::getDefaultPointerTransform() const {
+ return pointerTransforms[0];
}
std::string InputTarget::getPointerInfoString() const {
- if (useDefaultPointerInfo()) {
- const PointerInfo& pointerInfo = getDefaultPointerInfo();
- return StringPrintf("xOffset=%.1f, yOffset=%.1f windowScaleFactor=(%.1f, %.1f)",
- pointerInfo.xOffset, pointerInfo.yOffset, pointerInfo.windowXScale,
- pointerInfo.windowYScale);
+ std::string out;
+ if (useDefaultPointerTransform()) {
+ const ui::Transform& transform = getDefaultPointerTransform();
+ transform.dump(out, "default");
+ return out;
}
- std::string out;
for (uint32_t i = pointerIds.firstMarkedBit(); i <= pointerIds.lastMarkedBit(); i++) {
if (!pointerIds.hasBit(i)) {
continue;
}
- out += StringPrintf("\n pointerId %d: xOffset=%.1f, yOffset=%.1f "
- "windowScaleFactor=(%.1f, %.1f)",
- i, pointerInfos[i].xOffset, pointerInfos[i].yOffset,
- pointerInfos[i].windowXScale, pointerInfos[i].windowYScale);
+
+ out += "\n";
+ const std::string name = "pointerId " + std::to_string(i) + ":";
+ pointerTransforms[i].dump(out, name.c_str());
}
return out;
}
diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h
index 499a75f..4287538 100644
--- a/services/inputflinger/dispatcher/InputTarget.h
+++ b/services/inputflinger/dispatcher/InputTarget.h
@@ -18,28 +18,13 @@
#define _UI_INPUT_INPUTDISPATCHER_INPUTTARGET_H
#include <input/InputTransport.h>
+#include <ui/Transform.h>
#include <utils/BitSet.h>
#include <utils/RefBase.h>
namespace android::inputdispatcher {
/*
- * Information about each pointer for an InputTarget. This includes offset and scale so
- * all pointers can be normalized to a single offset and scale.
- *
- * These values are ignored for KeyEvents
- */
-struct PointerInfo {
- // The x and y offset to add to a MotionEvent as it is delivered.
- float xOffset = 0.0f;
- float yOffset = 0.0f;
-
- // Scaling factor to apply to MotionEvent as it is delivered.
- float windowXScale = 1.0f;
- float windowYScale = 1.0f;
-};
-
-/*
* An input target specifies how an input event is to be dispatched to a particular window
* including the window's input channel, control flags, a timeout, and an X / Y offset to
* be added to input event coordinates to compensate for the absolute position of the
@@ -119,13 +104,11 @@
// if FLAG_SPLIT is set.
BitSet32 pointerIds;
// The data is stored by the pointerId. Use the bit position of pointerIds to look up
- // PointerInfo per pointerId.
- PointerInfo pointerInfos[MAX_POINTERS];
+ // Transform per pointerId.
+ ui::Transform pointerTransforms[MAX_POINTERS];
- void addPointers(BitSet32 pointerIds, float xOffset, float yOffset, float windowXScale,
- float windowYScale);
- void setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
- float windowYScale);
+ void addPointers(BitSet32 pointerIds, const ui::Transform& transform);
+ void setDefaultPointerTransform(const ui::Transform& transform);
/**
* Returns whether the default pointer information should be used. This will be true when the
@@ -133,13 +116,13 @@
* and non splittable windows since we want all pointers for the EventEntry to go to this
* target.
*/
- bool useDefaultPointerInfo() const;
+ bool useDefaultPointerTransform() const;
/**
- * Returns the default PointerInfo object. This should be used when useDefaultPointerInfo is
+ * Returns the default Transform object. This should be used when useDefaultPointerTransform is
* true.
*/
- const PointerInfo& getDefaultPointerInfo() const;
+ const ui::Transform& getDefaultPointerTransform() const;
std::string getPointerInfoString() const;
};