Skip to content

Commit 0a18c9b

Browse files
prabirmspAndroid (Google) Code Review
authored andcommitted
Merge changes I7370ac64,If07fc359 into main
* changes: Use the cloned window's layer stack space for raw coordinates InputTarget: s/displayTransform/rawTransform
2 parents 8953005 + 72c6990 commit 0a18c9b

10 files changed

Lines changed: 172 additions & 56 deletions

File tree

libs/gui/WindowInfo.cpp

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ std::ostream& operator<<(std::ostream& out, const Region& region) {
5959
return out;
6060
}
6161

62+
status_t writeTransform(android::Parcel* parcel, const ui::Transform& transform) {
63+
return parcel->writeFloat(transform.dsdx()) ?:
64+
parcel->writeFloat(transform.dtdx()) ?:
65+
parcel->writeFloat(transform.tx()) ?:
66+
parcel->writeFloat(transform.dtdy()) ?:
67+
parcel->writeFloat(transform.dsdy()) ?:
68+
parcel->writeFloat(transform.ty());
69+
}
70+
71+
status_t readTransform(const android::Parcel* parcel, ui::Transform& transform) {
72+
float dsdx, dtdx, tx, dtdy, dsdy, ty;
73+
74+
const status_t status = parcel->readFloat(&dsdx) ?:
75+
parcel->readFloat(&dtdx) ?:
76+
parcel->readFloat(&tx) ?:
77+
parcel->readFloat(&dtdy) ?:
78+
parcel->readFloat(&dsdy) ?:
79+
parcel->readFloat(&ty);
80+
if (status != OK) {
81+
return status;
82+
}
83+
84+
transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
85+
return OK;
86+
}
87+
6288
} // namespace
6389

6490
void WindowInfo::setInputConfig(ftl::Flags<InputConfig> config, bool value) {
@@ -135,12 +161,7 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
135161
parcel->writeInt32(surfaceInset) ?:
136162
parcel->writeFloat(globalScaleFactor) ?:
137163
parcel->writeFloat(alpha) ?:
138-
parcel->writeFloat(transform.dsdx()) ?:
139-
parcel->writeFloat(transform.dtdx()) ?:
140-
parcel->writeFloat(transform.tx()) ?:
141-
parcel->writeFloat(transform.dtdy()) ?:
142-
parcel->writeFloat(transform.dsdy()) ?:
143-
parcel->writeFloat(transform.ty()) ?:
164+
writeTransform(parcel, transform) ?:
144165
parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
145166
parcel->writeInt32(ownerPid.val()) ?:
146167
parcel->writeInt32(ownerUid.val()) ?:
@@ -153,8 +174,12 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
153174
parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
154175
parcel->writeStrongBinder(windowToken) ?:
155176
parcel->writeStrongBinder(focusTransferTarget) ?:
156-
parcel->writeBool(canOccludePresentation);
177+
parcel->writeBool(canOccludePresentation) ?:
178+
parcel->writeBool(cloneLayerStackTransform.has_value());
157179
// clang-format on
180+
if (cloneLayerStackTransform) {
181+
status = status ?: writeTransform(parcel, *cloneLayerStackTransform);
182+
}
158183
return status;
159184
}
160185

@@ -174,10 +199,10 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
174199
return status;
175200
}
176201

177-
float dsdx, dtdx, tx, dtdy, dsdy, ty;
178202
int32_t lpFlags, lpType, touchOcclusionModeInt, inputConfigInt, ownerPidInt, ownerUidInt,
179203
displayIdInt;
180204
sp<IBinder> touchableRegionCropHandleSp;
205+
bool hasCloneLayerStackTransform = false;
181206

