Skip to content

Commit def8ff1

Browse files
author
Arpit Singh
committed
Remove temporary DisplayTopology types
This CL removes and replaces temporary DisplayTopology related struct and enums. Test: atest inputflinger_tests Bug: 367659738 Bug: 367660694 Flag: com.android.input.flags.connected_displays_cursor Change-Id: I5ca250b762832b35167ea9991a5ce4b00177ae84
1 parent a2562b0 commit def8ff1

3 files changed

Lines changed: 68 additions & 130 deletions

File tree

services/inputflinger/PointerChoreographer.cpp

Lines changed: 40 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,22 @@ std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowIn
9898
return privacySensitiveDisplays;
9999
}
100100

101+
vec2 calculatePositionOnDestinationViewport(const DisplayViewport& destinationViewport,
102+
float pointerOffset,
103+
DisplayTopologyPosition sourceBoundary) {
104+
// destination is opposite of the source boundary
105+
switch (sourceBoundary) {
106+
case DisplayTopologyPosition::RIGHT:
107+
return {0, pointerOffset}; // left edge
108+
case DisplayTopologyPosition::TOP:
109+
return {pointerOffset, destinationViewport.logicalBottom}; // bottom edge
110+
case DisplayTopologyPosition::LEFT:
111+
return {destinationViewport.logicalRight, pointerOffset}; // right edge
112+
case DisplayTopologyPosition::BOTTOM:
113+
return {pointerOffset, 0}; // top edge
114+
}
115+
}
116+
101117
} // namespace
102118

103119
// --- PointerChoreographer ---
@@ -327,19 +343,19 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
327343
// except sometimes near the corners.
328344
// In these cases this behaviour is not noticeable. We also do not apply unconsumed delta on
329345
// the destination display for the same reason.
330-
DisplayPosition sourceBoundary;
346+
DisplayTopologyPosition sourceBoundary;
331347
float cursorOffset = 0.0f;
332348
if (rotatedUnconsumedDelta.x > 0) {
333-
sourceBoundary = DisplayPosition::RIGHT;
349+
sourceBoundary = DisplayTopologyPosition::RIGHT;
334350
cursorOffset = rotatedCursorPosition.y;
335351
} else if (rotatedUnconsumedDelta.x < 0) {
336-
sourceBoundary = DisplayPosition::LEFT;
352+
sourceBoundary = DisplayTopologyPosition::LEFT;
337353
cursorOffset = rotatedCursorPosition.y;
338354
} else if (rotatedUnconsumedDelta.y > 0) {
339-
sourceBoundary = DisplayPosition::BOTTOM;
355+
sourceBoundary = DisplayTopologyPosition::BOTTOM;
340356
cursorOffset = rotatedCursorPosition.x;
341357
} else {
342-
sourceBoundary = DisplayPosition::TOP;
358+
sourceBoundary = DisplayTopologyPosition::TOP;
343359
cursorOffset = rotatedCursorPosition.x;
344360
}
345361

@@ -369,8 +385,9 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
369385
pc.fade(PointerControllerInterface::Transition::IMMEDIATE);
370386
pc.setDisplayViewport(destinationViewport);
371387
vec2 destinationPosition =
372-
calculateDestinationPosition(destinationViewport, cursorOffset - destinationOffset,
373-
sourceBoundary);
388+
calculatePositionOnDestinationViewport(destinationViewport,
389+
cursorOffset - destinationOffset,
390+
sourceBoundary);
374391

375392
// Transform position back to un-rotated coordinate space before sending it to controller
376393
destinationPosition = pc.getDisplayTransform().inverse().transform(destinationPosition.x,
@@ -379,22 +396,6 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
379396
pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
380397
}
381398

382-
vec2 PointerChoreographer::calculateDestinationPosition(const DisplayViewport& destinationViewport,
383-
float pointerOffset,
384-
DisplayPosition sourceBoundary) {
385-
// destination is opposite of the source boundary
386-
switch (sourceBoundary) {
387-
case DisplayPosition::RIGHT:
388-
return {0, pointerOffset}; // left edge
389-
case DisplayPosition::TOP:
390-
return {pointerOffset, destinationViewport.logicalBottom}; // bottom edge
391-
case DisplayPosition::LEFT:
392-
return {destinationViewport.logicalRight, pointerOffset}; // right edge
393-
case DisplayPosition::BOTTOM:
394-
return {pointerOffset, 0}; // top edge
395-
}
396-
}
397-
398399
void PointerChoreographer::processDrawingTabletEventLocked(const android::NotifyMotionArgs& args) {
399400
if (args.displayId == ui::LogicalDisplayId::INVALID) {
400401
return;
@@ -540,8 +541,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args)
540541
}
541542

