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 0000000000000..19fefb93b4876 --- /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/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt new file mode 100644 index 0000000000000..70a79d1aeb70f --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt @@ -0,0 +1,119 @@ +/* + * 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.Postsubmit +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.startRotation +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) + } + } + } + + @Postsubmit + @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) + } + } + + @Postsubmit + @Test + fun entireScreenCovered() { + testSpec.entireScreenCovered(testSpec.config.startRotation) + } + + @Postsubmit + @Test + fun launcherWindowNotVisible() { + testSpec.assertWm { + this.isAppWindowInvisible(LAUNCHER_COMPONENT, ignoreActivity = true) + } + } + + @Postsubmit + @Test + fun launcherLayerNotVisible() { + testSpec.assertLayers { this.isInvisible(LAUNCHER_COMPONENT) } + } + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests(repetitions = 5) + } + } +} diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml index 6f853c36ffd2a..3b9f33aaded18 100644 --- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml @@ -70,5 +70,15 @@ + + + + + + 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 0000000000000..fe7bced690f9e --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_button.xml @@ -0,0 +1,27 @@ + + + +