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

Commit 8419ae39 authored by Michael Mikhail's avatar Michael Mikhail Committed by Android (Google) Code Review
Browse files

Merge "Send binder calls in MediaResumeListener to background thread" into main

parents f7b5cd65 4f7d725c
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ constructor(
            field?.disconnect()
            field = value
        }

    private var currentUserId: Int = context.userId

    @VisibleForTesting
@@ -89,7 +90,7 @@ constructor(
                if (Intent.ACTION_USER_UNLOCKED == intent.action) {
                    val userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)
                    if (userId == currentUserId) {
                        loadMediaResumptionControls()
                        backgroundExecutor.execute { loadMediaResumptionControls() }
                    }
                }
            }
@@ -254,6 +255,7 @@ constructor(
            if (data.resumeAction == null && !data.hasCheckedForResume && isEligibleForResume) {
                // TODO also check for a media button receiver intended for restarting (b/154127084)
                // Set null action to prevent additional attempts to connect
                backgroundExecutor.execute {
                    mediaDataManager.setResumeAction(key, null)
                    Log.d(TAG, "Checking for service component for " + data.packageName)
                    val pm = context.packageManager
@@ -262,7 +264,6 @@ constructor(

                    val inf = resumeInfo?.filter { it.serviceInfo.packageName == data.packageName }
                    if (inf != null && inf.size > 0) {
                    backgroundExecutor.execute {
                        tryUpdateResumptionList(key, inf!!.get(0).componentInfo.componentName)
                    }
                }
+33 −26
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
        whenever(mockContext.packageManager).thenReturn(context.packageManager)
        whenever(mockContext.contentResolver).thenReturn(context.contentResolver)
        whenever(mockContext.userId).thenReturn(context.userId)
        whenever(mockContext.resources).thenReturn(context.resources)
        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false)

        executor = FakeExecutor(clock)
@@ -210,7 +211,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
    @Test
    fun testOnLoad_checksForResume_noService() {
        // When media data is loaded that has not been checked yet, and does not have a MBS
        resumeListener.onMediaDataLoaded(KEY, null, data)
        onMediaDataLoaded(KEY, null, data)

        // Then we report back to the manager
        verify(mediaDataManager).setResumeAction(KEY, null)
@@ -223,8 +224,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
        whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() }

        // When media data is loaded that has not been checked yet, and does not have a MBS
        resumeListener.onMediaDataLoaded(KEY, null, data)
        executor.runAllReady()
        onMediaDataLoaded(KEY, null, data)

        // Then we report back to the manager
        verify(mediaDataManager).setResumeAction(eq(KEY), eq(null))
@@ -234,7 +234,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
    fun testOnLoad_localCast_doesNotCheck() {
        // When media data is loaded that has not been checked yet, and is a local cast
        val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
        resumeListener.onMediaDataLoaded(KEY, null, dataCast)
        onMediaDataLoaded(KEY, null, dataCast, false)

        // Then we do not take action
        verify(mediaDataManager, never()).setResumeAction(any(), any())
@@ -244,7 +244,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
    fun testOnload_remoteCast_doesNotCheck() {
        // When media data is loaded that has not been checked yet, and is a remote cast
        val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE)
        resumeListener.onMediaDataLoaded(KEY, null, dataRcn)
        onMediaDataLoaded(KEY, null, dataRcn, resume = false)

        // Then we do not take action
        verify(mediaDataManager, never()).setResumeAction(any(), any())
@@ -257,7 +257,7 @@ class MediaResumeListenerTest : SysuiTestCase() {

        // When media data is loaded that has not been checked yet, and is a local cast
        val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
        resumeListener.onMediaDataLoaded(KEY, null, dataCast)
        onMediaDataLoaded(KEY, null, dataCast)

        // Then we report back to the manager
        verify(mediaDataManager).setResumeAction(KEY, null)
@@ -270,7 +270,7 @@ class MediaResumeListenerTest : SysuiTestCase() {

        // When media data is loaded that has not been checked yet, and is a remote cast
        val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE)
        resumeListener.onMediaDataLoaded(KEY, null, dataRcn)
        onMediaDataLoaded(KEY, null, dataRcn, false)

        // Then we do not take action
        verify(mediaDataManager, never()).setResumeAction(any(), any())
@@ -288,10 +288,9 @@ class MediaResumeListenerTest : SysuiTestCase() {

        // When media data is loaded that has not been checked yet, and does have a MBS
        val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
        resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
        onMediaDataLoaded(KEY, null, dataCopy)

        // Then we test whether the service is valid
        executor.runAllReady()
        verify(mediaDataManager).setResumeAction(eq(KEY), eq(null))
        verify(resumeBrowser).testConnection()

@@ -307,7 +306,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
    fun testOnLoad_doesNotCheckAgain() {
        // When a media data is loaded that has been checked already
        var dataCopy = data.copy(hasCheckedForResume = true)
        resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
        onMediaDataLoaded(KEY, null, dataCopy, resume = false)

        // Then we should not check it again
        verify(resumeBrowser, never()).testConnection()
@@ -320,17 +319,15 @@ class MediaResumeListenerTest : SysuiTestCase() {
        setUpMbsWithValidResolveInfo()
        resumeListener.onMediaDataLoaded(KEY, null, data)

        // We notify the manager to set a null action
        verify(mediaDataManager).setResumeAction(KEY, null)

        // If we then get another update from the app before the first check completes
        assertThat(executor.numPending()).isEqualTo(1)
        var dataWithCheck = data.copy(hasCheckedForResume = true)
        resumeListener.onMediaDataLoaded(KEY, null, dataWithCheck)

        // We do not try to start another check
        assertThat(executor.numPending()).isEqualTo(1)
        executor.runAllReady()
        verify(mediaDataManager).setResumeAction(KEY, null)
        verify(resumeBrowserFactory, times(1)).create(any(), any(), anyInt())
    }

    @Test
@@ -363,6 +360,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
        resumeListener.userUnlockReceiver.onReceive(context, intent)

        // Then we should attempt to find recent media for each saved component
        executor.runAllReady()
        verify(resumeBrowser, times(3)).findRecentMedia()

        // Then since the mock service found media, the manager should be informed
@@ -382,10 +380,9 @@ class MediaResumeListenerTest : SysuiTestCase() {

        // When media data is loaded that has not been checked yet, and does have a MBS
        val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
        resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
        onMediaDataLoaded(KEY, null, dataCopy)

        // Then we test whether the service is valid and set the resume action
        executor.runAllReady()
        verify(mediaDataManager).setResumeAction(eq(KEY), eq(null))
        verify(resumeBrowser).testConnection()
        verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor))
@@ -455,6 +452,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
        resumeListener.userUnlockReceiver.onReceive(mockContext, intent)

        // We add its resume controls
        executor.runAllReady()
        verify(resumeBrowser).findRecentMedia()
        verify(mediaDataManager)
            .addResumptionControls(anyInt(), any(), any(), any(), any(), any(), eq(PACKAGE_NAME))
@@ -527,7 +525,7 @@ class MediaResumeListenerTest : SysuiTestCase() {

        // When media data is loaded that has not been checked yet, and does have a MBS
        val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
        resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
        onMediaDataLoaded(KEY, null, dataCopy)

        // Then we store the new lastPlayed time
        verify(sharedPrefsEditor).putString(any(), (capture(componentCaptor)))
@@ -546,10 +544,9 @@ class MediaResumeListenerTest : SysuiTestCase() {
    fun testOnMediaDataLoaded_newKeyDifferent_oldMediaBrowserDisconnected() {
        setUpMbsWithValidResolveInfo()

        resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data)
        executor.runAllReady()
        onMediaDataLoaded(key = KEY, oldKey = null, data)

        resumeListener.onMediaDataLoaded(key = "newKey", oldKey = KEY, data)
        onMediaDataLoaded(key = "newKey", oldKey = KEY, data)

        verify(resumeBrowser).disconnect()
    }
@@ -561,8 +558,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
        // Set up mocks to return with an error
        whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() }

        resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data)
        executor.runAllReady()
        onMediaDataLoaded(key = KEY, oldKey = null, data)

        // Ensure we disconnect the browser
        verify(resumeBrowser).disconnect()
@@ -579,8 +575,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
            callbackCaptor.value.addTrack(description, component, resumeBrowser)
        }

        resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data)
        executor.runAllReady()
        onMediaDataLoaded(key = KEY, oldKey = null, data)

        // Ensure we disconnect the browser
        verify(resumeBrowser).disconnect()
@@ -598,8 +593,7 @@ class MediaResumeListenerTest : SysuiTestCase() {

        // Load media data that will require us to get the resume action
        val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false)
        resumeListener.onMediaDataLoaded(KEY, null, dataCopy)
        executor.runAllReady()
        onMediaDataLoaded(KEY, null, dataCopy)
        verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor))

        // Set up our factory to return a new browser so we can verify we disconnected the old one
@@ -634,6 +628,7 @@ class MediaResumeListenerTest : SysuiTestCase() {
        // When the first user unlocks and we query their recent media
        userCallbackCaptor.value.onUserChanged(firstUserId, context)
        resumeListener.userUnlockReceiver.onReceive(context, unlockIntent)
        executor.runAllReady()
        whenever(resumeBrowser.userId).thenReturn(userIdCaptor.value)
        verify(resumeBrowser, times(3)).findRecentMedia()

@@ -688,4 +683,16 @@ class MediaResumeListenerTest : SysuiTestCase() {
        whenever(pm.resolveServiceAsUser(any(), anyInt(), anyInt())).thenReturn(resolveInfo)
        whenever(pm.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)
    }

    private fun onMediaDataLoaded(
        key: String,
        oldKey: String?,
        data: MediaData,
        resume: Boolean = true
    ) {
        resumeListener.onMediaDataLoaded(key, oldKey, data)
        if (resume) {
            assertThat(executor.runAllReady()).isEqualTo(1)
        }
    }
}