542543
void PointerChoreographer::onControllerAddedOrRemovedLocked() {
543-
if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows() &&
544-
!com::android::input::flags::connected_displays_cursor()) {
544+
if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows()) {
545545
return;
546546
}
547547
bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() ||
@@ -607,11 +607,16 @@ void PointerChoreographer::notifyPointerCaptureChanged(
607607
mNextListener.notify(args);
608608
}
609609

610-
void PointerChoreographer::setDisplayTopology(
611-
const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>&
612-
displayTopology) {
610+
void PointerChoreographer::setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) {
613611
std::scoped_lock _l(getLock());
614-
mTopology = displayTopology;
612+
mTopology = displayTopologyGraph;
613+
614+
// make primary display default mouse display, if it was not set
615+
// or the existing display was removed
616+
if (mDefaultMouseDisplayId == ui::LogicalDisplayId::INVALID ||
617+
mTopology.graph.find(mDefaultMouseDisplayId) != mTopology.graph.end()) {
618+
mDefaultMouseDisplayId = mTopology.primaryDisplayId;
619+
}
615620
}
616621

617622
void PointerChoreographer::dump(std::string& dump) {
@@ -985,73 +990,17 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr
985990
return ConstructorDelegate(std::move(ctor));
986991
}
987992

988-
void PointerChoreographer::populateFakeDisplayTopologyLocked(
989-
const std::vector<gui::DisplayInfo>& displayInfos) {
990-
if (!com::android::input::flags::connected_displays_cursor()) {
991-
return;
992-
}
993-
994-
if (displayInfos.size() == mTopology.size()) {
995-
bool displaysChanged = false;
996-
for (const auto& displayInfo : displayInfos) {
997-
if (mTopology.find(displayInfo.displayId) == mTopology.end()) {
998-
displaysChanged = true;
999-
break;
1000-
}
1001-
}
1002-
1003-
if (!displaysChanged) {
1004-
return;
1005-
}
1006-
}
1007-
1008-
// create a fake topology assuming following order
1009-
// default-display (top-edge) -> next-display (right-edge) -> next-display (right-edge) ...
1010-
// This also adds a 100px offset on corresponding edge for better manual testing
1011-
// ┌────────┐
1012-
// │ next ├─────────┐
1013-
// ┌─└───────┐┤ next 2 │ ...
1014-
// │ default │└─────────┘
1015-
// └─────────┘
1016-
mTopology.clear();
1017-
1018-
// treat default display as base, in real topology it should be the primary-display
1019-
ui::LogicalDisplayId previousDisplay = ui::LogicalDisplayId::DEFAULT;
1020-
for (const auto& displayInfo : displayInfos) {
1021-
if (displayInfo.displayId == ui::LogicalDisplayId::DEFAULT) {
1022-
continue;
1023-
}
1024-
if (previousDisplay == ui::LogicalDisplayId::DEFAULT) {
1025-
mTopology[previousDisplay].push_back(
1026-
{displayInfo.displayId, DisplayPosition::TOP, 100});
1027-
mTopology[displayInfo.displayId].push_back(
1028-
{previousDisplay, DisplayPosition::BOTTOM, -100});
1029-
} else {
1030-
mTopology[previousDisplay].push_back(
1031-
{displayInfo.displayId, DisplayPosition::RIGHT, 100});
1032-
mTopology[displayInfo.displayId].push_back(
1033-
{previousDisplay, DisplayPosition::LEFT, -100});
1034-
}
1035-
previousDisplay = displayInfo.displayId;
1036-
}
1037-
1038-
// update default pointer display. In real topology it should be the primary-display
1039-
if (mTopology.find(mDefaultMouseDisplayId) == mTopology.end()) {
1040-
mDefaultMouseDisplayId = ui::LogicalDisplayId::DEFAULT;
1041-
}
1042-
}
1043-
1044993
std::optional<std::pair<const DisplayViewport*, float /*offset*/>>
1045994
PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId,
1046-
const DisplayPosition sourceBoundary,
995+
const DisplayTopologyPosition sourceBoundary,
1047996
float cursorOffset) const {
1048-
const auto& sourceNode = mTopology.find(sourceDisplayId);
1049-
if (sourceNode == mTopology.end()) {
997+
const auto& sourceNode = mTopology.graph.find(sourceDisplayId);
998+
if (sourceNode == mTopology.graph.end()) {
1050999
// Topology is likely out of sync with viewport info, wait for it to be updated
10511000
LOG(WARNING) << "Source display missing from topology " << sourceDisplayId;
10521001
return std::nullopt;
10531002
}
1054-
for (const AdjacentDisplay& adjacentDisplay : sourceNode->second) {
1003+
for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : sourceNode->second) {
10551004
if (adjacentDisplay.position != sourceBoundary) {
10561005
continue;
10571006
}
@@ -1064,8 +1013,8 @@ PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId so
10641013
continue;
10651014
}
10661015
// target position must be within target display boundary
1067-
const int32_t edgeSize =
1068-
sourceBoundary == DisplayPosition::TOP || sourceBoundary == DisplayPosition::BOTTOM
1016+
const int32_t edgeSize = sourceBoundary == DisplayTopologyPosition::TOP ||
1017+
sourceBoundary == DisplayTopologyPosition::BOTTOM
10691018
? (destinationViewport->logicalRight - destinationViewport->logicalLeft)
10701019
: (destinationViewport->logicalBottom - destinationViewport->logicalTop);
10711020
if (cursorOffset >= adjacentDisplay.offsetPx &&
@@ -1093,7 +1042,6 @@ void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfo
10931042
mPrivacySensitiveDisplays = std::move(newPrivacySensitiveDisplays);
10941043
mPointerChoreographer->onPrivacySensitiveDisplaysChangedLocked(mPrivacySensitiveDisplays);
10951044
}
1096-
mPointerChoreographer->populateFakeDisplayTopologyLocked(windowInfosUpdate.displayInfos);
10971045
}
10981046

10991047
void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfosLocked(

services/inputflinger/PointerChoreographer.h

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <android-base/thread_annotations.h>
2424
#include <gui/WindowInfosListener.h>
25+
#include <input/DisplayTopologyGraph.h>
2526
#include <type_traits>
2627
#include <unordered_set>
2728

@@ -80,6 +81,11 @@ class PointerChoreographerInterface : public InputListenerInterface {
8081
*/
8182
virtual void setFocusedDisplay(ui::LogicalDisplayId displayId) = 0;
8283

84+
/*
85+
* Used by InputManager to notify changes in the DisplayTopology
86+
*/
87+
virtual void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) = 0;
88+
8389
/**
8490
* This method may be called on any thread (usually by the input manager on a binder thread).
8591
*/
@@ -103,6 +109,7 @@ class PointerChoreographer : public PointerChoreographerInterface {
103109
ui::LogicalDisplayId displayId, DeviceId deviceId) override;
104110
void setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) override;
105111
void setFocusedDisplay(ui::LogicalDisplayId displayId) override;
112+
void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph);
106113

