Use reference-counting for listeners from MediaSourceEventDispatcher

Previously calling removeListener would remove all instances of that
listener. Now it only removes a single instance.

This probably should have been part of introducing the Multiset:
2bd4d61b9b

PiperOrigin-RevId: 301191940
This commit is contained in:
ibaker 2020-03-16 17:50:59 +00:00 committed by Oliver Woodman
parent aec6fe7e65
commit 5f8cc71d1b
2 changed files with 26 additions and 0 deletions

View File

@ -117,6 +117,10 @@ public class MediaSourceEventDispatcher {
/**
* Removes a listener from the event dispatcher.
*
* <p>If there are duplicate registrations of {@code {eventListener, listenerClass}} this will
* only remove one (so events dispatched to {@code listenerClass} will still be passed to {@code
* eventListener}).
*
* @param eventListener The listener to be removed.
* @param listenerClass The listener type passed to {@link #addEventListener(Handler, Object,
* Class)}.
@ -126,6 +130,7 @@ public class MediaSourceEventDispatcher {
if (listenerInfo.listener == eventListener
&& listenerInfo.listenerClass.equals(listenerClass)) {
listenerInfos.remove(listenerInfo);
return;
}
}
}

View File

@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.os.Handler;
import android.os.Looper;
@ -162,6 +163,26 @@ public class MediaSourceEventDispatcherTest {
verify(mediaAndDrmEventListener).onMediaPeriodCreated(WINDOW_INDEX, MEDIA_PERIOD_ID);
}
@Test
public void listenersAreCountedBasedOnListenerAndType() {
// Add the listener twice and remove it once.
eventDispatcher.addEventListener(
Util.createHandler(), mediaSourceEventListener, MediaSourceEventListener.class);
eventDispatcher.addEventListener(
Util.createHandler(), mediaSourceEventListener, MediaSourceEventListener.class);
eventDispatcher.removeEventListener(mediaSourceEventListener, MediaSourceEventListener.class);
eventDispatcher.dispatch(
MediaSourceEventListener::onMediaPeriodCreated, MediaSourceEventListener.class);
verify(mediaSourceEventListener).onMediaPeriodCreated(WINDOW_INDEX, MEDIA_PERIOD_ID);
// Remove it a second time and confirm the events stop being propagated.
eventDispatcher.removeEventListener(mediaSourceEventListener, MediaSourceEventListener.class);
verifyNoMoreInteractions(mediaSourceEventListener);
}
private interface MediaAndDrmEventListener
extends MediaSourceEventListener, DrmSessionEventListener {}
}