Merge "Add Flicker tests for launching app from Notification CUJ" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
64d297bc49
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.helpers
|
||||
|
||||
import android.app.Instrumentation
|
||||
import android.support.test.launcherhelper.ILauncherStrategy
|
||||
import android.support.test.launcherhelper.LauncherStrategyFactory
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import com.android.server.wm.flicker.testapp.ActivityOptions
|
||||
import com.android.server.wm.traces.common.FlickerComponentName
|
||||
import com.android.server.wm.traces.parser.toFlickerComponent
|
||||
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
|
||||
|
||||
class NotificationAppHelper @JvmOverloads constructor(
|
||||
instr: Instrumentation,
|
||||
launcherName: String = ActivityOptions.NOTIFICATION_ACTIVITY_LAUNCHER_NAME,
|
||||
component: FlickerComponentName =
|
||||
ActivityOptions.NOTIFICATION_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
|
||||
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
|
||||
.getInstance(instr)
|
||||
.launcherStrategy
|
||||
) : StandardAppHelper(instr, launcherName, component, launcherStrategy) {
|
||||
fun postNotification(device: UiDevice, wmHelper: WindowManagerStateHelper) {
|
||||
val button = device.wait(
|
||||
Until.findObject(By.res(getPackage(), "post_notification")),
|
||||
FIND_TIMEOUT)
|
||||
|
||||
require(button != null) {
|
||||
"Post notification button not found, this usually happens when the device " +
|
||||
"was left in an unknown state (e.g. in split screen)"
|
||||
}
|
||||
button.click()
|
||||
|
||||
device.wait(Until.findObject(By.text("Flicker Test Notification")), FIND_TIMEOUT)
|
||||
?: error("Flicker Notification not found")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.helpers
|
||||
|
||||
import android.app.Instrumentation
|
||||
import android.support.test.launcherhelper.ILauncherStrategy
|
||||
import android.support.test.launcherhelper.LauncherStrategyFactory
|
||||
import com.android.server.wm.flicker.testapp.ActivityOptions
|
||||
import com.android.server.wm.traces.common.FlickerComponentName
|
||||
import com.android.server.wm.traces.parser.toFlickerComponent
|
||||
|
||||
class ShowWhenLockedAppHelper @JvmOverloads constructor(
|
||||
instr: Instrumentation,
|
||||
launcherName: String = ActivityOptions.SHOW_WHEN_LOCKED_ACTIVITY_LAUNCHER_NAME,
|
||||
component: FlickerComponentName =
|
||||
ActivityOptions.SHOW_WHEN_LOCKED_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
|
||||
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
|
||||
.getInstance(instr)
|
||||
.launcherStrategy
|
||||
) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.launch
|
||||
|
||||
import android.platform.test.annotations.Postsubmit
|
||||
import android.platform.test.annotations.RequiresDevice
|
||||
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
|
||||
import com.android.server.wm.flicker.FlickerTestParameter
|
||||
import com.android.server.wm.flicker.FlickerTestParameterFactory
|
||||
import com.android.server.wm.flicker.annotation.Group1
|
||||
import com.android.server.wm.flicker.dsl.FlickerBuilder
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
/**
|
||||
* Test cold launching an app from a notification from the lock screen.
|
||||
*
|
||||
* To run this test: `atest FlickerTests:OpenAppFromLockNotificationCold`
|
||||
*/
|
||||
@RequiresDevice
|
||||
@RunWith(Parameterized::class)
|
||||
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Group1
|
||||
@Postsubmit
|
||||
open class OpenAppFromLockNotificationCold(testSpec: FlickerTestParameter)
|
||||
: OpenAppFromNotificationCold(testSpec) {
|
||||
|
||||
override val openingNotificationsFromLockScreen = true
|
||||
|
||||
override val transition: FlickerBuilder.() -> Unit
|
||||
get() = {
|
||||
// Needs to run at start of transition,
|
||||
// so before the transition defined in super.transition
|
||||
transitions {
|
||||
device.wakeUp()
|
||||
}
|
||||
|
||||
super.transition(this)
|
||||
|
||||
// Needs to run at the end of the setup, so after the setup defined in super.transition
|
||||
setup {
|
||||
eachRun {
|
||||
device.sleep()
|
||||
wmHelper.waitFor("noAppWindowsOnTop") {
|
||||
it.wmState.topVisibleAppWindow.isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates the test configurations.
|
||||
*
|
||||
* See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
|
||||
* repetitions, screen orientation and navigation modes.
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun getParams(): Collection<FlickerTestParameter> {
|
||||
return com.android.server.wm.flicker.FlickerTestParameterFactory.getInstance()
|
||||
.getConfigNonRotationTests(repetitions = 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.launch
|
||||
|
||||
import android.platform.test.annotations.Postsubmit
|
||||
import android.platform.test.annotations.RequiresDevice
|
||||
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
|
||||
import com.android.server.wm.flicker.FlickerTestParameter
|
||||
import com.android.server.wm.flicker.FlickerTestParameterFactory
|
||||
import com.android.server.wm.flicker.annotation.Group1
|
||||
import com.android.server.wm.flicker.dsl.FlickerBuilder
|
||||
import com.android.server.wm.traces.common.FlickerComponentName
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
/**
|
||||
* Test warm launching an app from a notification from the lock screen.
|
||||
*
|
||||
* To run this test: `atest FlickerTests:OpenAppFromLockNotificationWarm`
|
||||
*/
|
||||
@RequiresDevice
|
||||
@RunWith(Parameterized::class)
|
||||
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Group1
|
||||
@Postsubmit
|
||||
open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter)
|
||||
: OpenAppFromNotificationWarm(testSpec) {
|
||||
|
||||
override val openingNotificationsFromLockScreen = true
|
||||
|
||||
override val transition: FlickerBuilder.() -> Unit
|
||||
get() = {
|
||||
// Needs to run at start of transition,
|
||||
// so before the transition defined in super.transition
|
||||
transitions {
|
||||
device.wakeUp()
|
||||
}
|
||||
|
||||
super.transition(this)
|
||||
|
||||
// Needs to run at the end of the setup, so after the setup defined in super.transition
|
||||
setup {
|
||||
eachRun {
|
||||
device.sleep()
|
||||
wmHelper.waitFor("noAppWindowsOnTop") {
|
||||
it.wmState.topVisibleAppWindow.isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that we start of with no top windows and then [testApp] becomes the first and
|
||||
* only top window of the transition, with snapshot or splash screen windows optionally showing
|
||||
* first.
|
||||
*/
|
||||
@Test
|
||||
@Postsubmit
|
||||
open fun appWindowBecomesFirstAndOnlyTopWindow() {
|
||||
testSpec.assertWm {
|
||||
this.hasNoVisibleAppWindow()
|
||||
.then()
|
||||
.isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
|
||||
.then()
|
||||
.isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
|
||||
.then()
|
||||
.isAppWindowOnTop(testApp.component)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the screen is locked.
|
||||
*/
|
||||
@Test
|
||||
@Postsubmit
|
||||
fun screenLockedStart() {
|
||||
testSpec.assertLayersStart {
|
||||
isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates the test configurations.
|
||||
*
|
||||
* See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
|
||||
* repetitions, screen orientation and navigation modes.
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun getParams(): Collection<FlickerTestParameter> {
|
||||
return com.android.server.wm.flicker.FlickerTestParameterFactory.getInstance()
|
||||
.getConfigNonRotationTests(repetitions = 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.launch
|
||||
|
||||
import android.platform.test.annotations.Postsubmit
|
||||
import android.platform.test.annotations.RequiresDevice
|
||||
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
|
||||
import com.android.server.wm.flicker.FlickerTestParameter
|
||||
import com.android.server.wm.flicker.FlickerTestParameterFactory
|
||||
import com.android.server.wm.flicker.annotation.Group1
|
||||
import com.android.server.wm.flicker.dsl.FlickerBuilder
|
||||
import com.android.server.wm.flicker.helpers.ShowWhenLockedAppHelper
|
||||
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
|
||||
import com.android.server.wm.traces.common.FlickerComponentName
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
/**
|
||||
* Test cold launching an app from a notification from the lock screen when there is an app
|
||||
* overlaid on the lock screen.
|
||||
*
|
||||
* To run this test: `atest FlickerTests:OpenAppFromLockNotificationWithLockOverlayApp`
|
||||
*/
|
||||
@RequiresDevice
|
||||
@RunWith(Parameterized::class)
|
||||
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Group1
|
||||
@Postsubmit
|
||||
class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParameter)
|
||||
: OpenAppFromLockNotificationCold(testSpec) {
|
||||
private val showWhenLockedApp: ShowWhenLockedAppHelper =
|
||||
ShowWhenLockedAppHelper(instrumentation)
|
||||
|
||||
// Although we are technically still locked here, the overlay app means we should open the
|
||||
// notification shade as if we were unlocked.
|
||||
override val openingNotificationsFromLockScreen = false
|
||||
|
||||
override val transition: FlickerBuilder.() -> Unit
|
||||
get() = {
|
||||
super.transition(this)
|
||||
|
||||
setup {
|
||||
eachRun {
|
||||
device.wakeUpAndGoToHomeScreen()
|
||||
|
||||
// Launch an activity that is shown when the device is locked
|
||||
showWhenLockedApp.launchViaIntent(wmHelper)
|
||||
wmHelper.waitForFullScreenApp(showWhenLockedApp.component)
|
||||
|
||||
device.sleep()
|
||||
wmHelper.waitFor("noAppWindowsOnTop") {
|
||||
it.wmState.topVisibleAppWindow.isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
teardown {
|
||||
test {
|
||||
showWhenLockedApp.exit(wmHelper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
fun showWhenLockedAppWindowBecomesVisible() {
|
||||
testSpec.assertWm {
|
||||
this.hasNoVisibleAppWindow()
|
||||
.then()
|
||||
.isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
|
||||
.then()
|
||||
.isAppWindowOnTop(showWhenLockedApp.component)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
fun showWhenLockedAppLayerBecomesVisible() {
|
||||
testSpec.assertLayers {
|
||||
this.isInvisible(showWhenLockedApp.component)
|
||||
.then()
|
||||
.isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
|
||||
.then()
|
||||
.isVisible(showWhenLockedApp.component)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates the test configurations.
|
||||
*
|
||||
* See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
|
||||
* repetitions, screen orientation and navigation modes.
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun getParams(): Collection<FlickerTestParameter> {
|
||||
return com.android.server.wm.flicker.FlickerTestParameterFactory.getInstance()
|
||||
.getConfigNonRotationTests(repetitions = 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.launch
|
||||
|
||||
import android.platform.test.annotations.Postsubmit
|
||||
import android.platform.test.annotations.RequiresDevice
|
||||
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
|
||||
import com.android.server.wm.flicker.FlickerTestParameter
|
||||
import com.android.server.wm.flicker.FlickerTestParameterFactory
|
||||
import com.android.server.wm.flicker.annotation.Group1
|
||||
import com.android.server.wm.flicker.dsl.FlickerBuilder
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
/**
|
||||
* Test cold launching an app from a notification.
|
||||
*
|
||||
* To run this test: `atest FlickerTests:OpenAppFromNotificationCold`
|
||||
*/
|
||||
@RequiresDevice
|
||||
@RunWith(Parameterized::class)
|
||||
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Group1
|
||||
@Postsubmit
|
||||
open class OpenAppFromNotificationCold(testSpec: FlickerTestParameter)
|
||||
: OpenAppFromNotificationWarm(testSpec) {
|
||||
override val transition: FlickerBuilder.() -> Unit
|
||||
get() = {
|
||||
super.transition(this)
|
||||
|
||||
setup {
|
||||
eachRun {
|
||||
// Close the app that posted the notification to trigger a cold start next time
|
||||
// it is open - can't just kill it because that would remove the notification.
|
||||
taplInstrumentation.goHome()
|
||||
taplInstrumentation.workspace.switchToOverview()
|
||||
taplInstrumentation.overview.dismissAllTasks()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun appWindowBecomesVisible() = appWindowBecomesVisible_coldStart()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun appLayerBecomesVisible() = appLayerBecomesVisible_coldStart()
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates the test configurations.
|
||||
*
|
||||
* See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
|
||||
* repetitions, screen orientation and navigation modes.
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun getParams(): Collection<FlickerTestParameter> {
|
||||
return com.android.server.wm.flicker.FlickerTestParameterFactory.getInstance()
|
||||
.getConfigNonRotationTests(repetitions = 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm.flicker.launch
|
||||
|
||||
import android.platform.test.annotations.Postsubmit
|
||||
import android.platform.test.annotations.RequiresDevice
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowManager
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.Until
|
||||
import com.android.launcher3.tapl.LauncherInstrumentation
|
||||
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
|
||||
import com.android.server.wm.flicker.FlickerTestParameter
|
||||
import com.android.server.wm.flicker.FlickerTestParameterFactory
|
||||
import com.android.server.wm.flicker.annotation.Group1
|
||||
import com.android.server.wm.flicker.dsl.FlickerBuilder
|
||||
import com.android.server.wm.flicker.helpers.NotificationAppHelper
|
||||
import com.android.server.wm.flicker.helpers.setRotation
|
||||
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
/**
|
||||
* Test cold launching an app from a notification.
|
||||
*
|
||||
* To run this test: `atest FlickerTests:OpenAppFromNotificationWarm`
|
||||
*/
|
||||
@RequiresDevice
|
||||
@RunWith(Parameterized::class)
|
||||
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Group1
|
||||
@Postsubmit
|
||||
open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter)
|
||||
: OpenAppTransition(testSpec) {
|
||||
protected val taplInstrumentation = LauncherInstrumentation()
|
||||
|
||||
override val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
|
||||
|
||||
open val openingNotificationsFromLockScreen = false
|
||||
|
||||
override val transition: FlickerBuilder.() -> Unit
|
||||
get() = {
|
||||
setup {
|
||||
test {
|
||||
device.wakeUpAndGoToHomeScreen()
|
||||
this.setRotation(testSpec.startRotation)
|
||||
}
|
||||
eachRun {
|
||||
testApp.launchViaIntent(wmHelper)
|
||||
wmHelper.waitForFullScreenApp(testApp.component)
|
||||
testApp.postNotification(device, wmHelper)
|
||||
device.pressHome()
|
||||
wmHelper.waitForAppTransitionIdle()
|
||||
}
|
||||
}
|
||||
|
||||
transitions {
|
||||
var startY = 10
|
||||
var endY = 3 * device.displayHeight / 4
|
||||
var steps = 25
|
||||
if (openingNotificationsFromLockScreen) {
|
||||
val wm = instrumentation.context.getSystemService(WindowManager::class.java)
|
||||
val metricInsets = wm.currentWindowMetrics.windowInsets
|
||||
val insets = metricInsets.getInsetsIgnoringVisibility(
|
||||
WindowInsets.Type.statusBars()
|
||||
or WindowInsets.Type.displayCutout())
|
||||
|
||||
startY = insets.top + 100
|
||||
endY = device.displayHeight / 2
|
||||
steps = 4
|
||||
}
|
||||
|
||||
// Swipe down to show the notification shade
|
||||
val x = device.displayWidth / 2
|
||||
device.swipe(x, startY, x, endY, steps)
|
||||
device.waitForIdle(2000)
|
||||
instrumentation.uiAutomation.syncInputTransactions()
|
||||
|
||||
// Launch the activity by clicking the notification
|
||||
val notification = device.wait(Until.findObject(
|
||||
By.text("Flicker Test Notification")), 2000L)
|
||||
notification?.click() ?: error("Notification not found")
|
||||
instrumentation.uiAutomation.syncInputTransactions()
|
||||
|
||||
// Wait for the app to launch
|
||||
wmHelper.waitForFullScreenApp(testApp.component)
|
||||
}
|
||||
|
||||
teardown {
|
||||
test {
|
||||
testApp.exit(wmHelper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
|
||||
super.visibleLayersShownMoreThanOneConsecutiveEntry()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun appWindowBecomesVisible() = appWindowBecomesVisible_warmStart()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
override fun appLayerBecomesVisible() = appLayerBecomesVisible_warmStart()
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
fun notificationAppWindowVisibleAtEnd() {
|
||||
testSpec.assertWmEnd {
|
||||
this.isAppWindowVisible(testApp.component)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
fun notificationAppWindowOnTopAtEnd() {
|
||||
testSpec.assertWmEnd {
|
||||
this.isAppWindowOnTop(testApp.component)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Postsubmit
|
||||
fun notificationAppLayerVisibleAtEnd() {
|
||||
testSpec.assertLayersEnd {
|
||||
this.isVisible(testApp.component)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates the test configurations.
|
||||
*
|
||||
* See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
|
||||
* repetitions, screen orientation and navigation modes.
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun getParams(): Collection<FlickerTestParameter> {
|
||||
return FlickerTestParameterFactory.getInstance()
|
||||
.getConfigNonRotationTests(repetitions = 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,5 +130,27 @@
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ShowWhenLockedActivity"
|
||||
android:taskAffinity="com.android.server.wm.flicker.testapp.ShowWhenLockedActivity"
|
||||
android:theme="@style/CutoutShortEdges"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="ShowWhenLockedActivity"
|
||||
android:showWhenLocked="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".NotificationActivity"
|
||||
android:taskAffinity="com.android.server.wm.flicker.testapp.NotificationActivity"
|
||||
android:theme="@style/CutoutShortEdges"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
~ Copyright (C) 2022 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
||||
</vector>
|
||||
@@ -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:background="@android:color/holo_orange_light">
|
||||
<Button
|
||||
android:id="@+id/post_notification"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Post Notification" />
|
||||
</LinearLayout>
|
||||
@@ -72,4 +72,14 @@ public class ActivityOptions {
|
||||
public static final ComponentName EDITOR_POPUP_DIALOG_ACTIVITY_COMPONENT_NAME =
|
||||
new ComponentName(FLICKER_APP_PACKAGE,
|
||||
FLICKER_APP_PACKAGE + ".ImeEditorPopupDialogActivity");
|
||||
|
||||
public static final String SHOW_WHEN_LOCKED_ACTIVITY_LAUNCHER_NAME = "ShowWhenLockedApp";
|
||||
public static final ComponentName SHOW_WHEN_LOCKED_ACTIVITY_COMPONENT_NAME =
|
||||
new ComponentName(FLICKER_APP_PACKAGE,
|
||||
FLICKER_APP_PACKAGE + ".ShowWhenLockedActivity");
|
||||
|
||||
public static final String NOTIFICATION_ACTIVITY_LAUNCHER_NAME = "NotificationApp";
|
||||
public static final ComponentName NOTIFICATION_ACTIVITY_COMPONENT_NAME =
|
||||
new ComponentName(FLICKER_APP_PACKAGE,
|
||||
FLICKER_APP_PACKAGE + ".NotificationActivity");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.testapp;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.TaskStackBuilder;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
|
||||
public class NotificationActivity extends Activity {
|
||||
private static final String CHANNEL_ID = "notification_channel";
|
||||
private static final int NOTIFICATION_ID = 1;
|
||||
|
||||
@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.notification_button);
|
||||
|
||||
Button button = findViewById(R.id.post_notification);
|
||||
button.setOnClickListener(v -> postNotification());
|
||||
|
||||
createNotificationChannel();
|
||||
}
|
||||
|
||||
private void postNotification() {
|
||||
Intent resultIntent = new Intent(this, NotificationActivity.class);
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
|
||||
stackBuilder.addNextIntentWithParentStack(resultIntent);
|
||||
PendingIntent resultPendingIntent =
|
||||
stackBuilder.getPendingIntent(0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle("Flicker Test Notification")
|
||||
.setContentText("Flicker Test Notification")
|
||||
// Set the intent that will fire when the user taps the notification
|
||||
.setContentIntent(resultPendingIntent)
|
||||
.setAutoCancel(true);
|
||||
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build());
|
||||
}
|
||||
|
||||
private void createNotificationChannel() {
|
||||
CharSequence name = "channel_name";
|
||||
String description = "channel_description";
|
||||
int importance = NotificationManager.IMPORTANCE_HIGH;
|
||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
|
||||
channel.setDescription(description);
|
||||
// Register the channel with the system; you can't change the importance
|
||||
// or other notification behaviors after this
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.testapp;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class ShowWhenLockedActivity 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_simple);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user