From 607b01760f0fff1099dc99c68c67656cd3a2cfdc Mon Sep 17 00:00:00 2001 From: Matthew DeVore Date: Tue, 3 Dec 2024 20:05:54 +0000 Subject: [PATCH] TopologyScale: limit vertical padding In the original design, we don't allow the vertical padding to be more than the tallest display block on the top or bottom. This patch simply applies that strategy that was in the design. Test: TopologyScaleTest Bug: b/352648432 Flag: com.android.settings.flags.display_topology_pane_in_display_list Change-Id: Icd3e0c93e4201d8251de0be4ca636352115c657d --- .../display/DisplayTopology.kt | 14 ++++++++-- .../display/TopologyScaleTest.kt | 26 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/connecteddevice/display/DisplayTopology.kt b/src/com/android/settings/connecteddevice/display/DisplayTopology.kt index d483f4624d7..162d9d284fb 100644 --- a/src/com/android/settings/connecteddevice/display/DisplayTopology.kt +++ b/src/com/android/settings/connecteddevice/display/DisplayTopology.kt @@ -59,12 +59,14 @@ class TopologyScale(paneWidth : Int, displaysPos : Collection) { val displayBounds = RectF( Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_VALUE) var smallestDisplayDim = Float.MAX_VALUE + var biggestDisplayHeight = Float.MIN_VALUE // displayBounds is the smallest rect encompassing all displays, in display space. // smallestDisplayDim is the size of the smallest display edge, in display space. for (pos in displaysPos) { displayBounds.union(pos) smallestDisplayDim = minOf(smallestDisplayDim, pos.height(), pos.width()) + biggestDisplayHeight = max(biggestDisplayHeight, pos.height()) } // Set height according to the width and the aspect ratio of the display bounds. @@ -81,9 +83,17 @@ class TopologyScale(paneWidth : Int, displaysPos : Collection) { // Essentially, we just set the pane height based on the pre-determined pane width and the // aspect ratio of the display bounds. But we may need to increase it slightly to achieve // 20% padding above and below the display bounds - this is where the 0.6 comes from. - paneHeight = max( + val rawPaneHeight = max( paneWidth.toDouble() / displayBounds.width() * displayBounds.height(), - displayBounds.height() * blockRatio / 0.6).toInt() + displayBounds.height() * blockRatio / 0.6) + + // It is easy for the aspect ratio to result in an excessively tall pane, since the width is + // pre-determined and may be considerably wider than necessary. So we prevent the height + // from growing too large here, by limiting vertical padding to the size of the tallest + // display. This improves results for very tall display bounds. + paneHeight = min( + rawPaneHeight.toInt(), + (blockRatio * (displayBounds.height() + biggestDisplayHeight * 2f)).toInt()) // Set originPaneXY (the location of 0,0 in display space in the pane's coordinate system) // such that the display bounds rect is centered in the pane. diff --git a/tests/robotests/src/com/android/settings/connecteddevice/display/TopologyScaleTest.kt b/tests/robotests/src/com/android/settings/connecteddevice/display/TopologyScaleTest.kt index e02cd40650c..078436264e7 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/display/TopologyScaleTest.kt +++ b/tests/robotests/src/com/android/settings/connecteddevice/display/TopologyScaleTest.kt @@ -40,11 +40,11 @@ class TopologyScaleTest { // blockRatio is higher than 0.05 in order to make the smallest display edge (480 dp) 48dp // in the pane. assertEquals( - "{TopoScale blockRatio=0.100000 originPaneXY=288,216 paneHeight=480}", "" + scale) + "{TopoScale blockRatio=0.100000 originPaneXY=288,48 paneHeight=144}", "" + scale) - assertEquals(Point(352, 264), scale.displayToPaneCoor(PointF(640f, 480f))) - assertEquals(Point(320, 240), scale.displayToPaneCoor(PointF(320f, 240f))) - assertEquals(PointF(640f, 480f), scale.paneToDisplayCoor(Point(352, 264))) + assertEquals(Point(352, 96), scale.displayToPaneCoor(PointF(640f, 480f))) + assertEquals(Point(320, 72), scale.displayToPaneCoor(PointF(320f, 240f))) + assertEquals(PointF(640f, 480f), scale.paneToDisplayCoor(Point(352, 96))) } @Test @@ -76,4 +76,22 @@ class TopologyScaleTest { assertEquals(Point(96, 64), scale.displayToPaneCoor(PointF(0f, -320f))) assertPointF(220f, -430f, 0.001f, scale.paneToDisplayCoor(Point(140, 42))) } + + @Test + fun paneVerticalPaddingLimitedByTallestDisplay() { + val scale = TopologyScale( + /* paneWidth= */ 300, + listOf( + RectF(0f, 0f, 640f, 480f), + RectF(0f, 480f, 640f, 960f), + RectF(0f, 960f, 640f, 1440f), + RectF(0f, 1440f, 640f, 1920f), + RectF(0f, 1920f, 640f, 2400f), + RectF(0f, 2400f, 640f, 2880f))) + + assertEquals( + "{TopoScale blockRatio=0.100000 originPaneXY=118,48 paneHeight=384}", "" + scale) + assertEquals(Point(150, 48), scale.displayToPaneCoor(PointF(320f, 0f))) + assertPointF(-180f, 2880f, 0.001f, scale.paneToDisplayCoor(Point(100, 336))) + } }