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

Commit 5d87980a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move call to MediaRouter2Manager to worker thread" into rvc-qpr-dev

parents 8c35d007 0db7d12a
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -19,8 +19,12 @@ package com.android.systemui.media
import android.content.Context
import android.media.MediaRouter2Manager
import android.media.session.MediaController
import androidx.annotation.AnyThread
import androidx.annotation.MainThread
import androidx.annotation.WorkerThread
import com.android.settingslib.media.LocalMediaManager
import com.android.settingslib.media.MediaDevice
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.Dumpable
import com.android.systemui.dump.DumpManager
@@ -39,11 +43,12 @@ class MediaDeviceManager @Inject constructor(
    private val localMediaManagerFactory: LocalMediaManagerFactory,
    private val mr2manager: MediaRouter2Manager,
    @Main private val fgExecutor: Executor,
    @Background private val bgExecutor: Executor,
    private val mediaDataManager: MediaDataManager,
    private val dumpManager: DumpManager
) : MediaDataManager.Listener, Dumpable {
    private val listeners: MutableSet<Listener> = mutableSetOf()
    private val entries: MutableMap<String, Token> = mutableMapOf()
    private val entries: MutableMap<String, Entry> = mutableMapOf()

    init {
        mediaDataManager.addListener(this)
@@ -71,7 +76,7 @@ class MediaDeviceManager @Inject constructor(
            val controller = data.token?.let {
                MediaController(context, it)
            }
            entry = Token(key, oldKey, controller,
            entry = Entry(key, oldKey, controller,
                    localMediaManagerFactory.create(data.packageName))
            entries[key] = entry
            entry.start()
@@ -99,6 +104,7 @@ class MediaDeviceManager @Inject constructor(
        }
    }

    @MainThread
    private fun processDevice(key: String, oldKey: String?, device: MediaDevice?) {
        val enabled = device != null
        val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name)
@@ -114,12 +120,13 @@ class MediaDeviceManager @Inject constructor(
        fun onKeyRemoved(key: String)
    }

    private inner class Token(
    private inner class Entry(
        val key: String,
        val oldKey: String?,
        val controller: MediaController?,
        val localMediaManager: LocalMediaManager
    ) : LocalMediaManager.DeviceCallback {

        val token
            get() = controller?.sessionToken
        private var started = false
@@ -127,20 +134,27 @@ class MediaDeviceManager @Inject constructor(
            set(value) {
                if (!started || value != field) {
                    field = value
                    fgExecutor.execute {
                        processDevice(key, oldKey, value)
                    }
                }
        fun start() {
            }

        @AnyThread
        fun start() = bgExecutor.execute {
            localMediaManager.registerCallback(this)
            localMediaManager.startScan()
            updateCurrent()
            started = true
        }
        fun stop() {

        @AnyThread
        fun stop() = bgExecutor.execute {
            started = false
            localMediaManager.stopScan()
            localMediaManager.unregisterCallback(this)
        }

        fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
            val route = controller?.let {
                mr2manager.getRoutingSessionForMediaController(it)
@@ -152,14 +166,18 @@ class MediaDeviceManager @Inject constructor(
                println("    route=$route")
            }
        }
        override fun onDeviceListUpdate(devices: List<MediaDevice>?) = fgExecutor.execute {

        override fun onDeviceListUpdate(devices: List<MediaDevice>?) = bgExecutor.execute {
            updateCurrent()
        }

        override fun onSelectedDeviceStateChanged(device: MediaDevice, state: Int) {
            fgExecutor.execute {
            bgExecutor.execute {
                updateCurrent()
            }
        }

        @WorkerThread
        private fun updateCurrent() {
            val device = localMediaManager.getCurrentConnectedDevice()
            controller?.let {
+36 −12
Original line number Diff line number Diff line
@@ -72,7 +72,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    @Mock private lateinit var lmmFactory: LocalMediaManagerFactory
    @Mock private lateinit var lmm: LocalMediaManager
    @Mock private lateinit var mr2: MediaRouter2Manager
    private lateinit var fakeExecutor: FakeExecutor
    private lateinit var fakeFgExecutor: FakeExecutor
    private lateinit var fakeBgExecutor: FakeExecutor
    @Mock private lateinit var dumpster: DumpManager
    @Mock private lateinit var listener: MediaDeviceManager.Listener
    @Mock private lateinit var device: MediaDevice
@@ -87,9 +88,10 @@ public class MediaDeviceManagerTest : SysuiTestCase() {

    @Before
    fun setUp() {
        fakeExecutor = FakeExecutor(FakeSystemClock())
        manager = MediaDeviceManager(context, lmmFactory, mr2, fakeExecutor, mediaDataManager,
                dumpster)
        fakeFgExecutor = FakeExecutor(FakeSystemClock())
        fakeBgExecutor = FakeExecutor(FakeSystemClock())
        manager = MediaDeviceManager(context, lmmFactory, mr2, fakeFgExecutor, fakeBgExecutor,
                mediaDataManager, dumpster)
        manager.addListener(listener)

        // Configure mocks.
@@ -144,13 +146,15 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    fun loadAndRemoveMediaData() {
        manager.onMediaDataLoaded(KEY, null, mediaData)
        manager.onMediaDataRemoved(KEY)
        fakeBgExecutor.runAllReady()
        verify(lmm).unregisterCallback(any())
    }

    @Test
    fun loadMediaDataWithNullToken() {
        manager.onMediaDataLoaded(KEY, null, mediaData.copy(token = null))
        fakeExecutor.runAllReady()
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isTrue()
        assertThat(data.name).isEqualTo(DEVICE_NAME)
@@ -163,6 +167,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
        reset(listener)
        // WHEN data is loaded with a new key
        manager.onMediaDataLoaded(KEY, KEY_OLD, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        // THEN the listener for the old key should removed.
        verify(lmm).unregisterCallback(any())
        // AND a new device event emitted
@@ -186,6 +192,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    fun unknownOldKey() {
        val oldKey = "unknown"
        manager.onMediaDataLoaded(KEY, oldKey, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        verify(listener).onMediaDeviceChanged(eq(KEY), eq(oldKey), any())
    }

@@ -193,13 +201,16 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    fun updateToSessionTokenWithNullRoute() {
        // GIVEN that media data has been loaded with a null token
        manager.onMediaDataLoaded(KEY, null, mediaData.copy(token = null))
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        reset(listener)
        // WHEN media data is loaded with a different token
        // AND that token results in a null route
        reset(listener)
        whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null)
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        // THEN the device should be disabled
        fakeExecutor.runAllReady()
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isFalse()
        assertThat(data.name).isNull()
@@ -210,7 +221,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    fun deviceEventOnAddNotification() {
        // WHEN a notification is added
        manager.onMediaDataLoaded(KEY, null, mediaData)
        val deviceCallback = captureCallback()
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        // THEN the update is dispatched to the listener
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isTrue()
@@ -230,10 +242,12 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    @Test
    fun deviceListUpdate() {
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        val deviceCallback = captureCallback()
        // WHEN the device list changes
        deviceCallback.onDeviceListUpdate(mutableListOf(device))
        assertThat(fakeExecutor.runAllReady()).isEqualTo(1)
        assertThat(fakeBgExecutor.runAllReady()).isEqualTo(1)
        assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1)
        // THEN the update is dispatched to the listener
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isTrue()
@@ -244,10 +258,12 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    @Test
    fun selectedDeviceStateChanged() {
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        val deviceCallback = captureCallback()
        // WHEN the selected device changes state
        deviceCallback.onSelectedDeviceStateChanged(device, 1)
        assertThat(fakeExecutor.runAllReady()).isEqualTo(1)
        assertThat(fakeBgExecutor.runAllReady()).isEqualTo(1)
        assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1)
        // THEN the update is dispatched to the listener
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isTrue()
@@ -270,6 +286,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
        whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null)
        // WHEN a notification is added
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        // THEN the device is disabled
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isFalse()
@@ -281,13 +299,16 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    fun deviceDisabledWhenMR2ReturnsNullRouteInfoOnDeviceChanged() {
        // GIVEN a notif is added
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        reset(listener)
        // AND MR2Manager returns null for routing session
        whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null)
        // WHEN the selected device changes state
        val deviceCallback = captureCallback()
        deviceCallback.onSelectedDeviceStateChanged(device, 1)
        fakeExecutor.runAllReady()
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        // THEN the device is disabled
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isFalse()
@@ -299,13 +320,16 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
    fun deviceDisabledWhenMR2ReturnsNullRouteInfoOnDeviceListUpdate() {
        // GIVEN a notif is added
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        reset(listener)
        // GIVEN that MR2Manager returns null for routing session
        whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null)
        // WHEN the selected device changes state
        val deviceCallback = captureCallback()
        deviceCallback.onDeviceListUpdate(mutableListOf(device))
        fakeExecutor.runAllReady()
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        // THEN the device is disabled
        val data = captureDeviceData(KEY)
        assertThat(data.enabled).isFalse()