summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt53
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt217
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml9
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml27
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java33
6 files changed, 340 insertions, 1 deletions
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
new file mode 100644
index 000000000000..0cedc0a7147f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.wm.shell.flicker.helpers
+
+import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.helpers.FIND_TIMEOUT
+import com.android.server.wm.flicker.helpers.waitForIME
+import org.junit.Assert
+
+open class ImeAppHelper(
+ instr: Instrumentation,
+ launcherName: String = "ImeApp",
+ launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
+ .getInstance(instr)
+ .launcherStrategy
+) : FlickerAppHelper(instr, launcherName, launcherStrategy) {
+ open fun openIME(device: UiDevice) {
+ val editText = device.wait(
+ Until.findObject(By.res(getPackage(), "plain_text_input")),
+ 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 (!device.waitForIME()) {
+ Assert.fail("IME did not appear")
+ }
+ }
+
+ open fun closeIME(device: UiDevice) {
+ device.pressBack()
+ // Using only the AccessibilityInfo it is not possible to identify if the IME is active
+ device.waitForIdle(1000)
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index c3c576d3f28c..010aa0d7d832 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -39,7 +39,7 @@ import org.junit.runners.Parameterized
/**
* Test Pip launch.
- * To run this test: `atest FlickerTests:PipToAppTest`
+ * To run this test: `atest WMShellFlickerTests:PipToAppTest`
*/
@RequiresDevice
@RunWith(Parameterized::class)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
new file mode 100644
index 000000000000..43e022538685
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -0,0 +1,217 @@
+/*
+ * 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.wm.shell.flicker.pip
+
+import android.content.ComponentName
+import android.graphics.Region
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import android.util.Log
+import android.view.Surface
+import android.view.WindowManager
+import androidx.test.filters.RequiresDevice
+import com.android.compatibility.common.util.SystemUtil
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.dsl.runWithFlicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.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
+import java.io.IOException
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest WMShellFlickerTests:PipKeyboardTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class PipKeyboardTest(
+ rotationName: String,
+ rotation: Int
+) : PipTestBase(rotationName, rotation) {
+ private val windowManager: WindowManager =
+ instrumentation.context.getSystemService(WindowManager::class.java)
+
+ private val keyboardApp = ImeAppHelper(instrumentation, "ImeApp",
+ LauncherStrategyFactory.getInstance(instrumentation).launcherStrategy)
+
+ private val KEYBOARD_ACTIVITY: ComponentName = ComponentName.createRelative(
+ "com.android.wm.shell.flicker.testapp", ".ImeActivity")
+ private val PIP_ACTIVITY_WINDOW_NAME = "PipActivity"
+ private val INPUT_METHOD_WINDOW_NAME = "InputMethod"
+
+ private val testRepetitions = 10
+
+ private val keyboardScenario: FlickerBuilder
+ get() = FlickerBuilder(instrumentation).apply {
+ repeat { testRepetitions }
+ // disable layer tracing
+ withLayerTracing { null }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ device.pressHome()
+ // launch our target pip app
+ testApp.open()
+ this.setRotation(rotation)
+ testApp.clickEnterPipButton(device)
+ // open an app with an input field and a keyboard
+ // UiAutomator doesn't support to launch the multiple Activities in a task.
+ // So use launchActivity() for the Keyboard Activity.
+ launchActivity(KEYBOARD_ACTIVITY)
+ }
+ }
+ teardown {
+ test {
+ keyboardApp.exit()
+
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ }
+ }
+
+ /** Ensure the pip window remains visible throughout any keyboard interactions. */
+ @Test
+ fun pipWindow_doesNotLeaveTheScreen_onKeyboardOpenClose() {
+ val testTag = "pipWindow_doesNotLeaveTheScreen_onKeyboardOpenClose"
+ runWithFlicker(keyboardScenario) {
+ withTestName { testTag }
+ transitions {
+ // open the soft keyboard
+ keyboardApp.openIME(device)
+
+ // then close it again
+ keyboardApp.closeIME(device)
+ }
+ assertions {
+ windowManagerTrace {
+ all("PiP window must remain inside visible bounds") {
+ coversAtMostRegion(
+ partialWindowTitle = "PipActivity",
+ region = Region(windowManager.maximumWindowMetrics.bounds)
+ )
+ }
+ }
+ }
+ }
+ }
+
+ /** Ensure the pip window does not obscure the keyboard. */
+ @Test
+ fun pipWindow_doesNotObscure_keyboard() {
+ val testTag = "pipWindow_doesNotObscure_keyboard"
+ runWithFlicker(keyboardScenario) {
+ withTestName { testTag }
+ transitions {
+ // open the soft keyboard
+ keyboardApp.openIME(device)
+ }
+ teardown {
+ eachRun {
+ // close the keyboard
+ keyboardApp.closeIME(device)
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ end {
+ isAboveWindow(INPUT_METHOD_WINDOW_NAME, PIP_ACTIVITY_WINDOW_NAME)
+ }
+ }
+ }
+ }
+ }
+
+ private fun launchActivity(
+ activity: ComponentName? = null,
+ action: String? = null,
+ flags: Set<Int> = setOf(),
+ boolExtras: Map<String, Boolean> = mapOf(),
+ intExtras: Map<String, Int> = mapOf(),
+ stringExtras: Map<String, String> = mapOf()
+ ) {
+ require(activity != null || !action.isNullOrBlank()) {
+ "Cannot launch an activity with neither activity name nor action!"
+ }
+ val command = composeCommand(
+ "start", activity, action, flags, boolExtras, intExtras, stringExtras)
+ executeShellCommand(command)
+ }
+
+ private fun composeCommand(
+ command: String,
+ activity: ComponentName?,
+ action: String?,
+ flags: Set<Int>,
+ boolExtras: Map<String, Boolean>,
+ intExtras: Map<String, Int>,
+ stringExtras: Map<String, String>
+ ): String = buildString {
+ append("am ")
+ append(command)
+ activity?.let {
+ append(" -n ")
+ append(it.flattenToShortString())
+ }
+ action?.let {
+ append(" -a ")
+ append(it)
+ }
+ flags.forEach {
+ append(" -f ")
+ append(it)
+ }
+ boolExtras.forEach {
+ append(it.withFlag("ez"))
+ }
+ intExtras.forEach {
+ append(it.withFlag("ei"))
+ }
+ stringExtras.forEach {
+ append(it.withFlag("es"))
+ }
+ }
+
+ private fun Map.Entry<String, *>.withFlag(flag: String): String = " --$flag $key $value"
+
+ private fun executeShellCommand(cmd: String): String {
+ try {
+ return SystemUtil.runShellCommand(instrumentation, cmd)
+ } catch (e: IOException) {
+ Log.e("FlickerTests", "Error running shell command: $cmd")
+ throw e
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
index 95dc1d48eee8..3b66c58414e0 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -33,5 +33,14 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
+ <activity android:name=".ImeActivity"
+ android:taskAffinity="com.android.wm.shell.flicker.testapp.ImeActivity"
+ android:label="ImeApp"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml
new file mode 100644
index 000000000000..4708cfd48381
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_ime.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:focusableInTouchMode="true"
+ android:background="@android:color/holo_green_light">
+ <EditText android:id="@+id/plain_text_input"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:inputType="text"/>
+</LinearLayout>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java
new file mode 100644
index 000000000000..856728715c1c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/ImeActivity.java
@@ -0,0 +1,33 @@
+/*
+ * 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.wm.shell.flicker.testapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class ImeActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ WindowManager.LayoutParams p = getWindow().getAttributes();
+ p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
+ .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ getWindow().setAttributes(p);
+ setContentView(R.layout.activity_ime);
+ }
+}