Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt +24 −35 Original line number Diff line number Diff line Loading @@ -38,50 +38,44 @@ import org.junit.Test /** * Base test class containing common assertions for [ComponentMatcher.NAV_BAR], * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions * (layers visible in consecutive states, entire screen covered, etc.) * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions (layers * visible in consecutive states, entire screen covered, etc.) */ abstract class BaseTest @JvmOverloads constructor( abstract class BaseTest @JvmOverloads constructor( protected val testSpec: FlickerTestParameter, protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), protected val tapl: LauncherInstrumentation = LauncherInstrumentation() ) { init { testSpec.setIsTablet( WindowManagerStateHelper( instrumentation, clearCacheAfterParsing = false ).currentState.wmState.isTablet WindowManagerStateHelper(instrumentation, clearCacheAfterParsing = false) .currentState .wmState .isTablet ) } /** * Specification of the test transition to execute */ /** Specification of the test transition to execute */ abstract val transition: FlickerBuilder.() -> Unit /** * Entry point for the test runner. It will use this method to initialize and cache * flicker executions * 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 { setup { testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet) } setup { testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet) } transition() } } /** * Checks that all parts of the screen are covered during the transition */ /** Checks that all parts of the screen are covered during the transition */ open fun entireScreenCovered() = testSpec.entireScreenCovered() /** * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition */ /** Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition */ @Presubmit @Test open fun navBarLayerIsVisibleAtStartAndEnd() { Loading Loading @@ -111,9 +105,7 @@ abstract class BaseTest @JvmOverloads constructor( testSpec.navBarWindowIsAlwaysVisible() } /** * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition */ /** Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition */ @Presubmit @Test open fun taskBarLayerIsVisibleAtStartAndEnd() { Loading Loading @@ -142,7 +134,8 @@ abstract class BaseTest @JvmOverloads constructor( testSpec.statusBarLayerIsVisibleAtStartAndEnd() /** * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the transition * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the * transition */ @Presubmit @Test Loading @@ -156,26 +149,22 @@ abstract class BaseTest @JvmOverloads constructor( open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() /** * Checks that all layers that are visible on the trace, are visible for at least 2 * consecutive entries. * Checks that all layers that are visible on the trace, are visible for at least 2 consecutive * entries. */ @Presubmit @Test open fun visibleLayersShownMoreThanOneConsecutiveEntry() { testSpec.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() } testSpec.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() } } /** * Checks that all windows that are visible on the trace, are visible for at least 2 * consecutive entries. * Checks that all windows that are visible on the trace, are visible for at least 2 consecutive * entries. */ @Presubmit @Test open fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() } testSpec.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() } } } libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +108 −146 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ @file:JvmName("CommonAssertions") package com.android.wm.shell.flicker import android.view.Surface Loading @@ -26,15 +27,11 @@ import com.android.server.wm.traces.common.IComponentMatcher import com.android.server.wm.traces.common.region.Region fun FlickerTestParameter.appPairsDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } } fun FlickerTestParameter.appPairsDividerIsInvisibleAtEnd() { assertLayersEnd { this.notContains(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } assertLayersEnd { this.notContains(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } } fun FlickerTestParameter.appPairsDividerBecomesVisible() { Loading Loading @@ -82,27 +79,19 @@ fun FlickerTestParameter.splitScreenDismissed( } fun FlickerTestParameter.splitScreenDividerIsVisibleAtStart() { assertLayersStart { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersStart { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerIsInvisibleAtStart() { assertLayersStart { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersStart { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerIsInvisibleAtEnd() { assertLayersEnd { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersEnd { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerBecomesVisible() { Loading @@ -117,40 +106,20 @@ fun FlickerTestParameter.splitScreenDividerBecomesInvisible() { } } fun FlickerTestParameter.layerBecomesVisible( component: IComponentMatcher ) { assertLayers { this.isInvisible(component) .then() .isVisible(component) } fun FlickerTestParameter.layerBecomesVisible(component: IComponentMatcher) { assertLayers { this.isInvisible(component).then().isVisible(component) } } fun FlickerTestParameter.layerBecomesInvisible( component: IComponentMatcher ) { assertLayers { this.isVisible(component) .then() .isInvisible(component) } fun FlickerTestParameter.layerBecomesInvisible(component: IComponentMatcher) { assertLayers { this.isVisible(component).then().isInvisible(component) } } fun FlickerTestParameter.layerIsVisibleAtEnd( component: IComponentMatcher ) { assertLayersEnd { this.isVisible(component) } fun FlickerTestParameter.layerIsVisibleAtEnd(component: IComponentMatcher) { assertLayersEnd { this.isVisible(component) } } fun FlickerTestParameter.layerKeepVisible( component: IComponentMatcher ) { assertLayers { this.isVisible(component) } fun FlickerTestParameter.layerKeepVisible(component: IComponentMatcher) { assertLayers { this.isVisible(component) } } fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible( Loading @@ -164,13 +133,15 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible( .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component)) .then() .splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) } } fun FlickerTestParameter.splitAppLayerBoundsBecomesVisibleByDrag( component: IComponentMatcher ) { fun FlickerTestParameter.splitAppLayerBoundsBecomesVisibleByDrag(component: IComponentMatcher) { assertLayers { this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true) .then() Loading @@ -188,7 +159,11 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesInvisible( ) { assertLayers { this.splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) .then() .isVisible(component, true) .then() Loading Loading @@ -224,15 +199,27 @@ fun FlickerTestParameter.splitAppLayerBoundsChanges( assertLayers { if (landscapePosLeft) { this.splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) } else { this.splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) .then() .isInvisible(component) .then() .splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) } } } Loading @@ -257,14 +244,16 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( val displayBounds = WindowUtils.getDisplayBounds(rotation) return invoke { val dividerRegion = layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(component).coversAtMost( visibleRegion(component) .coversAtMost( if (displayBounds.width > displayBounds.height) { if (landscapePosLeft) { Region.from( 0, 0, (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, displayBounds.bounds.bottom) displayBounds.bounds.bottom ) } else { Region.from( (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, Loading @@ -279,7 +268,8 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( 0, 0, displayBounds.bounds.right, (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2) (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2 ) } else { Region.from( 0, Loading @@ -293,9 +283,7 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( } } fun FlickerTestParameter.appWindowBecomesVisible( component: IComponentMatcher ) { fun FlickerTestParameter.appWindowBecomesVisible(component: IComponentMatcher) { assertWm { this.isAppWindowInvisible(component) .then() Loading @@ -307,60 +295,32 @@ fun FlickerTestParameter.appWindowBecomesVisible( } } fun FlickerTestParameter.appWindowBecomesInvisible( component: IComponentMatcher ) { assertWm { this.isAppWindowVisible(component) .then() .isAppWindowInvisible(component) } fun FlickerTestParameter.appWindowBecomesInvisible(component: IComponentMatcher) { assertWm { this.isAppWindowVisible(component).then().isAppWindowInvisible(component) } } fun FlickerTestParameter.appWindowIsVisibleAtStart( component: IComponentMatcher ) { assertWmStart { this.isAppWindowVisible(component) } fun FlickerTestParameter.appWindowIsVisibleAtStart(component: IComponentMatcher) { assertWmStart { this.isAppWindowVisible(component) } } fun FlickerTestParameter.appWindowIsVisibleAtEnd( component: IComponentMatcher ) { assertWmEnd { this.isAppWindowVisible(component) } fun FlickerTestParameter.appWindowIsVisibleAtEnd(component: IComponentMatcher) { assertWmEnd { this.isAppWindowVisible(component) } } fun FlickerTestParameter.appWindowIsInvisibleAtStart( component: IComponentMatcher ) { assertWmStart { this.isAppWindowInvisible(component) } fun FlickerTestParameter.appWindowIsInvisibleAtStart(component: IComponentMatcher) { assertWmStart { this.isAppWindowInvisible(component) } } fun FlickerTestParameter.appWindowIsInvisibleAtEnd( component: IComponentMatcher ) { assertWmEnd { this.isAppWindowInvisible(component) } fun FlickerTestParameter.appWindowIsInvisibleAtEnd(component: IComponentMatcher) { assertWmEnd { this.isAppWindowInvisible(component) } } fun FlickerTestParameter.appWindowKeepVisible( component: IComponentMatcher ) { assertWm { this.isAppWindowVisible(component) } fun FlickerTestParameter.appWindowKeepVisible(component: IComponentMatcher) { assertWm { this.isAppWindowVisible(component) } } fun FlickerTestParameter.dockedStackDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) } assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) } } fun FlickerTestParameter.dockedStackDividerBecomesVisible() { Loading @@ -380,9 +340,7 @@ fun FlickerTestParameter.dockedStackDividerBecomesInvisible() { } fun FlickerTestParameter.dockedStackDividerNotExistsAtEnd() { assertLayersEnd { this.notContains(DOCKED_STACK_DIVIDER_COMPONENT) } assertLayersEnd { this.notContains(DOCKED_STACK_DIVIDER_COMPONENT) } } fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( Loading @@ -391,8 +349,7 @@ fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(primaryComponent) .overlaps(getPrimaryRegion(dividerRegion, rotation)) visibleRegion(primaryComponent).overlaps(getPrimaryRegion(dividerRegion, rotation)) } } Loading @@ -402,8 +359,7 @@ fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(primaryComponent) .overlaps(getPrimaryRegion(dividerRegion, rotation)) visibleRegion(primaryComponent).overlaps(getPrimaryRegion(dividerRegion, rotation)) } } Loading @@ -413,8 +369,7 @@ fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(secondaryComponent) .overlaps(getSecondaryRegion(dividerRegion, rotation)) visibleRegion(secondaryComponent).overlaps(getSecondaryRegion(dividerRegion, rotation)) } } Loading @@ -424,8 +379,7 @@ fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(secondaryComponent) .overlaps(getSecondaryRegion(dividerRegion, rotation)) visibleRegion(secondaryComponent).overlaps(getSecondaryRegion(dividerRegion, rotation)) } } Loading @@ -433,12 +387,16 @@ fun getPrimaryRegion(dividerRegion: Region, rotation: Int): Region { val displayBounds = WindowUtils.getDisplayBounds(rotation) return if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { Region.from( 0, 0, displayBounds.bounds.right, 0, 0, displayBounds.bounds.right, dividerRegion.bounds.top + WindowUtils.dockedStackDividerInset ) } else { Region.from( 0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset, 0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset, displayBounds.bounds.bottom ) } Loading @@ -448,13 +406,17 @@ fun getSecondaryRegion(dividerRegion: Region, rotation: Int): Region { val displayBounds = WindowUtils.getDisplayBounds(rotation) return if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { Region.from( 0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset, displayBounds.bounds.right, displayBounds.bounds.bottom 0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset, displayBounds.bounds.right, displayBounds.bounds.bottom ) } else { Region.from( dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0, displayBounds.bounds.right, displayBounds.bounds.bottom dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0, displayBounds.bounds.right, displayBounds.bounds.bottom ) } } libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt +5 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ @file:JvmName("CommonConstants") package com.android.wm.shell.flicker import com.android.server.wm.traces.common.ComponentNameMatcher Loading @@ -26,5 +27,8 @@ val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentNameMatcher("", "StageCoordinatorS val SPLIT_DECOR_MANAGER = ComponentNameMatcher("", "SplitDecorManager#") enum class Direction { UP, DOWN, LEFT, RIGHT UP, DOWN, LEFT, RIGHT } libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/MultiWindowUtils.kt +11 −5 Original line number Diff line number Diff line Loading @@ -33,17 +33,23 @@ object MultiWindowUtils { } fun getDevEnableNonResizableMultiWindow(context: Context): Int = Settings.Global.getInt(context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW) Settings.Global.getInt( context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW ) fun setDevEnableNonResizableMultiWindow(context: Context, configValue: Int) = Settings.Global.putInt(context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue) Settings.Global.putInt( context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue ) fun setSupportsNonResizableMultiWindow(instrumentation: Instrumentation, configValue: Int) = executeShellCommand( instrumentation, createConfigSupportsNonResizableMultiWindowCommand(configValue)) createConfigSupportsNonResizableMultiWindowCommand(configValue) ) fun resetMultiWindowConfig(instrumentation: Instrumentation) = executeShellCommand(instrumentation, resetMultiWindowConfigCommand) Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt +11 −13 Original line number Diff line number Diff line Loading @@ -79,25 +79,23 @@ class NotificationListener : NotificationListenerService() { ): StatusBarNotification? { instance?.run { return notifications.values.firstOrNull(predicate) } ?: throw IllegalStateException("NotificationListenerService is not connected") } ?: throw IllegalStateException("NotificationListenerService is not connected") } fun waitForNotificationToAppear( predicate: (StatusBarNotification) -> Boolean ): StatusBarNotification? { instance?.let { return waitForResult(extractor = { it.notifications.values.firstOrNull(predicate) }).second } ?: throw IllegalStateException("NotificationListenerService is not connected") return waitForResult(extractor = { it.notifications.values.firstOrNull(predicate) }) .second } ?: throw IllegalStateException("NotificationListenerService is not connected") } fun waitForNotificationToDisappear( predicate: (StatusBarNotification) -> Boolean ): Boolean { return instance?.let { wait { it.notifications.values.none(predicate) } } ?: throw IllegalStateException("NotificationListenerService is not connected") fun waitForNotificationToDisappear(predicate: (StatusBarNotification) -> Boolean): Boolean { return instance?.let { wait { it.notifications.values.none(predicate) } } ?: throw IllegalStateException("NotificationListenerService is not connected") } } } Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt +24 −35 Original line number Diff line number Diff line Loading @@ -38,50 +38,44 @@ import org.junit.Test /** * Base test class containing common assertions for [ComponentMatcher.NAV_BAR], * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions * (layers visible in consecutive states, entire screen covered, etc.) * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions (layers * visible in consecutive states, entire screen covered, etc.) */ abstract class BaseTest @JvmOverloads constructor( abstract class BaseTest @JvmOverloads constructor( protected val testSpec: FlickerTestParameter, protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), protected val tapl: LauncherInstrumentation = LauncherInstrumentation() ) { init { testSpec.setIsTablet( WindowManagerStateHelper( instrumentation, clearCacheAfterParsing = false ).currentState.wmState.isTablet WindowManagerStateHelper(instrumentation, clearCacheAfterParsing = false) .currentState .wmState .isTablet ) } /** * Specification of the test transition to execute */ /** Specification of the test transition to execute */ abstract val transition: FlickerBuilder.() -> Unit /** * Entry point for the test runner. It will use this method to initialize and cache * flicker executions * 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 { setup { testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet) } setup { testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet) } transition() } } /** * Checks that all parts of the screen are covered during the transition */ /** Checks that all parts of the screen are covered during the transition */ open fun entireScreenCovered() = testSpec.entireScreenCovered() /** * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition */ /** Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition */ @Presubmit @Test open fun navBarLayerIsVisibleAtStartAndEnd() { Loading Loading @@ -111,9 +105,7 @@ abstract class BaseTest @JvmOverloads constructor( testSpec.navBarWindowIsAlwaysVisible() } /** * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition */ /** Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition */ @Presubmit @Test open fun taskBarLayerIsVisibleAtStartAndEnd() { Loading Loading @@ -142,7 +134,8 @@ abstract class BaseTest @JvmOverloads constructor( testSpec.statusBarLayerIsVisibleAtStartAndEnd() /** * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the transition * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the * transition */ @Presubmit @Test Loading @@ -156,26 +149,22 @@ abstract class BaseTest @JvmOverloads constructor( open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() /** * Checks that all layers that are visible on the trace, are visible for at least 2 * consecutive entries. * Checks that all layers that are visible on the trace, are visible for at least 2 consecutive * entries. */ @Presubmit @Test open fun visibleLayersShownMoreThanOneConsecutiveEntry() { testSpec.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() } testSpec.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() } } /** * Checks that all windows that are visible on the trace, are visible for at least 2 * consecutive entries. * Checks that all windows that are visible on the trace, are visible for at least 2 consecutive * entries. */ @Presubmit @Test open fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() } testSpec.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() } } }
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +108 −146 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ @file:JvmName("CommonAssertions") package com.android.wm.shell.flicker import android.view.Surface Loading @@ -26,15 +27,11 @@ import com.android.server.wm.traces.common.IComponentMatcher import com.android.server.wm.traces.common.region.Region fun FlickerTestParameter.appPairsDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } } fun FlickerTestParameter.appPairsDividerIsInvisibleAtEnd() { assertLayersEnd { this.notContains(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } assertLayersEnd { this.notContains(APP_PAIR_SPLIT_DIVIDER_COMPONENT) } } fun FlickerTestParameter.appPairsDividerBecomesVisible() { Loading Loading @@ -82,27 +79,19 @@ fun FlickerTestParameter.splitScreenDismissed( } fun FlickerTestParameter.splitScreenDividerIsVisibleAtStart() { assertLayersStart { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersStart { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerIsInvisibleAtStart() { assertLayersStart { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersStart { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerIsInvisibleAtEnd() { assertLayersEnd { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } assertLayersEnd { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) } } fun FlickerTestParameter.splitScreenDividerBecomesVisible() { Loading @@ -117,40 +106,20 @@ fun FlickerTestParameter.splitScreenDividerBecomesInvisible() { } } fun FlickerTestParameter.layerBecomesVisible( component: IComponentMatcher ) { assertLayers { this.isInvisible(component) .then() .isVisible(component) } fun FlickerTestParameter.layerBecomesVisible(component: IComponentMatcher) { assertLayers { this.isInvisible(component).then().isVisible(component) } } fun FlickerTestParameter.layerBecomesInvisible( component: IComponentMatcher ) { assertLayers { this.isVisible(component) .then() .isInvisible(component) } fun FlickerTestParameter.layerBecomesInvisible(component: IComponentMatcher) { assertLayers { this.isVisible(component).then().isInvisible(component) } } fun FlickerTestParameter.layerIsVisibleAtEnd( component: IComponentMatcher ) { assertLayersEnd { this.isVisible(component) } fun FlickerTestParameter.layerIsVisibleAtEnd(component: IComponentMatcher) { assertLayersEnd { this.isVisible(component) } } fun FlickerTestParameter.layerKeepVisible( component: IComponentMatcher ) { assertLayers { this.isVisible(component) } fun FlickerTestParameter.layerKeepVisible(component: IComponentMatcher) { assertLayers { this.isVisible(component) } } fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible( Loading @@ -164,13 +133,15 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible( .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component)) .then() .splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) } } fun FlickerTestParameter.splitAppLayerBoundsBecomesVisibleByDrag( component: IComponentMatcher ) { fun FlickerTestParameter.splitAppLayerBoundsBecomesVisibleByDrag(component: IComponentMatcher) { assertLayers { this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true) .then() Loading @@ -188,7 +159,11 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesInvisible( ) { assertLayers { this.splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) .then() .isVisible(component, true) .then() Loading Loading @@ -224,15 +199,27 @@ fun FlickerTestParameter.splitAppLayerBoundsChanges( assertLayers { if (landscapePosLeft) { this.splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) } else { this.splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) .then() .isInvisible(component) .then() .splitAppLayerBoundsSnapToDivider( component, landscapePosLeft, portraitPosTop, endRotation) component, landscapePosLeft, portraitPosTop, endRotation ) } } } Loading @@ -257,14 +244,16 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( val displayBounds = WindowUtils.getDisplayBounds(rotation) return invoke { val dividerRegion = layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(component).coversAtMost( visibleRegion(component) .coversAtMost( if (displayBounds.width > displayBounds.height) { if (landscapePosLeft) { Region.from( 0, 0, (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, displayBounds.bounds.bottom) displayBounds.bounds.bottom ) } else { Region.from( (dividerRegion.bounds.left + dividerRegion.bounds.right) / 2, Loading @@ -279,7 +268,8 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( 0, 0, displayBounds.bounds.right, (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2) (dividerRegion.bounds.top + dividerRegion.bounds.bottom) / 2 ) } else { Region.from( 0, Loading @@ -293,9 +283,7 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider( } } fun FlickerTestParameter.appWindowBecomesVisible( component: IComponentMatcher ) { fun FlickerTestParameter.appWindowBecomesVisible(component: IComponentMatcher) { assertWm { this.isAppWindowInvisible(component) .then() Loading @@ -307,60 +295,32 @@ fun FlickerTestParameter.appWindowBecomesVisible( } } fun FlickerTestParameter.appWindowBecomesInvisible( component: IComponentMatcher ) { assertWm { this.isAppWindowVisible(component) .then() .isAppWindowInvisible(component) } fun FlickerTestParameter.appWindowBecomesInvisible(component: IComponentMatcher) { assertWm { this.isAppWindowVisible(component).then().isAppWindowInvisible(component) } } fun FlickerTestParameter.appWindowIsVisibleAtStart( component: IComponentMatcher ) { assertWmStart { this.isAppWindowVisible(component) } fun FlickerTestParameter.appWindowIsVisibleAtStart(component: IComponentMatcher) { assertWmStart { this.isAppWindowVisible(component) } } fun FlickerTestParameter.appWindowIsVisibleAtEnd( component: IComponentMatcher ) { assertWmEnd { this.isAppWindowVisible(component) } fun FlickerTestParameter.appWindowIsVisibleAtEnd(component: IComponentMatcher) { assertWmEnd { this.isAppWindowVisible(component) } } fun FlickerTestParameter.appWindowIsInvisibleAtStart( component: IComponentMatcher ) { assertWmStart { this.isAppWindowInvisible(component) } fun FlickerTestParameter.appWindowIsInvisibleAtStart(component: IComponentMatcher) { assertWmStart { this.isAppWindowInvisible(component) } } fun FlickerTestParameter.appWindowIsInvisibleAtEnd( component: IComponentMatcher ) { assertWmEnd { this.isAppWindowInvisible(component) } fun FlickerTestParameter.appWindowIsInvisibleAtEnd(component: IComponentMatcher) { assertWmEnd { this.isAppWindowInvisible(component) } } fun FlickerTestParameter.appWindowKeepVisible( component: IComponentMatcher ) { assertWm { this.isAppWindowVisible(component) } fun FlickerTestParameter.appWindowKeepVisible(component: IComponentMatcher) { assertWm { this.isAppWindowVisible(component) } } fun FlickerTestParameter.dockedStackDividerIsVisibleAtEnd() { assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) } assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) } } fun FlickerTestParameter.dockedStackDividerBecomesVisible() { Loading @@ -380,9 +340,7 @@ fun FlickerTestParameter.dockedStackDividerBecomesInvisible() { } fun FlickerTestParameter.dockedStackDividerNotExistsAtEnd() { assertLayersEnd { this.notContains(DOCKED_STACK_DIVIDER_COMPONENT) } assertLayersEnd { this.notContains(DOCKED_STACK_DIVIDER_COMPONENT) } } fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( Loading @@ -391,8 +349,7 @@ fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(primaryComponent) .overlaps(getPrimaryRegion(dividerRegion, rotation)) visibleRegion(primaryComponent).overlaps(getPrimaryRegion(dividerRegion, rotation)) } } Loading @@ -402,8 +359,7 @@ fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(primaryComponent) .overlaps(getPrimaryRegion(dividerRegion, rotation)) visibleRegion(primaryComponent).overlaps(getPrimaryRegion(dividerRegion, rotation)) } } Loading @@ -413,8 +369,7 @@ fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(secondaryComponent) .overlaps(getSecondaryRegion(dividerRegion, rotation)) visibleRegion(secondaryComponent).overlaps(getSecondaryRegion(dividerRegion, rotation)) } } Loading @@ -424,8 +379,7 @@ fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisibleAtEnd( ) { assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(secondaryComponent) .overlaps(getSecondaryRegion(dividerRegion, rotation)) visibleRegion(secondaryComponent).overlaps(getSecondaryRegion(dividerRegion, rotation)) } } Loading @@ -433,12 +387,16 @@ fun getPrimaryRegion(dividerRegion: Region, rotation: Int): Region { val displayBounds = WindowUtils.getDisplayBounds(rotation) return if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { Region.from( 0, 0, displayBounds.bounds.right, 0, 0, displayBounds.bounds.right, dividerRegion.bounds.top + WindowUtils.dockedStackDividerInset ) } else { Region.from( 0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset, 0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset, displayBounds.bounds.bottom ) } Loading @@ -448,13 +406,17 @@ fun getSecondaryRegion(dividerRegion: Region, rotation: Int): Region { val displayBounds = WindowUtils.getDisplayBounds(rotation) return if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { Region.from( 0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset, displayBounds.bounds.right, displayBounds.bounds.bottom 0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset, displayBounds.bounds.right, displayBounds.bounds.bottom ) } else { Region.from( dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0, displayBounds.bounds.right, displayBounds.bounds.bottom dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0, displayBounds.bounds.right, displayBounds.bounds.bottom ) } }
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt +5 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ @file:JvmName("CommonConstants") package com.android.wm.shell.flicker import com.android.server.wm.traces.common.ComponentNameMatcher Loading @@ -26,5 +27,8 @@ val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentNameMatcher("", "StageCoordinatorS val SPLIT_DECOR_MANAGER = ComponentNameMatcher("", "SplitDecorManager#") enum class Direction { UP, DOWN, LEFT, RIGHT UP, DOWN, LEFT, RIGHT }
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/MultiWindowUtils.kt +11 −5 Original line number Diff line number Diff line Loading @@ -33,17 +33,23 @@ object MultiWindowUtils { } fun getDevEnableNonResizableMultiWindow(context: Context): Int = Settings.Global.getInt(context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW) Settings.Global.getInt( context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW ) fun setDevEnableNonResizableMultiWindow(context: Context, configValue: Int) = Settings.Global.putInt(context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue) Settings.Global.putInt( context.contentResolver, Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, configValue ) fun setSupportsNonResizableMultiWindow(instrumentation: Instrumentation, configValue: Int) = executeShellCommand( instrumentation, createConfigSupportsNonResizableMultiWindowCommand(configValue)) createConfigSupportsNonResizableMultiWindowCommand(configValue) ) fun resetMultiWindowConfig(instrumentation: Instrumentation) = executeShellCommand(instrumentation, resetMultiWindowConfigCommand) Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt +11 −13 Original line number Diff line number Diff line Loading @@ -79,25 +79,23 @@ class NotificationListener : NotificationListenerService() { ): StatusBarNotification? { instance?.run { return notifications.values.firstOrNull(predicate) } ?: throw IllegalStateException("NotificationListenerService is not connected") } ?: throw IllegalStateException("NotificationListenerService is not connected") } fun waitForNotificationToAppear( predicate: (StatusBarNotification) -> Boolean ): StatusBarNotification? { instance?.let { return waitForResult(extractor = { it.notifications.values.firstOrNull(predicate) }).second } ?: throw IllegalStateException("NotificationListenerService is not connected") return waitForResult(extractor = { it.notifications.values.firstOrNull(predicate) }) .second } ?: throw IllegalStateException("NotificationListenerService is not connected") } fun waitForNotificationToDisappear( predicate: (StatusBarNotification) -> Boolean ): Boolean { return instance?.let { wait { it.notifications.values.none(predicate) } } ?: throw IllegalStateException("NotificationListenerService is not connected") fun waitForNotificationToDisappear(predicate: (StatusBarNotification) -> Boolean): Boolean { return instance?.let { wait { it.notifications.values.none(predicate) } } ?: throw IllegalStateException("NotificationListenerService is not connected") } } }