182207
// clang-format off
183208
status = parcel->readInt32(&lpFlags) ?:
@@ -188,12 +213,7 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
188213
parcel->readInt32(&surfaceInset) ?:
189214
parcel->readFloat(&globalScaleFactor) ?:
190215
parcel->readFloat(&alpha) ?:
191-
parcel->readFloat(&dsdx) ?:
192-
parcel->readFloat(&dtdx) ?:
193-
parcel->readFloat(&tx) ?:
194-
parcel->readFloat(&dtdy) ?:
195-
parcel->readFloat(&dsdy) ?:
196-
parcel->readFloat(&ty) ?:
216+
readTransform(parcel, /*byRef*/ transform) ?:
197217
parcel->readInt32(&touchOcclusionModeInt) ?:
198218
parcel->readInt32(&ownerPidInt) ?:
199219
parcel->readInt32(&ownerUidInt) ?:
@@ -206,8 +226,8 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
206226
parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
207227
parcel->readNullableStrongBinder(&windowToken) ?:
208228
parcel->readNullableStrongBinder(&focusTransferTarget) ?:
209-
parcel->readBool(&canOccludePresentation);
210-
229+
parcel->readBool(&canOccludePresentation)?:
230+
parcel->readBool(&hasCloneLayerStackTransform);
211231
// clang-format on
212232

213233
if (status != OK) {
@@ -216,14 +236,22 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
216236

217237
layoutParamsFlags = ftl::Flags<Flag>(lpFlags);
218238
layoutParamsType = static_cast<Type>(lpType);
219-
transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
220239
touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
221240
inputConfig = ftl::Flags<InputConfig>(inputConfigInt);
222241
ownerPid = Pid{ownerPidInt};
223242
ownerUid = Uid{static_cast<uid_t>(ownerUidInt)};
224243
touchableRegionCropHandle = touchableRegionCropHandleSp;
225244
displayId = ui::LogicalDisplayId{displayIdInt};
226245

246+
cloneLayerStackTransform =
247+
hasCloneLayerStackTransform ? std::make_optional<ui::Transform>() : std::nullopt;
248+
if (cloneLayerStackTransform) {
249+
status = readTransform(parcel, /*byRef*/ *cloneLayerStackTransform);
250+
if (status != OK) {
251+
return status;
252+
}
253+
}
254+
227255
return OK;
228256
}
229257

