1 /* 2 * Copyright (C) 2022 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 com.android.server.wm.flicker 18 19 import android.app.Instrumentation 20 import android.platform.test.annotations.Presubmit 21 import android.tools.common.traces.component.ComponentNameMatcher 22 import android.tools.device.flicker.junit.FlickerBuilderProvider 23 import android.tools.device.flicker.legacy.FlickerBuilder 24 import android.tools.device.flicker.legacy.LegacyFlickerTest 25 import android.util.Log 26 import androidx.test.platform.app.InstrumentationRegistry 27 import com.android.launcher3.tapl.LauncherInstrumentation 28 import org.junit.Assume 29 import org.junit.AssumptionViolatedException 30 import org.junit.Test 31 32 /** 33 * Base test class containing common assertions for [ComponentNameMatcher.NAV_BAR], 34 * [ComponentNameMatcher.TASK_BAR], [ComponentNameMatcher.STATUS_BAR], and general assertions 35 * (layers visible in consecutive states, entire screen covered, etc.) 36 */ 37 abstract class BaseTest 38 @JvmOverloads 39 constructor( 40 protected val flicker: LegacyFlickerTest, 41 protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), 42 protected val tapl: LauncherInstrumentation = LauncherInstrumentation() 43 ) { 44 init { 45 tapl.setExpectedRotationCheckEnabled(true) 46 } 47 48 private val logTag = this::class.java.simpleName 49 50 /** Specification of the test transition to execute */ 51 abstract val transition: FlickerBuilder.() -> Unit 52 53 /** 54 * Entry point for the test runner. It will use this method to initialize and cache flicker 55 * executions 56 */ 57 @FlickerBuilderProvider 58 fun buildFlicker(): FlickerBuilder { 59 return FlickerBuilder(instrumentation).apply { 60 setup { flicker.scenario.setIsTablet(wmHelper.currentState.wmState.isTablet) } 61 transition() 62 } 63 } 64 65 /** Checks that all parts of the screen are covered during the transition */ 66 @Presubmit @Test open fun entireScreenCovered() = flicker.entireScreenCovered() 67 68 /** 69 * Checks that the [ComponentNameMatcher.NAV_BAR] layer is visible during the whole transition 70 * 71 * Note: Phones only 72 */ 73 @Presubmit 74 @Test 75 open fun navBarLayerIsVisibleAtStartAndEnd() { 76 Assume.assumeFalse(flicker.scenario.isTablet) 77 flicker.navBarLayerIsVisibleAtStartAndEnd() 78 } 79 80 /** 81 * Checks the position of the [ComponentNameMatcher.NAV_BAR] at the start and end of the 82 * transition 83 * 84 * Note: Phones only 85 */ 86 @Presubmit 87 @Test 88 open fun navBarLayerPositionAtStartAndEnd() { 89 Assume.assumeFalse(flicker.scenario.isTablet) 90 flicker.navBarLayerPositionAtStartAndEnd() 91 } 92 93 /** 94 * Checks that the [ComponentNameMatcher.NAV_BAR] window is visible during the whole transition 95 * 96 * Note: Phones only 97 */ 98 @Presubmit 99 @Test 100 open fun navBarWindowIsAlwaysVisible() { 101 Assume.assumeFalse(flicker.scenario.isTablet) 102 Assume.assumeFalse(flicker.scenario.isLandscapeOrSeascapeAtStart) 103 flicker.navBarWindowIsAlwaysVisible() 104 } 105 106 /** 107 * Checks that the [ComponentNameMatcher.NAV_BAR] window is visible at the start and end of the 108 * transition 109 * 110 * Note: Phones only 111 */ 112 @Presubmit 113 @Test 114 open fun navBarWindowIsVisibleAtStartAndEnd() { 115 Assume.assumeFalse(flicker.scenario.isTablet) 116 flicker.navBarWindowIsVisibleAtStartAndEnd() 117 } 118 119 /** 120 * Checks that the [ComponentNameMatcher.TASK_BAR] window is visible at the start and end of the 121 * transition 122 * 123 * Note: Large screen only 124 */ 125 @Presubmit 126 @Test 127 open fun taskBarLayerIsVisibleAtStartAndEnd() { 128 Assume.assumeTrue(flicker.scenario.isTablet) 129 flicker.taskBarLayerIsVisibleAtStartAndEnd() 130 } 131 132 /** 133 * Checks that the [ComponentNameMatcher.TASK_BAR] window is visible during the whole transition 134 * 135 * Note: Large screen only 136 */ 137 @Presubmit 138 @Test 139 open fun taskBarWindowIsAlwaysVisible() { 140 Assume.assumeTrue(flicker.scenario.isTablet) 141 flicker.taskBarWindowIsAlwaysVisible() 142 } 143 144 /** 145 * Checks that the [ComponentNameMatcher.STATUS_BAR] layer is visible at the start and end of 146 * the transition 147 */ 148 @Presubmit 149 @Test 150 open fun statusBarLayerIsVisibleAtStartAndEnd() = flicker.statusBarLayerIsVisibleAtStartAndEnd() 151 152 /** 153 * Checks the position of the [ComponentNameMatcher.STATUS_BAR] at the start and end of the 154 * transition 155 */ 156 @Presubmit 157 @Test 158 open fun statusBarLayerPositionAtStartAndEnd() = flicker.statusBarLayerPositionAtStartAndEnd() 159 160 /** 161 * Checks that the [ComponentNameMatcher.STATUS_BAR] window is visible during the whole 162 * transition 163 */ 164 @Presubmit 165 @Test 166 open fun statusBarWindowIsAlwaysVisible() = flicker.statusBarWindowIsAlwaysVisible() 167 168 /** 169 * Checks that all layers that are visible on the trace, are visible for at least 2 consecutive 170 * entries. 171 */ 172 @Presubmit 173 @Test 174 open fun visibleLayersShownMoreThanOneConsecutiveEntry() { 175 flicker.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() } 176 } 177 178 /** 179 * Checks that all windows that are visible on the trace, are visible for at least 2 consecutive 180 * entries. 181 */ 182 @Presubmit 183 @Test 184 open fun visibleWindowsShownMoreThanOneConsecutiveEntry() { 185 flicker.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() } 186 } 187 188 open fun cujCompleted() { 189 runAndIgnoreAssumptionViolation { entireScreenCovered() } 190 runAndIgnoreAssumptionViolation { statusBarLayerIsVisibleAtStartAndEnd() } 191 runAndIgnoreAssumptionViolation { statusBarLayerPositionAtStartAndEnd() } 192 runAndIgnoreAssumptionViolation { statusBarWindowIsAlwaysVisible() } 193 runAndIgnoreAssumptionViolation { visibleLayersShownMoreThanOneConsecutiveEntry() } 194 runAndIgnoreAssumptionViolation { visibleWindowsShownMoreThanOneConsecutiveEntry() } 195 runAndIgnoreAssumptionViolation { taskBarLayerIsVisibleAtStartAndEnd() } 196 runAndIgnoreAssumptionViolation { taskBarWindowIsAlwaysVisible() } 197 runAndIgnoreAssumptionViolation { navBarLayerIsVisibleAtStartAndEnd() } 198 runAndIgnoreAssumptionViolation { navBarWindowIsAlwaysVisible() } 199 runAndIgnoreAssumptionViolation { navBarWindowIsVisibleAtStartAndEnd() } 200 } 201 202 protected fun runAndIgnoreAssumptionViolation(predicate: () -> Unit) { 203 try { 204 predicate() 205 } catch (e: AssumptionViolatedException) { 206 Log.e(logTag, "Assumption violation on CUJ complete", e) 207 } 208 } 209 } 210