Merge "Add tests for TV Pip notification intents"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5902a6dcb8
@@ -74,13 +74,17 @@ class NotificationListener : NotificationListenerService() {
|
||||
return wait { instance == null }
|
||||
}
|
||||
|
||||
fun waitForNotificationToAppear(predicate: (StatusBarNotification) -> Boolean): Boolean {
|
||||
fun waitForNotificationToAppear(
|
||||
predicate: (StatusBarNotification) -> Boolean
|
||||
): StatusBarNotification? {
|
||||
return instance?.let {
|
||||
wait { it.notifications.values.any(predicate) }
|
||||
waitForResult(extractor = { it.notifications.values.first(predicate) }).second
|
||||
} ?: throw IllegalStateException("NotificationListenerService is not connected")
|
||||
}
|
||||
|
||||
fun waitForNotificationToDisappear(predicate: (StatusBarNotification) -> Boolean): Boolean {
|
||||
fun waitForNotificationToDisappear(
|
||||
predicate: (StatusBarNotification) -> Boolean
|
||||
): Boolean {
|
||||
return instance?.let {
|
||||
wait { it.notifications.values.none(predicate) }
|
||||
} ?: throw IllegalStateException("NotificationListenerService is not connected")
|
||||
|
||||
@@ -66,6 +66,10 @@ abstract class BaseAppHelper(
|
||||
uiDevice.wait(Until.hasObject(appSelector), APP_LAUNCH_WAIT_TIME_MS)
|
||||
}
|
||||
|
||||
fun waitUntilClosed(): Boolean {
|
||||
return uiDevice.wait(Until.gone(appSelector), APP_CLOSE_WAIT_TIME_MS)
|
||||
}
|
||||
|
||||
fun forceStop() = activityManager?.forceStopPackage(packageName)
|
||||
|
||||
override fun getOpenAppIntent(): Intent {
|
||||
@@ -77,5 +81,6 @@ abstract class BaseAppHelper(
|
||||
|
||||
companion object {
|
||||
private const val APP_LAUNCH_WAIT_TIME_MS = 10_000L
|
||||
private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,7 @@ class PipAppHelper(
|
||||
assertNotNull("Pip menu close button is not found", closeButton)
|
||||
closeButton.click()
|
||||
|
||||
// Give it 1 second, just in case
|
||||
SystemClock.sleep(1_000)
|
||||
waitUntilClosed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.wm.shell.flicker.pip.tv
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.os.Bundle
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.view.Surface
|
||||
import androidx.test.filters.RequiresDevice
|
||||
@@ -25,6 +27,7 @@ import com.android.wm.shell.flicker.NotificationListener.Companion.stopNotificat
|
||||
import com.android.wm.shell.flicker.NotificationListener.Companion.waitForNotificationToAppear
|
||||
import com.android.wm.shell.flicker.NotificationListener.Companion.waitForNotificationToDisappear
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.FixMethodOrder
|
||||
@@ -64,7 +67,7 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)
|
||||
testApp.launchViaIntent()
|
||||
testApp.clickEnterPipButton()
|
||||
|
||||
assertTrue("Pip notification should have been posted",
|
||||
assertNotNull("Pip notification should have been posted",
|
||||
waitForNotificationToAppear { it.isPipNotificationWithTitle(testApp.label) })
|
||||
|
||||
testApp.closePipWindow()
|
||||
@@ -73,6 +76,43 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)
|
||||
waitForNotificationToDisappear { it.isPipNotificationWithTitle(testApp.label) })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pipNotification_closeIntent() {
|
||||
testApp.launchViaIntent()
|
||||
testApp.clickEnterPipButton()
|
||||
|
||||
val notification: StatusBarNotification = waitForNotificationToAppear {
|
||||
it.isPipNotificationWithTitle(testApp.label)
|
||||
} ?: throw AssertionError("Pip notification should have been posted")
|
||||
|
||||
notification.deleteIntent?.send()
|
||||
?: throw AssertionError("Pip notification should contain `delete_intent`")
|
||||
|
||||
assertTrue("Pip should have closed by sending the `delete_intent`",
|
||||
testApp.waitUntilClosed())
|
||||
assertTrue("Pip notification should have been dismissed",
|
||||
waitForNotificationToDisappear { it.isPipNotificationWithTitle(testApp.label) })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pipNotification_menuIntent() {
|
||||
testApp.launchViaIntent()
|
||||
testApp.clickEnterPipButton()
|
||||
|
||||
val notification: StatusBarNotification = waitForNotificationToAppear {
|
||||
it.isPipNotificationWithTitle(testApp.label)
|
||||
} ?: throw AssertionError("Pip notification should have been posted")
|
||||
|
||||
notification.contentIntent?.send()
|
||||
?: throw AssertionError("Pip notification should contain `content_intent`")
|
||||
|
||||
assertTrue("Pip menu should have been shown after sending `content_intent`",
|
||||
uiDevice.waitForTvPipMenu())
|
||||
|
||||
uiDevice.pressBack()
|
||||
testApp.closePipWindow()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
@@ -83,10 +123,23 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)
|
||||
}
|
||||
}
|
||||
|
||||
private const val PIP_NOTIFICATION_TAG = "PipNotification"
|
||||
private val StatusBarNotification.extras: Bundle?
|
||||
get() = notification?.extras
|
||||
|
||||
private val StatusBarNotification.title: String
|
||||
get() = notification?.extras?.getString(Notification.EXTRA_TITLE) ?: ""
|
||||
get() = extras?.getString(Notification.EXTRA_TITLE) ?: ""
|
||||
|
||||
/** Get TV extensions with [android.app.Notification.TvExtender.EXTRA_TV_EXTENDER]. */
|
||||
private val StatusBarNotification.tvExtensions: Bundle?
|
||||
get() = extras?.getBundle("android.tv.EXTENSIONS")
|
||||
|
||||
/** "Content" TV intent with key [android.app.Notification.TvExtender.EXTRA_CONTENT_INTENT]. */
|
||||
private val StatusBarNotification.contentIntent: PendingIntent?
|
||||
get() = tvExtensions?.getParcelable("content_intent")
|
||||
|
||||
/** "Delete" TV intent with key [android.app.Notification.TvExtender.EXTRA_DELETE_INTENT]. */
|
||||
private val StatusBarNotification.deleteIntent: PendingIntent?
|
||||
get() = tvExtensions?.getParcelable("delete_intent")
|
||||
|
||||
private fun StatusBarNotification.isPipNotificationWithTitle(expectedTitle: String): Boolean =
|
||||
tag == PIP_NOTIFICATION_TAG && title == expectedTitle
|
||||
tag == "PipNotification" && title == expectedTitle
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.tv
|
||||
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
|
||||
|
||||
fun UiDevice.waitForTvPipMenu(): Boolean {
|
||||
return wait(Until.findObject(By.res(SYSTEM_UI_PACKAGE_NAME, "pip_controls")), 3_000) != null
|
||||
}
|
||||
Reference in New Issue
Block a user