Merge "Forward device updates when info changes" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a2b34c4c21
@@ -216,4 +216,20 @@ data class MediaDeviceData
|
|||||||
|
|
||||||
/** Unique id for this device */
|
/** Unique id for this device */
|
||||||
val id: String? = null
|
val id: String? = null
|
||||||
)
|
) {
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -155,8 +155,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)
|
||||||
|
|||||||
@@ -47,7 +47,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
|
||||||
|
|
||||||
@@ -55,6 +57,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"
|
||||||
|
|
||||||
@@ -456,6 +459,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)
|
||||||
|
|||||||
Reference in New Issue
Block a user