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

Commit 783fee6d authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "Forward device updates when info changes"

parents 7f93c05e 6c02c67e
Loading
Loading
Loading
Loading
+17 −1
Original line number Original line Diff line number Diff line
@@ -219,4 +219,20 @@ data class MediaDeviceData


    /** Whether or not to show the broadcast button */
    /** Whether or not to show the broadcast button */
    val showBroadcastButton: Boolean
    val showBroadcastButton: Boolean
)
) {
    /**
     * Check whether [MediaDeviceData] objects are equal in all fields except the icon. The icon
     * is ignored because it can change by reference frequently depending on the device type's
     * implementation, but this is not usually relevant unless other info has changed
     */
    fun equalsWithoutIcon(other: MediaDeviceData?): Boolean {
        if (other == null) {
            return false
        }

        return enabled == other.enabled &&
            name == other.name &&
            intent == other.intent &&
            id == other.id
    }
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -168,8 +168,8 @@ class MediaDeviceManager @Inject constructor(
        private var playbackType = PLAYBACK_TYPE_UNKNOWN
        private var playbackType = PLAYBACK_TYPE_UNKNOWN
        private var current: MediaDeviceData? = null
        private var current: MediaDeviceData? = null
            set(value) {
            set(value) {
                val hasSameId = value?.id != null && value.id == field?.id
                val sameWithoutIcon = value != null && value.equalsWithoutIcon(field)
                if (!started || (!hasSameId && value != field)) {
                if (!started || !sameWithoutIcon) {
                    field = value
                    field = value
                    fgExecutor.execute {
                    fgExecutor.execute {
                        processDevice(key, oldKey, value)
                        processDevice(key, oldKey, value)
+86 −0
Original line number Original line Diff line number Diff line
@@ -56,7 +56,9 @@ import org.mockito.Mockito.any
import org.mockito.Mockito.mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.reset
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
import org.mockito.Mockito.`when` as whenever


@@ -64,6 +66,7 @@ private const val KEY = "TEST_KEY"
private const val KEY_OLD = "TEST_KEY_OLD"
private const val KEY_OLD = "TEST_KEY_OLD"
private const val PACKAGE = "PKG"
private const val PACKAGE = "PKG"
private const val SESSION_KEY = "SESSION_KEY"
private const val SESSION_KEY = "SESSION_KEY"
private const val DEVICE_ID = "DEVICE_ID"
private const val DEVICE_NAME = "DEVICE_NAME"
private const val DEVICE_NAME = "DEVICE_NAME"
private const val REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"
private const val REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"
private const val BROADCAST_APP_NAME = "BROADCAST_APP_NAME"
private const val BROADCAST_APP_NAME = "BROADCAST_APP_NAME"
@@ -477,6 +480,89 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
        verify(mr2, never()).getRoutingSessionForMediaController(eq(controller))
        verify(mr2, never()).getRoutingSessionForMediaController(eq(controller))
    }
    }


    @Test
    fun deviceIdChanged_informListener() {
        // GIVEN a notification is added, with a particular device connected
        whenever(device.id).thenReturn(DEVICE_ID)
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()

        // and later the manager gets a new device ID
        val deviceCallback = captureCallback()
        val updatedId = DEVICE_ID + "_new"
        whenever(device.id).thenReturn(updatedId)
        deviceCallback.onDeviceListUpdate(mutableListOf(device))

        // THEN the listener gets the updated info
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()

        val dataCaptor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
        verify(listener, times(2)).onMediaDeviceChanged(eq(KEY), any(), dataCaptor.capture())

        val firstDevice = dataCaptor.allValues.get(0)
        assertThat(firstDevice.id).isEqualTo(DEVICE_ID)

        val secondDevice = dataCaptor.allValues.get(1)
        assertThat(secondDevice.id).isEqualTo(updatedId)
    }

    @Test
    fun deviceNameChanged_informListener() {
        // GIVEN a notification is added, with a particular device connected
        whenever(device.id).thenReturn(DEVICE_ID)
        whenever(device.name).thenReturn(DEVICE_NAME)
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()

        // and later the manager gets a new device name
        val deviceCallback = captureCallback()
        val updatedName = DEVICE_NAME + "_new"
        whenever(device.name).thenReturn(updatedName)
        deviceCallback.onDeviceListUpdate(mutableListOf(device))

        // THEN the listener gets the updated info
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()

        val dataCaptor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
        verify(listener, times(2)).onMediaDeviceChanged(eq(KEY), any(), dataCaptor.capture())

        val firstDevice = dataCaptor.allValues.get(0)
        assertThat(firstDevice.name).isEqualTo(DEVICE_NAME)

        val secondDevice = dataCaptor.allValues.get(1)
        assertThat(secondDevice.name).isEqualTo(updatedName)
    }

    @Test
    fun deviceIconChanged_doesNotCallListener() {
        // GIVEN a notification is added, with a particular device connected
        whenever(device.id).thenReturn(DEVICE_ID)
        whenever(device.name).thenReturn(DEVICE_NAME)
        val firstIcon = mock(Drawable::class.java)
        whenever(device.icon).thenReturn(firstIcon)
        manager.onMediaDataLoaded(KEY, null, mediaData)
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()

        val dataCaptor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
        verify(listener).onMediaDeviceChanged(eq(KEY), any(), dataCaptor.capture())

        // and later the manager gets a callback with only the icon changed
        val deviceCallback = captureCallback()
        val secondIcon = mock(Drawable::class.java)
        whenever(device.icon).thenReturn(secondIcon)
        deviceCallback.onDeviceListUpdate(mutableListOf(device))

        // THEN the listener is not called again
        fakeBgExecutor.runAllReady()
        fakeFgExecutor.runAllReady()
        verifyNoMoreInteractions(listener)
    }

    @Test
    @Test
    fun testRemotePlaybackDeviceOverride() {
    fun testRemotePlaybackDeviceOverride() {
        whenever(route.name).thenReturn(DEVICE_NAME)
        whenever(route.name).thenReturn(DEVICE_NAME)