diff options
Diffstat (limited to 'tests')
36 files changed, 2092 insertions, 600 deletions
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp index 217a72b90fd4..7731e098d9f5 100644 --- a/tests/FlickerTests/Android.bp +++ b/tests/FlickerTests/Android.bp @@ -25,11 +25,17 @@ package { android_test { name: "FlickerTests", - srcs: ["src/**/*.java", "src/**/*.kt"], + srcs: [ + "src/**/*.java", + "src/**/*.kt", + ], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", platform_apis: true, certificate: "platform", + optimize: { + enabled: false, + }, test_suites: ["device-tests"], libs: ["android.test.runner"], static_libs: [ @@ -46,6 +52,9 @@ android_test { java_library { name: "wm-flicker-common-assertions", platform_apis: true, + optimize: { + enabled: false, + }, srcs: [ "src/**/*Assertions.java", "src/**/*Assertions.kt", @@ -56,20 +65,23 @@ java_library { static_libs: [ "flickerlib", "truth-prebuilt", - "app-helpers-core" + "app-helpers-core", ], } java_library { name: "wm-flicker-common-app-helpers", platform_apis: true, + optimize: { + enabled: false, + }, srcs: [ - "**/helpers/*" + "**/helpers/*", ], static_libs: [ "flickerlib", "flickertestapplib", "truth-prebuilt", - "app-helpers-core" + "app-helpers-core", ], -}
\ No newline at end of file +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt index a540dffb3c9c..2cc19438b927 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt @@ -14,134 +14,76 @@ * limitations under the License. */ +@file:JvmName("CommonAssertions") package com.android.server.wm.flicker -import android.platform.helpers.IAppHelper +import android.content.ComponentName import com.android.server.wm.flicker.helpers.WindowUtils -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.NAV_BAR_LAYER_NAME -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.NAV_BAR_WINDOW_NAME -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.STATUS_BAR_LAYER_NAME -import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.STATUS_BAR_WINDOW_NAME +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper -val HOME_WINDOW_TITLE = arrayOf("Wallpaper", "Launcher") +val LAUNCHER_COMPONENT = ComponentName("com.google.android.apps.nexuslauncher", + "com.google.android.apps.nexuslauncher.NexusLauncherActivity") -fun FlickerTestParameter.statusBarWindowIsAlwaysVisible() { +fun FlickerTestParameter.statusBarWindowIsVisible() { assertWm { - this.showsAboveAppWindow(STATUS_BAR_WINDOW_NAME) + this.isAboveAppWindowVisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) } } -fun FlickerTestParameter.navBarWindowIsAlwaysVisible() { +fun FlickerTestParameter.navBarWindowIsVisible() { assertWm { - this.showsAboveAppWindow(NAV_BAR_WINDOW_NAME) - } -} - -fun FlickerTestParameter.launcherReplacesAppWindowAsTopWindow(testApp: IAppHelper) { - assertWm { - this.showsAppWindowOnTop(testApp.getPackage()) - .then() - .showsAppWindowOnTop(*HOME_WINDOW_TITLE) - } -} - -fun FlickerTestParameter.launcherWindowBecomesVisible() { - assertWm { - this.hidesBelowAppWindow(*HOME_WINDOW_TITLE) - .then() - .showsBelowAppWindow(*HOME_WINDOW_TITLE) - } -} - -fun FlickerTestParameter.launcherWindowBecomesInvisible() { - assertWm { - this.showsBelowAppWindow(*HOME_WINDOW_TITLE) - .then() - .hidesBelowAppWindow(*HOME_WINDOW_TITLE) - } -} - -fun FlickerTestParameter.appWindowAlwaysVisibleOnTop(packageName: String) { - assertWm { - this.showsAppWindowOnTop(packageName) - } -} - -fun FlickerTestParameter.appWindowBecomesVisible(appName: String) { - assertWm { - this.hidesAppWindow(appName) - .then() - .showsAppWindow(appName) - } -} - -fun FlickerTestParameter.appWindowBecomesInVisible(appName: String) { - assertWm { - this.showsAppWindow(appName) - .then() - .hidesAppWindow(appName) + this.isAboveAppWindowVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) } } +/** + * If [allStates] is true, checks if the stack space of all displays is fully covered + * by any visible layer, during the whole transitions + * + * Otherwise, checks if the stack space of all displays is fully covered + * by any visible layer, at the start and end of the transition + * + * @param allStates if all states should be checked, othersie, just initial and final + */ @JvmOverloads -fun FlickerTestParameter.noUncoveredRegions( - beginRotation: Int, - endRotation: Int = beginRotation, - allStates: Boolean = true -) { - val startingBounds = WindowUtils.getDisplayBounds(beginRotation) - val endingBounds = WindowUtils.getDisplayBounds(endRotation) +fun FlickerTestParameter.entireScreenCovered(allStates: Boolean = true) { if (allStates) { assertLayers { - if (startingBounds == endingBounds) { - this.coversAtLeast(startingBounds) - } else { - this.coversAtLeast(startingBounds) - .then() - .coversAtLeast(endingBounds) + this.invoke("entireScreenCovered") { entry -> + entry.entry.displays.forEach { display -> + entry.visibleRegion().coversAtLeast(display.layerStackSpace) + } } } } else { assertLayersStart { - this.visibleRegion().coversAtLeast(startingBounds) + this.entry.displays.forEach { display -> + this.visibleRegion().coversAtLeast(display.layerStackSpace) + } } assertLayersEnd { - this.visibleRegion().coversAtLeast(endingBounds) + this.entry.displays.forEach { display -> + this.visibleRegion().coversAtLeast(display.layerStackSpace) + } } } } -@JvmOverloads -fun FlickerTestParameter.navBarLayerIsAlwaysVisible(rotatesScreen: Boolean = false) { - if (rotatesScreen) { - assertLayers { - this.isVisible(NAV_BAR_LAYER_NAME) - .then() - .isInvisible(NAV_BAR_LAYER_NAME) - .then() - .isVisible(NAV_BAR_LAYER_NAME) - } - } else { - assertLayers { - this.isVisible(NAV_BAR_LAYER_NAME) - } +fun FlickerTestParameter.navBarLayerIsVisible() { + assertLayersStart { + this.isVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + } + assertLayersEnd { + this.isVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) } } -@JvmOverloads -fun FlickerTestParameter.statusBarLayerIsAlwaysVisible(rotatesScreen: Boolean = false) { - if (rotatesScreen) { - assertLayers { - this.isVisible(STATUS_BAR_LAYER_NAME) - .then() - .isInvisible(STATUS_BAR_LAYER_NAME) - .then() - .isVisible(STATUS_BAR_LAYER_NAME) - } - } else { - assertLayers { - this.isVisible(STATUS_BAR_LAYER_NAME) - } +fun FlickerTestParameter.statusBarLayerIsVisible() { + assertLayersStart { + this.isVisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) + } + assertLayersEnd { + this.isVisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) } } @@ -154,10 +96,10 @@ fun FlickerTestParameter.navBarLayerRotatesAndScales( val endingPos = WindowUtils.getNavigationBarPosition(endRotation) assertLayersStart { - this.visibleRegion(NAV_BAR_LAYER_NAME).coversExactly(startingPos) + this.visibleRegion(WindowManagerStateHelper.NAV_BAR_COMPONENT).coversExactly(startingPos) } assertLayersEnd { - this.visibleRegion(NAV_BAR_LAYER_NAME).coversExactly(endingPos) + this.visibleRegion(WindowManagerStateHelper.NAV_BAR_COMPONENT).coversExactly(endingPos) } } @@ -170,54 +112,46 @@ fun FlickerTestParameter.statusBarLayerRotatesScales( val endingPos = WindowUtils.getStatusBarPosition(endRotation) assertLayersStart { - this.visibleRegion(STATUS_BAR_LAYER_NAME).coversExactly(startingPos) + this.visibleRegion(WindowManagerStateHelper.STATUS_BAR_COMPONENT).coversExactly(startingPos) } assertLayersEnd { - this.visibleRegion(STATUS_BAR_LAYER_NAME).coversExactly(endingPos) - } -} - -fun FlickerTestParameter.appLayerReplacesLauncher(appName: String) { - assertLayers { - this.isVisible(*HOME_WINDOW_TITLE) - .then() - .isVisible(appName) + this.visibleRegion(WindowManagerStateHelper.STATUS_BAR_COMPONENT).coversExactly(endingPos) } } -fun FlickerTestParameter.launcherLayerReplacesApp(testApp: IAppHelper) { - assertLayers { - this.isVisible(testApp.getPackage()) - .then() - .isInvisible(testApp.getPackage()) - .isVisible(*HOME_WINDOW_TITLE) - } -} - -fun FlickerTestParameter.layerBecomesVisible(packageName: String) { +/** + * Asserts that: + * [originalLayer] is visible at the start of the trace + * [originalLayer] becomes invisible during the trace and (in the same entry) [newLayer] + * becomes visible + * [newLayer] remains visible until the end of the trace + * + * @param originalLayer Layer that should be visible at the start + * @param newLayer Layer that should be visible at the end + * @param ignoreSnapshot If the snapshot layer should be ignored during the transition + * (useful mostly for app launch) + */ +fun FlickerTestParameter.replacesLayer( + originalLayer: ComponentName, + newLayer: ComponentName, + ignoreSnapshot: Boolean = false +) { assertLayers { - this.isInvisible(packageName) - .then() - .isVisible(packageName) + val assertion = this.isVisible(originalLayer) + if (ignoreSnapshot) { + assertion.then() + .isVisible(WindowManagerStateHelper.SNAPSHOT_COMPONENT, isOptional = true) + } + assertion.then().isVisible(newLayer) } -} -fun FlickerTestParameter.layerBecomesInvisible(packageName: String) { - assertLayers { - this.isVisible(packageName) - .then() - .isInvisible(packageName) + assertLayersStart { + this.isVisible(originalLayer) + .isInvisible(newLayer) } -} -fun FlickerTestParameter.focusChanges(vararg windows: String) { - assertEventLog { - this.focusChanges(windows) + assertLayersEnd { + this.isInvisible(originalLayer) + .isVisible(newLayer) } } - -fun FlickerTestParameter.focusDoesNotChange() { - assertEventLog { - this.focusDoesNotChange() - } -}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt index 71184c2e0aa2..90c851d6e266 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt @@ -1,3 +1,4 @@ + /* * Copyright (C) 2020 The Android Open Source Project * @@ -16,6 +17,8 @@ package com.android.server.wm.flicker.close +import android.platform.test.annotations.Postsubmit +import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -23,6 +26,7 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group1 import com.android.server.wm.flicker.dsl.FlickerBuilder import org.junit.FixMethodOrder +import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized @@ -46,6 +50,13 @@ class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio } } + @FlakyTest + @Test + override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() + + @Postsubmit + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() + companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt index 6786279ae107..e8391ed9cfa1 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt @@ -16,6 +16,8 @@ package com.android.server.wm.flicker.close +import android.platform.test.annotations.Postsubmit +import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -23,6 +25,7 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group1 import com.android.server.wm.flicker.dsl.FlickerBuilder import org.junit.FixMethodOrder +import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized @@ -46,6 +49,13 @@ class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio } } + @FlakyTest + @Test + override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() + + @Postsubmit + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() + companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt index f7f977d7bd0a..1efb6daae31b 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt @@ -19,30 +19,35 @@ package com.android.server.wm.flicker.close import android.app.Instrumentation import android.platform.test.annotations.Presubmit import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.helpers.StandardAppHelper import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.launcherReplacesAppWindowAsTopWindow -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.launcherLayerReplacesApp -import com.android.server.wm.flicker.launcherWindowBecomesVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.flicker.replacesLayer import org.junit.Test +/** + * Base test class for transitions that close an app back to the launcher screen + */ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter) { protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation) + + /** + * Specification of the test transition to execute + */ protected open val transition: FlickerBuilder.(Map<String, Any?>) -> Unit = { setup { eachRun { @@ -66,29 +71,29 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter) @Presubmit @Test - open fun navBarWindowIsAlwaysVisible() { - testSpec.navBarWindowIsAlwaysVisible() + open fun navBarWindowIsVisible() { + testSpec.navBarWindowIsVisible() } @Presubmit @Test - open fun statusBarWindowIsAlwaysVisible() { - testSpec.statusBarWindowIsAlwaysVisible() + open fun statusBarWindowIsVisible() { + testSpec.statusBarWindowIsVisible() } - @FlakyTest + @Presubmit @Test - open fun navBarLayerIsAlwaysVisible() { - testSpec.navBarLayerIsAlwaysVisible(rotatesScreen = testSpec.isRotated) + open fun navBarLayerIsVisible() { + testSpec.navBarLayerIsVisible() } @Presubmit @Test - open fun statusBarLayerIsAlwaysVisible() { - testSpec.statusBarLayerIsAlwaysVisible(rotatesScreen = testSpec.isRotated) + open fun statusBarLayerIsVisible() { + testSpec.statusBarLayerIsVisible() } - @FlakyTest + @Presubmit @Test open fun navBarLayerRotatesAndScales() { testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0) @@ -118,25 +123,31 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter) @Presubmit @Test - open fun noUncoveredRegions() { - testSpec.noUncoveredRegions(testSpec.config.startRotation, Surface.ROTATION_0) - } + open fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test open fun launcherReplacesAppWindowAsTopWindow() { - testSpec.launcherReplacesAppWindowAsTopWindow(testApp) + testSpec.assertWm { + this.isAppWindowOnTop(testApp.component) + .then() + .isAppWindowOnTop(LAUNCHER_COMPONENT) + } } @Presubmit @Test open fun launcherWindowBecomesVisible() { - testSpec.launcherWindowBecomesVisible() + testSpec.assertWm { + this.isAppWindowInvisible(LAUNCHER_COMPONENT) + .then() + .isAppWindowOnTop(LAUNCHER_COMPONENT) + } } @Presubmit @Test open fun launcherLayerReplacesApp() { - testSpec.launcherLayerReplacesApp(testApp) + testSpec.replacesLayer(testApp.component, LAUNCHER_COMPONENT) } -}
\ No newline at end of file +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt index 83fddae5b1a7..d224af97462e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt @@ -61,7 +61,8 @@ open class ImeAppHelper @JvmOverloads constructor( if (wmHelper == null) { device.waitForIdle() } else { - wmHelper.waitImeWindowShown() + wmHelper.waitImeShown() + wmHelper.waitForAppTransitionIdle() } } @@ -78,7 +79,7 @@ open class ImeAppHelper @JvmOverloads constructor( if (wmHelper == null) { device.waitForIdle() } else { - wmHelper.waitImeWindowGone() + wmHelper.waitImeGone() } } }
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt new file mode 100644 index 000000000000..3074e28b43fa --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.helpers + +import android.app.Instrumentation +import android.content.ComponentName +import android.support.test.launcherhelper.ILauncherStrategy +import android.support.test.launcherhelper.LauncherStrategyFactory +import com.android.server.wm.flicker.testapp.ActivityOptions + +class NonResizeableAppHelper @JvmOverloads constructor( + instr: Instrumentation, + launcherName: String = ActivityOptions.NON_RESIZEABLE_ACTIVITY_LAUNCHER_NAME, + component: ComponentName = ActivityOptions.NON_RESIZEABLE_ACTIVITY_COMPONENT_NAME, + launcherStrategy: ILauncherStrategy = LauncherStrategyFactory + .getInstance(instr) + .launcherStrategy +) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt new file mode 100644 index 000000000000..19fefb93b487 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.helpers + +import android.app.Instrumentation +import android.content.ComponentName +import android.support.test.launcherhelper.ILauncherStrategy +import android.support.test.launcherhelper.LauncherStrategyFactory +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper + +class TwoActivitiesAppHelper @JvmOverloads constructor( + instr: Instrumentation, + launcherName: String = ActivityOptions.BUTTON_ACTIVITY_LAUNCHER_NAME, + component: ComponentName = ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME, + launcherStrategy: ILauncherStrategy = LauncherStrategyFactory + .getInstance(instr) + .launcherStrategy +) : StandardAppHelper(instr, launcherName, component, launcherStrategy) { + fun openSecondActivity(device: UiDevice, wmHelper: WindowManagerStateHelper) { + val button = device.wait( + Until.findObject(By.res(getPackage(), "launch_second_activity")), + FIND_TIMEOUT) + + require(button != null) { + "Button not found, this usually happens when the device " + + "was left in an unknown state (e.g. in split screen)" + } + button.click() + wmHelper.waitForAppTransitionIdle() + wmHelper.waitForFullScreenApp(component) + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt index b5757fd21ee0..d17e77d74c1c 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt @@ -18,8 +18,8 @@ package com.android.server.wm.flicker.ime import android.app.Instrumentation import android.platform.test.annotations.Presubmit +import android.view.Surface import android.view.WindowManagerPolicyConstants -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerBuilderProvider @@ -28,15 +28,15 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group2 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder import org.junit.Test @@ -46,6 +46,14 @@ import org.junit.runners.Parameterized /** * Test IME window closing back to app window transitions. + * + * This test doesn't work on 90 degrees. According to the InputMethodService documentation: + * + * Don't show if this is not explicitly requested by the user and the input method + * is fullscreen. That would be too disruptive. + * + * More details on b/190352379 + * * To run this test: `atest FlickerTests:CloseImeAutoOpenWindowToAppTest` */ @RequiresDevice @@ -79,37 +87,55 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() @Presubmit @Test fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { - this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(IME_WINDOW_TITLE, - WindowManagerStateHelper.SPLASH_SCREEN_NAME, - WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)) + this.visibleWindowsShownMoreThanOneConsecutiveEntry() } } @Presubmit @Test - fun imeAppWindowIsAlwaysVisible() = testSpec.imeAppWindowIsAlwaysVisible(testApp) + fun imeAppWindowIsAlwaysVisible() { + testSpec.assertWm { + this.isAppWindowOnTop(testApp.component) + } + } @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() + fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible() - @FlakyTest + @Presubmit @Test - fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation) + fun entireScreenCovered() = testSpec.entireScreenCovered() + + @Presubmit + @Test + fun imeLayerVisibleStart() { + testSpec.assertLayersStart { + this.isVisible(WindowManagerStateHelper.IME_COMPONENT) + } + } + + @Presubmit + @Test + fun imeLayerInvisibleEnd() { + testSpec.assertLayersEnd { + this.isInvisible(WindowManagerStateHelper.IME_COMPONENT) + } + } @Presubmit @Test @@ -117,15 +143,19 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter @Presubmit @Test - fun imeAppLayerIsAlwaysVisible() = testSpec.imeAppLayerIsAlwaysVisible(testApp) + fun imeAppLayerIsAlwaysVisible() { + testSpec.assertLayers { + this.isVisible(testApp.component) + } + } - @FlakyTest + @Presubmit @Test fun navBarLayerRotatesAndScales() { testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation) } - @FlakyTest + @Presubmit @Test fun statusBarLayerRotatesScales() { testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation) @@ -145,8 +175,11 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests(repetitions = 5, + // b/190352379 (IME doesn't show on app launch in 90 degrees) + supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( - WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY) + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) ) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt index 549e44c511b9..6f0f55aa4888 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt @@ -30,14 +30,14 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group2 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder import org.junit.Test @@ -47,6 +47,14 @@ import org.junit.runners.Parameterized /** * Test IME window closing back to app window transitions. + * + * This test doesn't work on 90 degrees. According to the InputMethodService documentation: + * + * Don't show if this is not explicitly requested by the user and the input method + * is fullscreen. That would be too disruptive. + * + * More details on b/190352379 + * * To run this test: `atest FlickerTests:CloseImeAutoOpenWindowToHomeTest` */ @RequiresDevice @@ -75,51 +83,72 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete transitions { device.pressHome() wmHelper.waitForHomeActivityVisible() - wmHelper.waitImeWindowGone() + wmHelper.waitImeGone() } } } @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() @Presubmit @Test fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { - this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(IME_WINDOW_TITLE, - WindowManagerStateHelper.SPLASH_SCREEN_NAME, - WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)) + this.visibleWindowsShownMoreThanOneConsecutiveEntry() } } - @FlakyTest + @FlakyTest(bugId = 190189685) @Test - fun imeWindowBecomesInvisible() = testSpec.imeWindowBecomesInvisible() + fun imeAppWindowBecomesInvisible() { + testSpec.assertWm { + this.isAppWindowOnTop(testApp.component) + .then() + .appWindowNotOnTop(testApp.component) + } + } - @FlakyTest + @Presubmit @Test - fun imeAppWindowBecomesInvisible() = testSpec.imeAppWindowBecomesInvisible(testApp) + fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test - fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation, - Surface.ROTATION_0) + fun imeLayerVisibleStart() { + testSpec.assertLayersStart { + this.isVisible(WindowManagerStateHelper.IME_COMPONENT) + } + } - @FlakyTest + @Presubmit + @Test + fun imeLayerInvisibleEnd() { + testSpec.assertLayersEnd { + this.isInvisible(WindowManagerStateHelper.IME_COMPONENT) + } + } + + @Presubmit @Test fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible() @Presubmit @Test - fun imeAppLayerBecomesInvisible() = testSpec.imeAppLayerBecomesInvisible(testApp) + fun imeAppLayerBecomesInvisible() { + testSpec.assertLayers { + this.isVisible(testApp.component) + .then() + .isInvisible(testApp.component) + } + } - @FlakyTest + @Presubmit @Test fun navBarLayerRotatesAndScales() { testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0) @@ -133,18 +162,19 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() - @FlakyTest + @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() + fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible() @Presubmit @Test fun visibleLayersShownMoreThanOneConsecutiveEntry() { testSpec.assertLayers { - this.visibleLayersShownMoreThanOneConsecutiveEntry( - listOf(IME_WINDOW_TITLE, WindowManagerStateHelper.SPLASH_SCREEN_NAME)) + this.visibleLayersShownMoreThanOneConsecutiveEntry(listOf( + WindowManagerStateHelper.IME_COMPONENT, + WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT)) } } @@ -154,8 +184,11 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests(repetitions = 1, + // b/190352379 (IME doesn't show on app launch in 90 degrees) + supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( - WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY) + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) ) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt index 82ca074b5ef2..6751439709bf 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt @@ -28,13 +28,13 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group2 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.ImeAppHelper -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible import org.junit.Assume import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder @@ -61,7 +61,7 @@ class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) { return FlickerBuilder(instrumentation).apply { setup { test { - testApp.launchViaIntent() + testApp.launchViaIntent(wmHelper) } eachRun { testApp.openIME(device, wmHelper) @@ -80,37 +80,42 @@ class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() @Presubmit @Test fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { - this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(IME_WINDOW_TITLE, - WindowManagerStateHelper.SPLASH_SCREEN_NAME, - WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)) + this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf( + WindowManagerStateHelper.IME_COMPONENT, + WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT, + WindowManagerStateHelper.SNAPSHOT_COMPONENT)) } } @Presubmit @Test - fun imeAppWindowIsAlwaysVisible() = testSpec.imeAppWindowIsAlwaysVisible(testApp) + fun imeAppWindowIsAlwaysVisible() { + testSpec.assertWm { + this.isAppWindowOnTop(testApp.component) + } + } @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun statusBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation) + fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test @@ -146,7 +151,11 @@ class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun imeAppLayerIsAlwaysVisible() = testSpec.imeAppLayerIsAlwaysVisible(testApp) + fun imeAppLayerIsAlwaysVisible() { + testSpec.assertLayers { + this.isVisible(testApp.component) + } + } companion object { @Parameterized.Parameters(name = "{0}") @@ -156,4 +165,4 @@ class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) { .getConfigNonRotationTests(repetitions = 5) } } -}
\ No newline at end of file +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt index 703e4a125440..8aaf9251018f 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt @@ -30,13 +30,13 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group2 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.ImeAppHelper -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder import org.junit.Test @@ -68,7 +68,7 @@ class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) { transitions { device.pressHome() wmHelper.waitForHomeActivityVisible() - wmHelper.waitImeWindowGone() + wmHelper.waitImeGone() } teardown { eachRun { @@ -84,19 +84,20 @@ class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() @Presubmit @Test fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { - this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(IME_WINDOW_TITLE, - WindowManagerStateHelper.SPLASH_SCREEN_NAME, - WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME)) + this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf( + WindowManagerStateHelper.IME_COMPONENT, + WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT, + WindowManagerStateHelper.SNAPSHOT_COMPONENT)) } } @@ -106,20 +107,25 @@ class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) { @FlakyTest @Test - fun imeAppWindowBecomesInvisible() = testSpec.imeAppWindowBecomesInvisible(testApp) + fun imeAppWindowBecomesInvisible() { + testSpec.assertWm { + this.isAppWindowVisible(testApp.component) + .then() + .isAppWindowInvisible(testApp.component) + } + } @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun statusBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation, - Surface.ROTATION_0) + fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test @@ -127,7 +133,13 @@ class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun imeAppLayerBecomesInvisible() = testSpec.imeAppLayerBecomesInvisible(testApp) + fun imeAppLayerBecomesInvisible() { + testSpec.assertLayers { + this.isVisible(testApp.component) + .then() + .isInvisible(testApp.component) + } + } @Presubmit @Test @@ -144,8 +156,9 @@ class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) { @Test fun visibleLayersShownMoreThanOneConsecutiveEntry() { testSpec.assertLayers { - this.visibleLayersShownMoreThanOneConsecutiveEntry( - listOf(IME_WINDOW_TITLE, WindowManagerStateHelper.SPLASH_SCREEN_NAME)) + this.visibleLayersShownMoreThanOneConsecutiveEntry(listOf( + WindowManagerStateHelper.IME_COMPONENT, + WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT)) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt index 7e34469b8188..7659d9471e2f 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt @@ -14,128 +14,56 @@ * limitations under the License. */ +@file:JvmName("CommonAssertions") package com.android.server.wm.flicker.ime -import android.platform.helpers.IAppHelper import com.android.server.wm.flicker.FlickerTestParameter - -const val IME_WINDOW_TITLE = "InputMethod" - -fun FlickerTestParameter.imeLayerIsAlwaysVisible(rotatesScreen: Boolean = false) { - if (rotatesScreen) { - assertLayers { - this.isVisible(IME_WINDOW_TITLE) - .then() - .isInvisible(IME_WINDOW_TITLE) - .then() - .isVisible(IME_WINDOW_TITLE) - } - } else { - assertLayers { - this.isVisible(IME_WINDOW_TITLE) - } - } -} +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper fun FlickerTestParameter.imeLayerBecomesVisible() { assertLayers { - this.isInvisible(IME_WINDOW_TITLE) + this.isInvisible(WindowManagerStateHelper.IME_COMPONENT) .then() - .isVisible(IME_WINDOW_TITLE) + .isVisible(WindowManagerStateHelper.IME_COMPONENT) } } fun FlickerTestParameter.imeLayerBecomesInvisible() { assertLayers { - this.isVisible(IME_WINDOW_TITLE) + this.isVisible(WindowManagerStateHelper.IME_COMPONENT) .then() - .isInvisible(IME_WINDOW_TITLE) - } -} - -fun FlickerTestParameter.imeAppLayerIsAlwaysVisible(testApp: IAppHelper) { - assertLayers { - this.isVisible(testApp.getPackage()) - } -} - -fun FlickerTestParameter.imeAppWindowIsAlwaysVisible(testApp: IAppHelper) { - assertWm { - this.showsAppWindowOnTop(testApp.getPackage()) + .isInvisible(WindowManagerStateHelper.IME_COMPONENT) } } fun FlickerTestParameter.imeWindowIsAlwaysVisible(rotatesScreen: Boolean = false) { if (rotatesScreen) { assertWm { - this.showsNonAppWindow(IME_WINDOW_TITLE) + this.isNonAppWindowVisible(WindowManagerStateHelper.IME_COMPONENT) .then() - .hidesNonAppWindow(IME_WINDOW_TITLE) + .isNonAppWindowInvisible(WindowManagerStateHelper.IME_COMPONENT) .then() - .showsNonAppWindow(IME_WINDOW_TITLE) + .isNonAppWindowVisible(WindowManagerStateHelper.IME_COMPONENT) } } else { assertWm { - this.showsNonAppWindow(IME_WINDOW_TITLE) + this.isNonAppWindowVisible(WindowManagerStateHelper.IME_COMPONENT) } } } fun FlickerTestParameter.imeWindowBecomesVisible() { assertWm { - this.hidesNonAppWindow(IME_WINDOW_TITLE) + this.isNonAppWindowInvisible(WindowManagerStateHelper.IME_COMPONENT) .then() - .showsNonAppWindow(IME_WINDOW_TITLE) + .isNonAppWindowVisible(WindowManagerStateHelper.IME_COMPONENT) } } fun FlickerTestParameter.imeWindowBecomesInvisible() { assertWm { - this.showsNonAppWindow(IME_WINDOW_TITLE) + this.isNonAppWindowVisible(WindowManagerStateHelper.IME_COMPONENT) .then() - .hidesNonAppWindow(IME_WINDOW_TITLE) + .isNonAppWindowInvisible(WindowManagerStateHelper.IME_COMPONENT) } } - -fun FlickerTestParameter.imeAppWindowIsAlwaysVisible( - testApp: IAppHelper, - rotatesScreen: Boolean = false -) { - if (rotatesScreen) { - assertWm { - this.showsAppWindow(testApp.getPackage()) - .then() - .hidesAppWindow(testApp.getPackage()) - .then() - .showsAppWindow(testApp.getPackage()) - } - } else { - assertWm { - this.showsAppWindow(testApp.getPackage()) - } - } -} - -fun FlickerTestParameter.imeAppWindowBecomesVisible(windowName: String) { - assertWm { - this.hidesAppWindow(windowName) - .then() - .showsAppWindow(windowName) - } -} - -fun FlickerTestParameter.imeAppWindowBecomesInvisible(testApp: IAppHelper) { - assertWm { - this.showsAppWindowOnTop(testApp.getPackage()) - .then() - .appWindowNotOnTop(testApp.getPackage()) - } -} - -fun FlickerTestParameter.imeAppLayerBecomesInvisible(testApp: IAppHelper) { - assertLayers { - this.isVisible(testApp.getPackage()) - .then() - .isInvisible(testApp.getPackage()) - } -}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt index cae1b16c1c8c..665204bc9e1e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt @@ -28,16 +28,15 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group2 import com.android.server.wm.flicker.helpers.ImeAppHelper -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions -import com.android.server.wm.flicker.appWindowAlwaysVisibleOnTop +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -81,11 +80,11 @@ class OpenImeWindowTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() @Presubmit @Test @@ -93,19 +92,23 @@ class OpenImeWindowTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun appWindowAlwaysVisibleOnTop() = testSpec.appWindowAlwaysVisibleOnTop(testApp.`package`) + fun appWindowAlwaysVisibleOnTop() { + testSpec.assertWm { + this.isAppWindowOnTop(testApp.component) + } + } @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() + fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible() @Presubmit @Test - fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation) + fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test @@ -115,7 +118,7 @@ class OpenImeWindowTest(private val testSpec: FlickerTestParameter) { @Test fun layerAlwaysVisible() { testSpec.assertLayers { - this.isVisible(testApp.`package`) + this.isVisible(testApp.component) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt index b7673d5b0107..fe1b1cd4795d 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt @@ -17,6 +17,7 @@ package com.android.server.wm.flicker.ime import android.app.Instrumentation +import android.content.ComponentName import android.platform.test.annotations.Presubmit import android.view.Surface import android.view.WindowManagerPolicyConstants @@ -26,23 +27,22 @@ import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.annotation.Group2 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper import com.android.server.wm.flicker.helpers.reopenAppFromOverview import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.launcherWindowBecomesInvisible -import com.android.server.wm.flicker.appLayerReplacesLauncher +import com.android.server.wm.flicker.navBarWindowIsVisible import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.endRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -61,7 +61,6 @@ import org.junit.runners.Parameterized class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.config.startRotation) - private val testAppComponentName = ActivityOptions.IME_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME @FlickerBuilderProvider fun buildFlicker(): FlickerBuilder { @@ -73,14 +72,14 @@ class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) { } eachRun { device.pressRecentApps() - wmHelper.waitImeWindowGone() + wmHelper.waitImeGone() wmHelper.waitForAppTransitionIdle() this.setRotation(testSpec.config.startRotation) } } transitions { device.reopenAppFromOverview(wmHelper) - wmHelper.waitImeWindowShown() + wmHelper.waitImeShown() } teardown { test { @@ -92,23 +91,34 @@ class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() @Presubmit @Test fun visibleWindowsShownMoreThanOneConsecutiveEntry() { + val component = ComponentName("", "RecentTaskScreenshotSurface") testSpec.assertWm { - this.visibleWindowsShownMoreThanOneConsecutiveEntry() + this.visibleWindowsShownMoreThanOneConsecutiveEntry( + ignoreWindows = listOf(WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT, + WindowManagerStateHelper.SNAPSHOT_COMPONENT, + component) + ) } } @Presubmit @Test - fun launcherWindowBecomesInvisible() = testSpec.launcherWindowBecomesInvisible() + fun launcherWindowBecomesInvisible() { + testSpec.assertWm { + this.isAppWindowVisible(LAUNCHER_COMPONENT) + .then() + .isAppWindowInvisible(LAUNCHER_COMPONENT) + } + } @Presubmit @Test @@ -116,30 +126,56 @@ class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test - fun imeAppWindowIsAlwaysVisible() = testSpec.imeAppWindowIsAlwaysVisible(testApp, true) + fun imeAppWindowVisibility() { + // the app starts visible in live tile, then becomes invisible during animation and + // is again launched. Since we log 1x per frame, sometimes the activity visibility and + // the app visibility are updated together, sometimes not, thus ignore activity check + // at the start + testSpec.assertWm { + this.isAppWindowVisible(testApp.component, ignoreActivity = true) + .then() + .isAppWindowInvisible(testApp.component, ignoreActivity = true) + .then() + .isAppWindowVisible(testApp.component) + } + } @Presubmit @Test // During testing the launcher is always in portrait mode - fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation, - testSpec.config.endRotation) + fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible() @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() + fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible() @Presubmit @Test - fun imeLayerIsAlwaysVisible() = testSpec.imeLayerIsAlwaysVisible(true) + fun imeLayerIsBecomesVisible() { + testSpec.assertLayers { + this.isVisible(WindowManagerStateHelper.IME_COMPONENT) + .then() + .isInvisible(WindowManagerStateHelper.IME_COMPONENT) + .then() + .isVisible(WindowManagerStateHelper.IME_COMPONENT) + } + } @Presubmit @Test - fun appLayerReplacesLauncher() = - testSpec.appLayerReplacesLauncher(testAppComponentName.className) + fun appLayerReplacesLauncher() { + testSpec.assertLayers { + this.isVisible(LAUNCHER_COMPONENT) + .then() + .isVisible(WindowManagerStateHelper.SNAPSHOT_COMPONENT, isOptional = true) + .then() + .isVisible(testApp.component) + } + } @Presubmit @Test @@ -156,8 +192,14 @@ class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) { @Presubmit @Test fun visibleLayersShownMoreThanOneConsecutiveEntry() { + // depends on how much of the animation transactions are sent to SF at once + // sometimes this layer appears for 2-3 frames, sometimes for only 1 + val recentTaskComponent = ComponentName("", "RecentTaskScreenshotSurface") testSpec.assertLayers { - this.visibleLayersShownMoreThanOneConsecutiveEntry() + this.visibleLayersShownMoreThanOneConsecutiveEntry( + listOf(WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT, + WindowManagerStateHelper.SNAPSHOT_COMPONENT, recentTaskComponent) + ) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt index 0cae37c8d5ab..f9dd88e8cb29 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt @@ -17,27 +17,26 @@ package com.android.server.wm.flicker.ime import android.app.Instrumentation +import android.content.ComponentName import android.platform.test.annotations.Presubmit +import android.view.Surface import android.view.WindowManagerPolicyConstants -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import androidx.test.platform.app.InstrumentationRegistry - import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group2 -import com.android.server.wm.flicker.helpers.ImeAppHelper +import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarWindowIsVisible import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder import org.junit.Test @@ -54,10 +53,11 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group2 +@Presubmit class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParameter) { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val testApp = SimpleAppHelper(instrumentation) - private val imeTestApp = ImeAppHelper(instrumentation) + private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.config.startRotation) @FlickerBuilderProvider fun buildFlicker(): FlickerBuilder { @@ -66,7 +66,13 @@ class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParame eachRun { this.setRotation(testSpec.config.startRotation) testApp.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp.component) + wmHelper.waitForAppTransitionIdle() + imeTestApp.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp.component) + wmHelper.waitForAppTransitionIdle() + imeTestApp.openIME(device, wmHelper) } } @@ -74,57 +80,86 @@ class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParame eachRun { device.pressHome() wmHelper.waitForHomeActivityVisible() - } - test { - imeTestApp.exit(wmHelper) + testApp.exit() + imeTestApp.exit() } } transitions { // [Step1]: Swipe right from imeTestApp to testApp task + createTag(TAG_IME_VISIBLE) val displayBounds = WindowUtils.getDisplayBounds(testSpec.config.startRotation) - val displayCenterX = displayBounds.bounds.width() / 2 - device.swipe(displayCenterX, displayBounds.bounds.height(), - displayBounds.bounds.width(), displayBounds.bounds.height(), 20) + device.swipe(0, displayBounds.bounds.height(), + displayBounds.bounds.width(), displayBounds.bounds.height(), 50) + wmHelper.waitForFullScreenApp(testApp.component) + wmHelper.waitForAppTransitionIdle() + createTag(TAG_IME_INVISIBLE) } transitions { // [Step2]: Swipe left to back to imeTestApp task val displayBounds = WindowUtils.getDisplayBounds(testSpec.config.startRotation) - val displayCenterX = displayBounds.bounds.width() / 2 device.swipe(displayBounds.bounds.width(), displayBounds.bounds.height(), - displayCenterX, displayBounds.bounds.height(), 20) + 0, displayBounds.bounds.height(), 50) wmHelper.waitForFullScreenApp(imeTestApp.component) } } } - @FlakyTest @Test - fun imeAppWindowIsAlwaysVisible() = testSpec.imeAppWindowIsAlwaysVisible(imeTestApp) + fun imeAppWindowVisibility() { + val component = ComponentName(imeTestApp.`package`, "") + testSpec.assertWm { + this.isAppWindowOnTop(component) + .then() + .isAppWindowVisible(component, ignoreActivity = true) + } + } - @FlakyTest @Test - fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible() + fun navBarLayerIsVisibleAroundSwitching() { + testSpec.assertLayersStart { + isVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + } + testSpec.assertLayersEnd { + isVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + } + } - @FlakyTest @Test - fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible() + fun statusBarLayerIsVisibleAroundSwitching() { + testSpec.assertLayersStart { + isVisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) + } + testSpec.assertLayersEnd { + isVisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) + } + } - @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + fun imeLayerIsVisibleWhenSwitchingToImeApp() { + testSpec.assertLayersStart { + isVisible(WindowManagerStateHelper.IME_COMPONENT) + } + testSpec.assertLayersTag(TAG_IME_VISIBLE) { + isVisible(WindowManagerStateHelper.IME_COMPONENT) + } + testSpec.assertLayersEnd { + isVisible(WindowManagerStateHelper.IME_COMPONENT) + } + } - @FlakyTest @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + fun imeLayerIsInvisibleWhenSwitchingToTestApp() { + testSpec.assertLayersTag(TAG_IME_INVISIBLE) { + isInvisible(WindowManagerStateHelper.IME_COMPONENT) + } + } - @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() - @FlakyTest @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() companion object { @Parameterized.Parameters(name = "{0}") @@ -134,10 +169,13 @@ class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParame .getConfigNonRotationTests( repetitions = 3, supportedNavigationModes = listOf( - WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY - ) + ), + supportedRotations = listOf(Surface.ROTATION_0) ) } + + private const val TAG_IME_VISIBLE = "imeVisible" + private const val TAG_IME_INVISIBLE = "imeInVisible" } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt new file mode 100644 index 000000000000..42c252e70eea --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.launch + +import android.app.Instrumentation +import android.platform.test.annotations.Presubmit +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.entireScreenCovered +import com.android.server.wm.flicker.FlickerBuilderProvider +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.LAUNCHER_COMPONENT +import com.android.server.wm.flicker.repetitions +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.TwoActivitiesAppHelper +import com.android.server.wm.flicker.testapp.ActivityOptions +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test the back and forward transition between 2 activities. + * To run this test: `atest FlickerTests:ActivitiesTransitionTest` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class ActivitiesTransitionTest(val testSpec: FlickerTestParameter) { + val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val testApp: TwoActivitiesAppHelper = TwoActivitiesAppHelper(instrumentation) + + @FlickerBuilderProvider + fun buildFlicker(): FlickerBuilder { + return FlickerBuilder(instrumentation).apply { + withTestName { testSpec.name } + repeat { testSpec.config.repetitions } + setup { + eachRun { + testApp.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp.component) + } + } + teardown { + test { + testApp.exit() + } + } + transitions { + testApp.openSecondActivity(device, wmHelper) + device.pressBack() + wmHelper.waitForAppTransitionIdle() + wmHelper.waitForFullScreenApp(testApp.component) + } + } + } + + @Presubmit + @Test + fun finishSubActivity() { + testSpec.assertWm { + this.isAppWindowOnTop(ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME) + .then() + .isAppWindowOnTop(ActivityOptions.SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME) + .then() + .isAppWindowOnTop(ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME) + } + } + + @Presubmit + @Test + fun entireScreenCovered() = testSpec.entireScreenCovered() + + @Presubmit + @Test + fun launcherWindowNotVisible() { + testSpec.assertWm { + this.isAppWindowInvisible(LAUNCHER_COMPONENT, ignoreActivity = true) + } + } + + @Presubmit + @Test + fun launcherLayerNotVisible() { + testSpec.assertLayers { this.isInvisible(LAUNCHER_COMPONENT) } + } + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests(repetitions = 5) + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt deleted file mode 100644 index 01e34d9f8f97..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.server.wm.flicker.launch - -import android.platform.helpers.IAppHelper -import com.android.server.wm.flicker.FlickerTestParameter -import com.android.server.wm.flicker.HOME_WINDOW_TITLE - -fun FlickerTestParameter.appWindowReplacesLauncherAsTopWindow(testApp: IAppHelper) { - assertWm { - this.showsAppWindowOnTop(*HOME_WINDOW_TITLE) - .then() - .showsAppWindowOnTop("Snapshot", testApp.getPackage()) - } -}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt index 9ff0bdfe66ba..be919cd67c1e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt @@ -16,6 +16,8 @@ package com.android.server.wm.flicker.launch +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory @@ -33,8 +35,21 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** - * Test cold launch app from launcher. + * Test cold launching an app from launcher + * * To run this test: `atest FlickerTests:OpenAppColdTest` + * + * Actions: + * Make sure no apps are running on the device + * Launch an app [testApp] and wait animation to complete + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [OpenAppTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup */ @RequiresDevice @RunWith(Parameterized::class) @@ -42,6 +57,9 @@ import org.junit.runners.Parameterized @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 class OpenAppColdTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { + /** + * Defines the transition used to run the test + */ override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit get() = { super.transition(this, it) @@ -62,43 +80,46 @@ class OpenAppColdTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSp } } + /** {@inheritDoc} */ @FlakyTest @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() { - super.visibleLayersShownMoreThanOneConsecutiveEntry() + override fun navBarLayerRotatesAndScales() { + super.navBarLayerRotatesAndScales() } - @FlakyTest + /** {@inheritDoc} */ + @Postsubmit @Test - override fun navBarLayerIsAlwaysVisible() { - super.navBarLayerIsAlwaysVisible() - } + override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher() - @FlakyTest + /** {@inheritDoc} */ + @Postsubmit @Test - override fun navBarLayerRotatesAndScales() { - super.navBarLayerRotatesAndScales() - } + override fun appWindowReplacesLauncherAsTopWindow() = + super.appWindowReplacesLauncherAsTopWindow() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun statusBarLayerIsAlwaysVisible() { - super.statusBarLayerIsAlwaysVisible() - } + override fun launcherWindowBecomesInvisible() = super.launcherWindowBecomesInvisible() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun appLayerReplacesLauncher() { - super.appLayerReplacesLauncher() - } + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun appWindowReplacesLauncherAsTopWindow() { - super.appWindowReplacesLauncherAsTopWindow() - } + override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<FlickerTestParameter> { diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt index b073a7ca1495..3678f33aa46e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt @@ -16,6 +16,7 @@ package com.android.server.wm.flicker.launch +import android.platform.test.annotations.Presubmit import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory @@ -33,8 +34,23 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** - * Launch an app from the recents app view (the overview) + * Test launching an app from the recents app view (the overview) + * * To run this test: `atest FlickerTests:OpenAppFromOverviewTest` + * + * Actions: + * Launch [testApp] + * Press recents + * Relaunch an app [testApp] by selecting it in the overview screen, and wait animation to + * complete (only this action is traced) + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [OpenAppTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup */ @RequiresDevice @RunWith(Parameterized::class) @@ -42,6 +58,9 @@ import org.junit.runners.Parameterized @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { + /** + * Defines the transition used to run the test + */ override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit get() = { super.transition(this, it) @@ -63,37 +82,38 @@ class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) : OpenAppTransitio } } + /** {@inheritDoc} */ @FlakyTest @Test - override fun navBarLayerIsAlwaysVisible() { - super.navBarLayerIsAlwaysVisible() - } + override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun statusBarLayerIsAlwaysVisible() { - super.statusBarLayerIsAlwaysVisible() - } + override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun navBarLayerRotatesAndScales() { - super.navBarLayerRotatesAndScales() - } + override fun launcherWindowBecomesInvisible() = super.launcherWindowBecomesInvisible() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun statusBarLayerRotatesScales() { - super.statusBarLayerRotatesScales() - } + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() { - super.visibleLayersShownMoreThanOneConsecutiveEntry() - } + override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<FlickerTestParameter> { diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt new file mode 100644 index 000000000000..b7176122095b --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.launch + +import android.content.ComponentName +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.Surface +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.FlakyTest +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.helpers.NonResizeableAppHelper +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper +import com.google.common.truth.Truth +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test launching an app while the device is locked + * + * To run this test: `atest FlickerTests:OpenAppNonResizeableTest` + * + * Actions: + * Lock the device. + * Launch an app on top of the lock screen [testApp] and wait animation to complete + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [OpenAppTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { + override val testApp = NonResizeableAppHelper(instrumentation) + private val colorFadComponent = ComponentName("", "ColorFade BLAST#") + + /** + * Defines the transition used to run the test + */ + override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit + get() = { args -> + super.transition(this, args) + setup { + eachRun { + device.sleep() + wmHelper.waitFor("noAppWindowsOnTop") { + it.wmState.topVisibleAppWindow.isEmpty() + } + } + } + teardown { + eachRun { + testApp.exit(wmHelper) + } + } + transitions { + testApp.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp.component) + } + } + + /** + * Checks that the nav bar layer starts visible, becomes invisible during unlocking animation + * and becomes visible at the end + */ + @Presubmit + @Test + fun navBarLayerVisibilityChanges() { + testSpec.assertLayers { + this.isVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + .then() + .isInvisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + .then() + .isVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + } + } + + /** + * Checks that the app layer doesn't exist at the start of the transition, that it is + * created (invisible) and becomes visible during the transition + */ + @Presubmit + @Test + fun appLayerBecomesVisible() { + testSpec.assertLayers { + this.notContains(testApp.component) + .then() + .isInvisible(testApp.component) + .then() + .isVisible(testApp.component) + } + } + + /** + * Checks that the app window doesn't exist at the start of the transition, that it is + * created (invisible - optional) and becomes visible during the transition + * + * The `isAppWindowInvisible` step is optional because we log once per frame, upon logging, + * the window may be visible or not depending on what was processed until that moment. + */ + @Presubmit + @Test + fun appWindowBecomesVisible() { + testSpec.assertWm { + this.notContains(testApp.component) + .then() + .isAppWindowInvisible(testApp.component, + ignoreActivity = true, isOptional = true) + .then() + .isAppWindowVisible(testApp.component, ignoreActivity = true) + } + } + + /** + * Checks if [testApp] is visible at the end of the transition + */ + @Presubmit + @Test + fun appWindowBecomesVisibleAtEnd() { + testSpec.assertWmEnd { + this.isVisible(testApp.component) + } + } + + /** + * Checks that the nav bar starts the transition visible, then becomes invisible during + * then unlocking animation and becomes visible at the end of the transition + */ + @Postsubmit + @Test + fun navBarWindowsVisibilityChanges() { + testSpec.assertWm { + this.isAboveAppWindowVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + .then() + .isNonAppWindowInvisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + .then() + .isAboveAppWindowVisible(WindowManagerStateHelper.NAV_BAR_COMPONENT) + } + } + + /** {@inheritDoc} */ + @FlakyTest + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @FlakyTest + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = super.entireScreenCovered() + + /** + * Checks that the focus changes from the launcher to [testApp] + */ + @FlakyTest + @Test + override fun focusChanges() = super.focusChanges() + + /** + * Checks that the screen is locked at the start of the transition ([colorFadComponent]) + * layer is visible + */ + @Postsubmit + @Test + fun screenLockedStart() { + testSpec.assertLayersStart { + isVisible(colorFadComponent) + } + } + + /** + * This test checks if the launcher is visible at the start and the app at the end, + * it cannot use the regular assertion (check over time), because on lock screen neither + * the app not the launcher are visible, and there is no top visible window. + */ + @Postsubmit + @Test + override fun appWindowReplacesLauncherAsTopWindow() { + testSpec.assertWm { + this.invoke("noAppWindowsOnTop") { + Truth.assertWithMessage("Should not have any app window on top " + + "when the screen is locked") + .that(it.wmState.topVisibleAppWindow) + .isEmpty() + }.then() + .isAppWindowOnTop(testApp.component) + } + } + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests( + repetitions = 5, + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY), + supportedRotations = listOf(Surface.ROTATION_0) + ) + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt index b304d5f999df..14d17f82b805 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt @@ -22,30 +22,34 @@ import android.view.Surface import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter -import com.android.server.wm.flicker.appLayerReplacesLauncher +import com.android.server.wm.flicker.LAUNCHER_COMPONENT import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.endRotation -import com.android.server.wm.flicker.focusChanges +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.helpers.StandardAppHelper import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible import com.android.server.wm.flicker.repetitions +import com.android.server.wm.flicker.replacesLayer import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerIsVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.launcherWindowBecomesInvisible +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.SNAPSHOT_COMPONENT +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.SPLASH_SCREEN_COMPONENT import org.junit.Test abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) { protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() - protected val testApp: StandardAppHelper = SimpleAppHelper(instrumentation) + protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation) + /** + * Defines the transition used to run the test + */ protected open val transition: FlickerBuilder.(Map<String, Any?>) -> Unit = { withTestName { testSpec.name } repeat { testSpec.config.repetitions } @@ -62,6 +66,10 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) { } } + /** + * Entry point for the test runner. It will use this method to initialize and cache + * flicker executions + */ @FlickerBuilderProvider fun buildFlicker(): FlickerBuilder { return FlickerBuilder(instrumentation).apply { @@ -69,42 +77,60 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) { } } - @Presubmit - @Test - open fun navBarWindowIsAlwaysVisible() { - testSpec.navBarWindowIsAlwaysVisible() + /** + * Checks that the navigation bar window is visible during the whole transition + */ + open fun navBarWindowIsVisible() { + testSpec.navBarWindowIsVisible() } - @Presubmit - @Test - open fun navBarLayerIsAlwaysVisible() { - testSpec.navBarLayerIsAlwaysVisible(rotatesScreen = testSpec.isRotated) + /** + * Checks that the navigation bar layer is visible during the whole transition + */ + open fun navBarLayerIsVisible() { + testSpec.navBarLayerIsVisible() } + /** + * Checks the position of the navigation bar at the start and end of the transition + */ @Presubmit @Test open fun navBarLayerRotatesAndScales() { testSpec.navBarLayerRotatesAndScales(Surface.ROTATION_0, testSpec.config.endRotation) } + /** + * Checks that the status bar window is visible during the whole transition + */ @Presubmit @Test - open fun statusBarWindowIsAlwaysVisible() { - testSpec.statusBarWindowIsAlwaysVisible() + open fun statusBarWindowIsVisible() { + testSpec.statusBarWindowIsVisible() } + /** + * Checks that the status bar layer is visible during the whole transition + */ @Presubmit @Test - open fun statusBarLayerIsAlwaysVisible() { - testSpec.statusBarLayerIsAlwaysVisible(rotatesScreen = testSpec.isRotated) + open fun statusBarLayerIsVisible() { + testSpec.statusBarLayerIsVisible() } + /** + * Checks the position of the status bar at the start and end of the transition + */ @Presubmit @Test open fun statusBarLayerRotatesScales() { testSpec.statusBarLayerRotatesScales(Surface.ROTATION_0, testSpec.config.endRotation) } + /** + * Checks that all windows that are visible on the trace, are visible for at least 2 + * consecutive entries. + */ @Presubmit @Test open fun visibleWindowsShownMoreThanOneConsecutiveEntry() { @@ -113,6 +139,10 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) { } } + /** + * Checks that all layers that are visible on the trace, are visible for at least 2 + * consecutive entries. + */ @Presubmit @Test open fun visibleLayersShownMoreThanOneConsecutiveEntry() { @@ -121,34 +151,60 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) { } } + /** + * Checks that all parts of the screen are covered during the transition + */ @Presubmit @Test - // During testing the launcher is always in portrait mode - open fun noUncoveredRegions() { - testSpec.noUncoveredRegions(Surface.ROTATION_0, testSpec.config.endRotation) - } + open fun entireScreenCovered() = testSpec.entireScreenCovered() + /** + * Checks that the focus changes from the launcher to [testApp] + */ @Presubmit @Test open fun focusChanges() { - testSpec.focusChanges("NexusLauncherActivity", testApp.`package`) + testSpec.assertEventLog { + this.focusChanges("NexusLauncherActivity", testApp.`package`) + } } - @Presubmit - @Test + /** + * Checks that [LAUNCHER_COMPONENT] layer is visible at the start of the transition, and + * is replaced by [testApp], which remains visible until the end + */ open fun appLayerReplacesLauncher() { - testSpec.appLayerReplacesLauncher(testApp.`package`) + testSpec.replacesLayer(LAUNCHER_COMPONENT, testApp.component) } + /** + * Checks that [LAUNCHER_COMPONENT] window is visible at the start of the transition, and + * is replaced by a snapshot or splash screen (optional), and finally, is replaced by + * [testApp], which remains visible until the end + */ @Presubmit @Test open fun appWindowReplacesLauncherAsTopWindow() { - testSpec.appWindowReplacesLauncherAsTopWindow(testApp) + testSpec.assertWm { + this.isAppWindowOnTop(LAUNCHER_COMPONENT) + .then() + .isAppWindowOnTop(SNAPSHOT_COMPONENT, isOptional = true) + .then() + .isAppWindowOnTop(SPLASH_SCREEN_COMPONENT, isOptional = true) + .then() + .isAppWindowOnTop(testApp.component) + } } - @Presubmit - @Test + /** + * Checks that [LAUNCHER_COMPONENT] window is visible at the start, and + * becomes invisible during the transition + */ open fun launcherWindowBecomesInvisible() { - testSpec.launcherWindowBecomesInvisible() + testSpec.assertWm { + this.isAppWindowVisible(LAUNCHER_COMPONENT) + .then() + .isAppWindowInvisible(LAUNCHER_COMPONENT) + } } }
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt index e2705c764917..5edee0cf0ca0 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt @@ -16,6 +16,7 @@ package com.android.server.wm.flicker.launch +import android.platform.test.annotations.Presubmit import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory @@ -32,8 +33,22 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** - * Test warm launch app. + * Test warm launching an app from launcher + * * To run this test: `atest FlickerTests:OpenAppWarmTest` + * + * Actions: + * Launch [testApp] + * Press home + * Relaunch an app [testApp] and wait animation to complete (only this action is traced) + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [OpenAppTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup */ @RequiresDevice @RunWith(Parameterized::class) @@ -41,6 +56,9 @@ import org.junit.runners.Parameterized @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 class OpenAppWarmTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSpec) { + /** + * Defines the transition used to run the test + */ override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit get() = { super.transition(this, it) @@ -65,19 +83,38 @@ class OpenAppWarmTest(testSpec: FlickerTestParameter) : OpenAppTransition(testSp } } + /** {@inheritDoc} */ @FlakyTest @Test - override fun navBarLayerIsAlwaysVisible() { - super.navBarLayerIsAlwaysVisible() - } + override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() - @FlakyTest + /** {@inheritDoc} */ + @Presubmit @Test - override fun navBarLayerRotatesAndScales() { - super.navBarLayerRotatesAndScales() - } + override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher() + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun launcherWindowBecomesInvisible() = super.launcherWindowBecomesInvisible() + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun navBarLayerIsVisible() = super.navBarLayerIsVisible() + + /** {@inheritDoc} */ + @Presubmit + @Test + override fun navBarWindowIsVisible() = super.navBarWindowIsVisible() companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<FlickerTestParameter> { diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt new file mode 100644 index 000000000000..035aac1c5e86 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.quickswitch + +import android.app.Instrumentation +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.RequiresDevice +import android.view.Surface +import android.view.WindowManagerPolicyConstants +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.FlickerBuilderProvider +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.LAUNCHER_COMPONENT +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.NonResizeableAppHelper +import com.android.server.wm.flicker.helpers.SimpleAppHelper +import com.android.server.wm.flicker.helpers.WindowUtils +import com.android.server.wm.flicker.helpers.isRotated +import com.android.server.wm.flicker.navBarLayerIsVisible +import com.android.server.wm.flicker.navBarLayerRotatesAndScales +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.startRotation +import com.android.server.wm.flicker.statusBarLayerIsVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.SNAPSHOT_COMPONENT +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test quick switching back to previous app from last opened app + * + * To run this test: `atest FlickerTests:QuickSwitchBetweenTwoAppsBackTest` + * + * Actions: + * Launch an app [testApp1] + * Launch another app [testApp2] + * Swipe right from the bottom of the screen to quick switch back to the first app [testApp1] + * + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestParameter) { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + + private val testApp1 = SimpleAppHelper(instrumentation) + private val testApp2 = NonResizeableAppHelper(instrumentation) + + private val startDisplayBounds = WindowUtils.getDisplayBounds(testSpec.config.startRotation) + + @FlickerBuilderProvider + fun buildFlicker(): FlickerBuilder { + return FlickerBuilder(instrumentation).apply { + setup { + eachRun { + testApp1.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp1.component) + + testApp2.launchViaIntent(wmHelper) + wmHelper.waitForFullScreenApp(testApp2.component) + } + } + transitions { + // Swipe right from bottom to quick switch back + // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the middle + // as to not accidentally trigger a swipe back or forward action which would result + // in the same behavior but not testing quick swap. + device.swipe( + startDisplayBounds.bounds.right / 3, + startDisplayBounds.bounds.bottom, + 2 * startDisplayBounds.bounds.right / 3, + startDisplayBounds.bounds.bottom, + if (testSpec.config.startRotation.isRotated()) 75 else 30 + ) + + wmHelper.waitForFullScreenApp(testApp1.component) + wmHelper.waitForAppTransitionIdle() + } + + teardown { + test { + testApp1.exit() + testApp2.exit() + } + } + } + } + + /** + * Checks that the transition starts with [testApp2]'s windows filling/covering exactly the + * entirety of the display. + */ + @Postsubmit + @Test + fun startsWithApp2WindowsCoverFullScreen() { + testSpec.assertWmStart { + this.frameRegion(testApp2.component).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that the transition starts with [testApp2]'s layers filling/covering exactly the + * entirety of the display. + */ + @Postsubmit + @Test + fun startsWithApp2LayersCoverFullScreen() { + testSpec.assertLayersStart { + this.visibleRegion(testApp2.component).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that the transition starts with [testApp2] being the top window. + */ + @Postsubmit + @Test + fun startsWithApp2WindowBeingOnTop() { + testSpec.assertWmStart { + this.isAppWindowOnTop(testApp2.component) + } + } + + /** + * Checks that [testApp1] windows fill the entire screen (i.e. is "fullscreen") at the end of the + * transition once we have fully quick switched from [testApp2] back to the [testApp1]. + */ + @Postsubmit + @Test + fun endsWithApp1WindowsCoveringFullScreen() { + testSpec.assertWmEnd { + this.frameRegion(testApp1.component).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that [testApp1] layers fill the entire screen (i.e. is "fullscreen") at the end of the + * transition once we have fully quick switched from [testApp2] back to the [testApp1]. + */ + @Postsubmit + @Test + fun endsWithApp1LayersCoveringFullScreen() { + testSpec.assertLayersEnd { + this.visibleRegion(testApp1.component).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that [testApp1] is the top window at the end of the transition once we have fully quick + * switched from [testApp2] back to the [testApp1]. + */ + @Postsubmit + @Test + fun endsWithApp1BeingOnTop() { + testSpec.assertWmEnd { + this.isAppWindowOnTop(testApp1.component) + } + } + + /** + * Checks that [testApp1]'s window starts off invisible and becomes visible at some point before + * the end of the transition and then stays visible until the end of the transition. + */ + @Postsubmit + @Test + fun app1WindowBecomesAndStaysVisible() { + testSpec.assertWm { + this.isAppWindowInvisible(testApp1.component) + .then() + .isAppWindowVisible(SNAPSHOT_COMPONENT, isOptional = true) + .then() + .isAppWindowVisible(testApp1.component, ignoreActivity = true) + } + } + + /** + * Checks that [testApp1]'s layer starts off invisible and becomes visible at some point before + * the end of the transition and then stays visible until the end of the transition. + */ + @Postsubmit + @Test + fun app1LayerBecomesAndStaysVisible() { + testSpec.assertLayers { + this.isInvisible(testApp1.component) + .then() + .isVisible(testApp1.component) + } + } + + /** + * Checks that [testApp2]'s window starts off visible and becomes invisible at some point before + * the end of the transition and then stays invisible until the end of the transition. + */ + @Postsubmit + @Test + fun app2WindowBecomesAndStaysInvisible() { + testSpec.assertWm { + this.isAppWindowVisible(testApp2.component, ignoreActivity = true) + .then() + .isAppWindowInvisible(testApp2.component) + } + } + + /** + * Checks that [testApp2]'s layer starts off visible and becomes invisible at some point before + * the end of the transition and then stays invisible until the end of the transition. + */ + @Postsubmit + @Test + fun app2LayerBecomesAndStaysInvisible() { + testSpec.assertLayers { + this.isVisible(testApp2.component) + .then() + .isInvisible(testApp2.component) + } + } + + /** + * Checks that [testApp2]'s window is visible at least until [testApp1]'s window is visible. + * Ensures that at any point, either [testApp1] or [testApp2]'s windows are at least partially + * visible. + */ + @Postsubmit + @Test + fun app1WindowIsVisibleOnceApp2WindowIsInvisible() { + testSpec.assertWm { + this.isAppWindowVisible(testApp2.component) + .then() + // TODO: Do we actually want to test this? Seems too implementation specific... + .isAppWindowVisible(LAUNCHER_COMPONENT, isOptional = true) + .then() + .isAppWindowVisible(SNAPSHOT_COMPONENT, isOptional = true) + .then() + .isAppWindowVisible(testApp1.component) + } + } + + /** + * Checks that [testApp2]'s layer is visible at least until [testApp1]'s window is visible. + * Ensures that at any point, either [testApp1] or [testApp2]'s windows are at least partially + * visible. + */ + @Postsubmit + @Test + fun app1LayerIsVisibleOnceApp2LayerIsInvisible() { + testSpec.assertLayers { + this.isVisible(testApp2.component) + .then() + .isVisible(LAUNCHER_COMPONENT, isOptional = true) + .then() + .isVisible(SNAPSHOT_COMPONENT, isOptional = true) + .then() + .isVisible(testApp1.component) + } + } + + /** + * Checks that the navbar window is visible throughout the entire transition. + */ + @Postsubmit + @Test + fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible() + + /** + * Checks that the navbar layer is visible throughout the entire transition. + */ + @Postsubmit + @Test + fun navBarLayerAlwaysIsVisible() = testSpec.navBarLayerIsVisible() + + /** + * Checks that the navbar is always in the right position and covers the expected region. + * + * NOTE: This doesn't check that the navbar is visible or not. + */ + @Postsubmit + @Test + fun navbarIsAlwaysInRightPosition() = + testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation) + + /** + * Checks that the status bar window is visible throughout the entire transition. + */ + @Postsubmit + @Test + fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsVisible() + + /** + * Checks that the status bar layer is visible throughout the entire transition. + */ + @Postsubmit + @Test + fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsVisible() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests( + repetitions = 5, + supportedNavigationModes = listOf( + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY + ), + supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90) + ) + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt new file mode 100644 index 000000000000..ca8f8af2df94 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.quickswitch + +import android.app.Instrumentation +import android.platform.test.annotations.Presubmit +import android.platform.test.annotations.RequiresDevice +import android.view.Surface +import android.view.WindowManagerPolicyConstants +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.FlickerBuilderProvider +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.LAUNCHER_COMPONENT +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.entireScreenCovered +import com.android.server.wm.flicker.helpers.SimpleAppHelper +import com.android.server.wm.flicker.helpers.WindowUtils +import com.android.server.wm.flicker.navBarLayerIsVisible +import com.android.server.wm.flicker.navBarLayerRotatesAndScales +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.startRotation +import com.android.server.wm.flicker.statusBarLayerIsVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.SNAPSHOT_COMPONENT +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test quick switching to last opened app from launcher + * + * To run this test: `atest FlickerTests:QuickSwitchFromLauncherTest` + * + * Actions: + * Launch an app + * Navigate home to show launcher + * Swipe right from the bottom of the screen to quick switch back to the app + * + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val testApp = SimpleAppHelper(instrumentation) + private val startDisplayBounds = WindowUtils.getDisplayBounds(testSpec.config.startRotation) + + @FlickerBuilderProvider + fun buildFlicker(): FlickerBuilder { + return FlickerBuilder(instrumentation).apply { + setup { + eachRun { + testApp.launchViaIntent(wmHelper) + device.pressHome() + wmHelper.waitForHomeActivityVisible() + wmHelper.waitForWindowSurfaceDisappeared(testApp.component) + } + } + transitions { + // Swipe right from bottom to quick switch back + // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the middle + // as to not accidentally trigger a swipe back or forward action which would result + // in the same behavior but not testing quick swap. + device.swipe( + startDisplayBounds.bounds.right / 3, + startDisplayBounds.bounds.bottom, + 2 * startDisplayBounds.bounds.right / 3, + startDisplayBounds.bounds.bottom, + 50 + ) + + wmHelper.waitForFullScreenApp(testApp.component) + wmHelper.waitForAppTransitionIdle() + } + + teardown { + eachRun { + testApp.exit() + } + } + } + } + + /** + * Checks that [testApp] windows fill the entire screen (i.e. is "fullscreen") at the end of the + * transition once we have fully quick switched from the launcher back to the [testApp]. + */ + @Presubmit + @Test + fun endsWithAppWindowsCoveringFullScreen() { + testSpec.assertWmEnd { + this.frameRegion(testApp.component).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that [testApp] layers fill the entire screen (i.e. is "fullscreen") at the end of the + * transition once we have fully quick switched from the launcher back to the [testApp]. + */ + @Presubmit + @Test + fun endsWithAppLayersCoveringFullScreen() { + testSpec.assertLayersEnd { + this.visibleRegion(testApp.component).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that [testApp] is the top window at the end of the transition once we have fully quick + * switched from the launcher back to the [testApp]. + */ + @Presubmit + @Test + fun endsWithAppBeingOnTop() { + testSpec.assertWmEnd { + this.isAppWindowOnTop(testApp.component) + } + } + + /** + * Checks that the transition starts with the home activity being tagged as visible. + */ + @Presubmit + @Test + fun startsWithHomeActivityFlaggedVisible() { + testSpec.assertWmStart { + this.isHomeActivityVisible(true) + } + } + + /** + * Checks that the transition starts with the launcher windows filling/covering exactly the + * entirety of the display. + */ + @Presubmit + @Test + fun startsWithLauncherWindowsCoverFullScreen() { + testSpec.assertWmStart { + this.frameRegion(LAUNCHER_COMPONENT).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that the transition starts with the launcher layers filling/covering exactly the + * entirety of the display. + */ + @Presubmit + @Test + fun startsWithLauncherLayersCoverFullScreen() { + testSpec.assertLayersStart { + this.visibleRegion(LAUNCHER_COMPONENT).coversExactly(startDisplayBounds) + } + } + + /** + * Checks that the transition starts with the launcher being the top window. + */ + @Presubmit + @Test + fun startsWithLauncherBeingOnTop() { + testSpec.assertWmStart { + this.isAppWindowOnTop(LAUNCHER_COMPONENT) + } + } + + /** + * Checks that the transition ends with the home activity being flagged as not visible. By this + * point we should have quick switched away from the launcher back to the [testApp]. + */ + @Presubmit + @Test + fun endsWithHomeActivityFlaggedInvisible() { + testSpec.assertWmEnd { + this.isHomeActivityVisible(false) + } + } + + /** + * Checks that [testApp]'s window starts off invisible and becomes visible at some point before + * the end of the transition and then stays visible until the end of the transition. + */ + @Presubmit + @Test + fun appWindowBecomesAndStaysVisible() { + testSpec.assertWm { + this.isAppWindowInvisible(testApp.component, ignoreActivity = true) + .then() + .isAppWindowVisible(testApp.component, ignoreActivity = true) + } + } + + /** + * Checks that [testApp]'s layer starts off invisible and becomes visible at some point before + * the end of the transition and then stays visible until the end of the transition. + */ + @Presubmit + @Test + fun appLayerBecomesAndStaysVisible() { + testSpec.assertLayers { + this.isInvisible(testApp.component) + .then() + .isVisible(testApp.component) + } + } + + /** + * Checks that the launcher window starts off visible and becomes invisible at some point before + * the end of the transition and then stays invisible until the end of the transition. + */ + @Presubmit + @Test + fun launcherWindowBecomesAndStaysInvisible() { + testSpec.assertWm { + this.isAppWindowVisible(LAUNCHER_COMPONENT) + .then() + .isAppWindowInvisible(LAUNCHER_COMPONENT) + } + } + + /** + * Checks that the launcher layer starts off visible and becomes invisible at some point before + * the end of the transition and then stays invisible until the end of the transition. + */ + @Presubmit + @Test + fun launcherLayerBecomesAndStaysInvisible() { + testSpec.assertLayers { + this.isVisible(LAUNCHER_COMPONENT) + .then() + .isInvisible(LAUNCHER_COMPONENT) + } + } + + /** + * Checks that the launcher window is visible at least until the app window is visible. Ensures + * that at any point, either the launcher or [testApp] windows are at least partially visible. + */ + @Presubmit + @Test + fun appWindowIsVisibleOnceLauncherWindowIsInvisible() { + testSpec.assertWm { + this.isAppWindowVisible(LAUNCHER_COMPONENT) + .then() + .isAppWindowVisible(SNAPSHOT_COMPONENT) + .then() + .isAppWindowVisible(testApp.component) + } + } + + /** + * Checks that the launcher layer is visible at least until the app layer is visible. Ensures + * that at any point, either the launcher or [testApp] layers are at least partially visible. + */ + @Presubmit + @Test + fun appLayerIsVisibleOnceLauncherLayerIsInvisible() { + testSpec.assertLayers { + this.isVisible(LAUNCHER_COMPONENT) + .then() + .isVisible(SNAPSHOT_COMPONENT) + .then() + .isVisible(testApp.component) + } + } + + /** + * Checks that the navbar window is visible throughout the entire transition. + */ + @Presubmit + @Test + fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible() + + /** + * Checks that the navbar layer is visible throughout the entire transition. + */ + @Presubmit + @Test + fun navBarLayerAlwaysIsVisible() = testSpec.navBarLayerIsVisible() + + /** + * Checks that the navbar is always in the right position and covers the expected region. + * + * NOTE: This doesn't check that the navbar is visible or not. + */ + @Presubmit + @Test + fun navbarIsAlwaysInRightPosition() = + testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation) + + /** + * Checks that the status bar window is visible throughout the entire transition. + */ + @Presubmit + @Test + fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsVisible() + + /** + * Checks that the status bar layer is visible throughout the entire transition. + */ + @Presubmit + @Test + fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsVisible() + + /** + * Checks that the screen is always fully covered by visible layers throughout the transition. + */ + @Presubmit + @Test + fun screenIsAlwaysFilled() = testSpec.entireScreenCovered() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests( + repetitions = 5, + supportedNavigationModes = listOf( + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY + ), + // TODO: Test with 90 rotation + supportedRotations = listOf(Surface.ROTATION_0) + ) + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt index 69e8a8d08e58..d57c6698e35c 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt @@ -16,7 +16,6 @@ package com.android.server.wm.flicker.rotation -import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice @@ -25,7 +24,13 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.endRotation import com.android.server.wm.flicker.helpers.SimpleAppHelper +import com.android.server.wm.flicker.startRotation +import com.android.server.wm.flicker.statusBarLayerIsVisible +import com.android.server.wm.flicker.statusBarLayerRotatesScales +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.ROTATION_COMPONENT import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -61,39 +66,44 @@ class ChangeAppRotationTest( super.focusDoesNotChange() } - @Postsubmit + @Presubmit @Test fun screenshotLayerBecomesInvisible() { testSpec.assertLayers { - this.isVisible(testApp.getPackage()) + this.isVisible(testApp.component) .then() - .isVisible(SCREENSHOT_LAYER) + .isVisible(ROTATION_COMPONENT) .then() - .isVisible(testApp.getPackage()) + .isVisible(testApp.component) } } - @Postsubmit + @Presubmit @Test - override fun statusBarLayerRotatesScales() { - super.statusBarLayerRotatesScales() + fun statusBarWindowIsVisible() { + testSpec.statusBarWindowIsVisible() } @Presubmit @Test - override fun navBarWindowIsAlwaysVisible() { - super.navBarWindowIsAlwaysVisible() + fun statusBarLayerIsVisible() { + testSpec.statusBarLayerIsVisible() + } + + @Presubmit + @Test + fun statusBarLayerRotatesScales() { + testSpec.statusBarLayerRotatesScales( + testSpec.config.startRotation, testSpec.config.endRotation) } @FlakyTest @Test - override fun statusBarLayerIsAlwaysVisible() { - super.statusBarLayerIsAlwaysVisible() + override fun navBarLayerRotatesAndScales() { + super.navBarLayerRotatesAndScales() } companion object { - private const val SCREENSHOT_LAYER = "RotationLayer" - @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<FlickerTestParameter> { diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt index 4b888cd5aad0..612ff9d3a153 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt @@ -17,25 +17,20 @@ package com.android.server.wm.flicker.rotation import android.app.Instrumentation +import android.content.ComponentName import android.platform.test.annotations.Presubmit -import androidx.test.filters.FlakyTest import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.endRotation -import com.android.server.wm.flicker.focusDoesNotChange import com.android.server.wm.flicker.helpers.StandardAppHelper -import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerIsVisible import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible -import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.Test @@ -43,8 +38,6 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter) protected abstract val testApp: StandardAppHelper protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() - protected val startingPos get() = WindowUtils.getDisplayBounds(testSpec.config.startRotation) - protected val endingPos get() = WindowUtils.getDisplayBounds(testSpec.config.endRotation) protected open val transition: FlickerBuilder.(Map<String, Any?>) -> Unit = { setup { @@ -69,19 +62,19 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter) } } - @FlakyTest + @Presubmit @Test - open fun navBarWindowIsAlwaysVisible() { - testSpec.navBarWindowIsAlwaysVisible() + open fun navBarWindowIsVisible() { + testSpec.navBarWindowIsVisible() } - @FlakyTest + @Presubmit @Test - open fun navBarLayerIsAlwaysVisible() { - testSpec.navBarLayerIsAlwaysVisible(rotatesScreen = true) + open fun navBarLayerIsVisible() { + testSpec.navBarLayerIsVisible() } - @FlakyTest + @Presubmit @Test open fun navBarLayerRotatesAndScales() { testSpec.navBarLayerRotatesAndScales( @@ -90,31 +83,12 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter) @Presubmit @Test - open fun statusBarWindowIsAlwaysVisible() { - testSpec.statusBarWindowIsAlwaysVisible() - } - - @FlakyTest - @Test - open fun statusBarLayerIsAlwaysVisible() { - testSpec.statusBarLayerIsAlwaysVisible(rotatesScreen = true) - } - - @FlakyTest - @Test - open fun statusBarLayerRotatesScales() { - testSpec.statusBarLayerRotatesScales( - testSpec.config.startRotation, testSpec.config.endRotation) - } - - @FlakyTest - @Test open fun visibleLayersShownMoreThanOneConsecutiveEntry() { testSpec.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry( - ignoreLayers = listOf(WindowManagerStateHelper.SPLASH_SCREEN_NAME, - WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME, - "SecondaryHomeHandle" + ignoreLayers = listOf(WindowManagerStateHelper.SPLASH_SCREEN_COMPONENT, + WindowManagerStateHelper.SNAPSHOT_COMPONENT, + ComponentName("", "SecondaryHomeHandle") ) ) } @@ -130,22 +104,23 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter) @Presubmit @Test - open fun noUncoveredRegions() { - testSpec.noUncoveredRegions(testSpec.config.startRotation, - testSpec.config.endRotation, allStates = false) - } + open fun entireScreenCovered() = testSpec.entireScreenCovered() @Presubmit @Test open fun focusDoesNotChange() { - testSpec.focusDoesNotChange() + testSpec.assertEventLog { + this.focusDoesNotChange() + } } @Presubmit @Test open fun appLayerRotates_StartingPos() { testSpec.assertLayersStart { - this.visibleRegion(testApp.getPackage()).coversExactly(startingPos) + this.entry.displays.map { display -> + this.visibleRegion(testApp.component).coversExactly(display.layerStackSpace) + } } } @@ -153,7 +128,9 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter) @Test open fun appLayerRotates_EndingPos() { testSpec.assertLayersEnd { - this.visibleRegion(testApp.getPackage()).coversExactly(endingPos) + this.entry.displays.map { display -> + this.visibleRegion(testApp.component).coversExactly(display.layerStackSpace) + } } } }
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt index b153bece1133..48efe73312c3 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt @@ -16,8 +16,8 @@ package com.android.server.wm.flicker.rotation -import android.platform.test.annotations.Postsubmit import android.platform.test.annotations.Presubmit +import android.view.WindowManager import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory @@ -27,6 +27,7 @@ import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -60,42 +61,75 @@ class SeamlessAppRotationTest( } } - @FlakyTest(bugId = 140855415) + @Presubmit @Test - override fun statusBarWindowIsAlwaysVisible() { - super.statusBarWindowIsAlwaysVisible() + fun appWindowFullScreen() { + testSpec.assertWm { + this.invoke("isFullScreen") { + val appWindow = it.windowState(testApp.`package`) + val flags = appWindow.windowState?.attributes?.flags ?: 0 + appWindow.verify("isFullScreen") + .that(flags.and(WindowManager.LayoutParams.FLAG_FULLSCREEN)) + .isGreaterThan(0) + } + } } - @FlakyTest(bugId = 140855415) + @Presubmit @Test - override fun statusBarLayerIsAlwaysVisible() { - super.statusBarLayerIsAlwaysVisible() + fun appWindowSeamlessRotation() { + testSpec.assertWm { + this.invoke("isRotationSeamless") { + val appWindow = it.windowState(testApp.`package`) + val rotationAnimation = appWindow.windowState?.attributes?.rotationAnimation ?: 0 + appWindow.verify("isRotationSeamless") + .that(rotationAnimation + .and(WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS)) + .isGreaterThan(0) + } + } } @Presubmit @Test fun appLayerAlwaysVisible() { testSpec.assertLayers { - isVisible(testApp.`package`) + isVisible(testApp.component) } } - @FlakyTest(bugId = 185400889) + @Presubmit @Test fun appLayerRotates() { testSpec.assertLayers { - this.coversExactly(startingPos, testApp.`package`) - .then() - .coversExactly(endingPos, testApp.`package`) + this.invoke("entireScreenCovered") { entry -> + entry.entry.displays.map { display -> + entry.visibleRegion(testApp.component).coversExactly(display.layerStackSpace) + } + } } } - @Postsubmit + @Presubmit @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() { - super.visibleLayersShownMoreThanOneConsecutiveEntry() + fun statusBarWindowIsAlwaysInvisible() { + testSpec.assertWm { + this.isAboveAppWindowInvisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) + } } + @Presubmit + @Test + fun statusBarLayerIsAlwaysInvisible() { + testSpec.assertLayers { + this.isInvisible(WindowManagerStateHelper.STATUS_BAR_COMPONENT) + } + } + + @FlakyTest + @Test + override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() + companion object { private val testFactory = FlickerTestParameterFactory.getInstance() diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml index 1599ed4b280f..3b9f33aaded1 100644 --- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml @@ -59,5 +59,26 @@ <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> + <activity android:name=".NonResizeableActivity" + android:resizeableActivity="false" + android:taskAffinity="com.android.server.wm.flicker.testapp.NonResizeableActivity" + android:label="NonResizeableApp" + android:exported="true" + android:showOnLockScreen="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + <activity android:name=".ButtonActivity" + android:taskAffinity="com.android.server.wm.flicker.testapp.ButtonActivity" + android:configChanges="orientation|screenSize" + android:label="ButtonActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> </application> </manifest> diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_button.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_button.xml new file mode 100644 index 000000000000..fe7bced690f9 --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_button.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018 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. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/holo_orange_light"> + <Button + android:id="@+id/launch_second_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Second activity" /> +</LinearLayout> diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml index 4708cfd48381..c55e7c2720db 100644 --- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml +++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml @@ -23,5 +23,6 @@ <EditText android:id="@+id/plain_text_input" android:layout_height="wrap_content" android:layout_width="match_parent" + android:imeOptions="flagNoExtractUi" android:inputType="text"/> </LinearLayout> diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml new file mode 100644 index 000000000000..6d5a9dd29248 --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_non_resizeable.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2021 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. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="@android:color/holo_orange_light"> + + <TextView + android:id="@+id/NonResizeableTest" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:gravity="center_vertical|center_horizontal" + android:text="NonResizeableActivity" + android:textAppearance="?android:attr/textAppearanceLarge"/> + +</LinearLayout>
\ No newline at end of file diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java index 0ccc49897202..224d2ac38a11 100644 --- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java @@ -41,4 +41,14 @@ public class ActivityOptions { public static final ComponentName SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME = new ComponentName(FLICKER_APP_PACKAGE, FLICKER_APP_PACKAGE + ".SimpleActivity"); + + public static final String NON_RESIZEABLE_ACTIVITY_LAUNCHER_NAME = "NonResizeableApp"; + public static final ComponentName NON_RESIZEABLE_ACTIVITY_COMPONENT_NAME = + new ComponentName(FLICKER_APP_PACKAGE, + FLICKER_APP_PACKAGE + ".NonResizeableActivity"); + + public static final String BUTTON_ACTIVITY_LAUNCHER_NAME = "ButtonApp"; + public static final ComponentName BUTTON_ACTIVITY_COMPONENT_NAME = + new ComponentName(FLICKER_APP_PACKAGE, + FLICKER_APP_PACKAGE + ".ButtonActivity"); } diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ButtonActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ButtonActivity.java new file mode 100644 index 000000000000..b42ac2a6fd97 --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ButtonActivity.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 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.server.wm.flicker.testapp; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.WindowManager; +import android.widget.Button; + +public class ButtonActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + WindowManager.LayoutParams p = getWindow().getAttributes(); + p.layoutInDisplayCutoutMode = WindowManager.LayoutParams + .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + getWindow().setAttributes(p); + setContentView(R.layout.activity_button); + + Button button = findViewById(R.id.launch_second_activity); + button.setOnClickListener(v -> { + Intent intent = new Intent(ButtonActivity.this, SimpleActivity.class); + startActivity(intent); + }); + } +} diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NonResizeableActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NonResizeableActivity.java new file mode 100644 index 000000000000..61019d8b3716 --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/NonResizeableActivity.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 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.server.wm.flicker.testapp; + +import android.app.Activity; +import android.app.KeyguardManager; +import android.os.Bundle; + +public class NonResizeableActivity extends Activity { + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + setContentView(R.layout.activity_non_resizeable); + + setShowWhenLocked(true); + setTurnScreenOn(true); + KeyguardManager keyguardManager = getSystemService(KeyguardManager.class); + if (keyguardManager != null) { + keyguardManager.requestDismissKeyguard(this, null); + } + } +} diff --git a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java index bcd6ed73e133..824f91e1e826 100644 --- a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java +++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java @@ -45,6 +45,7 @@ public final class FrameworksTestsFilter extends SelectTest { // Test specifications for FrameworksMockingCoreTests. "android.app.activity.ActivityThreadClientTest", "android.view.DisplayTest", + "android.window.ConfigurationHelperTest", // Test specifications for FrameworksCoreTests. "android.app.servertransaction.", // all tests under the package. "android.view.CutoutSpecificationTest", @@ -59,10 +60,8 @@ public final class FrameworksTestsFilter extends SelectTest { "android.view.RoundedCornersTest", "android.view.WindowMetricsTest", "android.view.PendingInsetsControllerTest", - "android.window.WindowContextTest", - "android.window.WindowMetricsHelperTest", + "android.window.", // all tests under the package. "android.app.activity.ActivityThreadTest", - "android.window.WindowContextControllerTest" }; public FrameworksTestsFilter(Bundle testArgs) { |