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

Commit 39b9066f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Test PipNotification when there is a MediaSession" am: 445e6238

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12977413

Change-Id: Ide114402624d2ba2093b6e4255c3ae2979f6a0f2
parents 67eadbd4 445e6238
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
    <uses-permission android:name="android.permission.READ_LOGS"/>
    <!-- Force-stop test apps -->
    <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
    <!-- Control test app's media session -->
    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
    <application>
        <uses-library android:name="android.test.runner"/>

+12 −2
Original line number Diff line number Diff line
@@ -74,11 +74,21 @@ class NotificationListener : NotificationListenerService() {
            return wait { instance == null }
        }

        fun findNotification(
            predicate: (StatusBarNotification) -> Boolean
        ): StatusBarNotification? {
            instance?.run {
                return notifications.values.firstOrNull(predicate)
            } ?: throw IllegalStateException("NotificationListenerService is not connected")
        }

        fun waitForNotificationToAppear(
            predicate: (StatusBarNotification) -> Boolean
        ): StatusBarNotification? {
            return instance?.let {
                waitForResult(extractor = { it.notifications.values.first(predicate) }).second
            instance?.let {
                return waitForResult(extractor = {
                    it.notifications.values.firstOrNull(predicate)
                }).second
            } ?: throw IllegalStateException("NotificationListenerService is not connected")
        }

+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ abstract class BaseAppHelper(
) {
    protected val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)

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

    private val activityManager: ActivityManager?
+24 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.wm.shell.flicker.helpers

import android.app.Instrumentation
import android.media.session.MediaController
import android.media.session.MediaSessionManager
import android.os.SystemClock
import android.view.KeyEvent.KEYCODE_WINDOW
import androidx.test.uiautomator.By
@@ -35,6 +37,15 @@ class PipAppHelper(
        TEST_APP_PIP_ACTIVITY_LABEL,
        TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
) {
    private val mediaSessionManager: MediaSessionManager
        get() = context.getSystemService(MediaSessionManager::class.java)
                ?: error("Could not get MediaSessionManager")

    private val mediaController: MediaController?
        get() = mediaSessionManager.getActiveSessions(null).firstOrNull {
            it.packageName == packageName
        }

    fun clickEnterPipButton() {
        val enterPipButton = uiDevice.findObject(By.res(packageName, "enter_pip"))
        assertNotNull("Pip button not found, this usually happens when the device " +
@@ -50,6 +61,19 @@ class PipAppHelper(
        }
    }

    fun clickStartMediaSessionButton() {
        val startButton = uiDevice.findObject(By.res(packageName, "media_session_start"))
        assertNotNull("Start button not found, this usually happens when the device " +
                "was left in an unknown state (e.g. in split screen)", startButton)
        startButton.click()
    }

    fun pauseMedia() = mediaController?.transportControls?.pause()
            ?: error("No active media session found")

    fun stopMedia() = mediaController?.transportControls?.stop()
            ?: error("No active media session found")

    fun closePipWindow() {
        // TODO(b/172321238): remove this check once and simply call closePipWindow once the TV
        //  logic is integrated there.
+52 −4
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@ import android.os.Bundle
import android.service.notification.StatusBarNotification
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.NotificationListener.Companion.findNotification
import com.android.wm.shell.flicker.NotificationListener.Companion.startNotificationListener
import com.android.wm.shell.flicker.NotificationListener.Companion.stopNotificationListener
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.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.FixMethodOrder
@@ -83,10 +85,10 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)

        val notification: StatusBarNotification = waitForNotificationToAppear {
            it.isPipNotificationWithTitle(testApp.label)
        } ?: throw AssertionError("Pip notification should have been posted")
        } ?: fail("Pip notification should have been posted")

        notification.deleteIntent?.send()
            ?: throw AssertionError("Pip notification should contain `delete_intent`")
            ?: fail("Pip notification should contain `delete_intent`")

        assertTrue("Pip should have closed by sending the `delete_intent`",
                testApp.waitUntilClosed())
@@ -101,10 +103,10 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)

        val notification: StatusBarNotification = waitForNotificationToAppear {
            it.isPipNotificationWithTitle(testApp.label)
        } ?: throw AssertionError("Pip notification should have been posted")
        } ?: fail("Pip notification should have been posted")

        notification.contentIntent?.send()
            ?: throw AssertionError("Pip notification should contain `content_intent`")
            ?: fail("Pip notification should contain `content_intent`")

        assertTrue("Pip menu should have been shown after sending `content_intent`",
                uiDevice.waitForTvPipMenu())
@@ -113,7 +115,53 @@ class TvPipNotificationTests(rotationName: String, rotation: Int)
        testApp.closePipWindow()
    }

    @Test
    fun pipNotification_mediaSessionTitle_isDisplayed() {
        testApp.launchViaIntent()
        // Start media session and to PiP
        testApp.clickStartMediaSessionButton()
        testApp.clickEnterPipButton()

        // Wait for the correct notification to show up...
        waitForNotificationToAppear {
            it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PLAYING)
        } ?: fail("Pip notification with media session title should have been posted")
        // ... and make sure "regular" PiP notification is now shown
        assertNull("Regular notification should not have been posted",
            findNotification { it.isPipNotificationWithTitle(testApp.label) })

        // Pause the media session. When paused the application updates the title for the media
        // session. This change should be reflected in the notification.
        testApp.pauseMedia()

        // Wait for the "paused" notification to show up...
        waitForNotificationToAppear {
            it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PAUSED)
        } ?: fail("Pip notification with media session title should have been posted")
        // ... and make sure "playing" PiP notification is gone
        assertNull("Regular notification should not have been posted",
                findNotification { it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PLAYING) })

        // Now stop the media session, which should revert the title to the "default" one.
        testApp.stopMedia()

        // Wait for the "regular" notification to show up...
        waitForNotificationToAppear {
            it.isPipNotificationWithTitle(testApp.label)
        } ?: fail("Pip notification with media session title should have been posted")
        // ... and make sure previous ("paused") notification is gone
        assertNull("Regular notification should not have been posted",
                findNotification { it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PAUSED) })

        testApp.closePipWindow()
    }

    private fun fail(message: String): Nothing = throw AssertionError(message)

    companion object {
        private const val TITLE_MEDIA_SESSION_PLAYING = "TestApp media is playing"
        private const val TITLE_MEDIA_SESSION_PAUSED = "TestApp media is paused"

        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): Collection<Array<Any>> {
Loading