diff options
| author | 2024-02-05 16:24:43 +0000 | |
|---|---|---|
| committer | 2024-02-08 16:55:43 +0000 | |
| commit | 2bf6aaf17397948ff888937b1c4c660ab130dc64 (patch) | |
| tree | 7f495783592eb5a7c1c84598b13901e8684c6f6a | |
| parent | c7858862b7ef5a5559ad4186d785a1dade39ce15 (diff) | |
Remove unneeded status bar side insets when cutout is at the bottom
When the cutout is in the bottom corner, and is considered to be a
"bottom" cutout, instead of a "side" cutout, it still shares a short
edge with the status bar. Because of that, we were adding side insets
to the status bar, even when not needed.
The fix is to exclude bottom cutouts from the intersection calculations.
Fixes: 321957421
Test: StatusBarContentInsetsProviderTest
Test: Manually
Flag: NONE
Change-Id: I76c3cde7ad5c19058b9d6a22e08c0497fc53164f
2 files changed, 102 insertions, 51 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt index 53b262bd29a1..8b6880c3cb67 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt @@ -69,6 +69,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { context.createConfigurationContext(it.arguments[0] as Configuration) } configurationController = ConfigurationControllerImpl(contextMock) + setNoCutout() } @Test @@ -178,7 +179,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { val dotWidth = 10 val statusBarContentHeight = 15 - whenever(dc.boundingRects).thenReturn(listOf(dcBounds)) + setCutoutBounds(top = dcBounds) // THEN rotations which share a short side should use the greater value between rounded // corner padding and the display cutout's size @@ -285,11 +286,8 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { val dotWidth = 10 val statusBarContentHeight = 15 - val protectionInfo = mock<CameraProtectionInfo> { - whenever(this.cutoutBounds).thenReturn(protectionBounds) - } - whenever(sysUICutout.cameraProtection).thenReturn(protectionInfo) - whenever(dc.boundingRects).thenReturn(listOf(dcBounds)) + setCameraProtectionBounds(protectionBounds) + setCutoutBounds(top = dcBounds) // THEN rotations which share a short side should use the greater value between rounded // corner padding, the display cutout's size, and the camera protections' size. @@ -381,11 +379,36 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { assertRects(expectedBounds, bounds, currentRotation, targetRotation) } + private fun Rect(left: Int, top: Int, right: Int, bottom: Int) = + android.graphics.Rect(left, top, right, bottom) + @Test fun testCalculateInsetsForRotationWithRotatedResources_topRightCutout_noCameraProtection() { - // GIVEN a device in portrait mode with width < height and a display cutout in the top-left val screenBounds = Rect(0, 0, 1000, 2000) - val dcBounds = Rect(900, 0, 1000, 100) + val dcWidth = 100 + val dcHeight = 50 + val dcBoundsPortrait = + Rect( + left = screenBounds.right - dcWidth, + top = 0, + right = screenBounds.right, + bottom = dcHeight + ) + val dcBoundsLandscape = Rect(left = 0, top = 0, right = dcHeight, bottom = dcWidth) + val dcBoundsSeascape = + Rect( + left = screenBounds.right - dcHeight, + top = screenBounds.bottom - dcWidth, + right = screenBounds.right - dcHeight, + bottom = screenBounds.bottom - dcWidth + ) + val dcBoundsUpsideDown = + Rect( + left = 0, + top = screenBounds.bottom - dcHeight, + right = dcWidth, + bottom = screenBounds.bottom - dcHeight + ) val minLeftPadding = 20 val minRightPadding = 20 val sbHeightPortrait = 100 @@ -395,15 +418,15 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { val dotWidth = 10 val statusBarContentHeight = 15 - whenever(dc.boundingRects).thenReturn(listOf(dcBounds)) - - // THEN rotations which share a short side should use the greater value between rounded - // corner padding and the display cutout's size var targetRotation = ROTATION_NONE - var expectedBounds = Rect(minLeftPadding, - 0, - dcBounds.left - dotWidth, - sbHeightPortrait) + setCutoutBounds(top = dcBoundsPortrait) + var expectedBounds = + Rect( + left = minLeftPadding, + top = 0, + right = dcBoundsPortrait.left - dotWidth, + bottom = sbHeightPortrait + ) var bounds = calculateInsetsForRotationWithRotatedResources( currentRotation, @@ -421,10 +444,14 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { assertRects(expectedBounds, bounds, currentRotation, targetRotation) targetRotation = ROTATION_LANDSCAPE - expectedBounds = Rect(dcBounds.height(), - 0, - screenBounds.height() - minRightPadding, - sbHeightLandscape) + setCutoutBounds(top = dcBoundsLandscape) + expectedBounds = + Rect( + left = dcBoundsLandscape.height(), + top = 0, + right = screenBounds.height() - minRightPadding, + bottom = sbHeightLandscape + ) bounds = calculateInsetsForRotationWithRotatedResources( currentRotation, @@ -441,13 +468,15 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { assertRects(expectedBounds, bounds, currentRotation, targetRotation) - // THEN the side that does NOT share a short side with the display cutout ignores the - // display cutout bounds targetRotation = ROTATION_UPSIDE_DOWN - expectedBounds = Rect(minLeftPadding, - 0, - screenBounds.width() - minRightPadding, - sbHeightPortrait) + setCutoutBounds(bottom = dcBoundsUpsideDown) + expectedBounds = + Rect( + left = minLeftPadding, + top = 0, + right = screenBounds.width() - minRightPadding, + bottom = sbHeightPortrait + ) bounds = calculateInsetsForRotationWithRotatedResources( currentRotation, @@ -464,12 +493,15 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { assertRects(expectedBounds, bounds, currentRotation, targetRotation) - // Phone in portrait, seascape (rot_270) bounds targetRotation = ROTATION_SEASCAPE - expectedBounds = Rect(minLeftPadding, - 0, - screenBounds.height() - dcBounds.height() - dotWidth, - sbHeightLandscape) + setCutoutBounds(bottom = dcBoundsSeascape) + expectedBounds = + Rect( + left = minLeftPadding, + top = 0, + right = screenBounds.height() - minRightPadding, + bottom = sbHeightLandscape + ) bounds = calculateInsetsForRotationWithRotatedResources( currentRotation, @@ -502,19 +534,12 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { val dotWidth = 10 val statusBarContentHeight = 15 - val protectionInfo = mock<CameraProtectionInfo> { - whenever(this.cutoutBounds).thenReturn(protectionBounds) - } - whenever(sysUICutout.cameraProtection).thenReturn(protectionInfo) - whenever(dc.boundingRects).thenReturn(listOf(dcBounds)) + setCameraProtectionBounds(protectionBounds) - // THEN rotations which share a short side should use the greater value between rounded - // corner padding, the display cutout's size, and the camera protections' size. var targetRotation = ROTATION_NONE - var expectedBounds = Rect(minLeftPadding, - 0, - protectionBounds.left - dotWidth, - sbHeightPortrait) + setCutoutBounds(top = dcBounds) + var expectedBounds = + Rect(minLeftPadding, 0, protectionBounds.left - dotWidth, sbHeightPortrait) var bounds = calculateInsetsForRotationWithRotatedResources( currentRotation, @@ -600,7 +625,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { @Test fun calculateInsetsForRotationWithRotatedResources_bottomAlignedMarginDisabled_noTopInset() { - whenever(dc.boundingRects).thenReturn(emptyList()) + setNoCutout() val bounds = calculateInsetsForRotationWithRotatedResources( currentRotation = ROTATION_NONE, @@ -663,11 +688,8 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { val dotWidth = 10 val statusBarContentHeight = 15 - val protectionInfo = mock<CameraProtectionInfo> { - whenever(this.cutoutBounds).thenReturn(protectionBounds) - } - whenever(sysUICutout.cameraProtection).thenReturn(protectionInfo) - whenever(dc.boundingRects).thenReturn(listOf(dcBounds)) + setCameraProtectionBounds(protectionBounds) + setCutoutBounds(top = dcBounds) // THEN only the landscape/seascape rotations should avoid the cutout area because of the // potential letterboxing @@ -865,7 +887,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { val dotWidth = 10 val statusBarContentHeight = 15 - whenever(dc.boundingRects).thenReturn(listOf(dcBounds)) + setCutoutBounds(top = dcBounds) // THEN left should be set to the display cutout width, and right should use the minRight val targetRotation = ROTATION_NONE @@ -1008,7 +1030,32 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { "Rects must match. currentRotation=${RotationUtils.toString(currentRotation)}" + " targetRotation=${RotationUtils.toString(targetRotation)}" + " expected=$expected actual=$actual", - expected.equals(actual)) + expected.equals(actual) + ) + } + + private fun setNoCutout() { + setCutoutBounds() + } + + private fun setCutoutBounds( + left: Rect = Rect(), + top: Rect = Rect(), + right: Rect = Rect(), + bottom: Rect = Rect() + ) { + whenever(dc.boundingRects) + .thenReturn(listOf(left, top, right, bottom).filter { !it.isEmpty }) + whenever(dc.boundingRectLeft).thenReturn(left) + whenever(dc.boundingRectTop).thenReturn(top) + whenever(dc.boundingRectRight).thenReturn(right) + whenever(dc.boundingRectBottom).thenReturn(bottom) + } + + private fun setCameraProtectionBounds(protectionBounds: Rect) { + val protectionInfo = + mock<CameraProtectionInfo> { whenever(this.cutoutBounds).thenReturn(protectionBounds) } + whenever(sysUICutout.cameraProtection).thenReturn(protectionInfo) } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt index e84b7a077b21..ac203db209e0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt @@ -494,7 +494,8 @@ private fun getStatusBarContentBounds( val logicalDisplayWidth = if (targetRotation.isHorizontal()) height else width - val cutoutRects = sysUICutout?.cutout?.boundingRects + // Exclude the bottom rect, as it doesn't intersect with the status bar. + val cutoutRects = sysUICutout?.cutout?.boundingRectsLeftRightTop if (cutoutRects.isNullOrEmpty()) { return Rect(minLeft, insetTop, logicalDisplayWidth - minRight, sbHeight) } @@ -547,6 +548,9 @@ private fun rectUnion(first: Rect, second: Rect) = Rect(first).apply { union(sec private fun Rect.intersects(other: Rect): Boolean = intersects(other.left, other.top, other.right, other.bottom) +private val DisplayCutout.boundingRectsLeftRightTop + get() = listOf(boundingRectLeft, boundingRectRight, boundingRectTop).filter { !it.isEmpty } + /* * Returns the inset top of the status bar. * |