diff options
4 files changed, 97 insertions, 26 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt index e8f0e069c98d..d0642ccf9714 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt @@ -33,23 +33,31 @@ class MediaDataCombineLatest @Inject constructor( init { dataSource.addListener(object : MediaDataManager.Listener { override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { - if (oldKey != null && !oldKey.equals(key)) { - val s = entries[oldKey]?.second - entries[key] = data to entries[oldKey]?.second - entries.remove(oldKey) + if (oldKey != null && oldKey != key && entries.contains(oldKey)) { + entries[key] = data to entries.remove(oldKey)?.second + update(key, oldKey) } else { entries[key] = data to entries[key]?.second + update(key, key) } - update(key, oldKey) } override fun onMediaDataRemoved(key: String) { remove(key) } }) deviceSource.addListener(object : MediaDeviceManager.Listener { - override fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) { - entries[key] = entries[key]?.first to data - update(key, key) + override fun onMediaDeviceChanged( + key: String, + oldKey: String?, + data: MediaDeviceData? + ) { + if (oldKey != null && oldKey != key && entries.contains(oldKey)) { + entries[key] = entries.remove(oldKey)?.first to data + update(key, oldKey) + } else { + entries[key] = entries[key]?.first to data + update(key, key) + } } override fun onKeyRemoved(key: String) { remove(key) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index 7ae2dc5c0941..143f8496e7aa 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -71,7 +71,8 @@ class MediaDeviceManager @Inject constructor( val controller = data.token?.let { MediaController(context, it) } - entry = Token(key, controller, localMediaManagerFactory.create(data.packageName)) + entry = Token(key, oldKey, controller, + localMediaManagerFactory.create(data.packageName)) entries[key] = entry entry.start() } @@ -98,23 +99,24 @@ class MediaDeviceManager @Inject constructor( } } - private fun processDevice(key: String, device: MediaDevice?) { + private fun processDevice(key: String, oldKey: String?, device: MediaDevice?) { val enabled = device != null val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name) listeners.forEach { - it.onMediaDeviceChanged(key, data) + it.onMediaDeviceChanged(key, oldKey, data) } } interface Listener { /** Called when the route has changed for a given notification. */ - fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) + fun onMediaDeviceChanged(key: String, oldKey: String?, data: MediaDeviceData?) /** Called when the notification was removed. */ fun onKeyRemoved(key: String) } private inner class Token( val key: String, + val oldKey: String?, val controller: MediaController?, val localMediaManager: LocalMediaManager ) : LocalMediaManager.DeviceCallback { @@ -125,7 +127,7 @@ class MediaDeviceManager @Inject constructor( set(value) { if (!started || value != field) { field = value - processDevice(key, value) + processDevice(key, oldKey, value) } } fun start() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java index dbc5596d9f4e..492b33e3c4a6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import android.graphics.Color; @@ -47,6 +48,7 @@ import java.util.Map; public class MediaDataCombineLatestTest extends SysuiTestCase { private static final String KEY = "TEST_KEY"; + private static final String OLD_KEY = "TEST_KEY_OLD"; private static final String APP = "APP"; private static final String PACKAGE = "PKG"; private static final int BG_COLOR = Color.RED; @@ -97,7 +99,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void eventNotEmittedWithoutMedia() { // WHEN device source emits an event without media data - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // THEN an event isn't emitted verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any()); } @@ -105,7 +107,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void emitEventAfterDeviceFirst() { // GIVEN that a device event has already been received - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // WHEN media event is received mDataListener.onMediaDataLoaded(KEY, null, mMediaData); // THEN the listener receives a combined event @@ -119,7 +121,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { // GIVEN that media event has already been received mDataListener.onMediaDataLoaded(KEY, null, mMediaData); // WHEN device event is received - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // THEN the listener receives a combined event ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture()); @@ -127,6 +129,64 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { } @Test + public void migrateKeyMediaFirst() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + reset(mListener); + // WHEN a key migration event is received + mDataListener.onMediaDataLoaded(KEY, OLD_KEY, mMediaData); + // THEN the listener receives a combined event + ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void migrateKeyDeviceFirst() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + reset(mListener); + // WHEN a key migration event is received + mDeviceListener.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData); + // THEN the listener receives a combined event + ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void migrateKeyMediaAfter() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData); + reset(mListener); + // WHEN a second key migration event is received for media + mDataListener.onMediaDataLoaded(KEY, OLD_KEY, mMediaData); + // THEN the key has already been migrated + ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void migrateKeyDeviceAfter() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + mDataListener.onMediaDataLoaded(KEY, OLD_KEY, mMediaData); + reset(mListener); + // WHEN a second key migration event is received for the device + mDeviceListener.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData); + // THEN the key has already be migrated + ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test public void mediaDataRemoved() { // WHEN media data is removed without first receiving device or data mDataListener.onMediaDataRemoved(KEY); @@ -143,7 +203,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void mediaDataRemovedAfterDeviceEvent() { - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); mDataListener.onMediaDataRemoved(KEY); verify(mListener).onMediaDataRemoved(eq(KEY)); } @@ -152,7 +212,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { public void mediaDataKeyUpdated() { // GIVEN that device and media events have already been received mDataListener.onMediaDataLoaded(KEY, null, mMediaData); - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // WHEN the key is changed mDataListener.onMediaDataLoaded("NEW_KEY", KEY, mMediaData); // THEN the listener gets a load event with the correct keys @@ -163,7 +223,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void getDataIncludesDevice() { // GIVEN that device and media events have been received - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); mDataListener.onMediaDataLoaded(KEY, null, mMediaData); // THEN the result of getData includes device info diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index fc22eeb3ea68..3c6e19f0ec6f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -166,7 +166,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() { // THEN the listener for the old key should removed. verify(lmm).unregisterCallback(any()) // AND a new device event emitted - val data = captureDeviceData(KEY) + val data = captureDeviceData(KEY, KEY_OLD) assertThat(data.enabled).isTrue() assertThat(data.name).isEqualTo(DEVICE_NAME) } @@ -179,13 +179,14 @@ public class MediaDeviceManagerTest : SysuiTestCase() { // WHEN the new key is the same as the old key manager.onMediaDataLoaded(KEY, KEY, mediaData) // THEN no event should be emitted - verify(listener, never()).onMediaDeviceChanged(eq(KEY), any()) + verify(listener, never()).onMediaDeviceChanged(eq(KEY), eq(null), any()) } @Test fun unknownOldKey() { - manager.onMediaDataLoaded(KEY, "unknown", mediaData) - verify(listener).onMediaDeviceChanged(eq(KEY), any()) + val oldKey = "unknown" + manager.onMediaDataLoaded(KEY, oldKey, mediaData) + verify(listener).onMediaDeviceChanged(eq(KEY), eq(oldKey), any()) } @Test @@ -223,7 +224,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() { manager.removeListener(listener) // THEN it doesn't receive device events manager.onMediaDataLoaded(KEY, null, mediaData) - verify(listener, never()).onMediaDeviceChanged(eq(KEY), any()) + verify(listener, never()).onMediaDeviceChanged(eq(KEY), eq(null), any()) } @Test @@ -318,9 +319,9 @@ public class MediaDeviceManagerTest : SysuiTestCase() { return captor.getValue() } - fun captureDeviceData(key: String): MediaDeviceData { + fun captureDeviceData(key: String, oldKey: String? = null): MediaDeviceData { val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) - verify(listener).onMediaDeviceChanged(eq(key), captor.capture()) + verify(listener).onMediaDeviceChanged(eq(key), eq(oldKey), captor.capture()) return captor.getValue() } } |