107114
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
108115
void notifyKey(const NotifyKeyArgs& args) override;
@@ -113,24 +120,6 @@ class PointerChoreographer : public PointerChoreographerInterface {
113120
void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
114121
void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override;
115122

116-
// TODO(b/362719483) remove these when real topology is available
117-
enum class DisplayPosition {
118-
RIGHT,
119-
TOP,
120-
LEFT,
121-
BOTTOM,
122-
ftl_last = BOTTOM,
123-
};
124-
125-
struct AdjacentDisplay {
126-
ui::LogicalDisplayId displayId;
127-
DisplayPosition position;
128-
float offsetPx;
129-
};
130-
void setDisplayTopology(
131-
const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>&
132-
displayTopology);
133-
134123
void dump(std::string& dump) override;
135124

136125
private:
@@ -174,18 +163,16 @@ class PointerChoreographer : public PointerChoreographerInterface {
174163
void handleUnconsumedDeltaLocked(PointerControllerInterface& pc, const vec2& unconsumedDelta)
175164
REQUIRES(getLock());
176165

177-
void populateFakeDisplayTopologyLocked(const std::vector<gui::DisplayInfo>& displayInfos)
178-
REQUIRES(getLock());
179-
180166
std::optional<std::pair<const DisplayViewport*, float /*offset*/>> findDestinationDisplayLocked(
181-
const ui::LogicalDisplayId sourceDisplayId, const DisplayPosition sourceBoundary,
182-
float cursorOffset) const REQUIRES(getLock());
183-
184-
static vec2 calculateDestinationPosition(const DisplayViewport& destinationViewport,
185-
float pointerOffset, DisplayPosition sourceBoundary);
167+
const ui::LogicalDisplayId sourceDisplayId,
168+
const DisplayTopologyPosition sourceBoundary, float cursorOffset) const
169+
REQUIRES(getLock());
186170

187-
std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>> mTopology
188-
GUARDED_BY(getLock());
171+
/* Topology is initialized with default-constructed value, which is an empty topology. Till we
172+
* receive setDisplayTopology call.
173+
* Meanwhile Choreographer will treat every display as independent disconnected display.
174+
*/
175+
DisplayTopologyGraph mTopology GUARDED_BY(getLock());
189176

190177
/* This listener keeps tracks of visible privacy sensitive displays and updates the
191178
* choreographer if there are any changes.

services/inputflinger/tests/PointerChoreographer_test.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,16 +2633,14 @@ class PointerChoreographerDisplayTopologyTestFixture
26332633
ui::ROTATION_0),
26342634
};
26352635

2636-
std::unordered_map<ui::LogicalDisplayId, std::vector<PointerChoreographer::AdjacentDisplay>>
2637-
mTopology{
2638-
{DISPLAY_CENTER_ID,
2639-
{{DISPLAY_TOP_ID, PointerChoreographer::DisplayPosition::TOP, 10.0f},
2640-
{DISPLAY_RIGHT_ID, PointerChoreographer::DisplayPosition::RIGHT, 10.0f},
2641-
{DISPLAY_BOTTOM_ID, PointerChoreographer::DisplayPosition::BOTTOM, 10.0f},
2642-
{DISPLAY_LEFT_ID, PointerChoreographer::DisplayPosition::LEFT, 10.0f},
2643-
{DISPLAY_TOP_RIGHT_CORNER_ID, PointerChoreographer::DisplayPosition::RIGHT,
2644-
-90.0f}}},
2645-
};
2636+
DisplayTopologyGraph mTopology{DISPLAY_CENTER_ID,
2637+
{{DISPLAY_CENTER_ID,
2638+
{{DISPLAY_TOP_ID, DisplayTopologyPosition::TOP, 10.0f},
2639+
{DISPLAY_RIGHT_ID, DisplayTopologyPosition::RIGHT, 10.0f},
2640+
{DISPLAY_BOTTOM_ID, DisplayTopologyPosition::BOTTOM, 10.0f},
2641+
{DISPLAY_LEFT_ID, DisplayTopologyPosition::LEFT, 10.0f},
2642+
{DISPLAY_TOP_RIGHT_CORNER_ID, DisplayTopologyPosition::RIGHT,
2643+
-90.0f}}}}};
26462644

26472645
private:
26482646
DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height,
@@ -2706,6 +2704,11 @@ INSTANTIATE_TEST_SUITE_P(
27062704
testing::Values(
27072705
// Note: Upon viewport transition cursor will be positioned at the boundary of the
27082706
// destination, as we drop any unconsumed delta.
2707+
std::make_tuple("PrimaryDisplayIsDefault", AINPUT_SOURCE_MOUSE,
2708+
ControllerType::MOUSE, ToolType::MOUSE,
2709+
vec2(50, 50) /* initial x/y */, vec2(0, 0) /* delta x/y */,
2710+
PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
2711+
vec2(50, 50) /* destination x/y */),
27092712
std::make_tuple("UnchangedDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE,
27102713
ToolType::MOUSE, vec2(50, 50) /* initial x/y */,
27112714
vec2(25, 25) /* delta x/y */,

0 commit comments

Comments
 (0)