Clarify docs around listener hierarchies in MediaSourceEventDispatcher
Also add a couple of tests to enforce the documentation. PiperOrigin-RevId: 301796102
This commit is contained in:
parent
818925d4a7
commit
181177a245
@ -103,6 +103,11 @@ public class MediaSourceEventDispatcher {
|
||||
* event dispatched to {@code listenerClass} will only be passed to the {@code eventListener}
|
||||
* once.
|
||||
*
|
||||
* <p><b>NOTE</b>: This doesn't interact well with hierarchies of listener interfaces. If a
|
||||
* listener is registered with a super-class type then it will only receive events dispatched
|
||||
* directly to that super-class type. Similarly, if a listener is registered with a sub-class type
|
||||
* then it will only receive events dispatched directly to that sub-class.
|
||||
*
|
||||
* @param handler A handler on the which listener events will be posted.
|
||||
* @param eventListener The listener to be added.
|
||||
* @param listenerClass The type used to register the listener. Can be a superclass of {@code
|
||||
|
@ -18,15 +18,18 @@ package com.google.android.exoplayer2.util;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
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;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@ -123,6 +126,33 @@ public class MediaSourceEventDispatcherTest {
|
||||
verify(mediaAndDrmEventListener, never()).onDrmKeysLoaded();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listenerDoesntReceiveEventsDispatchedToSubclass() {
|
||||
SubclassListener subclassListener = mock(SubclassListener.class);
|
||||
eventDispatcher.addEventListener(
|
||||
new Handler(Looper.getMainLooper()), subclassListener, MediaSourceEventListener.class);
|
||||
|
||||
eventDispatcher.dispatch(SubclassListener::subclassMethod, SubclassListener.class);
|
||||
|
||||
// subclassListener can handle the call to subclassMethod, but it isn't called because
|
||||
// it was registered 'as-a' MediaSourceEventListener, not SubclassListener.
|
||||
verify(subclassListener, never()).subclassMethod(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listenerDoesntReceiveEventsDispatchedToSuperclass() {
|
||||
SubclassListener subclassListener = mock(SubclassListener.class);
|
||||
eventDispatcher.addEventListener(
|
||||
new Handler(Looper.getMainLooper()), subclassListener, SubclassListener.class);
|
||||
|
||||
eventDispatcher.dispatch(
|
||||
MediaSourceEventListener::onMediaPeriodCreated, MediaSourceEventListener.class);
|
||||
|
||||
// subclassListener 'is-a' a MediaSourceEventListener, but it isn't called because the event
|
||||
// is dispatched specifically to listeners registered as MediaSourceEventListener.
|
||||
verify(subclassListener, never()).onMediaPeriodCreated(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listenersAreCopiedToNewDispatcher() {
|
||||
eventDispatcher.addEventListener(
|
||||
@ -185,4 +215,8 @@ public class MediaSourceEventDispatcherTest {
|
||||
|
||||
private interface MediaAndDrmEventListener
|
||||
extends MediaSourceEventListener, DrmSessionEventListener {}
|
||||
|
||||
private interface SubclassListener extends MediaSourceEventListener {
|
||||
void subclassMethod(int windowIndex, @Nullable MediaPeriodId mediaPeriodId);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user