1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm.flicker.notification 18 19 import android.platform.systemui_tapl.controller.NotificationIdentity 20 import android.platform.systemui_tapl.ui.Root 21 import android.platform.test.annotations.Postsubmit 22 import android.platform.test.annotations.Presubmit 23 import android.platform.test.rule.DisableNotificationCooldownSettingRule 24 import android.tools.flicker.junit.FlickerParametersRunnerFactory 25 import android.tools.flicker.legacy.FlickerBuilder 26 import android.tools.flicker.legacy.FlickerTestData 27 import android.tools.flicker.legacy.LegacyFlickerTest 28 import android.tools.flicker.legacy.LegacyFlickerTestFactory 29 import android.tools.helpers.wakeUpAndGoToHomeScreen 30 import android.tools.traces.component.ComponentNameMatcher 31 import android.view.WindowInsets 32 import android.view.WindowManager 33 import com.android.server.wm.flicker.helpers.NotificationAppHelper 34 import com.android.server.wm.flicker.helpers.setRotation 35 import com.android.server.wm.flicker.navBarLayerIsVisibleAtEnd 36 import com.android.server.wm.flicker.navBarLayerPositionAtEnd 37 import com.android.server.wm.flicker.navBarWindowIsVisibleAtEnd 38 import com.android.server.wm.flicker.taskBarLayerIsVisibleAtEnd 39 import com.android.server.wm.flicker.taskBarWindowIsVisibleAtEnd 40 import org.junit.Assume 41 import org.junit.ClassRule 42 import org.junit.FixMethodOrder 43 import org.junit.Ignore 44 import org.junit.Test 45 import org.junit.runner.RunWith 46 import org.junit.runners.MethodSorters 47 import org.junit.runners.Parameterized 48 49 /** 50 * Test cold launching an app from a notification. 51 * 52 * To run this test: `atest FlickerTestsNotification:OpenAppFromNotificationWarmTest` 53 */ 54 @RunWith(Parameterized::class) 55 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) 56 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 57 open class OpenAppFromNotificationWarmTest(flicker: LegacyFlickerTest) : 58 OpenAppTransition(flicker) { 59 override val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation) 60 61 /** {@inheritDoc} */ 62 override val transition: FlickerBuilder.() -> Unit <lambda>null63 get() = { 64 setup { 65 device.wakeUpAndGoToHomeScreen() 66 this.setRotation(flicker.scenario.startRotation) 67 launchAppAndPostNotification() 68 goHome() 69 } 70 71 transitions { openAppFromNotification() } 72 73 teardown { testApp.exit(wmHelper) } 74 } 75 launchAppAndPostNotificationnull76 protected fun FlickerTestData.launchAppAndPostNotification() { 77 testApp.launchViaIntent(wmHelper) 78 wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify() 79 testApp.postNotification(wmHelper) 80 } 81 FlickerTestDatanull82 protected fun FlickerTestData.goHome() { 83 device.pressHome() 84 wmHelper 85 .StateSyncBuilder() 86 .withHomeActivityVisible() 87 .withWindowSurfaceDisappeared(ComponentNameMatcher.NOTIFICATION_SHADE) 88 .waitForAndVerify() 89 } 90 openAppFromNotificationnull91 protected fun FlickerTestData.openAppFromNotification() { 92 doOpenAppAndWait() 93 } 94 FlickerTestDatanull95 protected fun FlickerTestData.openAppFromLockNotification() { 96 val wm: WindowManager = 97 instrumentation.context.getSystemService(WindowManager::class.java) 98 ?: error("Unable to connect to WindowManager service") 99 val metricInsets = wm.currentWindowMetrics.windowInsets 100 val insets = 101 metricInsets.getInsetsIgnoringVisibility( 102 WindowInsets.Type.statusBars() or WindowInsets.Type.displayCutout() 103 ) 104 105 doOpenAppAndWait() 106 } 107 FlickerTestDatanull108 protected fun FlickerTestData.doOpenAppAndWait() { 109 val shade = Root.get().openNotificationShade() 110 111 // Launch the activity by clicking the notification 112 // Post notification and ensure that it's collapsed 113 val notification = 114 shade.notificationStack.findNotification( 115 NotificationIdentity( 116 type = NotificationIdentity.Type.BY_TEXT, 117 text = "Flicker Test Notification", 118 ) 119 ) 120 121 notification.clickToApp() 122 // Wait for the app to launch 123 wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify() 124 } 125 appWindowBecomesVisiblenull126 @Presubmit @Test override fun appWindowBecomesVisible() = appWindowBecomesVisible_warmStart() 127 128 @Presubmit @Test override fun appLayerBecomesVisible() = appLayerBecomesVisible_warmStart() 129 130 @Presubmit 131 @Test 132 open fun notificationAppWindowVisibleAtEnd() { 133 flicker.assertWmEnd { this.isAppWindowVisible(testApp) } 134 } 135 136 @Presubmit 137 @Test notificationAppWindowOnTopAtEndnull138 open fun notificationAppWindowOnTopAtEnd() { 139 flicker.assertWmEnd { this.isAppWindowOnTop(testApp) } 140 } 141 142 @Presubmit 143 @Test notificationAppLayerVisibleAtEndnull144 open fun notificationAppLayerVisibleAtEnd() { 145 flicker.assertLayersEnd { this.isVisible(testApp) } 146 } 147 148 /** 149 * Checks that the [ComponentNameMatcher.TASK_BAR] window is visible at the end of the 150 * transition 151 * 152 * Note: Large screen only 153 */ 154 @Presubmit 155 @Test taskBarWindowIsVisibleAtEndnull156 open fun taskBarWindowIsVisibleAtEnd() { 157 Assume.assumeTrue(usesTaskbar) 158 flicker.taskBarWindowIsVisibleAtEnd() 159 } 160 161 /** 162 * Checks that the [ComponentNameMatcher.TASK_BAR] layer is visible at the end of the transition 163 * 164 * Note: Large screen only 165 */ 166 @Presubmit 167 @Test taskBarLayerIsVisibleAtEndnull168 open fun taskBarLayerIsVisibleAtEnd() { 169 Assume.assumeTrue(usesTaskbar) 170 flicker.taskBarLayerIsVisibleAtEnd() 171 } 172 173 /** Checks the position of the [ComponentNameMatcher.NAV_BAR] at the end of the transition */ 174 @Presubmit 175 @Test navBarLayerPositionAtEndnull176 open fun navBarLayerPositionAtEnd() { 177 Assume.assumeFalse(usesTaskbar) 178 flicker.navBarLayerPositionAtEnd() 179 } 180 181 /** {@inheritDoc} */ 182 @Presubmit 183 @Test navBarLayerIsVisibleAtEndnull184 open fun navBarLayerIsVisibleAtEnd() { 185 Assume.assumeFalse(usesTaskbar) 186 flicker.navBarLayerIsVisibleAtEnd() 187 } 188 189 @Presubmit 190 @Test navBarWindowIsVisibleAtEndnull191 open fun navBarWindowIsVisibleAtEnd() { 192 Assume.assumeFalse(usesTaskbar) 193 flicker.navBarWindowIsVisibleAtEnd() 194 } 195 196 /** {@inheritDoc} */ 197 @Test 198 @Ignore("Display is off at the start") taskBarLayerIsVisibleAtStartAndEndnull199 override fun taskBarLayerIsVisibleAtStartAndEnd() {} 200 201 /** {@inheritDoc} */ 202 @Test 203 @Postsubmit taskBarWindowIsAlwaysVisiblenull204 override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible() 205 206 companion object { 207 /** 208 * Creates the test configurations. 209 * 210 * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and 211 * navigation modes. 212 */ 213 @Parameterized.Parameters(name = "{0}") 214 @JvmStatic 215 fun getParams() = LegacyFlickerTestFactory.nonRotationTests() 216 217 /** Ensures that posted notifications will alert and HUN even just after boot. */ 218 @ClassRule 219 @JvmField 220 val disablenotificationCooldown = DisableNotificationCooldownSettingRule() 221 } 222 } 223