1 /*
<lambda>null2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.tools.utils
18 
19 import android.graphics.Rect
20 import android.graphics.Region
21 import android.tools.datatypes.ActiveBuffer
22 import android.tools.datatypes.Matrix33
23 import android.tools.datatypes.defaultColor
24 import android.tools.datatypes.intersection
25 import android.tools.traces.surfaceflinger.Flag
26 import android.tools.traces.surfaceflinger.HwcCompositionType
27 import android.tools.traces.surfaceflinger.Layer
28 import android.tools.traces.surfaceflinger.Transform
29 import androidx.core.graphics.toRectF
30 
31 class MockLayerBuilder(private val name: String) {
32     companion object {
33         private var idCounter = 1
34     }
35 
36     private val children = mutableListOf<MockLayerBuilder>()
37     private var type = "BufferStateLayer"
38     private val id = idCounter++
39     private var parentId = -1
40     private var isVisible = true
41     private var absoluteBounds: Rect? = null
42     private var zIndex = 0
43     private var isOpaque = true
44 
45     fun addChild(layer: MockLayerBuilder): MockLayerBuilder = apply { this.children.add(layer) }
46 
47     fun setContainerLayer(): MockLayerBuilder = apply {
48         this.type = "ContainerLayer"
49         this.isOpaque = false
50         this.isVisible = false
51     }
52 
53     fun setVisible(): MockLayerBuilder = apply { this.isVisible = true }
54 
55     fun setInvisible(): MockLayerBuilder = apply { this.isVisible = false }
56 
57     fun addChildren(rootLayers: Collection<MockLayerBuilder>): MockLayerBuilder = apply {
58         rootLayers.forEach { addChild(it) }
59     }
60 
61     fun setAbsoluteBounds(bounds: Rect): MockLayerBuilder = apply { this.absoluteBounds = bounds }
62 
63     fun build(): Layer {
64         val absoluteBounds = this.absoluteBounds
65         requireNotNull(absoluteBounds) { "Layer has no bounds set..." }
66 
67         val transform = Transform.from(0, Matrix33.identity(0f, 0f))
68 
69         val thisLayer =
70             Layer.from(
71                 name,
72                 id,
73                 parentId,
74                 z = zIndex,
75                 visibleRegion = if (isVisible) Region(absoluteBounds) else Region(),
76                 activeBuffer =
77                     ActiveBuffer.from(absoluteBounds.width(), absoluteBounds.height(), 1, 1),
78                 flags = if (isVisible) 0 else Flag.HIDDEN.value,
79                 bounds = absoluteBounds.toRectF(),
80                 color = defaultColor(),
81                 isOpaque = isVisible && isOpaque,
82                 shadowRadius = 0f,
83                 cornerRadius = 0f,
84                 screenBounds = absoluteBounds.toRectF(),
85                 transform = transform,
86                 currFrame = 0,
87                 effectiveScalingMode = 0,
88                 bufferTransform = transform,
89                 hwcCompositionType = HwcCompositionType.HWC_TYPE_UNSPECIFIED,
90                 crop = absoluteBounds.toRectF(),
91                 backgroundBlurRadius = 0,
92                 isRelativeOf = false,
93                 zOrderRelativeOfId = -1,
94                 stackId = 0,
95                 excludesCompositionState = false
96             )
97 
98         val layers = mutableListOf<Layer>()
99         layers.add(thisLayer)
100 
101         // var indexCount = 1
102         children.forEach { child ->
103             child.parentId = this.id
104             // it.zIndex = this.zIndex + indexCount
105 
106             val childAbsoluteBounds = child.absoluteBounds
107             if (childAbsoluteBounds == null) {
108                 child.absoluteBounds = this.absoluteBounds
109             } else {
110                 child.absoluteBounds = childAbsoluteBounds.intersection(absoluteBounds)
111             }
112 
113             thisLayer.addChild(child.build())
114         }
115 
116         return thisLayer
117     }
118 }
119