DisplayTopology: user cannot drag only display

When dragging a single display, we don't constrain the position of the
display, and the user can drag it anywhere on the fragment. As such we
need to either prevent the drag or refresh the pane always if there is
only one display. This CL chooses the former.

Flag: com.android.settings.flags.display_topology_pane_in_display_list
Test: atest DisplayTopologyPreferenceTest.kt
Bug: b/352650922
Change-Id: Icb101b734ce9b88435f64a71bf77f878f9b230e0
This commit is contained in:
Matthew DeVore
2025-01-16 01:51:50 +00:00
parent 878f860fd3
commit b9ea2e327f
2 changed files with 45 additions and 2 deletions

View File

@@ -404,8 +404,12 @@ class DisplayTopologyPreference(context : Context)
private fun onBlockTouchDown(
displayId: Int, displayPos: RectF, block: DisplayBlock, ev: MotionEvent): Boolean {
val stationaryDisps = (mTopologyInfo ?: return false)
.positions.filter { it.first != displayId }
val positions = (mTopologyInfo ?: return false).positions
// Do not allow dragging for single-display topology, since there is nothing to clamp it to.
if (positions.size <= 1) { return false }
val stationaryDisps = positions.filter { it.first != displayId }
// We have to use rawX and rawY for the coordinates since the view receiving the event is
// also the view that is moving. We need coordinates relative to something that isn't

View File

@@ -102,6 +102,15 @@ class DisplayTopologyPreferenceTest {
.map { preference.mPaneContent.getChildAt(it) as DisplayBlock }
.toList()
fun singleDisplayTopology(): DisplayTopology {
val primaryId = 22;
val root = DisplayTopology.TreeNode(
primaryId, /* width= */ 200f, /* height= */ 160f, POSITION_LEFT, /* offset= */ 0f)
return DisplayTopology(root, primaryId)
}
fun twoDisplayTopology(childPosition: Int, childOffset: Float): DisplayTopology {
val primaryId = 1
@@ -287,6 +296,36 @@ class DisplayTopologyPreferenceTest {
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(1)
}
@Test
fun cannotMoveSingleDisplay() {
injector.topology = singleDisplayTopology()
preparePane()
val paneChildren = getPaneChildren()
assertThat(paneChildren).hasSize(1)
val block = paneChildren[0]
val origY = block.unpaddedY
block.dispatchTouchEvent(MotionEventBuilder.newBuilder()
.setAction(MotionEvent.ACTION_DOWN)
.setPointer(0f, 0f)
.build())
block.dispatchTouchEvent(MotionEventBuilder.newBuilder()
.setAction(MotionEvent.ACTION_MOVE)
.setPointer(0f, 30f)
.build())
assertThat(block.unpaddedY).isWithin(0.01f).of(origY)
block.dispatchTouchEvent(MotionEventBuilder.newBuilder()
.setAction(MotionEvent.ACTION_UP)
.build())
// Block should be back to original position.
assertThat(block.unpaddedY).isWithin(0.01f).of(origY)
}
@Test
fun updatedTopologyCancelsDragIfNonTrivialChange() {
val (leftBlock, rightBlock) = setupTwoDisplays(POSITION_LEFT, /* childOffset= */ 42f)