ScreenDecorHwcLayer: request and report transparent regions
I6c5d29614dc8d65d8481150ce717a440192083a0 plumbs the transparent region to the HAL blocking region for DISPLAY_DECORATION layers. Make ScreenDecorHwcLayer call requestTransparentRegion, which will make the ViewRootImpl compute the transparent region. Then override gatherTransparentRegion to remove sections where it draws. Bug: 212736475 Test: atest ScreenDecorHwcLayerTest Change-Id: I0debc8a96dea34ff03ec089233523fe279ecbb00
This commit is contained in:
committed by
shawnlin
parent
24d954694a
commit
9382674db2
@@ -49,7 +49,7 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView {
|
||||
private val shouldDrawCutout: Boolean = DisplayCutout.getFillBuiltInDisplayCutout(
|
||||
context.resources, context.display?.uniqueId)
|
||||
private var displayMode: Display.Mode? = null
|
||||
private val location = IntArray(2)
|
||||
protected val location = IntArray(2)
|
||||
protected var displayRotation = 0
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
|
||||
@@ -65,7 +65,8 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView {
|
||||
@JvmField val protectionPath: Path = Path()
|
||||
private val protectionRectOrig: RectF = RectF()
|
||||
private val protectionPathOrig: Path = Path()
|
||||
private var cameraProtectionProgress: Float = HIDDEN_CAMERA_PROTECTION_SCALE
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
|
||||
var cameraProtectionProgress: Float = HIDDEN_CAMERA_PROTECTION_SCALE
|
||||
private var cameraProtectionAnimator: ValueAnimator? = null
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
@@ -273,4 +274,4 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,22 @@ import android.graphics.PixelFormat
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.graphics.PorterDuffXfermode
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Region
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.hardware.graphics.common.AlphaInterpretation
|
||||
import android.hardware.graphics.common.DisplayDecorationSupport
|
||||
import android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM
|
||||
import android.view.DisplayCutout.BOUNDS_POSITION_LEFT
|
||||
import android.view.DisplayCutout.BOUNDS_POSITION_LENGTH
|
||||
import android.view.DisplayCutout.BOUNDS_POSITION_TOP
|
||||
import android.view.DisplayCutout.BOUNDS_POSITION_RIGHT
|
||||
import android.view.RoundedCorner
|
||||
import android.view.RoundedCorners
|
||||
import android.view.Surface
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.floor
|
||||
|
||||
/**
|
||||
* When the HWC of the device supports Composition.DISPLAY_DECORATON, we use this layer to draw
|
||||
@@ -38,13 +49,16 @@ import android.view.RoundedCorners
|
||||
*/
|
||||
class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport)
|
||||
: DisplayCutoutBaseView(context) {
|
||||
public val colorMode: Int
|
||||
val colorMode: Int
|
||||
private val useInvertedAlphaColor: Boolean
|
||||
private val color: Int
|
||||
private val bgColor: Int
|
||||
private val cornerFilter: ColorFilter
|
||||
private val cornerBgFilter: ColorFilter
|
||||
private val clearPaint: Paint
|
||||
@JvmField val transparentRect: Rect = Rect()
|
||||
private val debugTransparentRegionPaint: Paint?
|
||||
private val tempRect: Rect = Rect()
|
||||
|
||||
private var roundedCornerTopSize = 0
|
||||
private var roundedCornerBottomSize = 0
|
||||
@@ -61,6 +75,10 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
bgColor = Color.TRANSPARENT
|
||||
colorMode = ActivityInfo.COLOR_MODE_DEFAULT
|
||||
useInvertedAlphaColor = false
|
||||
debugTransparentRegionPaint = Paint().apply {
|
||||
color = 0x2f00ff00 // semi-transparent green
|
||||
style = Paint.Style.FILL
|
||||
}
|
||||
} else {
|
||||
colorMode = ActivityInfo.COLOR_MODE_A8
|
||||
useInvertedAlphaColor = displayDecorationSupport.alphaInterpretation ==
|
||||
@@ -72,6 +90,7 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
color = Color.BLACK
|
||||
bgColor = Color.TRANSPARENT
|
||||
}
|
||||
debugTransparentRegionPaint = null
|
||||
}
|
||||
cornerFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
cornerBgFilter = PorterDuffColorFilter(bgColor, PorterDuff.Mode.SRC_OUT)
|
||||
@@ -82,6 +101,9 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
if (!DEBUG_COLOR) {
|
||||
parent.requestTransparentRegion(this)
|
||||
}
|
||||
viewRootImpl.setDisplayDecoration(true)
|
||||
|
||||
if (useInvertedAlphaColor) {
|
||||
@@ -93,12 +115,172 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
// If updating onDraw, also update gatherTransparentRegion
|
||||
if (useInvertedAlphaColor) {
|
||||
canvas.drawColor(bgColor)
|
||||
}
|
||||
// Cutouts are drawn in DisplayCutoutBaseView.onDraw()
|
||||
super.onDraw(canvas)
|
||||
drawRoundedCorners(canvas)
|
||||
|
||||
debugTransparentRegionPaint?.let {
|
||||
calculateTransparentRect()
|
||||
canvas.drawRect(transparentRect, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun gatherTransparentRegion(region: Region?): Boolean {
|
||||
region?.let {
|
||||
calculateTransparentRect()
|
||||
region.op(transparentRect, Region.Op.INTERSECT)
|
||||
}
|
||||
// Always return false - views underneath this should always be visible.
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* The transparent rect is calculated by subtracting the regions of cutouts, cutout protect and
|
||||
* rounded corners from the region with fullscreen display size.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
fun calculateTransparentRect() {
|
||||
transparentRect.set(0, 0, width, height)
|
||||
|
||||
// Remove cutout region.
|
||||
removeCutoutFromTransparentRegion()
|
||||
|
||||
// Remove cutout protection region.
|
||||
removeCutoutProtectionFromTransparentRegion()
|
||||
|
||||
// Remove rounded corner region.
|
||||
removeRoundedCornersFromTransparentRegion()
|
||||
}
|
||||
|
||||
private fun removeCutoutFromTransparentRegion() {
|
||||
displayInfo.displayCutout?.let {
|
||||
cutout ->
|
||||
if (!cutout.boundingRectLeft.isEmpty) {
|
||||
transparentRect.left =
|
||||
cutout.boundingRectLeft.right.coerceAtLeast(transparentRect.left)
|
||||
}
|
||||
if (!cutout.boundingRectTop.isEmpty) {
|
||||
transparentRect.top =
|
||||
cutout.boundingRectTop.bottom.coerceAtLeast(transparentRect.top)
|
||||
}
|
||||
if (!cutout.boundingRectRight.isEmpty) {
|
||||
transparentRect.right =
|
||||
cutout.boundingRectRight.left.coerceAtMost(transparentRect.right)
|
||||
}
|
||||
if (!cutout.boundingRectBottom.isEmpty) {
|
||||
transparentRect.bottom =
|
||||
cutout.boundingRectBottom.top.coerceAtMost(transparentRect.bottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeCutoutProtectionFromTransparentRegion() {
|
||||
if (protectionRect.isEmpty) {
|
||||
return
|
||||
}
|
||||
|
||||
val centerX = protectionRect.centerX()
|
||||
val centerY = protectionRect.centerY()
|
||||
val scaledDistanceX = (centerX - protectionRect.left) * cameraProtectionProgress
|
||||
val scaledDistanceY = (centerY - protectionRect.top) * cameraProtectionProgress
|
||||
tempRect.set(
|
||||
floor(centerX - scaledDistanceX).toInt(),
|
||||
floor(centerY - scaledDistanceY).toInt(),
|
||||
ceil(centerX + scaledDistanceX).toInt(),
|
||||
ceil(centerY + scaledDistanceY).toInt()
|
||||
)
|
||||
|
||||
// Find out which edge the protectionRect belongs and remove that edge from the transparent
|
||||
// region.
|
||||
val leftDistance = tempRect.left
|
||||
val topDistance = tempRect.top
|
||||
val rightDistance = width - tempRect.right
|
||||
val bottomDistance = height - tempRect.bottom
|
||||
val minDistance = minOf(leftDistance, topDistance, rightDistance, bottomDistance)
|
||||
when (minDistance) {
|
||||
leftDistance -> {
|
||||
transparentRect.left = tempRect.right.coerceAtLeast(transparentRect.left)
|
||||
}
|
||||
topDistance -> {
|
||||
transparentRect.top = tempRect.bottom.coerceAtLeast(transparentRect.top)
|
||||
}
|
||||
rightDistance -> {
|
||||
transparentRect.right = tempRect.left.coerceAtMost(transparentRect.right)
|
||||
}
|
||||
bottomDistance -> {
|
||||
transparentRect.bottom = tempRect.top.coerceAtMost(transparentRect.bottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeRoundedCornersFromTransparentRegion() {
|
||||
var hasTopOrBottomCutouts = false
|
||||
var hasLeftOrRightCutouts = false
|
||||
displayInfo.displayCutout?.let {
|
||||
cutout ->
|
||||
hasTopOrBottomCutouts = !cutout.boundingRectTop.isEmpty ||
|
||||
!cutout.boundingRectBottom.isEmpty
|
||||
hasLeftOrRightCutouts = !cutout.boundingRectLeft.isEmpty ||
|
||||
!cutout.boundingRectRight.isEmpty
|
||||
}
|
||||
// The goal is to remove the rounded corner areas as small as possible so that we can have a
|
||||
// larger transparent region. Therefore, we should always remove from the short edge sides
|
||||
// if possible.
|
||||
val isShortEdgeTopBottom = width < height
|
||||
if (isShortEdgeTopBottom) {
|
||||
// Short edges on top & bottom.
|
||||
if (!hasTopOrBottomCutouts && hasLeftOrRightCutouts) {
|
||||
// If there are cutouts only on left or right edges, remove left and right sides
|
||||
// for rounded corners.
|
||||
transparentRect.left = getRoundedCornerSizeByPosition(BOUNDS_POSITION_LEFT)
|
||||
.coerceAtLeast(transparentRect.left)
|
||||
transparentRect.right =
|
||||
(width - getRoundedCornerSizeByPosition(BOUNDS_POSITION_RIGHT))
|
||||
.coerceAtMost(transparentRect.right)
|
||||
} else {
|
||||
// If there are cutouts on top or bottom edges or no cutout at all, remove top
|
||||
// and bottom sides for rounded corners.
|
||||
transparentRect.top = getRoundedCornerSizeByPosition(BOUNDS_POSITION_TOP)
|
||||
.coerceAtLeast(transparentRect.top)
|
||||
transparentRect.bottom =
|
||||
(height - getRoundedCornerSizeByPosition(BOUNDS_POSITION_BOTTOM))
|
||||
.coerceAtMost(transparentRect.bottom)
|
||||
}
|
||||
} else {
|
||||
// Short edges on left & right.
|
||||
if (hasTopOrBottomCutouts && !hasLeftOrRightCutouts) {
|
||||
// If there are cutouts only on top or bottom edges, remove top and bottom sides
|
||||
// for rounded corners.
|
||||
transparentRect.top = getRoundedCornerSizeByPosition(BOUNDS_POSITION_TOP)
|
||||
.coerceAtLeast(transparentRect.top)
|
||||
transparentRect.bottom =
|
||||
(height - getRoundedCornerSizeByPosition(BOUNDS_POSITION_BOTTOM))
|
||||
.coerceAtMost(transparentRect.bottom)
|
||||
} else {
|
||||
// If there are cutouts on left or right edges or no cutout at all, remove left
|
||||
// and right sides for rounded corners.
|
||||
transparentRect.left = getRoundedCornerSizeByPosition(BOUNDS_POSITION_LEFT)
|
||||
.coerceAtLeast(transparentRect.left)
|
||||
transparentRect.right =
|
||||
(width - getRoundedCornerSizeByPosition(BOUNDS_POSITION_RIGHT))
|
||||
.coerceAtMost(transparentRect.right)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRoundedCornerSizeByPosition(position: Int): Int {
|
||||
val delta = displayRotation - Surface.ROTATION_0
|
||||
return when ((position + delta) % BOUNDS_POSITION_LENGTH) {
|
||||
BOUNDS_POSITION_LEFT -> roundedCornerTopSize.coerceAtLeast(roundedCornerBottomSize)
|
||||
BOUNDS_POSITION_TOP -> roundedCornerTopSize
|
||||
BOUNDS_POSITION_RIGHT -> roundedCornerTopSize.coerceAtLeast(roundedCornerBottomSize)
|
||||
BOUNDS_POSITION_BOTTOM -> roundedCornerBottomSize
|
||||
else -> throw IllegalArgumentException("Incorrect position: $position")
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawRoundedCorners(canvas: Canvas) {
|
||||
|
||||
@@ -847,14 +847,20 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
pw.println(" mIsRoundedCornerMultipleRadius:" + mIsRoundedCornerMultipleRadius);
|
||||
pw.println(" mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
|
||||
pw.println(" mPendingRotationChange:" + mPendingRotationChange);
|
||||
pw.println(" mHwcScreenDecorationSupport:");
|
||||
if (mHwcScreenDecorationSupport == null) {
|
||||
pw.println(" null");
|
||||
} else {
|
||||
pw.println(" format: "
|
||||
if (mHwcScreenDecorationSupport != null) {
|
||||
pw.println(" mHwcScreenDecorationSupport:");
|
||||
pw.println(" format="
|
||||
+ PixelFormat.formatToString(mHwcScreenDecorationSupport.format));
|
||||
pw.println(" alphaInterpretation: "
|
||||
pw.println(" alphaInterpretation="
|
||||
+ alphaInterpretationToString(mHwcScreenDecorationSupport.alphaInterpretation));
|
||||
} else {
|
||||
pw.println(" mHwcScreenDecorationSupport: null");
|
||||
}
|
||||
if (mScreenDecorHwcLayer != null) {
|
||||
pw.println(" mScreenDecorHwcLayer:");
|
||||
pw.println(" transparentRegion=" + mScreenDecorHwcLayer.transparentRect);
|
||||
} else {
|
||||
pw.println(" mScreenDecorHwcLayer: null");
|
||||
}
|
||||
pw.println(" mRoundedDefault(x,y)=(" + mRoundedDefault.x + "," + mRoundedDefault.y + ")");
|
||||
pw.println(" mRoundedDefaultTop(x,y)=(" + mRoundedDefaultTop.x + "," + mRoundedDefaultTop.y
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui
|
||||
|
||||
import android.graphics.Insets
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.hardware.graphics.common.DisplayDecorationSupport
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.Display
|
||||
import android.view.DisplayCutout
|
||||
import android.view.DisplayInfo
|
||||
import android.view.View
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.R
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class ScreenDecorHwcLayerTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var mockDisplay: Display
|
||||
@Mock private lateinit var mockRootView: View
|
||||
|
||||
private val displayWidth = 100
|
||||
private val displayHeight = 200
|
||||
private val cutoutSize = 10
|
||||
private val roundedSizeTop = 15
|
||||
private val roundedSizeBottom = 20
|
||||
|
||||
private lateinit var decorHwcLayer: ScreenDecorHwcLayer
|
||||
private val cutoutTop: DisplayCutout = DisplayCutout.Builder()
|
||||
.setSafeInsets(Insets.of(0, cutoutSize, 0, 0))
|
||||
.setBoundingRectTop(Rect(1, 0, 2, cutoutSize))
|
||||
.build()
|
||||
|
||||
private val cutoutRight: DisplayCutout = DisplayCutout.Builder()
|
||||
.setSafeInsets(Insets.of(0, 0, cutoutSize, 0))
|
||||
.setBoundingRectRight(Rect(displayWidth - cutoutSize, 50, displayWidth, 52))
|
||||
.build()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
mContext.orCreateTestableResources.addOverride(
|
||||
R.array.config_displayUniqueIdArray, arrayOf<String>())
|
||||
mContext.orCreateTestableResources.addOverride(
|
||||
R.bool.config_fillMainBuiltInDisplayCutout, true)
|
||||
|
||||
val decorationSupport = DisplayDecorationSupport()
|
||||
decorationSupport.format = PixelFormat.R_8
|
||||
decorHwcLayer = Mockito.spy(ScreenDecorHwcLayer(mContext, decorationSupport))
|
||||
whenever(decorHwcLayer.width).thenReturn(displayWidth)
|
||||
whenever(decorHwcLayer.height).thenReturn(displayHeight)
|
||||
whenever(decorHwcLayer.display).thenReturn(mockDisplay)
|
||||
whenever(decorHwcLayer.rootView).thenReturn(mockRootView)
|
||||
whenever(mockRootView.left).thenReturn(0)
|
||||
whenever(mockRootView.top).thenReturn(0)
|
||||
whenever(mockRootView.right).thenReturn(displayWidth)
|
||||
whenever(mockRootView.bottom).thenReturn(displayHeight)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_noCutout_noRoundedCorner_noProtection() {
|
||||
setupConfigs(null, 0, 0, RectF(), 0f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, 0, decorHwcLayer.width, decorHwcLayer.height))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_onlyShortEdgeCutout() {
|
||||
setupConfigs(cutoutTop, 0, 0, RectF(), 0f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, cutoutSize, decorHwcLayer.width, decorHwcLayer.height))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_onlyLongEdgeCutout() {
|
||||
setupConfigs(cutoutRight, 0, 0, RectF(), 0f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, 0, decorHwcLayer.width - cutoutSize, decorHwcLayer.height))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_onlyRoundedCorners() {
|
||||
setupConfigs(null, roundedSizeTop, roundedSizeBottom, RectF(), 0f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, roundedSizeTop, decorHwcLayer.width,
|
||||
decorHwcLayer.height - roundedSizeBottom))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_onlyCutoutProtection() {
|
||||
setupConfigs(null, 0, 0, RectF(48f, 1f, 52f, 5f), 0.5f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, 4, decorHwcLayer.width, decorHwcLayer.height))
|
||||
|
||||
decorHwcLayer.cameraProtectionProgress = 1f
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, 5, decorHwcLayer.width, decorHwcLayer.height))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_hasShortEdgeCutout_hasRoundedCorner_hasCutoutProtection() {
|
||||
setupConfigs(cutoutTop, roundedSizeTop, roundedSizeBottom, RectF(48f, 1f, 52f, 5f), 1f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(0, 15, decorHwcLayer.width, decorHwcLayer.height - 20))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransparentRegion_hasLongEdgeCutout_hasRoundedCorner_hasCutoutProtection() {
|
||||
setupConfigs(cutoutRight, roundedSizeTop, roundedSizeBottom, RectF(48f, 1f, 52f, 5f), 1f)
|
||||
|
||||
decorHwcLayer.calculateTransparentRect()
|
||||
|
||||
assertThat(decorHwcLayer.transparentRect)
|
||||
.isEqualTo(Rect(20, 5, decorHwcLayer.width - 20, decorHwcLayer.height))
|
||||
}
|
||||
|
||||
private fun setupConfigs(
|
||||
cutout: DisplayCutout?,
|
||||
roundedTop: Int,
|
||||
roundedBottom: Int,
|
||||
protectionRect: RectF,
|
||||
protectionProgress: Float
|
||||
) {
|
||||
whenever(mockDisplay.getDisplayInfo(eq(decorHwcLayer.displayInfo))
|
||||
).then {
|
||||
val info = it.getArgument<DisplayInfo>(0)
|
||||
info.displayCutout = cutout
|
||||
return@then true
|
||||
}
|
||||
decorHwcLayer.updateRoundedCornerSize(roundedTop, roundedBottom)
|
||||
decorHwcLayer.protectionRect.set(protectionRect)
|
||||
decorHwcLayer.cameraProtectionProgress = protectionProgress
|
||||
decorHwcLayer.updateCutout()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user