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. * 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 eventListener The listener to be removed.
* @param listenerClass The listener type passed to {@link #addEventListener(Handler, Object, * @param listenerClass The listener type passed to {@link #addEventListener(Handler, Object,
* Class)}. * Class)}.
@ -126,6 +130,7 @@ public class MediaSourceEventDispatcher {
if (listenerInfo.listener == eventListener if (listenerInfo.listener == eventListener
&& listenerInfo.listenerClass.equals(listenerClass)) { && listenerInfo.listenerClass.equals(listenerClass)) {
listenerInfos.remove(listenerInfo); 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.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@ -162,6 +163,26 @@ public class MediaSourceEventDispatcherTest {
verify(mediaAndDrmEventListener).onMediaPeriodCreated(WINDOW_INDEX, MEDIA_PERIOD_ID); 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 private interface MediaAndDrmEventListener
extends MediaSourceEventListener, DrmSessionEventListener {} extends MediaSourceEventListener, DrmSessionEventListener {}
} }