summaryrefslogtreecommitdiff
path: root/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt
blob: 6383da5a0a980b8c4f5385f2c3925103370bea21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Copyright (C) 2020 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.test

import android.annotation.ColorInt
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Rect
import android.util.Log
import androidx.test.ext.junit.rules.ActivityScenarioRule
import com.android.server.wm.flicker.monitor.LayersTraceMonitor
import com.android.server.wm.flicker.monitor.withSFTracing
import com.android.server.wm.traces.common.layers.LayersTrace
import junit.framework.Assert
import org.junit.After
import org.junit.Before
import org.junit.Rule
import java.io.FileOutputStream
import java.io.IOException
import java.util.concurrent.CountDownLatch

open class SurfaceTracingTestBase(useBlastAdapter: Boolean) :
        SurfaceViewBufferTestBase(useBlastAdapter) {
    @get:Rule
    var scenarioRule: ActivityScenarioRule<MainActivity> =
            ActivityScenarioRule<MainActivity>(MainActivity::class.java)

    @Before
    override fun setup() {
        super.setup()
        stopLayerTrace()
        addSurfaceView()
    }

    @After
    override fun teardown() {
        super.teardown()
        scenarioRule.getScenario().close()
    }

    fun withTrace(predicate: (it: MainActivity) -> Unit): LayersTrace {
        return withSFTracing(TRACE_FLAGS,
                outputDir = instrumentation.targetContext.dataDir.toPath()) {
            scenarioRule.getScenario().onActivity {
                predicate(it)
            }
        }
    }

    fun withTrace(predicate: () -> Unit): LayersTrace {
        return withSFTracing(TRACE_FLAGS,
                outputDir = instrumentation.targetContext.dataDir.toPath()) {
                predicate()
        }
    }

    fun runOnUiThread(predicate: (it: MainActivity) -> Unit) {
        scenarioRule.getScenario().onActivity {
            predicate(it)
        }
    }

    private fun addSurfaceView() {
        lateinit var surfaceReadyLatch: CountDownLatch
        scenarioRule.getScenario().onActivity {
            surfaceReadyLatch = it.addSurfaceView(defaultBufferSize)
        }
        surfaceReadyLatch.await()
        // sleep to finish animations
        instrumentation.waitForIdleSync()
    }

    private fun stopLayerTrace() {
        val tmpDir = instrumentation.targetContext.dataDir.toPath()
        LayersTraceMonitor(tmpDir).stop()
    }

    fun checkPixels(bounds: Rect, @ColorInt color: Int) {
        val screenshot = instrumentation.getUiAutomation().takeScreenshot()
        val pixels = IntArray(screenshot.width * screenshot.height)
        screenshot.getPixels(pixels, 0, screenshot.width, 0, 0, screenshot.width, screenshot.height)
        for (i in bounds.left + 10..bounds.right - 10) {
            for (j in bounds.top + 10..bounds.bottom - 10) {
                val actualColor = pixels[j * screenshot.width + i]
                if (actualColor != color) {
                    val screenshotPath = instrumentation.targetContext
                            .getExternalFilesDir(null)?.resolve("screenshot.png")
                    try {
                        FileOutputStream(screenshotPath).use { out ->
                            screenshot.compress(Bitmap.CompressFormat.PNG, 100, out)
                        }
                        Log.e("SurfaceViewBufferTests", "Bitmap written to $screenshotPath")
                    } catch (e: IOException) {
                        Log.e("SurfaceViewBufferTests", "Error writing bitmap to file", e)
                    }
                }
                Assert.assertEquals("Checking $bounds found mismatch $i,$j",
                        Color.valueOf(color), Color.valueOf(actualColor))
            }
        }
    }

    private companion object {
        private const val TRACE_FLAGS =
                (1 shl 0) or (1 shl 5) or (1 shl 6) // TRACE_CRITICAL | TRACE_BUFFERS | TRACE_SYNC
    }
}