1 /*
2  * Copyright (C) 2020 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 com.android.test
17 
18 import android.graphics.Color
19 import android.graphics.Point
20 import android.graphics.Rect
21 import android.os.SystemClock
22 import android.tools.common.flicker.subject.layers.LayersTraceSubject
23 import com.android.test.SurfaceViewBufferTestBase.Companion.ScalingMode
24 import com.android.test.SurfaceViewBufferTestBase.Companion.Transform
25 import junit.framework.Assert.assertEquals
26 import junit.framework.Assert.assertTrue
27 import org.junit.Assert
28 import org.junit.Test
29 import org.junit.runner.RunWith
30 import org.junit.runners.Parameterized
31 import java.util.concurrent.CountDownLatch
32 import java.util.concurrent.TimeUnit
33 
34 @RunWith(Parameterized::class)
35 class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastAdapter) {
36     @Test
37     fun testSetBuffersGeometry_0x0_resetsBufferSize() {
38         val trace = withTrace { activity ->
39             activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, 0, 0,
40                     R8G8B8A8_UNORM)
41             activity.mSurfaceProxy.ANativeWindowLock()
42             activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
43             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
44         }
45 
46         // verify buffer size is reset to default buffer size
47         LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
48     }
49 
50     @Test
51     fun testSetBuffersGeometry_smallerThanBuffer() {
52         val bufferSize = Point(300, 200)
53         val trace = withTrace { activity ->
54             activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
55                     R8G8B8A8_UNORM)
56             activity.drawFrame()
57             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
58         }
59 
60         LayersTraceSubject(trace).layer("SurfaceView", 1).also {
61             it.hasBufferSize(bufferSize)
62             it.hasLayerSize(defaultBufferSize)
63             it.hasScalingMode(ScalingMode.SCALE_TO_WINDOW.ordinal)
64         }
65     }
66 
67     @Test
68     fun testSetBuffersGeometry_largerThanBuffer() {
69         val bufferSize = Point(3000, 2000)
70         val trace = withTrace { activity ->
71             activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
72                     R8G8B8A8_UNORM)
73             activity.drawFrame()
74             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
75         }
76 
77         LayersTraceSubject(trace).layer("SurfaceView", 1).also {
78             it.hasBufferSize(bufferSize)
79             it.hasLayerSize(defaultBufferSize)
80             it.hasScalingMode(ScalingMode.SCALE_TO_WINDOW.ordinal)
81         }
82     }
83 
84     @Test
85     fun testSetBufferScalingMode_freeze() {
86         val bufferSize = Point(300, 200)
87         val trace = withTrace { activity ->
88             activity.drawFrame()
89             assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
90             activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
91                     R8G8B8A8_UNORM)
92             assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
93             assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
94             // Change buffer size and set scaling mode to freeze
95             activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, Point(0, 0),
96                     R8G8B8A8_UNORM)
97 
98             // first dequeued buffer does not have the new size so it should be rejected.
99             activity.mSurfaceProxy.SurfaceQueueBuffer(0)
100             activity.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
101             activity.mSurfaceProxy.SurfaceQueueBuffer(1)
102             assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
103         }
104 
105         // verify buffer size is reset to default buffer size
106         LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
107         Assert.assertThrows(AssertionError::class.java) {
108             LayersTraceSubject(trace).layer("SurfaceView", 2)
109         }
110         LayersTraceSubject(trace).layer("SurfaceView", 3).hasBufferSize(bufferSize)
111     }
112 
113     @Test
114     fun testSetBuffersTransform_FLIP() {
115         val transforms = arrayOf(Transform.FLIP_H, Transform.FLIP_V, Transform.ROT_180).withIndex()
116         for ((index, transform) in transforms) {
117             val trace = withTrace { activity ->
118                 activity.mSurfaceProxy.ANativeWindowSetBuffersTransform(transform)
119                 activity.mSurfaceProxy.ANativeWindowLock()
120                 activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
121                 activity.mSurfaceProxy.waitUntilBufferDisplayed(index + 1L, 500 /* ms */)
122             }
123 
124             LayersTraceSubject(trace).layer("SurfaceView", index + 1L).also {
125                 it.hasBufferSize(defaultBufferSize)
126                 it.hasLayerSize(defaultBufferSize)
127                 it.hasBufferOrientation(transform.value)
128             }
129         }
130     }
131 
132     @Test
133     fun testSurfaceViewResizeImmediatelyWithNonFreezeScaling() {
134         val surfaceViewPosition = Rect()
135         var trace = withTrace { activity ->
136             activity.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
137             assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
138             activity.mSurfaceProxy.drawBuffer(0, Color.BLUE)
139             activity.mSurfaceProxy.SurfaceQueueBuffer(0)
140             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
141             activity.mSurfaceView!!.getBoundsOnScreen(surfaceViewPosition)
142         }
143 
144         runOnUiThread {
145             val svBounds = Rect(0, 0, defaultBufferSize.x, defaultBufferSize.y)
146             svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
147             checkPixels(svBounds, Color.BLUE)
148         }
149 
150         // check that the layer and buffer starts with the default size
151         LayersTraceSubject(trace).layer("SurfaceView", 1).also {
152             it.hasBufferSize(defaultBufferSize)
153             it.hasLayerSize(defaultBufferSize)
154         }
155         val newSize = Point(1280, 960)
156         lateinit var resizeCountDownLatch: CountDownLatch
157         runOnUiThread {
158             resizeCountDownLatch = it.resizeSurfaceView(newSize)
159         }
160         assertTrue(resizeCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
161         // wait for sf to handle the resize transaction request
162         SystemClock.sleep(500)
163         trace = withTrace { _ ->
164             // take a trace with the new size
165         }
166 
167         // check that the layer size has changed and the buffer is now streched to the new layer
168         // size
169         runOnUiThread {
170             val svBounds = Rect(0, 0, newSize.x, newSize.y)
171             svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
172             checkPixels(svBounds, Color.BLUE)
173         }
174 
175         LayersTraceSubject(trace).layer("SurfaceView", 1).also {
176             it.hasLayerSize(newSize)
177             it.hasBufferSize(defaultBufferSize)
178         }
179     }
180 
181     @Test
182     fun testSurfaceViewDoesNotResizeWithDefaultScaling() {
183         val surfaceViewPosition = Rect()
184         var trace = withTrace { activity ->
185             assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
186             activity.mSurfaceProxy.drawBuffer(0, Color.BLUE)
187             activity.mSurfaceProxy.SurfaceQueueBuffer(0)
188             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
189             activity.mSurfaceView!!.getBoundsOnScreen(surfaceViewPosition)
190         }
191 
192         runOnUiThread {
193             val svBounds = Rect(0, 0, defaultBufferSize.x, defaultBufferSize.y)
194             svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
195             checkPixels(svBounds, Color.BLUE)
196         }
197 
198         // check that the layer and buffer starts with the default size
199         LayersTraceSubject(trace).layer("SurfaceView", 1).also {
200             it.hasBufferSize(defaultBufferSize)
201             it.hasLayerSize(defaultBufferSize)
202         }
203         val newSize = Point(1280, 960)
204         lateinit var resizeCountDownLatch: CountDownLatch
205         runOnUiThread {
206             resizeCountDownLatch = it.resizeSurfaceView(newSize)
207         }
208         assertTrue(resizeCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
209         // wait for sf to handle the resize transaction request
210         SystemClock.sleep(500)
211         trace = withTrace { _ ->
212             // take a trace after the size change
213         }
214 
215         // check the layer and buffer remains the same size
216         runOnUiThread {
217             val svBounds = Rect(0, 0, defaultBufferSize.x, defaultBufferSize.y)
218             svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
219             checkPixels(svBounds, Color.BLUE)
220         }
221 
222         LayersTraceSubject(trace).layer("SurfaceView", 1).also {
223             it.hasLayerSize(defaultBufferSize)
224             it.hasBufferSize(defaultBufferSize)
225         }
226     }
227 }
228