Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58dc55b6 authored by Sergey Nikolaienkov's avatar Sergey Nikolaienkov
Browse files

Prepare .wm.shell.flicker for test migration

Move common constants to a separate class.
Rename abstract FlickerAppHelper to BaseAppHelper.
Give BaseAppHelper a UiDevice (from androidx).
Make BaseAppHelper resposiblt for creating launcher.
Teach BaseAppHelper to launch app via intent and force-stop it.
Teach PipAppHelper to properly close Pip on TVs and work around
hasPipWindow() method not working on tv.

Bug: 171520419
Test: atest WMShellFlickerTests
Change-Id: Icc102a51351605b4adb27c3a1c2d73030eac33ff
parent c0b6daaf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
    <!-- Workaround grant runtime permission exception from b/152733071 -->
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
    <uses-permission android:name="android.permission.READ_LOGS"/>
    <!-- Force-stop test apps -->
    <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
    <application>
        <uses-library android:name="android.test.runner"/>
    </application>
+36 −0
Original line number Diff line number Diff line
@@ -14,18 +14,23 @@
 * limitations under the License.
 */

package com.android.wm.shell.flicker.helpers
package com.android.wm.shell.flicker

import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import com.android.server.wm.flicker.helpers.StandardAppHelper
import android.content.ComponentName

abstract class FlickerAppHelper(
    instr: Instrumentation,
    launcherName: String,
    launcherStrategy: ILauncherStrategy
) : StandardAppHelper(instr, sFlickerPackage, launcherName, launcherStrategy) {
    companion object {
        var sFlickerPackage = "com.android.wm.shell.flicker.testapp"
    }
}
const val IME_WINDOW_NAME = "InputMethod"
const val PIP_WINDOW_NAME = "PipMenuActivity"

// Test App
const val TEST_APP_PACKAGE_NAME = "com.android.wm.shell.flicker.testapp"
// Test App > Pip Activity
val TEST_APP_PIP_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
        TEST_APP_PACKAGE_NAME, ".PipActivity")
const val TEST_APP_PIP_ACTIVITY_LABEL = "PipApp"
const val TEST_APP_PIP_ACTIVITY_WINDOW_NAME = "PipActivity"
// Test App > Ime Activity
val TEST_APP_IME_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
        TEST_APP_PACKAGE_NAME, ".ImeActivity")
const val TEST_APP_IME_ACTIVITY_LABEL = "ImeApp"

const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
 No newline at end of file
+81 −0
Original line number Diff line number Diff line
/*
 * 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.ActivityManager
import android.app.Instrumentation
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager.FEATURE_LEANBACK
import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
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.StandardAppHelper
import com.android.wm.shell.flicker.TEST_APP_PACKAGE_NAME

abstract class BaseAppHelper(
    instrumentation: Instrumentation,
    launcherName: String,
    private val launcherActivityComponent: ComponentName
) : StandardAppHelper(
        instrumentation,
        TEST_APP_PACKAGE_NAME,
        launcherName,
        LauncherStrategyFactory.getInstance(instrumentation).launcherStrategy
) {
    protected val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)

    private val context: Context
        get() = mInstrumentation.context

    private val activityManager: ActivityManager?
        get() = context.getSystemService(ActivityManager::class.java)

    private val appSelector = By.pkg(packageName).depth(0)

    protected val isTelevision: Boolean
        get() = context.packageManager.run {
            hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY)
        }

    val label: String
        get() = context.packageManager.run {
            getApplicationLabel(getApplicationInfo(packageName, 0)).toString()
        }

    fun launchViaIntent() {
        context.startActivity(openAppIntent)

        uiDevice.wait(Until.hasObject(appSelector), APP_LAUNCH_WAIT_TIME_MS)
    }

    fun forceStop() = activityManager?.forceStopPackage(packageName)

    override fun getOpenAppIntent(): Intent {
        val intent = Intent()
        intent.component = launcherActivityComponent
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        return intent
    }

    companion object {
        private const val APP_LAUNCH_WAIT_TIME_MS = 10_000L
    }
}
+14 −15
Original line number Diff line number Diff line
@@ -17,37 +17,36 @@
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 com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_LABEL
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(
    instrumentation: Instrumentation
) : BaseAppHelper(
        instrumentation,
        TEST_APP_IME_ACTIVITY_LABEL,
        TEST_APP_IME_ACTIVITY_COMPONENT_NAME
) {
    fun openIME() {
        val editText = uiDevice.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()) {
        if (!uiDevice.waitForIME()) {
            Assert.fail("IME did not appear")
        }
    }

    open fun closeIME(device: UiDevice) {
        device.pressBack()
    fun closeIME() {
        uiDevice.pressBack()
        // Using only the AccessibilityInfo it is not possible to identify if the IME is active
        device.waitForIdle(1000)
        uiDevice.waitForIdle(1000)
    }
}
 No newline at end of file
+43 −16
Original line number Diff line number Diff line
@@ -17,29 +17,56 @@
package com.android.wm.shell.flicker.helpers

import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import android.os.SystemClock
import android.view.KeyEvent.KEYCODE_WINDOW
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import com.android.server.wm.flicker.helpers.hasPipWindow
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.helpers.closePipWindow
import org.junit.Assert
import com.android.server.wm.flicker.helpers.hasPipWindow
import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_LABEL
import org.junit.Assert.assertNotNull

class PipAppHelper(
    instr: Instrumentation,
    launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
            .getInstance(instr)
            .launcherStrategy
) : FlickerAppHelper(instr, "PipApp", launcherStrategy) {
    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 " +
    instrumentation: Instrumentation
) : BaseAppHelper(
        instrumentation,
        TEST_APP_PIP_ACTIVITY_LABEL,
        TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
) {
    fun clickEnterPipButton() {
        val enterPipButton = uiDevice.findObject(By.res(packageName, "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()
        device.hasPipWindow()

        // TODO(b/172321238): remove this check once hasPipWindow is fixed on TVs
        if (!isTelevision) {
            uiDevice.hasPipWindow()
        } else {
            // Simply wait for 3 seconds
            SystemClock.sleep(3_000)
        }
    }

    fun closePipWindow(device: UiDevice) {
        device.closePipWindow()
    fun closePipWindow() {
        // TODO(b/172321238): remove this check once and simply call closePipWindow once the TV
        //  logic is integrated there.
        if (!isTelevision) {
            uiDevice.closePipWindow()
        } else {
            // Bring up Pip menu
            uiDevice.pressKeyCode(KEYCODE_WINDOW)

            // Wait for the menu to come up and render the close button
            val closeButton = uiDevice.wait(
                    Until.findObject(By.res(SYSTEM_UI_PACKAGE_NAME, "close_button")), 3_000)
            assertNotNull("Pip menu close button is not found", closeButton)
            closeButton.click()

            // Give it 1 second, just in case
            SystemClock.sleep(1_000)
        }
    }
}
Loading