• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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 package android.tools.flicker.subject.layers
17 
18 import android.tools.Timestamp
19 import android.tools.datatypes.Size
20 import android.tools.flicker.assertions.Fact
21 import android.tools.flicker.subject.FlickerSubject
22 import android.tools.flicker.subject.region.RegionSubject
23 import android.tools.function.AssertionPredicate
24 import android.tools.io.Reader
25 import android.tools.traces.surfaceflinger.Layer
26 
27 /**
28  * Subject for [Layer] objects, used to make assertions over behaviors that occur on a single layer
29  * of a SurfaceFlinger state.
30  *
31  * To make assertions over a layer from a state it is recommended to create a subject using
32  * [LayerTraceEntrySubject.layer](layerName)
33  *
34  * Alternatively, it is also possible to use [LayerSubject](myLayer).
35  *
36  * Example:
37  * ```
38  *    val trace = LayersTraceParser().parse(myTraceFile)
39  *    val subject = LayersTraceSubject(trace).first()
40  *        .layer("ValidLayer")
41  *        .exists()
42  *        .hasBufferSize(BUFFER_SIZE)
43  *        .invoke { myCustomAssertion(this) }
44  * ```
45  */
46 class LayerSubject
47 @JvmOverloads
48 constructor(
49     override val timestamp: Timestamp,
50     val layer: Layer,
51     public override val reader: Reader? = null,
52 ) : FlickerSubject() {
53     val isVisible: Boolean
54         get() = layer.isVisible
55 
56     val isInvisible: Boolean
57         get() = !layer.isVisible
58 
59     val name: String
60         get() = layer.name
61 
62     /** Visible region calculated by the Composition Engine */
63     val visibleRegion: RegionSubject
64         get() = RegionSubject(layer.visibleRegion, timestamp, reader)
65 
66     val visibilityReason: Collection<String>
67         get() = layer.visibilityReason
68 
69     /**
70      * Visible region calculated by the Composition Engine (when available) or calculated based on
71      * the layer bounds and transform
72      */
73     val screenBounds: RegionSubject
74         get() = RegionSubject(layer.screenBounds, timestamp, reader)
75 
76     override val selfFacts = listOf(Fact("Frame", layer.currFrame), Fact("Layer", layer.name))
77 
78     /** If the [layer] exists, executes a custom [assertion] on the current subject */
<lambda>null79     operator fun invoke(assertion: AssertionPredicate<Layer>): LayerSubject = apply {
80         assertion.verify(this.layer)
81     }
82 
83     /**
84      * Asserts that current subject has an [Layer.activeBuffer]
85      *
86      * @param expected expected buffer size
87      */
<lambda>null88     fun hasBufferSize(expected: Size): LayerSubject = apply {
89         val bufferSize = Size.from(layer.activeBuffer.width, layer.activeBuffer.height)
90         check { "Buffer size" }.that(bufferSize).isEqual(expected)
91     }
92 
93     /**
94      * Asserts that current subject has an [Layer.screenBounds]
95      *
96      * @param expected expected layer bounds size
97      */
<lambda>null98     fun hasLayerSize(expected: Size): LayerSubject = apply {
99         val layerSize =
100             Size.from(layer.screenBounds.width().toInt(), layer.screenBounds.height().toInt())
101         check { "Number of layers" }.that(layerSize).isEqual(expected)
102     }
103 
104     /** Asserts that current subject has an [Layer.effectiveScalingMode] equals to [expected] */
<lambda>null105     fun hasScalingMode(expected: Int): LayerSubject = apply {
106         check { "Scaling mode" }.that(layer.effectiveScalingMode).isEqual(expected)
107     }
108 
109     /**
110      * Asserts that current subject has an [Layer.bufferTransform] orientation equals to [expected]
111      */
<lambda>null112     fun hasBufferOrientation(expected: Int): LayerSubject = apply {
113         // see Transform::getOrientation
114         val bufferTransformType = layer.bufferTransform.type ?: 0
115         val actualOrientation = (bufferTransformType shr 8) and 0xFF
116         check { "Buffer orientation" }.that(actualOrientation).isEqual(expected)
117     }
118 
toStringnull119     override fun toString(): String {
120         return "Layer:${layer.name} frame#${layer.currFrame}"
121     }
122 }
123