libs/gui/include/gui/WindowInfo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,14 @@ struct WindowInfo : public Parcelable {
220220
// An alpha of 1.0 means fully opaque and 0.0 means fully transparent.
221221
float alpha;
222222

223-
// Transform applied to individual windows.
223+
// Transform applied to individual windows for input.
224+
// Maps display coordinates to the window's input coordinate space.
224225
ui::Transform transform;
225226

227+
// Transform applied to get to the layer stack space of the cloned window for input.
228+
// Maps display coordinates of the clone window to the layer stack space of the cloned window.
229+
std::optional<ui::Transform> cloneLayerStackTransform;
230+
226231
/*
227232
* This is filled in by the WM relative to the frame and then translated
228233
* to absolute coordinates by SurfaceFlinger once the frame is computed.

libs/gui/tests/WindowInfo_test.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,18 @@ TEST(WindowInfo, ParcellingWithoutToken) {
4040
ASSERT_EQ(OK, i.writeToParcel(&p));
4141
p.setDataPosition(0);
4242
i2.readFromParcel(&p);
43-
ASSERT_TRUE(i2.token == nullptr);
43+
ASSERT_EQ(i2.token, nullptr);
44+
}
45+
46+
TEST(WindowInfo, ParcellingWithoutCloneTransform) {
47+
WindowInfo i, i2;
48+
i.cloneLayerStackTransform.reset();
49+
50+
Parcel p;
51+
ASSERT_EQ(OK, i.writeToParcel(&p));
52+
p.setDataPosition(0);
53+
i2.readFromParcel(&p);
54+
ASSERT_EQ(i2.cloneLayerStackTransform, std::nullopt);
4455
}
4556

4657
TEST(WindowInfo, Parcelling) {
@@ -71,6 +82,8 @@ TEST(WindowInfo, Parcelling) {
7182
i.applicationInfo.token = new BBinder();
7283
i.applicationInfo.dispatchingTimeoutMillis = 0x12345678ABCD;
7384
i.focusTransferTarget = new BBinder();
85+
i.cloneLayerStackTransform = ui::Transform();
86+
i.cloneLayerStackTransform->set({5, -1, 100, 4, 0, 40, 0, 0, 1});
7487

7588
Parcel p;
7689
i.writeToParcel(&p);
@@ -100,6 +113,7 @@ TEST(WindowInfo, Parcelling) {
100113
ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
101114
ASSERT_EQ(i.applicationInfo, i2.applicationInfo);
102115
ASSERT_EQ(i.focusTransferTarget, i2.focusTransferTarget);
116+
ASSERT_EQ(i.cloneLayerStackTransform, i2.cloneLayerStackTransform);
103117
}
104118

105119
TEST(InputApplicationInfo, Parcelling) {

libs/input/input_flags.aconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,13 @@ flag {
224224
description: "Allow cursor to transition across multiple connected displays"
225225
bug: "362719483"
226226
}
227+
228+
flag {
229+
name: "use_cloned_screen_coordinates_as_raw"
230+
namespace: "input"
231+
description: "Use the cloned window's layer stack (screen) space as the raw coordinate space for input going to clones"
232+
bug: "377846505"
233+
metadata {
234+
purpose: PURPOSE_BUGFIX
235+
}
236+
}

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato
418418
if (inputTarget.useDefaultPointerTransform() && !zeroCoords) {
419419
const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
420420
return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
421-
inputTarget.displayTransform,
421+
inputTarget.rawTransform,
422422
inputTarget.globalScaleFactor, uid, vsyncId,
423423
windowId);
424424
}
@@ -439,7 +439,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato
439439
transform =
440440
&inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds()));
441441
const ui::Transform inverseTransform = transform->inverse();
442-
displayTransform = &inputTarget.displayTransform;
442+
displayTransform = &inputTarget.rawTransform;
443443

444444
// Iterate through all pointers in the event to normalize against the first.
445445
for (size_t i = 0; i < motionEntry.getPointerCount(); i++) {
@@ -929,15 +929,15 @@ InputTarget createInputTarget(const std::shared_ptr<Connection>& connection,
929929
const sp<android::gui::WindowInfoHandle>& windowHandle,
930930
InputTarget::DispatchMode dispatchMode,
931931
ftl::Flags<InputTarget::Flags> targetFlags,
932-
const ui::Transform& displayTransform,
932+
const ui::Transform& rawTransform,
933933
std::optional<nsecs_t> firstDownTimeInTarget) {
934934
LOG_ALWAYS_FATAL_IF(connection == nullptr);
935935
InputTarget inputTarget{connection};
936936
inputTarget.windowHandle = windowHandle;
937937
inputTarget.dispatchMode = dispatchMode;
938938
inputTarget.flags = targetFlags;
939939
inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
940-
inputTarget.displayTransform = displayTransform;
940+
inputTarget.rawTransform = rawTransform;
941941
inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
942942
return inputTarget;
943943
}
@@ -3013,11 +3013,10 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa
30133013
windowHandle->getName().c_str());
30143014
return;
30153015
}
3016-
inputTargets.push_back(createInputTarget(connection, windowHandle, dispatchMode,
3017-
targetFlags,
3018-
mWindowInfos.getDisplayTransform(
3019-
windowHandle->getInfo()->displayId),
3020-
firstDownTimeInTarget));
3016+
inputTargets.push_back(
3017+
createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
3018+
mWindowInfos.getRawTransform(*windowHandle->getInfo()),
3019+
firstDownTimeInTarget));
30213020
it = inputTargets.end() - 1;
30223021
}
30233022

@@ -3068,11 +3067,10 @@ void InputDispatcher::addPointerWindowTargetLocked(
30683067
windowHandle->getName().c_str());
30693068
return;
30703069
}
3071-
inputTargets.push_back(createInputTarget(connection, windowHandle, dispatchMode,
3072-
targetFlags,
3073-
mWindowInfos.getDisplayTransform(
3074-
windowHandle->getInfo()->displayId),
3075-
firstDownTimeInTarget));
3070+
inputTargets.push_back(
3071+
createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
3072+
mWindowInfos.getRawTransform(*windowHandle->getInfo()),
3073+
firstDownTimeInTarget));
30763074
it = inputTargets.end() - 1;
30773075
}
30783076

@@ -3104,9 +3102,10 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>&
31043102
for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
31053103
InputTarget target{monitor.connection};
31063104
// target.firstDownTimeInTarget is not set for global monitors. It is only required in split
3107-
// touch and global monitoring works as intended even without setting firstDownTimeInTarget
3108-
target.displayTransform = mWindowInfos.getDisplayTransform(displayId);
3109-
target.setDefaultPointerTransform(target.displayTransform);
3105+
// touch and global monitoring works as intended even without setting firstDownTimeInTarget.
3106+
// Since global monitors don't have windows, use the display transform as the raw transform.
3107+
target.rawTransform = mWindowInfos.getDisplayTransform(displayId);
3108+
target.setDefaultPointerTransform(target.rawTransform);
31103109
inputTargets.push_back(target);
31113110
}
31123111
}
@@ -4291,9 +4290,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
42914290
motionEntry.downTime, targets);
42924291
} else {
42934292
targets.emplace_back(fallbackTarget);
4293+
// Since we don't have a window, use the display transform as the raw transform.
42944294
const ui::Transform displayTransform =
42954295
mWindowInfos.getDisplayTransform(motionEntry.displayId);
4296-
targets.back().displayTransform = displayTransform;
4296+
targets.back().rawTransform = displayTransform;
42974297
targets.back().setDefaultPointerTransform(displayTransform);
42984298
}
42994299
logOutboundMotionDetails("cancel - ", motionEntry);
@@ -4376,9 +4376,10 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
43764376
targets);
43774377
} else {
43784378
targets.emplace_back(connection, targetFlags);
4379+
// Since we don't have a window, use the display transform as the raw transform.
43794380
const ui::Transform displayTransform =
43804381
mWindowInfos.getDisplayTransform(motionEntry.displayId);
4381-
targets.back().displayTransform = displayTransform;
4382+
targets.back().rawTransform = displayTransform;
43824383
targets.back().setDefaultPointerTransform(displayTransform);
43834384
}
43844385
logOutboundMotionDetails("down - ", motionEntry);
@@ -5289,6 +5290,16 @@ ui::Transform InputDispatcher::DispatcherWindowInfo::getDisplayTransform(
52895290
: kIdentityTransform;
52905291
}
52915292

5293+
ui::Transform InputDispatcher::DispatcherWindowInfo::getRawTransform(
5294+
const android::gui::WindowInfo& windowInfo) const {
5295+
// If the window has a cloneLayerStackTransform, always use it as the transform for the "getRaw"
5296+
// APIs. If not, fall back to using the DisplayInfo transform of the window's display.
5297+
return (input_flags::use_cloned_screen_coordinates_as_raw() &&
5298+
windowInfo.cloneLayerStackTransform)
5299+
? *windowInfo.cloneLayerStackTransform
5300+
: getDisplayTransform(windowInfo.displayId);
5301+
}
5302+
52925303
std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const {
52935304
std::string dump;
52945305
if (!mWindowHandlesByDisplay.empty()) {
@@ -6567,9 +6578,8 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
65676578
createInputTarget(connection, windowHandle,
65686579
InputTarget::DispatchMode::AS_IS,
65696580
dispatchEntry->targetFlags,
6570-
mWindowInfos.getDisplayTransform(
6571-
windowHandle->getInfo()
6572-
->displayId),
6581+
mWindowInfos.getRawTransform(
6582+
*windowHandle->getInfo()),
65736583
downTime));
65746584
}
65756585
}

services/inputflinger/dispatcher/InputDispatcher.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ class InputDispatcher : public android::InputDispatcherInterface {
384384
// Get the transform for display, returns Identity-transform if display is missing.
385385
ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const;
386386

387+
// Get the raw transform to use for motion events going to the given window.
388+
ui::Transform getRawTransform(const android::gui::WindowInfo&) const;
389+
387390
// Lookup for WindowInfoHandle from token and optionally a display-id. In cases where
388391
// display-id is not provided lookup is done for all displays.
389392
sp<android::gui::WindowInfoHandle> findWindowHandle(

services/inputflinger/dispatcher/InputTarget.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ class InputTarget {
7777
// (ignored for KeyEvents)
7878
float globalScaleFactor = 1.0f;
7979

80-
// Current display transform. Used for compatibility for raw coordinates.
81-
ui::Transform displayTransform;
80+
// The raw coordinate transform that's used for compatibility for MotionEvent's getRaw APIs.
81+
ui::Transform rawTransform;
8282

8383
// Event time for the first motion event (ACTION_DOWN) dispatched to this input target if
8484
// FLAG_SPLIT is set.

0 commit comments

Comments
 (0)