diff options
46 files changed, 2490 insertions, 2439 deletions
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp index baff952edc72..070dacbcd91f 100644 --- a/tests/FlickerTests/Android.bp +++ b/tests/FlickerTests/Android.bp @@ -16,7 +16,7 @@ android_test { name: "FlickerTests", - srcs: ["src/**/*.java"], + srcs: ["src/**/*.java", "src/**/*.kt"], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", platform_apis: true, diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java deleted file mode 100644 index ed6f33e62031..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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; - -import static android.view.Surface.rotationToString; - -import static com.android.server.wm.flicker.CommonTransitions.changeAppRotation; -import static com.android.server.wm.flicker.WindowUtils.getAppPosition; -import static com.android.server.wm.flicker.WindowUtils.getNavigationBarPosition; -import static com.android.server.wm.flicker.WindowUtils.getStatusBarPosition; -import static com.android.server.wm.flicker.WmTraceSubject.assertThat; - -import android.graphics.Rect; -import android.util.Log; -import android.view.Surface; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Cycle through supported app rotations. - * To run this test: {@code atest FlickerTest:ChangeAppRotationTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class ChangeAppRotationTest extends FlickerTestBase { - private int mBeginRotation; - private int mEndRotation; - - public ChangeAppRotationTest(String beginRotationName, String endRotationName, - int beginRotation, int endRotation) { - this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - this.mBeginRotation = beginRotation; - this.mEndRotation = endRotation; - } - - @Parameters(name = "{0}-{1}") - public static Collection<Object[]> getParams() { - int[] supportedRotations = - {Surface.ROTATION_0, Surface.ROTATION_90}; - Collection<Object[]> params = new ArrayList<>(); - for (int begin : supportedRotations) { - for (int end : supportedRotations) { - if (begin != end) { - params.add(new Object[]{rotationToString(begin), rotationToString(end), begin, - end}); - } - } - } - return params; - } - - @Override - TransitionRunner getTransitionToRun() { - return changeAppRotation(mTestApp, mUiDevice, mBeginRotation, mEndRotation) - .includeJankyRuns().build(); - } - - @FlakyTest(bugId = 140855415) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_navBarWindowIsAlwaysVisible() { - checkResults(result -> assertThat(result) - .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @FlakyTest(bugId = 140855415) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_statusBarWindowIsAlwaysVisible() { - checkResults(result -> assertThat(result) - .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test - public void checkPosition_navBarLayerRotatesAndScales() { - Rect startingPos = getNavigationBarPosition(mBeginRotation); - Rect endingPos = getNavigationBarPosition(mEndRotation); - checkResults(result -> { - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos) - .inTheBeginning(); - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos).atTheEnd(); - } - ); - } - - @Test - public void checkPosition_appLayerRotates() { - Rect startingPos = getAppPosition(mBeginRotation); - Rect endingPos = getAppPosition(mEndRotation); - Log.e(TAG, "startingPos=" + startingPos + " endingPos=" + endingPos); - checkResults(result -> { - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(mTestApp.getPackage(), startingPos).inTheBeginning(); - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(mTestApp.getPackage(), endingPos).atTheEnd(); - } - ); - } - - @Test - public void checkPosition_statusBarLayerScales() { - Rect startingPos = getStatusBarPosition(mBeginRotation); - Rect endingPos = getStatusBarPosition(mEndRotation); - checkResults(result -> { - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos) - .inTheBeginning(); - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd(); - } - ); - } - - @Ignore("Flaky. Pending debug") - @Test - public void checkVisibility_screenshotLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(mTestApp.getPackage()) - .then() - .replaceVisibleLayer(mTestApp.getPackage(), SCREENSHOT_LAYER) - .then() - .showsLayer(mTestApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER) - .then() - .replaceVisibleLayer(SCREENSHOT_LAYER, mTestApp.getPackage()) - .forAllEntries()); - } - - @FlakyTest(bugId = 140855415) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_navBarLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @FlakyTest(bugId = 140855415) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_statusBarLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java deleted file mode 100644 index 58dcb9948c85..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2019 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; - -import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test IME window closing back to app window transitions. - * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CloseImeAutoOpenWindowToAppTest extends CloseImeWindowToAppTest { - - public CloseImeAutoOpenWindowToAppTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation()); - } - - @Override - TransitionRunner getTransitionToRun() { - return editTextLoseFocusToApp((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @FlakyTest(bugId = 141458352) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_imeLayerBecomesInvisible() { - super.checkVisibility_imeLayerBecomesInvisible(); - } - - @FlakyTest(bugId = 141458352) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_imeAppLayerIsAlwaysVisible() { - super.checkVisibility_imeAppLayerIsAlwaysVisible(); - } - - @FlakyTest(bugId = 141458352) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_imeAppWindowIsAlwaysVisible() { - super.checkVisibility_imeAppWindowIsAlwaysVisible(); - } - -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java deleted file mode 100644 index 7f610a695e7e..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2019 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; - -import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test IME window closing back to app window transitions. - * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CloseImeAutoOpenWindowToHomeTest extends CloseImeWindowToHomeTest { - - public CloseImeAutoOpenWindowToHomeTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation()); - } - - @Override - TransitionRunner getTransitionToRun() { - return editTextLoseFocusToHome((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @FlakyTest(bugId = 141458352) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_imeWindowBecomesInvisible() { - super.checkVisibility_imeWindowBecomesInvisible(); - } - - @FlakyTest(bugId = 141458352) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_imeLayerBecomesInvisible() { - super.checkVisibility_imeLayerBecomesInvisible(); - } - - @FlakyTest(bugId = 157449248) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_imeAppWindowBecomesInvisible() { - super.checkVisibility_imeAppWindowBecomesInvisible(); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java deleted file mode 100644 index 57ad7e76e540..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.ImeAppHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test IME window closing back to app window transitions. - * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CloseImeWindowToAppTest extends NonRotationTestBase { - - static final String IME_WINDOW_TITLE = "InputMethod"; - - public CloseImeWindowToAppTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); - } - - @Override - TransitionRunner getTransitionToRun() { - return editTextLoseFocusToApp((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Ignore("Flaky. Pending debug") - @Test - public void checkVisibility_imeLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(IME_WINDOW_TITLE) - .then() - .hidesLayer(IME_WINDOW_TITLE) - .forAllEntries()); - } - - @Test - public void checkVisibility_imeAppLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(mTestApp.getPackage()) - .forAllEntries()); - } - - @Test - public void checkVisibility_imeAppWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAppWindowOnTop(mTestApp.getPackage()) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java deleted file mode 100644 index 12d11794c1bd..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.ImeAppHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test IME window closing to home transitions. - * To run this test: {@code atest FlickerTests:CloseImeWindowToHomeTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CloseImeWindowToHomeTest extends NonRotationTestBase { - - static final String IME_WINDOW_TITLE = "InputMethod"; - - public CloseImeWindowToHomeTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); - } - - @Override - TransitionRunner getTransitionToRun() { - return editTextLoseFocusToHome((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Test - public void checkVisibility_imeWindowBecomesInvisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsImeWindow(IME_WINDOW_TITLE) - .then() - .hidesImeWindow(IME_WINDOW_TITLE) - .forAllEntries()); - } - - @FlakyTest(bugId = 153739621) - @Ignore - @Test - public void checkVisibility_imeLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .skipUntilFirstAssertion() - .showsLayer(IME_WINDOW_TITLE) - .then() - .hidesLayer(IME_WINDOW_TITLE) - .forAllEntries()); - } - - @FlakyTest(bugId = 153739621) - @Ignore - @Test - public void checkVisibility_imeAppLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .skipUntilFirstAssertion() - .showsLayer(mTestApp.getPackage()) - .then() - .hidesLayer(mTestApp.getPackage()) - .forAllEntries()); - } - - @Test - public void checkVisibility_imeAppWindowBecomesInvisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAppWindowOnTop(mTestApp.getPackage()) - .then() - .hidesAppWindowOnTop(mTestApp.getPackage()) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java deleted file mode 100644 index b1854c3294de..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * 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; - -import static android.os.SystemClock.sleep; -import static android.view.Surface.rotationToString; - -import static com.android.server.wm.flicker.helpers.AutomationUtils.clearRecents; -import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen; -import static com.android.server.wm.flicker.helpers.AutomationUtils.expandPipWindow; -import static com.android.server.wm.flicker.helpers.AutomationUtils.launchSplitScreen; -import static com.android.server.wm.flicker.helpers.AutomationUtils.stopPackage; - -import android.app.Instrumentation; -import android.content.Context; -import android.content.Intent; -import android.os.RemoteException; -import android.platform.helpers.IAppHelper; -import android.util.Rational; -import android.view.Surface; - -import androidx.annotation.Nullable; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder; -import com.android.server.wm.flicker.helpers.AutomationUtils; -import com.android.server.wm.flicker.helpers.ImeAppHelper; -import com.android.server.wm.flicker.helpers.PipAppHelper; - -/** - * Collection of common transitions which can be used to test different apps or scenarios. - */ -class CommonTransitions { - - public static final int ITERATIONS = 1; - private static final String TAG = "FLICKER"; - private static final long APP_LAUNCH_TIMEOUT = 10000; - - private static void setRotation(UiDevice device, int rotation) { - try { - switch (rotation) { - case Surface.ROTATION_270: - device.setOrientationLeft(); - break; - - case Surface.ROTATION_90: - device.setOrientationRight(); - break; - - case Surface.ROTATION_0: - default: - device.setOrientationNatural(); - } - // Wait for animation to complete - sleep(1000); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Build a test tag for the test - * @param testName Name of the transition(s) being tested - * @param app App being launcher - * @param rotation Initial screen rotation - * - * @return test tag with pattern <NAME>__<APP>__<ROTATION> - */ - private static String buildTestTag(String testName, IAppHelper app, int rotation) { - return buildTestTag( - testName, app, /* app2 */ null, rotation, rotation, /* description */ ""); - } - - /** - * Build a test tag for the test - * @param testName Name of the transition(s) being tested - * @param app App being launcher - * @param beginRotation Initial screen rotation - * @param endRotation End screen rotation (if any, otherwise use same as initial) - * - * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION> - */ - private static String buildTestTag(String testName, IAppHelper app, int beginRotation, - int endRotation) { - return buildTestTag( - testName, app, /* app2 */ null, beginRotation, endRotation, /* description */ ""); - } - - /** - * Build a test tag for the test - * @param testName Name of the transition(s) being tested - * @param app App being launcher - * @param app2 Second app being launched (if any) - * @param beginRotation Initial screen rotation - * @param endRotation End screen rotation (if any, otherwise use same as initial) - * @param extraInfo Additional information to append to the tag - * - * @return test tag with pattern <NAME>__<APP(S)>__<ROTATION(S)>[__<EXTRA>] - */ - private static String buildTestTag(String testName, IAppHelper app, @Nullable IAppHelper app2, - int beginRotation, int endRotation, String extraInfo) { - StringBuilder testTag = new StringBuilder(); - testTag.append(testName) - .append("__") - .append(app.getLauncherName()); - - if (app2 != null) { - testTag.append("-") - .append(app2.getLauncherName()); - } - - testTag.append("__") - .append(rotationToString(beginRotation)); - - if (endRotation != beginRotation) { - testTag.append("-") - .append(rotationToString(endRotation)); - } - - if (!extraInfo.isEmpty()) { - testTag.append("__") - .append(extraInfo); - } - - return testTag.toString(); - } - - static TransitionBuilder openAppWarm(IAppHelper testApp, UiDevice - device, int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("openAppWarm", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBeforeAll(() -> setRotation(device, beginRotation)) - .runBeforeAll(testApp::open) - .runBefore(device::pressHome) - .runBefore(device::waitForIdle) - .runBefore(() -> setRotation(device, beginRotation)) - .run(testApp::open) - .runAfterAll(testApp::exit) - .runAfterAll(AutomationUtils::setDefaultWait) - .repeat(ITERATIONS); - } - - static TransitionBuilder closeAppWithBackKey(IAppHelper testApp, UiDevice - device, int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("closeAppWithBackKey", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(testApp::open) - .runBefore(device::waitForIdle) - .run(device::pressBack) - .run(device::waitForIdle) - .runAfterAll(testApp::exit) - .runAfterAll(AutomationUtils::setDefaultWait) - .repeat(ITERATIONS); - } - - static TransitionBuilder closeAppWithHomeKey(IAppHelper testApp, UiDevice - device, int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("closeAppWithHomeKey", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(testApp::open) - .runBefore(device::waitForIdle) - .run(device::pressHome) - .run(device::waitForIdle) - .runAfterAll(testApp::exit) - .runAfterAll(AutomationUtils::setDefaultWait) - .repeat(ITERATIONS); - } - - static TransitionBuilder openAppCold(IAppHelper testApp, - UiDevice device, int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("openAppCold", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBeforeAll(() -> setRotation(device, beginRotation)) - .runBefore(testApp::exit) - .runBefore(device::waitForIdle) - .run(testApp::open) - .runAfterAll(testApp::exit) - .runAfterAll(() -> setRotation(device, Surface.ROTATION_0)) - .repeat(ITERATIONS); - } - - static TransitionBuilder changeAppRotation(IAppHelper testApp, UiDevice - device, int beginRotation, int endRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("changeAppRotation", testApp, beginRotation, endRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBeforeAll(testApp::open) - .runBefore(() -> setRotation(device, beginRotation)) - .run(() -> setRotation(device, endRotation)) - .runAfterAll(testApp::exit) - .runAfterAll(() -> setRotation(device, Surface.ROTATION_0)) - .repeat(ITERATIONS); - } - - static TransitionBuilder changeAppRotation(Intent intent, String intentId, Context context, - UiDevice device, int beginRotation, int endRotation) { - final String testTag = "changeAppRotation_" + intentId + "_" + - rotationToString(beginRotation) + "_" + rotationToString(endRotation); - return TransitionRunner.newBuilder() - .withTag(testTag) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBeforeAll(() -> { - context.startActivity(intent); - device.wait(Until.hasObject(By.pkg(intent.getComponent() - .getPackageName()).depth(0)), APP_LAUNCH_TIMEOUT); - } - ) - .runBefore(() -> setRotation(device, beginRotation)) - .run(() -> setRotation(device, endRotation)) - .runAfterAll(() -> stopPackage(context, intent.getComponent().getPackageName())) - .runAfterAll(() -> setRotation(device, Surface.ROTATION_0)) - .repeat(ITERATIONS); - } - - static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBeforeAll(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .runBefore(device::waitForIdle) - .runBefore(() -> sleep(500)) - .run(() -> launchSplitScreen(device)) - .runAfter(() -> exitSplitScreen(device)) - .runAfterAll(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder splitScreenToLauncher(IAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBeforeAll(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .runBefore(device::waitForIdle) - .runBefore(() -> launchSplitScreen(device)) - .run(() -> exitSplitScreen(device)) - .runAfterAll(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder editTextSetFocus(ImeAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("editTextSetFocus", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBefore(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .run(() -> testApp.openIME(device)) - .runAfterAll(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder resizeSplitScreen(Instrumentation instr, IAppHelper testAppTop, - ImeAppHelper testAppBottom, UiDevice device, int beginRotation, Rational startRatio, - Rational stopRatio) { - String description = startRatio.toString().replace("/", "-") + "_to_" - + stopRatio.toString().replace("/", "-"); - String testTag = buildTestTag("resizeSplitScreen", testAppTop, testAppBottom, - beginRotation, beginRotation, description); - return TransitionRunner.newBuilder() - .withTag(testTag) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBeforeAll(() -> setRotation(device, beginRotation)) - .runBeforeAll(() -> clearRecents(instr)) - .runBefore(testAppBottom::open) - .runBefore(device::pressHome) - .runBefore(testAppTop::open) - .runBefore(device::waitForIdle) - .runBefore(() -> launchSplitScreen(device)) - .runBefore(() -> { - UiObject2 snapshot = device.findObject( - By.res(device.getLauncherPackageName(), "snapshot")); - snapshot.click(); - }) - .runBefore(() -> testAppBottom.openIME(device)) - .runBefore(device::pressBack) - .runBefore(() -> AutomationUtils.resizeSplitScreen(device, startRatio)) - .run(() -> AutomationUtils.resizeSplitScreen(device, stopRatio)) - .runAfter(() -> exitSplitScreen(device)) - .runAfter(device::pressHome) - .runAfterAll(testAppTop::exit) - .runAfterAll(testAppBottom::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder editTextLoseFocusToHome(ImeAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("editTextLoseFocusToHome", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBefore(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .runBefore(() -> testApp.openIME(device)) - .run(device::pressHome) - .run(device::waitForIdle) - .runAfterAll(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder editTextLoseFocusToApp(ImeAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("editTextLoseFocusToApp", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBefore(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .runBefore(() -> testApp.openIME(device)) - .run(device::pressBack) - .run(device::waitForIdle) - .runAfterAll(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("enterPipMode", testApp, beginRotation)) - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBefore(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .run(() -> testApp.clickEnterPipButton(device)) - .runAfter(() -> testApp.closePipWindow(device)) - .runAfterAll(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("exitPipModeToHome", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBefore(() -> setRotation(device, beginRotation)) - .runBefore(testApp::open) - .run(() -> testApp.clickEnterPipButton(device)) - .run(() -> testApp.closePipWindow(device)) - .run(device::waitForIdle) - .run(testApp::exit) - .repeat(ITERATIONS); - } - - static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device, - int beginRotation) { - return TransitionRunner.newBuilder() - .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation)) - .recordAllRuns() - .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .run(device::pressHome) - .run(() -> setRotation(device, beginRotation)) - .run(testApp::open) - .run(() -> testApp.clickEnterPipButton(device)) - .run(() -> expandPipWindow(device)) - .run(device::waitForIdle) - .run(testApp::exit) - .repeat(ITERATIONS); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt new file mode 100644 index 000000000000..b69e6a9736a3 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt @@ -0,0 +1,446 @@ +/* + * 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 + +import android.app.Instrumentation +import android.content.Context +import android.content.Intent +import android.os.RemoteException +import android.os.SystemClock +import android.platform.helpers.IAppHelper +import android.util.Rational +import android.view.Surface +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import com.android.server.wm.flicker.helpers.AutomationUtils +import com.android.server.wm.flicker.helpers.ImeAppHelper +import com.android.server.wm.flicker.helpers.PipAppHelper + +/** + * Collection of common transitions which can be used to test different apps or scenarios. + */ +internal object CommonTransitions { + private const val ITERATIONS = 1 + private const val APP_LAUNCH_TIMEOUT: Long = 10000 + private fun setRotation(device: UiDevice, rotation: Int) { + try { + when (rotation) { + Surface.ROTATION_270 -> device.setOrientationLeft() + Surface.ROTATION_90 -> device.setOrientationRight() + Surface.ROTATION_0 -> device.setOrientationNatural() + else -> device.setOrientationNatural() + } + // Wait for animation to complete + SystemClock.sleep(1000) + } catch (e: RemoteException) { + throw RuntimeException(e) + } + } + + /** + * Build a test tag for the test + * @param testName Name of the transition(s) being tested + * @param app App being launcher + * @param rotation Initial screen rotation + * + * @return test tag with pattern <NAME>__<APP>__<ROTATION> + </ROTATION></APP></NAME> */ + private fun buildTestTag(testName: String, app: IAppHelper, rotation: Int): String { + return buildTestTag( + testName, app, rotation, rotation, app2 = null, extraInfo = "") + } + + /** + * Build a test tag for the test + * @param testName Name of the transition(s) being tested + * @param app App being launcher + * @param beginRotation Initial screen rotation + * @param endRotation End screen rotation (if any, otherwise use same as initial) + * + * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION> + </END_ROTATION></BEGIN_ROTATION></APP></NAME> */ + private fun buildTestTag( + testName: String, + app: IAppHelper, + beginRotation: Int, + endRotation: Int + ): String { + return buildTestTag( + testName, app, beginRotation, endRotation, app2 = null, extraInfo = "") + } + + /** + * Build a test tag for the test + * @param testName Name of the transition(s) being tested + * @param app App being launcher + * @param app2 Second app being launched (if any) + * @param beginRotation Initial screen rotation + * @param endRotation End screen rotation (if any, otherwise use same as initial) + * @param extraInfo Additional information to append to the tag + * + * @return test tag with pattern <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>] + </EXTRA></NAME> */ + private fun buildTestTag( + testName: String, + app: IAppHelper, + beginRotation: Int, + endRotation: Int, + app2: IAppHelper?, + extraInfo: String + ): String { + val testTag = StringBuilder() + testTag.append(testName) + .append("__") + .append(app.launcherName) + if (app2 != null) { + testTag.append("-") + .append(app2.launcherName) + } + testTag.append("__") + .append(Surface.rotationToString(beginRotation)) + if (endRotation != beginRotation) { + testTag.append("-") + .append(Surface.rotationToString(endRotation)) + } + if (extraInfo.isNotEmpty()) { + testTag.append("__") + .append(extraInfo) + } + return testTag.toString() + } + + fun openAppWarm( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("openAppWarm", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBeforeAll { setRotation(device, beginRotation) } + .runBeforeAll { testApp.open() } + .runBefore { device.pressHome() } + .runBefore { device.waitForIdle() } + .runBefore { setRotation(device, beginRotation) } + .run { testApp.open() } + .runAfterAll { testApp.exit() } + .runAfterAll { AutomationUtils.setDefaultWait() } + .repeat(ITERATIONS) + } + + fun closeAppWithBackKey( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("closeAppWithBackKey", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { testApp.open() } + .runBefore { device.waitForIdle() } + .run { device.pressBack() } + .run { device.waitForIdle() } + .runAfterAll { testApp.exit() } + .runAfterAll { AutomationUtils.setDefaultWait() } + .repeat(ITERATIONS) + } + + fun closeAppWithHomeKey( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("closeAppWithHomeKey", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { testApp.open() } + .runBefore { device.waitForIdle() } + .run { device.pressHome() } + .run { device.waitForIdle() } + .runAfterAll { testApp.exit() } + .runAfterAll { AutomationUtils.setDefaultWait() } + .repeat(ITERATIONS) + } + + fun openAppCold( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("openAppCold", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { device.pressHome() } + .runBeforeAll { setRotation(device, beginRotation) } + .runBefore { testApp.exit() } + .runBefore { device.waitForIdle() } + .run { testApp.open() } + .runAfterAll { testApp.exit() } + .runAfterAll { setRotation(device, Surface.ROTATION_0) } + .repeat(ITERATIONS) + } + + fun changeAppRotation( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int, + endRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("changeAppRotation", testApp, beginRotation, endRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBeforeAll { testApp.open() } + .runBefore { setRotation(device, beginRotation) } + .run { setRotation(device, endRotation) } + .runAfterAll { testApp.exit() } + .runAfterAll { setRotation(device, Surface.ROTATION_0) } + .repeat(ITERATIONS) + } + + fun changeAppRotation( + intent: Intent, + intentId: String, + context: Context, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int, + endRotation: Int + ): TransitionRunner.TransitionBuilder { + val testTag = "changeAppRotation_" + intentId + "_" + + Surface.rotationToString(beginRotation) + "_" + + Surface.rotationToString(endRotation) + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(testTag) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBeforeAll { + context.startActivity(intent) + device.wait(Until.hasObject(By.pkg(intent.component?.packageName) + .depth(0)), APP_LAUNCH_TIMEOUT) + } + .runBefore { setRotation(device, beginRotation) } + .run { setRotation(device, endRotation) } + .runAfterAll { AutomationUtils.stopPackage(context, intent.component?.packageName) } + .runAfterAll { setRotation(device, Surface.ROTATION_0) } + .repeat(ITERATIONS) + } + + fun appToSplitScreen( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBeforeAll { setRotation(device, beginRotation) } + .runBefore { testApp.open() } + .runBefore { device.waitForIdle() } + .runBefore { SystemClock.sleep(500) } + .run { AutomationUtils.launchSplitScreen(device) } + .runAfter { AutomationUtils.exitSplitScreen(device) } + .runAfterAll { testApp.exit() } + .repeat(ITERATIONS) + } + + fun splitScreenToLauncher( + testApp: IAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { testApp.open() } + .runBefore { device.waitForIdle() } + .runBefore { AutomationUtils.launchSplitScreen(device) } + .run { AutomationUtils.exitSplitScreen(device) } + .runAfterAll { testApp.exit() } + .repeat(ITERATIONS) + } + + fun editTextSetFocus( + testApp: ImeAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("editTextSetFocus", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { device.pressHome() } + .runBefore { setRotation(device, beginRotation) } + .runBefore { testApp.open() } + .run { testApp.openIME(device) } + .runAfterAll { testApp.exit() } + .repeat(ITERATIONS) + } + + fun resizeSplitScreen( + testAppTop: IAppHelper, + testAppBottom: ImeAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int, + startRatio: Rational, + stopRatio: Rational + ): TransitionRunner.TransitionBuilder { + val description = (startRatio.toString().replace("/", "-") + "_to_" + + stopRatio.toString().replace("/", "-")) + val testTag = buildTestTag("resizeSplitScreen", testAppTop, beginRotation, + beginRotation, testAppBottom, description) + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(testTag) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBeforeAll { setRotation(device, beginRotation) } + .runBeforeAll { AutomationUtils.clearRecents(instrumentation) } + .runBefore { testAppBottom.open() } + .runBefore { device.pressHome() } + .runBefore { testAppTop.open() } + .runBefore { device.waitForIdle() } + .runBefore { AutomationUtils.launchSplitScreen(device) } + .runBefore { + val snapshot = device.findObject( + By.res(device.launcherPackageName, "snapshot")) + snapshot.click() + } + .runBefore { testAppBottom.openIME(device) } + .runBefore { device.pressBack() } + .runBefore { AutomationUtils.resizeSplitScreen(device, startRatio) } + .run { AutomationUtils.resizeSplitScreen(device, stopRatio) } + .runAfter { AutomationUtils.exitSplitScreen(device) } + .runAfter { device.pressHome() } + .runAfterAll { testAppTop.exit() } + .runAfterAll { testAppBottom.exit() } + .repeat(ITERATIONS) + } + + fun editTextLoseFocusToHome( + testApp: ImeAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("editTextLoseFocusToHome", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { device.pressHome() } + .runBefore { setRotation(device, beginRotation) } + .runBefore { testApp.open() } + .runBefore { testApp.openIME(device) } + .run { device.pressHome() } + .run { device.waitForIdle() } + .runAfterAll { testApp.exit() } + .repeat(ITERATIONS) + } + + fun editTextLoseFocusToApp( + testApp: ImeAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("editTextLoseFocusToApp", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { device.pressHome() } + .runBefore { setRotation(device, beginRotation) } + .runBefore { testApp.open() } + .runBefore { testApp.openIME(device) } + .run { device.pressBack() } + .run { device.waitForIdle() } + .runAfterAll { testApp.exit() } + .repeat(ITERATIONS) + } + + fun enterPipMode( + testApp: PipAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("enterPipMode", testApp, beginRotation)) + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { device.pressHome() } + .runBefore { setRotation(device, beginRotation) } + .runBefore { testApp.open() } + .run { testApp.clickEnterPipButton(device) } + .runAfter { testApp.closePipWindow(device) } + .runAfterAll { testApp.exit() } + .repeat(ITERATIONS) + } + + fun exitPipModeToHome( + testApp: PipAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("exitPipModeToHome", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .runBefore { device.pressHome() } + .runBefore { setRotation(device, beginRotation) } + .runBefore { testApp.open() } + .run { testApp.clickEnterPipButton(device) } + .run { testApp.closePipWindow(device) } + .run { device.waitForIdle() } + .run { testApp.exit() } + .repeat(ITERATIONS) + } + + fun exitPipModeToApp( + testApp: PipAppHelper, + instrumentation: Instrumentation, + device: UiDevice, + beginRotation: Int + ): TransitionRunner.TransitionBuilder { + return TransitionRunner.TransitionBuilder(instrumentation) + .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation)) + .recordAllRuns() + .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() } + .run { device.pressHome() } + .run { setRotation(device, beginRotation) } + .run { testApp.open() } + .run { testApp.clickEnterPipButton(device) } + .run { AutomationUtils.expandPipWindow(device) } + .run { device.waitForIdle() } + .run { testApp.exit() } + .repeat(ITERATIONS) + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java deleted file mode 100644 index dec5680e17f5..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 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; - -import android.app.Instrumentation; -import android.platform.helpers.IAppHelper; -import android.util.Rational; -import android.view.Surface; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.UiDevice; - -import com.android.server.wm.flicker.helpers.ImeAppHelper; -import com.android.server.wm.flicker.helpers.PipAppHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -/** - * Tests to help debug individual transitions, capture video recordings and create test cases. - */ -@LargeTest -@Ignore("Used for debugging transitions used in FlickerTests.") -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class DebugTest { - private IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - private UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - - /** - * atest FlickerTests:DebugTest#openAppCold - */ - @Test - public void openAppCold() { - CommonTransitions.openAppCold(testApp, uiDevice, Surface.ROTATION_0) - .recordAllRuns().build().run(); - } - - /** - * atest FlickerTests:DebugTest#openAppWarm - */ - @Test - public void openAppWarm() { - CommonTransitions.openAppWarm(testApp, uiDevice, Surface.ROTATION_0) - .recordAllRuns().build().run(); - } - - /** - * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft - */ - @Test - public void changeOrientationFromNaturalToLeft() { - CommonTransitions.changeAppRotation(testApp, uiDevice, Surface.ROTATION_0, - Surface.ROTATION_270).recordAllRuns().build().run(); - } - - /** - * atest FlickerTests:DebugTest#closeAppWithBackKey - */ - @Test - public void closeAppWithBackKey() { - CommonTransitions.closeAppWithBackKey(testApp, uiDevice, Surface.ROTATION_0) - .recordAllRuns().build().run(); - } - - /** - * atest FlickerTests:DebugTest#closeAppWithHomeKey - */ - @Test - public void closeAppWithHomeKey() { - CommonTransitions.closeAppWithHomeKey(testApp, uiDevice, Surface.ROTATION_0) - .recordAllRuns().build().run(); - } - - /** - * atest FlickerTests:DebugTest#openAppToSplitScreen - */ - @Test - public void openAppToSplitScreen() { - CommonTransitions.appToSplitScreen(testApp, uiDevice, - Surface.ROTATION_0).includeJankyRuns().recordAllRuns() - .build().run(); - } - - /** - * atest FlickerTests:DebugTest#splitScreenToLauncher - */ - @Test - public void splitScreenToLauncher() { - CommonTransitions.splitScreenToLauncher(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns().recordAllRuns().build().run(); - } - - /** - * atest FlickerTests:DebugTest#resizeSplitScreen - */ - @Test - public void resizeSplitScreen() { - Instrumentation instr = InstrumentationRegistry.getInstrumentation(); - ImeAppHelper bottomApp = new ImeAppHelper(instr); - CommonTransitions.resizeSplitScreen(instr, testApp, bottomApp, uiDevice, Surface.ROTATION_0, - new Rational(1, 3), new Rational(2, 3)) - .includeJankyRuns().build().run(); - } - - // IME tests - - /** - * atest FlickerTests:DebugTest#editTextSetFocus - */ - @Test - public void editTextSetFocus() { - ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns() - .build().run(); - } - - /** - * atest FlickerTests:DebugTest#editTextLoseFocusToHome - */ - @Test - public void editTextLoseFocusToHome() { - ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns() - .build().run(); - } - - /** - * atest FlickerTests:DebugTest#editTextLoseFocusToApp - */ - @Test - public void editTextLoseFocusToApp() { - ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns() - .build().run(); - } - - // PIP tests - - /** - * atest FlickerTests:DebugTest#enterPipMode - */ - @Test - public void enterPipMode() { - PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.enterPipMode(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns() - .build().run(); - } - - /** - * atest FlickerTests:DebugTest#exitPipModeToHome - */ - @Test - public void exitPipModeToHome() { - PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.exitPipModeToHome(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns() - .build().run(); - } - - /** - * atest FlickerTests:DebugTest#exitPipModeToApp - */ - @Test - public void exitPipModeToApp() { - PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.exitPipModeToApp(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns() - .build().run(); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt new file mode 100644 index 000000000000..f871ea59ea71 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt @@ -0,0 +1,188 @@ +/* + * 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 + +import android.platform.helpers.IAppHelper +import android.util.Rational +import android.view.Surface +import androidx.test.InstrumentationRegistry +import androidx.test.filters.LargeTest +import androidx.test.runner.AndroidJUnit4 +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.helpers.ImeAppHelper +import com.android.server.wm.flicker.helpers.PipAppHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters + +/** + * Tests to help debug individual transitions, capture video recordings and create test cases. + */ +@LargeTest +@Ignore("Used for debugging transitions used in FlickerTests.") +@RunWith(AndroidJUnit4::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class DebugTest { + private val instrumentation = InstrumentationRegistry.getInstrumentation() + private val testApp: IAppHelper = StandardAppHelper(instrumentation, + "com.android.server.wm.flicker.testapp", "SimpleApp") + private val uiDevice = UiDevice.getInstance(instrumentation) + + /** + * atest FlickerTests:DebugTest#openAppCold + */ + @Test + fun openAppCold() { + CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, Surface.ROTATION_0) + .recordAllRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#openAppWarm + */ + @Test + fun openAppWarm() { + CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, Surface.ROTATION_0) + .recordAllRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft + */ + @Test + fun changeOrientationFromNaturalToLeft() { + CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice, Surface.ROTATION_0, + Surface.ROTATION_270).recordAllRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#closeAppWithBackKey + */ + @Test + fun closeAppWithBackKey() { + CommonTransitions.closeAppWithBackKey(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).recordAllRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#closeAppWithHomeKey + */ + @Test + fun closeAppWithHomeKey() { + CommonTransitions.closeAppWithHomeKey(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).recordAllRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#openAppToSplitScreen + */ + @Test + fun openAppToSplitScreen() { + CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).includeJankyRuns().recordAllRuns() + .build().run() + } + + /** + * atest FlickerTests:DebugTest#splitScreenToLauncher + */ + @Test + fun splitScreenToLauncher() { + CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).includeJankyRuns().recordAllRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#resizeSplitScreen + */ + @Test + fun resizeSplitScreen() { + val bottomApp = ImeAppHelper(instrumentation) + CommonTransitions.resizeSplitScreen( + testApp, + bottomApp, + instrumentation, + uiDevice, + Surface.ROTATION_0, + Rational(1, 3), Rational(2, 3) + ).includeJankyRuns().build().run() + } + // IME tests + /** + * atest FlickerTests:DebugTest#editTextSetFocus + */ + @Test + fun editTextSetFocus() { + val testApp = ImeAppHelper(instrumentation) + CommonTransitions.editTextSetFocus(testApp, instrumentation, uiDevice, Surface.ROTATION_0) + .includeJankyRuns() + .build().run() + } + + /** + * atest FlickerTests:DebugTest#editTextLoseFocusToHome + */ + @Test + fun editTextLoseFocusToHome() { + val testApp = ImeAppHelper(instrumentation) + CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).includeJankyRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#editTextLoseFocusToApp + */ + @Test + fun editTextLoseFocusToApp() { + val testApp = ImeAppHelper(instrumentation) + CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).includeJankyRuns().build().run() + } + // PIP tests + /** + * atest FlickerTests:DebugTest#enterPipMode + */ + @Test + fun enterPipMode() { + val testApp = PipAppHelper(instrumentation) + CommonTransitions.enterPipMode(testApp, instrumentation, uiDevice, Surface.ROTATION_0) + .includeJankyRuns().build().run() + } + + /** + * atest FlickerTests:DebugTest#exitPipModeToHome + */ + @Test + fun exitPipModeToHome() { + val testApp = PipAppHelper(instrumentation) + CommonTransitions.exitPipModeToHome(testApp, instrumentation, uiDevice, Surface.ROTATION_0) + .includeJankyRuns() + .build().run() + } + + /** + * atest FlickerTests:DebugTest#exitPipModeToApp + */ + @Test + fun exitPipModeToApp() { + val testApp = PipAppHelper(instrumentation) + CommonTransitions.exitPipModeToApp(testApp, instrumentation, uiDevice, Surface.ROTATION_0) + .includeJankyRuns().build().run() + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java deleted file mode 100644 index 6bbf684d567f..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.helpers.AutomationUtils.setDefaultWait; - -import static com.google.common.truth.Truth.assertWithMessage; - -import android.platform.helpers.IAppHelper; -import android.util.Log; - -import androidx.test.InstrumentationRegistry; -import androidx.test.uiautomator.UiDevice; - -import com.android.server.wm.flicker.TransitionRunner.TransitionResult; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; - -import java.util.HashMap; -import java.util.List; -import java.util.function.Consumer; - -/** - * Base class of all Flicker test that performs common functions for all flicker tests: - * <p> - * - Caches transitions so that a transition is run once and the transition results are used by - * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods - * multiple times. - * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed. - * - Fails tests if results are not available for any test due to jank. - */ -public abstract class FlickerTestBase { - public static final String TAG = "FLICKER"; - static final String SCREENSHOT_LAYER = "RotationLayer"; - static final String NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"; - static final String STATUS_BAR_WINDOW_TITLE = "StatusBar"; - static final String DOCKED_STACK_DIVIDER = "DockedStackDivider"; - private static HashMap<String, List<TransitionResult>> transitionResults = - new HashMap<>(); - IAppHelper mTestApp; - UiDevice mUiDevice; - private List<TransitionResult> mResults; - private TransitionResult mLastResult = null; - - @Before - public void setUp() { - mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - } - - /** - * Teardown any system settings and clean up test artifacts from the file system. - * - * Note: test artifacts for failed tests will remain on the device. - */ - @AfterClass - public static void teardown() { - setDefaultWait(); - transitionResults.values().stream() - .flatMap(List::stream) - .forEach(result -> { - if (result.canDelete()) { - result.delete(); - } else { - if (result.layersTraceExists()) { - Log.e(TAG, "Layers trace saved to " + result.getLayersTracePath()); - } - if (result.windowManagerTraceExists()) { - Log.e(TAG, "WindowManager trace saved to " + result - .getWindowManagerTracePath - ()); - } - if (result.screenCaptureVideoExists()) { - Log.e(TAG, "Screen capture video saved to " + result - .screenCaptureVideoPath().toString()); - } - } - }); - } - - /** - * Runs a transition, returns a cached result if the transition has run before. - */ - void run(TransitionRunner transition) { - if (transitionResults.containsKey(transition.getTestTag())) { - mResults = transitionResults.get(transition.getTestTag()); - return; - } - mResults = transition.run().getResults(); - /* Fail if we don't have any results due to jank */ - assertWithMessage("No results to test because all transition runs were invalid because " - + "of Jank").that(mResults).isNotEmpty(); - transitionResults.put(transition.getTestTag(), mResults); - } - - /** - * Runs a transition, returns a cached result if the transition has run before. - */ - @Before - public void runTransition() { - run(getTransitionToRun()); - } - - /** - * Gets the transition that will be executed - */ - abstract TransitionRunner getTransitionToRun(); - - /** - * Goes through a list of transition results and checks assertions on each result. - */ - void checkResults(Consumer<TransitionResult> assertion) { - - for (TransitionResult result : mResults) { - mLastResult = result; - assertion.accept(result); - } - mLastResult = null; - } - - /** - * Kludge to mark a file for saving. If {@code checkResults} fails, the last result is not - * cleared. This indicates the assertion failed for the result, so mark it for saving. - */ - @After - public void markArtifactsForSaving() { - if (mLastResult != null) { - mLastResult.flagForSaving(); - } - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt new file mode 100644 index 000000000000..d7586d0db915 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt @@ -0,0 +1,137 @@ +/* + * 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 + +import android.platform.helpers.IAppHelper +import android.util.Log +import androidx.test.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.helpers.AutomationUtils +import com.google.common.truth.Truth +import org.junit.After +import org.junit.AfterClass +import org.junit.Before + +/** + * Base class of all Flicker test that performs common functions for all flicker tests: + * + * + * - Caches transitions so that a transition is run once and the transition results are used by + * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods + * multiple times. + * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed. + * - Fails tests if results are not available for any test due to jank. + */ +abstract class FlickerTestBase { + lateinit var testApp: IAppHelper + open val instrumentation by lazy { + InstrumentationRegistry.getInstrumentation() + } + val uiDevice by lazy { + UiDevice.getInstance(instrumentation) + } + lateinit var tesults: List<TransitionResult> + private var lastResult: TransitionResult? = null + + /** + * Runs a transition, returns a cached result if the transition has run before. + */ + fun run(transition: TransitionRunner) { + if (transitionResults.containsKey(transition.testTag)) { + tesults = transitionResults[transition.testTag] + ?: throw IllegalStateException("Results do not contain test tag " + + transition.testTag) + return + } + tesults = transition.run().results + /* Fail if we don't have any results due to jank */ + Truth.assertWithMessage("No results to test because all transition runs were invalid " + + "because of Jank").that(tesults).isNotEmpty() + transitionResults[transition.testTag] = tesults + } + + /** + * Runs a transition, returns a cached result if the transition has run before. + */ + @Before + fun runTransition() { + run(transitionToRun) + } + + /** + * Gets the transition that will be executed + */ + abstract val transitionToRun: TransitionRunner + + /** + * Goes through a list of transition results and checks assertions on each result. + */ + fun checkResults(assertion: (TransitionResult) -> Unit) { + for (result in tesults) { + lastResult = result + assertion(result) + } + lastResult = null + } + + /** + * Kludge to mark a file for saving. If `checkResults` fails, the last result is not + * cleared. This indicates the assertion failed for the result, so mark it for saving. + */ + @After + fun markArtifactsForSaving() { + lastResult?.flagForSaving() + } + + companion object { + const val TAG = "FLICKER" + const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar" + const val STATUS_BAR_WINDOW_TITLE = "StatusBar" + const val DOCKED_STACK_DIVIDER = "DockedStackDivider" + private val transitionResults = mutableMapOf<String, List<TransitionResult>>() + + /** + * Teardown any system settings and clean up test artifacts from the file system. + * + * Note: test artifacts for failed tests will remain on the device. + */ + @AfterClass + @JvmStatic + fun teardown() { + AutomationUtils.setDefaultWait() + transitionResults.values + .flatten() + .forEach { + if (it.canDelete()) { + it.delete() + } else { + if (it.layersTraceExists()) { + Log.e(TAG, "Layers trace saved to ${it.layersTracePath}") + } + if (it.windowManagerTraceExists()) { + Log.e(TAG, + "WindowManager trace saved to ${it.windowManagerTracePath}") + } + if (it.screenCaptureVideoExists()) { + Log.e(TAG, + "Screen capture video saved to ${it.screenCaptureVideoPath()}") + } + } + } + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java deleted file mode 100644 index 54941dc0f585..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2019 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; - -import static android.view.Surface.rotationToString; - -import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds; - -import android.graphics.Rect; -import android.view.Surface; - -import androidx.test.filters.FlakyTest; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runners.Parameterized.Parameters; - -import java.util.ArrayList; -import java.util.Collection; - -public abstract class NonRotationTestBase extends FlickerTestBase { - - int mBeginRotation; - - public NonRotationTestBase(String beginRotationName, int beginRotation) { - this.mBeginRotation = beginRotation; - } - - @Parameters(name = "{0}") - public static Collection<Object[]> getParams() { - int[] supportedRotations = - {Surface.ROTATION_0, Surface.ROTATION_90}; - Collection<Object[]> params = new ArrayList<>(); - - for (int begin : supportedRotations) { - params.add(new Object[]{rotationToString(begin), begin}); - } - - return params; - } - - @FlakyTest(bugId = 141361128) - @Ignore("Waiting bug feedback") - @Test - public void checkCoveredRegion_noUncoveredRegions() { - Rect displayBounds = getDisplayBounds(mBeginRotation); - checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion( - displayBounds).forAllEntries()); - } - - @FlakyTest(bugId = 141361128) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_navBarLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @FlakyTest(bugId = 141361128) - @Ignore("Waiting bug feedback") - @Test - public void checkVisibility_statusBarLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt new file mode 100644 index 000000000000..653fecd5219f --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt @@ -0,0 +1,72 @@ +/* + * 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 + +import android.view.Surface +import androidx.test.filters.FlakyTest +import org.junit.Ignore +import org.junit.Test +import org.junit.runners.Parameterized + +abstract class NonRotationTestBase( + beginRotationName: String, + protected val beginRotation: Int +) : FlickerTestBase() { + @FlakyTest(bugId = 141361128) + @Ignore("Waiting bug feedback") + @Test + fun checkCoveredRegion_noUncoveredRegions() { + val displayBounds = WindowUtils.getDisplayBounds(beginRotation) + checkResults { + LayersTraceSubject.assertThat(it).coversRegion( + displayBounds).forAllEntries() + } + } + + @FlakyTest(bugId = 141361128) + @Ignore("Waiting bug feedback") + @Test + fun checkVisibility_navBarLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @FlakyTest(bugId = 141361128) + @Ignore("Waiting bug feedback") + @Test + fun checkVisibility_statusBarLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries() + } + } + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<Array<Any>> { + val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90) + val params: MutableCollection<Array<Any>> = ArrayList() + for (begin in supportedRotations) { + params.add(arrayOf(Surface.rotationToString(begin), begin)) + } + return params + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java deleted file mode 100644 index c150e0994316..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.openAppCold; -import static com.android.server.wm.flicker.WmTraceSubject.assertThat; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test cold launch app from launcher. - * To run this test: {@code atest FlickerTests:OpenAppColdTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OpenAppColdTest extends NonRotationTestBase { - - public OpenAppColdTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - } - - @Override - TransitionRunner getTransitionToRun() { - return openAppCold(mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Test - public void checkVisibility_wallpaperWindowBecomesInvisible() { - checkResults(result -> assertThat(result) - .showsBelowAppWindow("Wallpaper") - .then() - .hidesBelowAppWindow("Wallpaper") - .forAllEntries()); - } - - @FlakyTest(bugId = 140855415) - @Ignore("Waiting bug feedback") - @Test - public void checkZOrder_appWindowReplacesLauncherAsTopWindow() { - checkResults(result -> assertThat(result) - .showsAppWindowOnTop( - "com.android.launcher3/.Launcher") - .then() - .showsAppWindowOnTop(mTestApp.getPackage()) - .forAllEntries()); - } - - @Test - public void checkVisibility_wallpaperLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer("Wallpaper") - .then() - .replaceVisibleLayer("Wallpaper", mTestApp.getPackage()) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java deleted file mode 100644 index 00da62fe2ee5..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.appToSplitScreen; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test open app to split screen. - * To run this test: {@code atest FlickerTests:OpenAppToSplitScreenTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OpenAppToSplitScreenTest extends NonRotationTestBase { - - public OpenAppToSplitScreenTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - } - - @Override - TransitionRunner getTransitionToRun() { - return appToSplitScreen(mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns() - .build(); - } - - @Test - public void checkVisibility_navBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test - public void checkVisibility_statusBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test - public void checkVisibility_dividerLayerBecomesVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .hidesLayer(DOCKED_STACK_DIVIDER) - .then() - .showsLayer(DOCKED_STACK_DIVIDER) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java deleted file mode 100644 index 62ae254709b1..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.openAppWarm; -import static com.android.server.wm.flicker.WmTraceSubject.assertThat; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test warm launch app. - * To run this test: {@code atest FlickerTests:OpenAppWarmTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OpenAppWarmTest extends NonRotationTestBase { - - public OpenAppWarmTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - } - - @Override - TransitionRunner getTransitionToRun() { - return openAppWarm(mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Test - public void checkVisibility_wallpaperBecomesInvisible() { - checkResults(result -> assertThat(result) - .showsBelowAppWindow("Wallpaper") - .then() - .hidesBelowAppWindow("Wallpaper") - .forAllEntries()); - } - - @FlakyTest(bugId = 140855415) - @Ignore("Waiting bug feedback") - @Test - public void checkZOrder_appWindowReplacesLauncherAsTopWindow() { - checkResults(result -> assertThat(result) - .showsAppWindowOnTop( - "com.android.launcher3/.Launcher") - .then() - .showsAppWindowOnTop(mTestApp.getPackage()) - .forAllEntries()); - } - - @Test - public void checkVisibility_wallpaperLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer("Wallpaper") - .then() - .replaceVisibleLayer("Wallpaper", mTestApp.getPackage()) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java deleted file mode 100644 index fcb022c280da..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.editTextSetFocus; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.ImeAppHelper; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test IME window opening transitions. - * To run this test: {@code atest FlickerTests:OpenImeWindowTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OpenImeWindowTest extends NonRotationTestBase { - - private static final String IME_WINDOW_TITLE = "InputMethod"; - - public OpenImeWindowTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); - } - - @Override - TransitionRunner getTransitionToRun() { - return editTextSetFocus((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Test - public void checkVisibility_imeWindowBecomesVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .skipUntilFirstAssertion() - .hidesImeWindow(IME_WINDOW_TITLE) - .then() - .showsImeWindow(IME_WINDOW_TITLE) - .forAllEntries()); - } - - @Test - public void checkVisibility_imeLayerBecomesVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .hidesLayer(IME_WINDOW_TITLE) - .then() - .showsLayer(IME_WINDOW_TITLE) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java deleted file mode 100644 index cf51d780d7d2..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java +++ /dev/null @@ -1,75 +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; - -import static com.android.server.wm.flicker.helpers.AutomationUtils.closePipWindow; -import static com.android.server.wm.flicker.helpers.AutomationUtils.hasPipWindow; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; -import androidx.test.uiautomator.UiDevice; - -import com.android.server.wm.flicker.helpers.PipAppHelper; - -import org.junit.AfterClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public abstract class PipTestBase extends NonRotationTestBase { - static final String sPipWindowTitle = "PipMenuActivity"; - - public PipTestBase(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - - this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - } - - @AfterClass - public static void teardown() { - UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - - if (hasPipWindow(device)) { - closePipWindow(device); - } - } - - @Test - public void checkVisibility_pipWindowBecomesVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .skipUntilFirstAssertion() - .showsAppWindowOnTop(sPipWindowTitle) - .then() - .hidesAppWindow(sPipWindowTitle) - .forAllEntries()); - } - - @Test - public void checkVisibility_pipLayerBecomesVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .skipUntilFirstAssertion() - .showsLayer(sPipWindowTitle) - .then() - .hidesLayer(sPipWindowTitle) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java deleted file mode 100644 index 5e67ada5ff55..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2019 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; - -import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToApp; - -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.PipAppHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test Pip launch. - * To run this test: {@code atest FlickerTests:PipToAppTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@FlakyTest(bugId = 152738416) -@Ignore("Waiting bug feedback") -public class PipToAppTest extends PipTestBase { - public PipToAppTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - } - - @Override - TransitionRunner getTransitionToRun() { - return exitPipModeToApp((PipAppHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Test - public void checkVisibility_backgroundWindowVisibleBehindPipLayer() { - checkResults(result -> WmTraceSubject.assertThat(result) - .skipUntilFirstAssertion() - .showsAppWindowOnTop(sPipWindowTitle) - .then() - .showsBelowAppWindow("Wallpaper") - .then() - .showsAppWindowOnTop(mTestApp.getPackage()) - .then() - .hidesAppWindowOnTop(mTestApp.getPackage()) - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java deleted file mode 100644 index af713c7b39b7..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2019 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; - -import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToHome; - -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import com.android.server.wm.flicker.helpers.PipAppHelper; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -/** - * Test Pip launch. - * To run this test: {@code atest FlickerTests:PipToHomeTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@FlakyTest(bugId = 152738416) -@Ignore("Waiting bug feedback") -public class PipToHomeTest extends PipTestBase { - public PipToHomeTest(String beginRotationName, int beginRotation) { - super(beginRotationName, beginRotation); - } - - @Override - TransitionRunner getTransitionToRun() { - return exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, mBeginRotation) - .includeJankyRuns().build(); - } - - @Ignore - @Test - public void checkVisibility_backgroundWindowVisibleBehindPipLayer() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAppWindowOnTop(sPipWindowTitle) - .then() - .showsBelowAppWindow("Wallpaper") - .then() - .showsAppWindowOnTop("Wallpaper") - .forAllEntries()); - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java deleted file mode 100644 index 9516af624f6f..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.resizeSplitScreen; -import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds; -import static com.android.server.wm.flicker.WindowUtils.getDockedStackDividerInset; -import static com.android.server.wm.flicker.WindowUtils.getNavigationBarHeight; -import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen; -import static com.android.server.wm.flicker.helpers.AutomationUtils.isInSplitScreen; - -import static com.google.common.truth.Truth.assertThat; - -import android.app.Instrumentation; -import android.graphics.Rect; -import android.util.Rational; -import android.view.Surface; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.UiDevice; - -import com.android.server.wm.flicker.helpers.ImeAppHelper; - -import org.junit.AfterClass; -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -/** - * Test split screen resizing window transitions. - * To run this test: {@code atest FlickerTests:ResizeSplitScreenTest} - * - * Currently it runs only in 0 degrees because of b/156100803 - */ -@LargeTest -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@FlakyTest(bugId = 159096424) -@Ignore("Waiting bug feedback") -public class ResizeSplitScreenTest extends FlickerTestBase { - - private static String sSimpleActivity = "SimpleActivity"; - private static String sImeActivity = "ImeActivity"; - - public ResizeSplitScreenTest() { - this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - } - - @Override - TransitionRunner getTransitionToRun() { - Instrumentation instr = InstrumentationRegistry.getInstrumentation(); - ImeAppHelper bottomApp = new ImeAppHelper(instr); - return resizeSplitScreen(instr, mTestApp, bottomApp, mUiDevice, Surface.ROTATION_0, - new Rational(1, 3), new Rational(2, 3)) - .includeJankyRuns().build(); - } - - @Test - public void checkVisibility_topAppLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(sSimpleActivity) - .forAllEntries()); - } - - @Test - public void checkVisibility_bottomAppLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(sImeActivity) - .forAllEntries()); - } - - @Test - public void checkVisibility_dividerLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(DOCKED_STACK_DIVIDER) - .forAllEntries()); - } - - @Test - @Ignore("Waiting feedback") - public void checkPosition_appsStartingBounds() { - Rect displayBounds = getDisplayBounds(); - checkResults(result -> { - LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(), - result.getLayersTracePath(), result.getLayersTraceChecksum()); - - assertThat(entries.getEntries()).isNotEmpty(); - Rect startingDividerBounds = entries.getEntries().get(0).getVisibleBounds - (DOCKED_STACK_DIVIDER); - - Rect startingTopAppBounds = new Rect(0, 0, startingDividerBounds.right, - startingDividerBounds.top + getDockedStackDividerInset()); - - Rect startingBottomAppBounds = new Rect(0, - startingDividerBounds.bottom - getDockedStackDividerInset(), - displayBounds.right, - displayBounds.bottom - getNavigationBarHeight()); - - LayersTraceSubject.assertThat(result) - .hasVisibleRegion("SimpleActivity", startingTopAppBounds) - .inTheBeginning(); - - LayersTraceSubject.assertThat(result) - .hasVisibleRegion("ImeActivity", startingBottomAppBounds) - .inTheBeginning(); - }); - } - - @Test - @Ignore("Waiting feedback") - public void checkPosition_appsEndingBounds() { - Rect displayBounds = getDisplayBounds(); - checkResults(result -> { - LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(), - result.getLayersTracePath(), result.getLayersTraceChecksum()); - - assertThat(entries.getEntries()).isNotEmpty(); - Rect endingDividerBounds = entries.getEntries().get( - entries.getEntries().size() - 1).getVisibleBounds( - DOCKED_STACK_DIVIDER); - - Rect startingTopAppBounds = new Rect(0, 0, endingDividerBounds.right, - endingDividerBounds.top + getDockedStackDividerInset()); - - Rect startingBottomAppBounds = new Rect(0, - endingDividerBounds.bottom - getDockedStackDividerInset(), - displayBounds.right, - displayBounds.bottom - getNavigationBarHeight()); - - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(sSimpleActivity, startingTopAppBounds) - .atTheEnd(); - - LayersTraceSubject.assertThat(result) - .hasVisibleRegion(sImeActivity, startingBottomAppBounds) - .atTheEnd(); - }); - } - - @Test - public void checkVisibility_navBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE) - .forAllEntries()); - } - - @Test - public void checkVisibility_statusBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE) - .forAllEntries()); - } - - @Test - @FlakyTest(bugId = 156223549) - @Ignore("Waiting bug feedback") - public void checkVisibility_topAppWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAppWindow(sSimpleActivity) - .forAllEntries()); - } - - @Test - @FlakyTest(bugId = 156223549) - @Ignore("Waiting bug feedback") - public void checkVisibility_bottomAppWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAppWindow(sImeActivity) - .forAllEntries()); - } - - @AfterClass - public static void teardown() { - UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - - if (isInSplitScreen(device)) { - exitSplitScreen(device); - } - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt new file mode 100644 index 000000000000..873d60771cb4 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt @@ -0,0 +1,131 @@ +/* + * 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 + +import android.view.Surface +import androidx.test.filters.FlakyTest +import org.junit.Ignore +import org.junit.Test +import org.junit.runners.Parameterized + +abstract class RotationTestBase( + beginRotationName: String, + endRotationName: String, + protected val beginRotation: Int, + protected val endRotation: Int +) : FlickerTestBase() { + @FlakyTest(bugId = 140855415) + @Ignore("Waiting bug feedback") + @Test + fun checkVisibility_navBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @FlakyTest(bugId = 140855415) + @Ignore("Waiting bug feedback") + @Test + fun checkVisibility_statusBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @Test + fun checkPosition_navBarLayerRotatesAndScales() { + val startingPos = WindowUtils.getNavigationBarPosition(beginRotation) + val endingPos = WindowUtils.getNavigationBarPosition(endRotation) + if (startingPos == endingPos) { + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos) + .forAllEntries() + } + } else { + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos) + .inTheBeginning() + } + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos) + .atTheEnd() + } + } + } + + @Test + fun checkPosition_statusBarLayerRotatesScales() { + val startingPos = WindowUtils.getStatusBarPosition(beginRotation) + val endingPos = WindowUtils.getStatusBarPosition(endRotation) + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos) + .inTheBeginning() + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd() + } + } + + @FlakyTest(bugId = 140855415) + @Ignore("Waiting bug feedback") + @Test + fun checkVisibility_navBarLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @FlakyTest(bugId = 140855415) + @Ignore("Waiting bug feedback") + @Test + fun checkVisibility_statusBarLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries() + } + } + + companion object { + const val SCREENSHOT_LAYER = "RotationLayer" + + @Parameterized.Parameters(name = "{0}-{1}") + @JvmStatic + fun getParams(): Collection<Array<Any>> { + val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90) + val params: MutableCollection<Array<Any>> = mutableListOf() + for (begin in supportedRotations) { + for (end in supportedRotations) { + if (begin != end) { + params.add(arrayOf( + Surface.rotationToString(begin), + Surface.rotationToString(end), + begin, + end + )) + } + } + } + return params + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java deleted file mode 100644 index 3cff8683eca5..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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; - -import static android.view.Surface.rotationToString; - -import static com.android.server.wm.flicker.CommonTransitions.changeAppRotation; -import static com.android.server.wm.flicker.WindowUtils.getAppPosition; -import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds; -import static com.android.server.wm.flicker.WindowUtils.getNavigationBarPosition; -import static com.android.server.wm.flicker.testapp.ActivityOptions.EXTRA_STARVE_UI_THREAD; -import static com.android.server.wm.flicker.testapp.ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME; - -import android.content.Intent; -import android.graphics.Rect; -import android.view.Surface; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.LargeTest; - -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Cycle through supported app rotations using seamless rotations. - * To run this test: {@code atest FlickerTests:SeamlessAppRotationTest} - */ -@LargeTest -@RunWith(Parameterized.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@FlakyTest(bugId = 147659548) -@Ignore("Waiting bug feedback") -public class SeamlessAppRotationTest extends FlickerTestBase { - private int mBeginRotation; - private int mEndRotation; - private Intent mIntent; - - public SeamlessAppRotationTest(String testId, Intent intent, int beginRotation, - int endRotation) { - this.mIntent = intent; - this.mBeginRotation = beginRotation; - this.mEndRotation = endRotation; - } - - @Parameters(name = "{0}") - public static Collection<Object[]> getParams() { - int[] supportedRotations = - {Surface.ROTATION_0, Surface.ROTATION_90}; - Collection<Object[]> params = new ArrayList<>(); - - ArrayList<Intent> testIntents = new ArrayList<>(); - - // launch test activity that supports seamless rotation - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setComponent(SEAMLESS_ACTIVITY_COMPONENT_NAME); - testIntents.add(intent); - - // launch test activity that supports seamless rotation with a busy UI thread to miss frames - // when the app is asked to redraw - intent = new Intent(intent); - intent.putExtra(EXTRA_STARVE_UI_THREAD, true); - testIntents.add(intent); - - for (Intent testIntent : testIntents) { - for (int begin : supportedRotations) { - for (int end : supportedRotations) { - if (begin != end) { - String testId = rotationToString(begin) + "_" + rotationToString(end); - if (testIntent.getExtras() != null && - testIntent.getExtras().getBoolean(EXTRA_STARVE_UI_THREAD)) { - testId += "_" + "BUSY_UI_THREAD"; - } - params.add(new Object[]{testId, testIntent, begin, end}); - } - } - } - } - return params; - } - - @Override - TransitionRunner getTransitionToRun() { - String intentId = ""; - if (mIntent.getExtras() != null && - mIntent.getExtras().getBoolean(EXTRA_STARVE_UI_THREAD)) { - intentId = "BUSY_UI_THREAD"; - } - - return changeAppRotation(mIntent, intentId, InstrumentationRegistry.getContext(), - mUiDevice, mBeginRotation, mEndRotation).build(); - } - - @Test - public void checkVisibility_navBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test - public void checkPosition_navBarLayerRotatesAndScales() { - Rect startingPos = getNavigationBarPosition(mBeginRotation); - Rect endingPos = getNavigationBarPosition(mEndRotation); - if (startingPos.equals(endingPos)) { - checkResults(result -> LayersTraceSubject.assertThat(result) - .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos) - .forAllEntries()); - } else { - checkResults(result -> LayersTraceSubject.assertThat(result) - .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos) - .inTheBeginning()); - checkResults(result -> LayersTraceSubject.assertThat(result) - .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos) - .atTheEnd()); - } - } - - @Test - public void checkPosition_appLayerRotates() { - Rect startingPos = getAppPosition(mBeginRotation); - Rect endingPos = getAppPosition(mEndRotation); - if (startingPos.equals(endingPos)) { - checkResults(result -> LayersTraceSubject.assertThat(result) - .hasVisibleRegion(mIntent.getComponent().getPackageName(), startingPos) - .forAllEntries()); - } else { - checkResults(result -> LayersTraceSubject.assertThat(result) - .hasVisibleRegion(mIntent.getComponent().getPackageName(), startingPos) - .then() - .hasVisibleRegion(mIntent.getComponent().getPackageName(), endingPos) - .forAllEntries()); - } - } - - @Test - public void checkCoveredRegion_noUncoveredRegions() { - Rect startingBounds = getDisplayBounds(mBeginRotation); - Rect endingBounds = getDisplayBounds(mEndRotation); - if (startingBounds.equals(endingBounds)) { - checkResults(result -> - LayersTraceSubject.assertThat(result) - .coversRegion(startingBounds) - .forAllEntries()); - } else { - checkResults(result -> - LayersTraceSubject.assertThat(result) - .coversRegion(startingBounds) - .then() - .coversRegion(endingBounds) - .forAllEntries()); - } - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java deleted file mode 100644 index 9e9c82903b51..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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; - -import static com.android.server.wm.flicker.CommonTransitions.splitScreenToLauncher; -import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds; -import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen; -import static com.android.server.wm.flicker.helpers.AutomationUtils.isInSplitScreen; - -import android.view.Surface; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.UiDevice; - -import org.junit.AfterClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -/** - * Test open app to split screen. - * To run this test: {@code atest FlickerTests:SplitScreenToLauncherTest} - */ -@LargeTest -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class SplitScreenToLauncherTest extends FlickerTestBase { - - public SplitScreenToLauncherTest() { - this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), - "com.android.server.wm.flicker.testapp", "SimpleApp"); - } - - @Override - TransitionRunner getTransitionToRun() { - return splitScreenToLauncher(mTestApp, mUiDevice, Surface.ROTATION_0) - .includeJankyRuns().build(); - } - - @Test - public void checkCoveredRegion_noUncoveredRegions() { - checkResults(result -> - LayersTraceSubject.assertThat(result) - .coversRegion(getDisplayBounds()).forAllEntries()); - } - - @Test - public void checkVisibility_dividerLayerBecomesInVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(DOCKED_STACK_DIVIDER) - .then() - .hidesLayer(DOCKED_STACK_DIVIDER) - .forAllEntries()); - } - - @Test - public void checkVisibility_appLayerBecomesInVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(mTestApp.getPackage()) - .then() - .hidesLayer(mTestApp.getPackage()) - .forAllEntries()); - } - - @Test - public void checkVisibility_navBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test - public void checkVisibility_statusBarWindowIsAlwaysVisible() { - checkResults(result -> WmTraceSubject.assertThat(result) - .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()); - } - - @AfterClass - public static void teardown() { - UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - - if (isInSplitScreen(device)) { - exitSplitScreen(device); - } - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt index 42977f549162..e579533d2bb7 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.android.server.wm.flicker.helpers; +package com.android.server.wm.flicker.helpers -import android.app.Instrumentation; +import android.app.Instrumentation +import com.android.server.wm.flicker.StandardAppHelper -import com.android.server.wm.flicker.StandardAppHelper; - -public abstract class FlickerAppHelper extends StandardAppHelper { - - static int sFindTimeout = 10000; - static String sFlickerPackage = "com.android.server.wm.flicker.testapp"; - - public FlickerAppHelper(Instrumentation instr, String launcherName) { - super(instr, sFlickerPackage, launcherName); +abstract class FlickerAppHelper( + instr: Instrumentation, + launcherName: String +) : StandardAppHelper(instr, sFlickerPackage, launcherName) { + companion object { + var sFindTimeout = 10000 + var sFlickerPackage = "com.android.server.wm.flicker.testapp" } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt index 1b2c48405f6e..d587f1e383c5 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -14,19 +14,13 @@ * limitations under the License. */ -package com.android.server.wm.flicker.helpers; +package com.android.server.wm.flicker.helpers -import android.app.Instrumentation; +import android.app.Instrumentation +import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiDevice; - -public class ImeAppAutoFocusHelper extends ImeAppHelper { - - public ImeAppAutoFocusHelper(Instrumentation instr) { - super(instr, "ImeAppAutoFocus"); - } - - public void openIME(UiDevice device) { +class ImeAppAutoFocusHelper(instr: Instrumentation) : ImeAppHelper(instr, "ImeAppAutoFocus") { + override fun openIME(device: UiDevice) { // do nothing (the app is focused automatically) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java deleted file mode 100644 index 095722d59fc7..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2019 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 static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import android.app.Instrumentation; - -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -public class ImeAppHelper extends FlickerAppHelper { - - ImeAppHelper(Instrumentation instr, String launcherName) { - super(instr, launcherName); - } - - public ImeAppHelper(Instrumentation instr) { - this(instr, "ImeApp"); - } - - public void openIME(UiDevice device) { - UiObject2 editText = device.wait( - Until.findObject(By.res(getPackage(), "plain_text_input")), - AutomationUtils.FIND_TIMEOUT); - assertNotNull("Text field not found, this usually happens when the device was left " - + "in an unknown state (e.g. in split screen)", editText); - editText.click(); - - if (!AutomationUtils.waitForIME(device)) { - fail("IME did not appear"); - } - } -} 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 new file mode 100644 index 000000000000..979cbeaca539 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt @@ -0,0 +1,40 @@ +/* + * 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.helpers + +import android.app.Instrumentation +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import org.junit.Assert + +open class ImeAppHelper( + instr: Instrumentation, + launcherName: String = "ImeApp" +) : FlickerAppHelper(instr, launcherName) { + open fun openIME(device: UiDevice) { + val editText = device.wait( + Until.findObject(By.res(getPackage(), "plain_text_input")), + AutomationUtils.FIND_TIMEOUT) + Assert.assertNotNull("Text field not found, this usually happens when the device " + + "was left in an unknown state (e.g. in split screen)", editText) + editText.click() + if (!AutomationUtils.waitForIME(device)) { + Assert.fail("IME did not appear") + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java deleted file mode 100644 index f2b7a7e351fc..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2019 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 static com.android.server.wm.flicker.helpers.AutomationUtils.hasPipWindow; - -import static org.junit.Assert.assertNotNull; - -import android.app.Instrumentation; - -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; - -public class PipAppHelper extends FlickerAppHelper { - - public PipAppHelper(Instrumentation instr) { - super(instr, "PipApp"); - } - - public void clickEnterPipButton(UiDevice device) { - UiObject2 enterPipButton = device.findObject(By.res(getPackage(), "enter_pip")); - assertNotNull("Pip button not found, this usually happens when the device was left " - + "in an unknown state (e.g. in split screen)", enterPipButton); - enterPipButton.click(); - hasPipWindow(device); - } - - public void closePipWindow(UiDevice device) { - AutomationUtils.closePipWindow(device); - } - -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt new file mode 100644 index 000000000000..daee810b6899 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt @@ -0,0 +1,36 @@ +/* + * 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.helpers + +import android.app.Instrumentation +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import org.junit.Assert + +class PipAppHelper(instr: Instrumentation) : FlickerAppHelper(instr, "PipApp") { + fun clickEnterPipButton(device: UiDevice) { + val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip")) + Assert.assertNotNull("Pip button not found, this usually happens when the device " + + "was left in an unknown state (e.g. in split screen)", enterPipButton) + enterPipButton.click() + AutomationUtils.hasPipWindow(device) + } + + fun closePipWindow(device: UiDevice) { + AutomationUtils.closePipWindow(device) + } +} 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 new file mode 100644 index 000000000000..6946618806b8 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt @@ -0,0 +1,71 @@ +/* + * 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.ime + +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test IME window closing back to app window transitions. + * To run this test: `atest FlickerTests:CloseImeWindowToAppTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class CloseImeAutoOpenWindowToAppTest( + beginRotationName: String, + beginRotation: Int +) : CloseImeWindowToAppTest(beginRotationName, beginRotation) { + init { + testApp = ImeAppAutoFocusHelper(instrumentation) + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppAutoFocusHelper, + instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @FlakyTest(bugId = 141458352) + @Ignore("Waiting bug feedback") + @Test + override fun checkVisibility_imeLayerBecomesInvisible() { + super.checkVisibility_imeLayerBecomesInvisible() + } + + @FlakyTest(bugId = 141458352) + @Ignore("Waiting bug feedback") + @Test + override fun checkVisibility_imeAppLayerIsAlwaysVisible() { + super.checkVisibility_imeAppLayerIsAlwaysVisible() + } + + @FlakyTest(bugId = 141458352) + @Ignore("Waiting bug feedback") + @Test + override fun checkVisibility_imeAppWindowIsAlwaysVisible() { + super.checkVisibility_imeAppWindowIsAlwaysVisible() + } +} 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 new file mode 100644 index 000000000000..a1030d8248b7 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt @@ -0,0 +1,71 @@ +/* + * 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.ime + +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test IME window closing back to app window transitions. + * To run this test: `atest FlickerTests:CloseImeWindowToAppTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class CloseImeAutoOpenWindowToHomeTest( + beginRotationName: String, + beginRotation: Int +) : CloseImeWindowToHomeTest(beginRotationName, beginRotation) { + init { + testApp = ImeAppAutoFocusHelper(instrumentation) + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppAutoFocusHelper, + instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @FlakyTest(bugId = 141458352) + @Ignore("Waiting bug feedback") + @Test + override fun checkVisibility_imeWindowBecomesInvisible() { + super.checkVisibility_imeWindowBecomesInvisible() + } + + @FlakyTest(bugId = 141458352) + @Ignore("Waiting bug feedback") + @Test + override fun checkVisibility_imeLayerBecomesInvisible() { + super.checkVisibility_imeLayerBecomesInvisible() + } + + @FlakyTest(bugId = 157449248) + @Ignore("Waiting bug feedback") + @Test + override fun checkVisibility_imeAppWindowBecomesInvisible() { + super.checkVisibility_imeAppWindowBecomesInvisible() + } +} 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 new file mode 100644 index 000000000000..6e7c92b97bfb --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt @@ -0,0 +1,86 @@ +/* + * 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.ime + +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.ImeAppHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test IME window closing back to app window transitions. + * To run this test: `atest FlickerTests:CloseImeWindowToAppTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +open class CloseImeWindowToAppTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = ImeAppHelper(instrumentation) + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppHelper, + instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @Ignore("Flaky. Pending debug") + @Test + open fun checkVisibility_imeLayerBecomesInvisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(IME_WINDOW_TITLE) + .then() + .hidesLayer(IME_WINDOW_TITLE) + .forAllEntries() + } + } + + @Test + open fun checkVisibility_imeAppLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(testApp.getPackage()) + .forAllEntries() + } + } + + @Test + open fun checkVisibility_imeAppWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindowOnTop(testApp.getPackage()) + .forAllEntries() + } + } + + companion object { + const val IME_WINDOW_TITLE = "InputMethod" + } +} 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 new file mode 100644 index 000000000000..7b155ebd93e1 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt @@ -0,0 +1,107 @@ +/* + * 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.ime + +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.ImeAppHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test IME window closing to home transitions. + * To run this test: `atest FlickerTests:CloseImeWindowToHomeTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +open class CloseImeWindowToHomeTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = ImeAppHelper(instrumentation) + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppHelper, + instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @Test + open fun checkVisibility_imeWindowBecomesInvisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsImeWindow(IME_WINDOW_TITLE) + .then() + .hidesImeWindow(IME_WINDOW_TITLE) + .forAllEntries() + } + } + + @FlakyTest(bugId = 153739621) + @Ignore + @Test + open fun checkVisibility_imeLayerBecomesInvisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .skipUntilFirstAssertion() + .showsLayer(IME_WINDOW_TITLE) + .then() + .hidesLayer(IME_WINDOW_TITLE) + .forAllEntries() + } + } + + @FlakyTest(bugId = 153739621) + @Ignore + @Test + fun checkVisibility_imeAppLayerBecomesInvisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .skipUntilFirstAssertion() + .showsLayer(testApp.getPackage()) + .then() + .hidesLayer(testApp.getPackage()) + .forAllEntries() + } + } + + @Test + open fun checkVisibility_imeAppWindowBecomesInvisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindowOnTop(testApp.getPackage()) + .then() + .hidesAppWindowOnTop(testApp.getPackage()) + .forAllEntries() + } + } + + companion object { + const val IME_WINDOW_TITLE: String = "InputMethod" + } +} 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 new file mode 100644 index 000000000000..9885359a0fb7 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt @@ -0,0 +1,78 @@ +/* + * 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.ime + +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.ImeAppHelper +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test IME window opening transitions. + * To run this test: `atest FlickerTests:OpenImeWindowTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class OpenImeWindowTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = ImeAppHelper(instrumentation) + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.editTextSetFocus(testApp as ImeAppHelper, + instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @Test + fun checkVisibility_imeWindowBecomesVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .skipUntilFirstAssertion() + .hidesImeWindow(IME_WINDOW_TITLE) + .then() + .showsImeWindow(IME_WINDOW_TITLE) + .forAllEntries() + } + } + + @Test + fun checkVisibility_imeLayerBecomesVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .hidesLayer(IME_WINDOW_TITLE) + .then() + .showsLayer(IME_WINDOW_TITLE) + .forAllEntries() + } + } + + companion object { + private const val IME_WINDOW_TITLE = "InputMethod" + } +} 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 new file mode 100644 index 000000000000..943a52592910 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt @@ -0,0 +1,89 @@ +/* + * 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 androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.StandardAppHelper +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test cold launch app from launcher. + * To run this test: `atest FlickerTests:OpenAppColdTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class OpenAppColdTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = StandardAppHelper(instrumentation, + "com.android.server.wm.flicker.testapp", "SimpleApp") + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @Test + fun checkVisibility_wallpaperWindowBecomesInvisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsBelowAppWindow("Wallpaper") + .then() + .hidesBelowAppWindow("Wallpaper") + .forAllEntries() + } + } + + @FlakyTest(bugId = 140855415) + @Ignore("Waiting bug feedback") + @Test + fun checkZOrder_appWindowReplacesLauncherAsTopWindow() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindowOnTop( + "com.android.launcher3/.Launcher") + .then() + .showsAppWindowOnTop(testApp.getPackage()) + .forAllEntries() + } + } + + @Test + fun checkVisibility_wallpaperLayerBecomesInvisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer("Wallpaper") + .then() + .replaceVisibleLayer("Wallpaper", testApp.getPackage()) + .forAllEntries() + } + } +}
\ 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 new file mode 100644 index 000000000000..7964d949e737 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt @@ -0,0 +1,89 @@ +/* + * 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 androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.StandardAppHelper +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test warm launch app. + * To run this test: `atest FlickerTests:OpenAppWarmTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class OpenAppWarmTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = StandardAppHelper(instrumentation, + "com.android.server.wm.flicker.testapp", "SimpleApp") + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, beginRotation) + .includeJankyRuns().build() + + @Test + fun checkVisibility_wallpaperBecomesInvisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsBelowAppWindow("Wallpaper") + .then() + .hidesBelowAppWindow("Wallpaper") + .forAllEntries() + } + } + + @FlakyTest(bugId = 140855415) + @Ignore("Waiting bug feedback") + @Test + fun checkZOrder_appWindowReplacesLauncherAsTopWindow() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindowOnTop( + "com.android.launcher3/.Launcher") + .then() + .showsAppWindowOnTop(testApp.getPackage()) + .forAllEntries() + } + } + + @Test + fun checkVisibility_wallpaperLayerBecomesInvisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer("Wallpaper") + .then() + .replaceVisibleLayer("Wallpaper", testApp.getPackage()) + .forAllEntries() + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt new file mode 100644 index 000000000000..79321f9488ad --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt @@ -0,0 +1,81 @@ +/* + * 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.pip + +import androidx.test.InstrumentationRegistry +import androidx.test.filters.LargeTest +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.AutomationUtils +import com.android.server.wm.flicker.helpers.PipAppHelper +import org.junit.AfterClass +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +abstract class PipTestBase( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = PipAppHelper(instrumentation) + } + + @Test + fun checkVisibility_pipWindowBecomesVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .skipUntilFirstAssertion() + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .hidesAppWindow(sPipWindowTitle) + .forAllEntries() + } + } + + @Test + fun checkVisibility_pipLayerBecomesVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .skipUntilFirstAssertion() + .showsLayer(sPipWindowTitle) + .then() + .hidesLayer(sPipWindowTitle) + .forAllEntries() + } + } + + companion object { + const val sPipWindowTitle = "PipMenuActivity" + + @AfterClass + @JvmStatic + fun teardown() { + val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + if (AutomationUtils.hasPipWindow(device)) { + AutomationUtils.closePipWindow(device) + } + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt new file mode 100644 index 000000000000..bfececa72d4e --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt @@ -0,0 +1,65 @@ +/* + * 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.pip + +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.PipAppHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test Pip launch. + * To run this test: `atest FlickerTests:PipToAppTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@FlakyTest(bugId = 152738416) +@Ignore("Waiting bug feedback") +class PipToAppTest( + beginRotationName: String, + beginRotation: Int +) : PipTestBase(beginRotationName, beginRotation) { + override val transitionToRun: TransitionRunner + get() = CommonTransitions.exitPipModeToApp(testApp as PipAppHelper, instrumentation, + uiDevice, beginRotation) + .includeJankyRuns().build() + + @Test + fun checkVisibility_backgroundWindowVisibleBehindPipLayer() { + checkResults { + WmTraceSubject.assertThat(it) + .skipUntilFirstAssertion() + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .showsBelowAppWindow("Wallpaper") + .then() + .showsAppWindowOnTop(testApp.getPackage()) + .then() + .hidesAppWindowOnTop(testApp.getPackage()) + .forAllEntries() + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt new file mode 100644 index 000000000000..ecfcd8298c3f --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt @@ -0,0 +1,63 @@ +/* + * 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.pip + +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.PipAppHelper +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test Pip launch. + * To run this test: `atest FlickerTests:PipToHomeTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@FlakyTest(bugId = 152738416) +@Ignore("Waiting bug feedback") +class PipToHomeTest( + beginRotationName: String, + beginRotation: Int +) : PipTestBase(beginRotationName, beginRotation) { + override val transitionToRun: TransitionRunner + get() = CommonTransitions.exitPipModeToHome(testApp as PipAppHelper, instrumentation, + uiDevice, beginRotation) + .includeJankyRuns().build() + + @Ignore + @Test + fun checkVisibility_backgroundWindowVisibleBehindPipLayer() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .showsBelowAppWindow("Wallpaper") + .then() + .showsAppWindowOnTop("Wallpaper") + .forAllEntries() + } + } +} 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 new file mode 100644 index 000000000000..7a581d066c2b --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt @@ -0,0 +1,85 @@ +/* + * 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.rotation + +import android.util.Log +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.RotationTestBase +import com.android.server.wm.flicker.StandardAppHelper +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WindowUtils +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Cycle through supported app rotations. + * To run this test: `atest FlickerTest:ChangeAppRotationTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class ChangeAppRotationTest( + beginRotationName: String, + endRotationName: String, + beginRotation: Int, + endRotation: Int +) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) { + init { + testApp = StandardAppHelper(instrumentation, + "com.android.server.wm.flicker.testapp", "SimpleApp") + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice, + beginRotation, endRotation) + .includeJankyRuns().build() + + @Test + fun checkPosition_appLayerRotates() { + val startingPos = WindowUtils.getAppPosition(beginRotation) + val endingPos = WindowUtils.getAppPosition(endRotation) + Log.e(TAG, "startingPos=$startingPos endingPos=$endingPos") + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(testApp.getPackage(), startingPos).inTheBeginning() + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(testApp.getPackage(), endingPos).atTheEnd() + } + } + + @Ignore("Flaky. Pending debug") + @Test + fun checkVisibility_screenshotLayerBecomesInvisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(testApp.getPackage()) + .then() + .replaceVisibleLayer(testApp.getPackage(), SCREENSHOT_LAYER) + .then() + .showsLayer(testApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER) + .then() + .replaceVisibleLayer(SCREENSHOT_LAYER, testApp.getPackage()) + .forAllEntries() + } + } +} 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 new file mode 100644 index 000000000000..d53af6f53bf2 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt @@ -0,0 +1,146 @@ +/* + * 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.rotation + +import android.content.Intent +import android.view.Surface +import androidx.test.InstrumentationRegistry +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.RotationTestBase +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WindowUtils +import com.android.server.wm.flicker.testapp.ActivityOptions +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Cycle through supported app rotations using seamless rotations. + * To run this test: `atest FlickerTests:SeamlessAppRotationTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@FlakyTest(bugId = 147659548) +@Ignore("Waiting bug feedback") +class SeamlessAppRotationTest( + private val intent: Intent, + beginRotationName: String, + endRotationName: String, + beginRotation: Int, + endRotation: Int +) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) { + override val transitionToRun: TransitionRunner + get() { + var intentId = "" + if (intent.extras?.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) { + intentId = "BUSY_UI_THREAD" + } + return CommonTransitions.changeAppRotation(intent, intentId, + InstrumentationRegistry.getContext(), instrumentation, uiDevice, + beginRotation, endRotation).build() + } + + @Test + fun checkPosition_appLayerRotates() { + val startingPos = WindowUtils.getAppPosition(beginRotation) + val endingPos = WindowUtils.getAppPosition(endRotation) + if (startingPos == endingPos) { + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(intent.component?.packageName ?: "", startingPos) + .forAllEntries() + } + } else { + checkResults { + LayersTraceSubject.assertThat(it) + .hasVisibleRegion(intent.component?.packageName ?: "", startingPos) + .then() + .hasVisibleRegion(intent.component?.packageName ?: "", endingPos) + .forAllEntries() + } + } + } + + @Test + fun checkCoveredRegion_noUncoveredRegions() { + val startingBounds = WindowUtils.getDisplayBounds(beginRotation) + val endingBounds = WindowUtils.getDisplayBounds(endRotation) + if (startingBounds == endingBounds) { + checkResults { + LayersTraceSubject.assertThat(it) + .coversRegion(startingBounds) + .forAllEntries() + } + } else { + checkResults { + LayersTraceSubject.assertThat(it) + .coversRegion(startingBounds) + .then() + .coversRegion(endingBounds) + .forAllEntries() + } + } + } + + companion object { + // launch test activity that supports seamless rotation + + // launch test activity that supports seamless rotation with a busy UI thread to miss frames + // when the app is asked to redraw + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<Array<Any>> { + val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90) + val params: MutableCollection<Array<Any>> = ArrayList() + val testIntents = ArrayList<Intent>() + + // launch test activity that supports seamless rotation + var intent = Intent(Intent.ACTION_MAIN) + intent.component = ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME + testIntents.add(intent) + + // launch test activity that supports seamless rotation with a busy UI thread to miss frames + // when the app is asked to redraw + intent = Intent(intent) + intent.putExtra(ActivityOptions.EXTRA_STARVE_UI_THREAD, true) + testIntents.add(intent) + for (testIntent in testIntents) { + for (begin in supportedRotations) { + for (end in supportedRotations) { + if (begin != end) { + var testId: String = Surface.rotationToString(begin) + + "_" + Surface.rotationToString(end) + if (testIntent.extras?.getBoolean( + ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) { + testId += "_" + "BUSY_UI_THREAD" + } + params.add(arrayOf(testId, testIntent, begin, end)) + } + } + } + } + return params + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt new file mode 100644 index 000000000000..b5611a45a2e7 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt @@ -0,0 +1,78 @@ +/* + * 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.splitscreen + +import androidx.test.filters.LargeTest +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.NonRotationTestBase +import com.android.server.wm.flicker.StandardAppHelper +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WmTraceSubject +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test open app to split screen. + * To run this test: `atest FlickerTests:OpenAppToSplitScreenTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class OpenAppToSplitScreenTest( + beginRotationName: String, + beginRotation: Int +) : NonRotationTestBase(beginRotationName, beginRotation) { + init { + testApp = StandardAppHelper(instrumentation, + "com.android.server.wm.flicker.testapp", "SimpleApp") + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice, + beginRotation).includeJankyRuns().build() + + @Test + fun checkVisibility_navBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @Test + fun checkVisibility_statusBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @Test + fun checkVisibility_dividerLayerBecomesVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .hidesLayer(DOCKED_STACK_DIVIDER) + .then() + .showsLayer(DOCKED_STACK_DIVIDER) + .forAllEntries() + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt new file mode 100644 index 000000000000..b6cce266ab88 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt @@ -0,0 +1,202 @@ +/* + * 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.splitscreen + +import android.graphics.Region +import android.util.Rational +import android.view.Surface +import androidx.test.InstrumentationRegistry +import androidx.test.filters.FlakyTest +import androidx.test.filters.LargeTest +import androidx.test.runner.AndroidJUnit4 +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.FlickerTestBase +import com.android.server.wm.flicker.LayersTrace +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.StandardAppHelper +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.TransitionResult +import com.android.server.wm.flicker.WindowUtils +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.AutomationUtils +import com.android.server.wm.flicker.helpers.ImeAppHelper +import com.google.common.truth.Truth +import org.junit.AfterClass +import org.junit.FixMethodOrder +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters + +/** + * Test split screen resizing window transitions. + * To run this test: `atest FlickerTests:ResizeSplitScreenTest` + * + * Currently it runs only in 0 degrees because of b/156100803 + */ +@LargeTest +@RunWith(AndroidJUnit4::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@FlakyTest(bugId = 159096424) +@Ignore("Waiting bug feedback") +class ResizeSplitScreenTest : FlickerTestBase() { + init { + testApp = StandardAppHelper(instrumentation, + "com.android.server.wm.flicker.testapp", "SimpleApp") + } + + override val transitionToRun: TransitionRunner + get() { + val bottomApp = ImeAppHelper(instrumentation) + return CommonTransitions.resizeSplitScreen(testApp, bottomApp, instrumentation, + uiDevice, Surface.ROTATION_0, + Rational(1, 3), Rational(2, 3)) + .includeJankyRuns().build() + } + + @Test + fun checkVisibility_topAppLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(sSimpleActivity) + .forAllEntries() + } + } + + @Test + fun checkVisibility_bottomAppLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(sImeActivity) + .forAllEntries() + } + } + + @Test + fun checkVisibility_dividerLayerIsAlwaysVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(DOCKED_STACK_DIVIDER) + .forAllEntries() + } + } + + @Test + @Ignore("Waiting feedback") + fun checkPosition_appsStartingBounds() { + val displayBounds = WindowUtils.getDisplayBounds() + checkResults { result: TransitionResult -> + val entries = LayersTrace.parseFrom(result.layersTrace, + result.layersTracePath, result.layersTraceChecksum) + Truth.assertThat(entries.entries).isNotEmpty() + val startingDividerBounds = entries.entries[0].getVisibleBounds( + DOCKED_STACK_DIVIDER).bounds + val startingTopAppBounds = Region(0, 0, startingDividerBounds.right, + startingDividerBounds.top + WindowUtils.getDockedStackDividerInset()) + val startingBottomAppBounds = Region(0, + startingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(), + displayBounds.right, + displayBounds.bottom - WindowUtils.getNavigationBarHeight()) + LayersTraceSubject.assertThat(result) + .hasVisibleRegion("SimpleActivity", startingTopAppBounds) + .inTheBeginning() + LayersTraceSubject.assertThat(result) + .hasVisibleRegion("ImeActivity", startingBottomAppBounds) + .inTheBeginning() + } + } + + @Test + @Ignore("Waiting feedback") + fun checkPosition_appsEndingBounds() { + val displayBounds = WindowUtils.getDisplayBounds() + checkResults { result: TransitionResult -> + val entries = LayersTrace.parseFrom(result.layersTrace, + result.layersTracePath, result.layersTraceChecksum) + Truth.assertThat(entries.entries).isNotEmpty() + val endingDividerBounds = entries.entries[entries.entries.size - 1].getVisibleBounds( + DOCKED_STACK_DIVIDER).bounds + val startingTopAppBounds = Region(0, 0, endingDividerBounds.right, + endingDividerBounds.top + WindowUtils.getDockedStackDividerInset()) + val startingBottomAppBounds = Region(0, + endingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(), + displayBounds.right, + displayBounds.bottom - WindowUtils.getNavigationBarHeight()) + LayersTraceSubject.assertThat(result) + .hasVisibleRegion(sSimpleActivity, startingTopAppBounds) + .atTheEnd() + LayersTraceSubject.assertThat(result) + .hasVisibleRegion(sImeActivity, startingBottomAppBounds) + .atTheEnd() + } + } + + @Test + fun checkVisibility_navBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE) + .forAllEntries() + } + } + + @Test + fun checkVisibility_statusBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE) + .forAllEntries() + } + } + + @Test + @FlakyTest(bugId = 156223549) + @Ignore("Waiting bug feedback") + fun checkVisibility_topAppWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindow(sSimpleActivity) + .forAllEntries() + } + } + + @Test + @FlakyTest(bugId = 156223549) + @Ignore("Waiting bug feedback") + fun checkVisibility_bottomAppWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAppWindow(sImeActivity) + .forAllEntries() + } + } + + companion object { + private const val sSimpleActivity = "SimpleActivity" + private const val sImeActivity = "ImeActivity" + + @AfterClass + @JvmStatic + fun teardown() { + val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + if (AutomationUtils.isInSplitScreen(device)) { + AutomationUtils.exitSplitScreen(device) + } + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt new file mode 100644 index 000000000000..fdcafdb12a78 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt @@ -0,0 +1,111 @@ +/* + * 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.splitscreen + +import android.view.Surface +import androidx.test.InstrumentationRegistry +import androidx.test.filters.LargeTest +import androidx.test.runner.AndroidJUnit4 +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.CommonTransitions +import com.android.server.wm.flicker.FlickerTestBase +import com.android.server.wm.flicker.LayersTraceSubject +import com.android.server.wm.flicker.StandardAppHelper +import com.android.server.wm.flicker.TransitionRunner +import com.android.server.wm.flicker.WindowUtils +import com.android.server.wm.flicker.WmTraceSubject +import com.android.server.wm.flicker.helpers.AutomationUtils +import org.junit.AfterClass +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters + +/** + * Test open app to split screen. + * To run this test: `atest FlickerTests:SplitScreenToLauncherTest` + */ +@LargeTest +@RunWith(AndroidJUnit4::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class SplitScreenToLauncherTest : FlickerTestBase() { + init { + testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(), + "com.android.server.wm.flicker.testapp", "SimpleApp") + } + + override val transitionToRun: TransitionRunner + get() = CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice, + Surface.ROTATION_0).includeJankyRuns().build() + + @Test + fun checkCoveredRegion_noUncoveredRegions() { + checkResults { + LayersTraceSubject.assertThat(it) + .coversRegion(WindowUtils.getDisplayBounds()).forAllEntries() + } + } + + @Test + fun checkVisibility_dividerLayerBecomesInVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(DOCKED_STACK_DIVIDER) + .then() + .hidesLayer(DOCKED_STACK_DIVIDER) + .forAllEntries() + } + } + + @Test + fun checkVisibility_appLayerBecomesInVisible() { + checkResults { + LayersTraceSubject.assertThat(it) + .showsLayer(testApp.getPackage()) + .then() + .hidesLayer(testApp.getPackage()) + .forAllEntries() + } + } + + @Test + fun checkVisibility_navBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries() + } + } + + @Test + fun checkVisibility_statusBarWindowIsAlwaysVisible() { + checkResults { + WmTraceSubject.assertThat(it) + .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries() + } + } + + companion object { + @AfterClass + @JvmStatic + fun teardown() { + val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + if (AutomationUtils.isInSplitScreen(device)) { + AutomationUtils.exitSplitScreen(device) + } + } + } +} |