Merge "Migrate from old key when combining device and media data" into rvc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
20ef70906c
@@ -33,24 +33,32 @@ class MediaDataCombineLatest @Inject constructor(
|
|||||||
init {
|
init {
|
||||||
dataSource.addListener(object : MediaDataManager.Listener {
|
dataSource.addListener(object : MediaDataManager.Listener {
|
||||||
override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
|
override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
|
||||||
if (oldKey != null && !oldKey.equals(key)) {
|
if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
|
||||||
val s = entries[oldKey]?.second
|
entries[key] = data to entries.remove(oldKey)?.second
|
||||||
entries[key] = data to entries[oldKey]?.second
|
update(key, oldKey)
|
||||||
entries.remove(oldKey)
|
|
||||||
} else {
|
} else {
|
||||||
entries[key] = data to entries[key]?.second
|
entries[key] = data to entries[key]?.second
|
||||||
|
update(key, key)
|
||||||
}
|
}
|
||||||
update(key, oldKey)
|
|
||||||
}
|
}
|
||||||
override fun onMediaDataRemoved(key: String) {
|
override fun onMediaDataRemoved(key: String) {
|
||||||
remove(key)
|
remove(key)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
deviceSource.addListener(object : MediaDeviceManager.Listener {
|
deviceSource.addListener(object : MediaDeviceManager.Listener {
|
||||||
override fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) {
|
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
|
entries[key] = entries[key]?.first to data
|
||||||
update(key, key)
|
update(key, key)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
override fun onKeyRemoved(key: String) {
|
override fun onKeyRemoved(key: String) {
|
||||||
remove(key)
|
remove(key)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ class MediaDeviceManager @Inject constructor(
|
|||||||
val controller = data.token?.let {
|
val controller = data.token?.let {
|
||||||
MediaController(context, it)
|
MediaController(context, it)
|
||||||
}
|
}
|
||||||
entry = Token(key, controller, localMediaManagerFactory.create(data.packageName))
|
entry = Token(key, oldKey, controller,
|
||||||
|
localMediaManagerFactory.create(data.packageName))
|
||||||
entries[key] = entry
|
entries[key] = entry
|
||||||
entry.start()
|
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 enabled = device != null
|
||||||
val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name)
|
val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name)
|
||||||
listeners.forEach {
|
listeners.forEach {
|
||||||
it.onMediaDeviceChanged(key, data)
|
it.onMediaDeviceChanged(key, oldKey, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
/** Called when the route has changed for a given notification. */
|
/** 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. */
|
/** Called when the notification was removed. */
|
||||||
fun onKeyRemoved(key: String)
|
fun onKeyRemoved(key: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class Token(
|
private inner class Token(
|
||||||
val key: String,
|
val key: String,
|
||||||
|
val oldKey: String?,
|
||||||
val controller: MediaController?,
|
val controller: MediaController?,
|
||||||
val localMediaManager: LocalMediaManager
|
val localMediaManager: LocalMediaManager
|
||||||
) : LocalMediaManager.DeviceCallback {
|
) : LocalMediaManager.DeviceCallback {
|
||||||
@@ -125,7 +127,7 @@ class MediaDeviceManager @Inject constructor(
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (!started || value != field) {
|
if (!started || value != field) {
|
||||||
field = value
|
field = value
|
||||||
processDevice(key, value)
|
processDevice(key, oldKey, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun start() {
|
fun start() {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.any;
|
|||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
@@ -47,6 +48,7 @@ import java.util.Map;
|
|||||||
public class MediaDataCombineLatestTest extends SysuiTestCase {
|
public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||||
|
|
||||||
private static final String KEY = "TEST_KEY";
|
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 APP = "APP";
|
||||||
private static final String PACKAGE = "PKG";
|
private static final String PACKAGE = "PKG";
|
||||||
private static final int BG_COLOR = Color.RED;
|
private static final int BG_COLOR = Color.RED;
|
||||||
@@ -97,7 +99,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void eventNotEmittedWithoutMedia() {
|
public void eventNotEmittedWithoutMedia() {
|
||||||
// WHEN device source emits an event without media data
|
// WHEN device source emits an event without media data
|
||||||
mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
|
mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// THEN an event isn't emitted
|
// THEN an event isn't emitted
|
||||||
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any());
|
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any());
|
||||||
}
|
}
|
||||||
@@ -105,7 +107,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void emitEventAfterDeviceFirst() {
|
public void emitEventAfterDeviceFirst() {
|
||||||
// GIVEN that a device event has already been received
|
// GIVEN that a device event has already been received
|
||||||
mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
|
mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// WHEN media event is received
|
// WHEN media event is received
|
||||||
mDataListener.onMediaDataLoaded(KEY, null, mMediaData);
|
mDataListener.onMediaDataLoaded(KEY, null, mMediaData);
|
||||||
// THEN the listener receives a combined event
|
// THEN the listener receives a combined event
|
||||||
@@ -119,13 +121,71 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
// GIVEN that media event has already been received
|
// GIVEN that media event has already been received
|
||||||
mDataListener.onMediaDataLoaded(KEY, null, mMediaData);
|
mDataListener.onMediaDataLoaded(KEY, null, mMediaData);
|
||||||
// WHEN device event is received
|
// WHEN device event is received
|
||||||
mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
|
mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// THEN the listener receives a combined event
|
// THEN the listener receives a combined event
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture());
|
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void mediaDataRemoved() {
|
public void mediaDataRemoved() {
|
||||||
// WHEN media data is removed without first receiving device or data
|
// WHEN media data is removed without first receiving device or data
|
||||||
@@ -143,7 +203,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mediaDataRemovedAfterDeviceEvent() {
|
public void mediaDataRemovedAfterDeviceEvent() {
|
||||||
mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
|
mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
mDataListener.onMediaDataRemoved(KEY);
|
mDataListener.onMediaDataRemoved(KEY);
|
||||||
verify(mListener).onMediaDataRemoved(eq(KEY));
|
verify(mListener).onMediaDataRemoved(eq(KEY));
|
||||||
}
|
}
|
||||||
@@ -152,7 +212,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
public void mediaDataKeyUpdated() {
|
public void mediaDataKeyUpdated() {
|
||||||
// GIVEN that device and media events have already been received
|
// GIVEN that device and media events have already been received
|
||||||
mDataListener.onMediaDataLoaded(KEY, null, mMediaData);
|
mDataListener.onMediaDataLoaded(KEY, null, mMediaData);
|
||||||
mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData);
|
mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// WHEN the key is changed
|
// WHEN the key is changed
|
||||||
mDataListener.onMediaDataLoaded("NEW_KEY", KEY, mMediaData);
|
mDataListener.onMediaDataLoaded("NEW_KEY", KEY, mMediaData);
|
||||||
// THEN the listener gets a load event with the correct keys
|
// THEN the listener gets a load event with the correct keys
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
|
|||||||
// THEN the listener for the old key should removed.
|
// THEN the listener for the old key should removed.
|
||||||
verify(lmm).unregisterCallback(any())
|
verify(lmm).unregisterCallback(any())
|
||||||
// AND a new device event emitted
|
// AND a new device event emitted
|
||||||
val data = captureDeviceData(KEY)
|
val data = captureDeviceData(KEY, KEY_OLD)
|
||||||
assertThat(data.enabled).isTrue()
|
assertThat(data.enabled).isTrue()
|
||||||
assertThat(data.name).isEqualTo(DEVICE_NAME)
|
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
|
// WHEN the new key is the same as the old key
|
||||||
manager.onMediaDataLoaded(KEY, KEY, mediaData)
|
manager.onMediaDataLoaded(KEY, KEY, mediaData)
|
||||||
// THEN no event should be emitted
|
// THEN no event should be emitted
|
||||||
verify(listener, never()).onMediaDeviceChanged(eq(KEY), any())
|
verify(listener, never()).onMediaDeviceChanged(eq(KEY), eq(null), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun unknownOldKey() {
|
fun unknownOldKey() {
|
||||||
manager.onMediaDataLoaded(KEY, "unknown", mediaData)
|
val oldKey = "unknown"
|
||||||
verify(listener).onMediaDeviceChanged(eq(KEY), any())
|
manager.onMediaDataLoaded(KEY, oldKey, mediaData)
|
||||||
|
verify(listener).onMediaDeviceChanged(eq(KEY), eq(oldKey), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -223,7 +224,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
|
|||||||
manager.removeListener(listener)
|
manager.removeListener(listener)
|
||||||
// THEN it doesn't receive device events
|
// THEN it doesn't receive device events
|
||||||
manager.onMediaDataLoaded(KEY, null, mediaData)
|
manager.onMediaDataLoaded(KEY, null, mediaData)
|
||||||
verify(listener, never()).onMediaDeviceChanged(eq(KEY), any())
|
verify(listener, never()).onMediaDeviceChanged(eq(KEY), eq(null), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -318,9 +319,9 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
|
|||||||
return captor.getValue()
|
return captor.getValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun captureDeviceData(key: String): MediaDeviceData {
|
fun captureDeviceData(key: String, oldKey: String? = null): MediaDeviceData {
|
||||||
val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
|
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()
|
return captor.getValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user