diff --git a/library/core/src/main/java/com/google/android/exoplayer2/MediaSourceList.java b/library/core/src/main/java/com/google/android/exoplayer2/MediaSourceList.java index bdd00fe54d..e690ea3626 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/MediaSourceList.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/MediaSourceList.java @@ -702,45 +702,59 @@ import java.util.Set; // DrmSessionEventListener implementation @Override - public void onDrmSessionAcquired() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionAcquired(), - DrmSessionEventListener.class); + public void onDrmSessionAcquired( + int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmSessionAcquired, DrmSessionEventListener.class); + } } @Override - public void onDrmKeysLoaded() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysLoaded(), - DrmSessionEventListener.class); + public void onDrmKeysLoaded( + int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmKeysLoaded, DrmSessionEventListener.class); + } } @Override - public void onDrmSessionManagerError(Exception error) { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionManagerError(error), - DrmSessionEventListener.class); + public void onDrmSessionManagerError( + int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId, Exception error) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + (listener, innerWindowIndex, innerMediaPeriodId) -> + listener.onDrmSessionManagerError(innerWindowIndex, innerMediaPeriodId, error), + DrmSessionEventListener.class); + } } @Override - public void onDrmKeysRestored() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRestored(), - DrmSessionEventListener.class); + public void onDrmKeysRestored( + int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmKeysRestored, DrmSessionEventListener.class); + } } @Override - public void onDrmKeysRemoved() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRemoved(), - DrmSessionEventListener.class); + public void onDrmKeysRemoved( + int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmKeysRemoved, DrmSessionEventListener.class); + } } @Override - public void onDrmSessionReleased() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionReleased(), - DrmSessionEventListener.class); + public void onDrmSessionReleased( + int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmSessionReleased, DrmSessionEventListener.class); + } } /** Updates the event dispatcher and returns whether the event should be dispatched. */ diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java index 715a1c0f14..fceaa14b73 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java @@ -576,48 +576,49 @@ public class AnalyticsCollector // DefaultDrmSessionManager.EventListener implementation. @Override - public final void onDrmSessionAcquired() { - EventTime eventTime = generateReadingMediaPeriodEventTime(); + public final void onDrmSessionAcquired(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId); for (AnalyticsListener listener : listeners) { listener.onDrmSessionAcquired(eventTime); } } @Override - public final void onDrmKeysLoaded() { - EventTime eventTime = generateReadingMediaPeriodEventTime(); + public final void onDrmKeysLoaded(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId); for (AnalyticsListener listener : listeners) { listener.onDrmKeysLoaded(eventTime); } } @Override - public final void onDrmSessionManagerError(Exception error) { - EventTime eventTime = generateReadingMediaPeriodEventTime(); + public final void onDrmSessionManagerError( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, Exception error) { + EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId); for (AnalyticsListener listener : listeners) { listener.onDrmSessionManagerError(eventTime, error); } } @Override - public final void onDrmKeysRestored() { - EventTime eventTime = generateReadingMediaPeriodEventTime(); + public final void onDrmKeysRestored(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId); for (AnalyticsListener listener : listeners) { listener.onDrmKeysRestored(eventTime); } } @Override - public final void onDrmKeysRemoved() { - EventTime eventTime = generateReadingMediaPeriodEventTime(); + public final void onDrmKeysRemoved(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId); for (AnalyticsListener listener : listeners) { listener.onDrmKeysRemoved(eventTime); } } @Override - public final void onDrmSessionReleased() { - EventTime eventTime = generatePlayingMediaPeriodEventTime(); + public final void onDrmSessionReleased(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId); for (AnalyticsListener listener : listeners) { listener.onDrmSessionReleased(eventTime); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java index ad8a5c9854..fa6487587e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java @@ -275,8 +275,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; // re-used or not. if (eventDispatcher != null) { eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionAcquired(), - DrmSessionEventListener.class); + DrmSessionEventListener::onDrmSessionAcquired, DrmSessionEventListener.class); } } } @@ -301,7 +300,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } releaseCallback.onSessionReleased(this); } - dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionReleased()); + dispatchEvent(DrmSessionEventListener::onDrmSessionReleased); if (eventDispatcher != null) { eventDispatchers.remove(eventDispatcher); } @@ -326,7 +325,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; try { sessionId = mediaDrm.openSession(); mediaCrypto = mediaDrm.createMediaCrypto(sessionId); - dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionAcquired()); + dispatchEvent(DrmSessionEventListener::onDrmSessionAcquired); state = STATE_OPENED; Assertions.checkNotNull(sessionId); return true; @@ -390,7 +389,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; onError(new KeysExpiredException()); } else { state = STATE_OPENED_WITH_KEYS; - dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRestored()); + dispatchEvent(DrmSessionEventListener::onDrmKeysRestored); } } break; @@ -460,7 +459,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; byte[] responseData = (byte[]) response; if (mode == DefaultDrmSessionManager.MODE_RELEASE) { mediaDrm.provideKeyResponse(Util.castNonNull(offlineLicenseKeySetId), responseData); - dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRestored()); + dispatchEvent(DrmSessionEventListener::onDrmKeysRestored); } else { byte[] keySetId = mediaDrm.provideKeyResponse(sessionId, responseData); if ((mode == DefaultDrmSessionManager.MODE_DOWNLOAD @@ -471,7 +470,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; offlineLicenseKeySetId = keySetId; } state = STATE_OPENED_WITH_KEYS; - dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysLoaded()); + dispatchEvent(DrmSessionEventListener::onDrmKeysLoaded); } } catch (Exception e) { onKeysError(e); @@ -495,7 +494,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; private void onError(final Exception e) { lastException = new DrmSessionException(e); - dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionManagerError(e)); + dispatchEvent( + (listener, windowIndex, mediaPeriodId) -> + listener.onDrmSessionManagerError(windowIndex, mediaPeriodId, e)); if (state != STATE_OPENED_WITH_KEYS) { state = STATE_ERROR; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java index dbfde1cc9a..8335831ce0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java @@ -489,7 +489,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager { final MissingSchemeDataException error = new MissingSchemeDataException(uuid); if (eventDispatcher != null) { eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionManagerError(error), + (listener, windowIndex, mediaPeriodId) -> + listener.onDrmSessionManagerError(windowIndex, mediaPeriodId, error), DrmSessionEventListener.class); } return new ErrorStateDrmSession(new DrmSessionException(error)); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionEventListener.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionEventListener.java index dd306d952f..b4482408b1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionEventListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionEventListener.java @@ -15,16 +15,28 @@ */ package com.google.android.exoplayer2.drm; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; /** Listener of {@link DrmSessionManager} events. */ public interface DrmSessionEventListener { - /** Called each time a drm session is acquired. */ - default void onDrmSessionAcquired() {} + /** + * Called each time a drm session is acquired. + * + * @param windowIndex The window index in the timeline this media period belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} associated with the drm session. + */ + default void onDrmSessionAcquired(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {} - /** Called each time keys are loaded. */ - default void onDrmKeysLoaded() {} + /** + * Called each time keys are loaded. + * + * @param windowIndex The window index in the timeline this media period belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} associated with the drm session. + */ + default void onDrmKeysLoaded(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {} /** * Called when a drm error occurs. @@ -36,16 +48,34 @@ public interface DrmSessionEventListener { * such behavior). This method is called to provide the application with an opportunity to log the * error if it wishes to do so. * + * @param windowIndex The window index in the timeline this media period belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} associated with the drm session. * @param error The corresponding exception. */ - default void onDrmSessionManagerError(Exception error) {} + default void onDrmSessionManagerError( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, Exception error) {} - /** Called each time offline keys are restored. */ - default void onDrmKeysRestored() {} + /** + * Called each time offline keys are restored. + * + * @param windowIndex The window index in the timeline this media period belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} associated with the drm session. + */ + default void onDrmKeysRestored(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {} - /** Called each time offline keys are removed. */ - default void onDrmKeysRemoved() {} + /** + * Called each time offline keys are removed. + * + * @param windowIndex The window index in the timeline this media period belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} associated with the drm session. + */ + default void onDrmKeysRemoved(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {} - /** Called each time a drm session is released. */ - default void onDrmSessionReleased() {} + /** + * Called each time a drm session is released. + * + * @param windowIndex The window index in the timeline this media period belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} associated with the drm session. + */ + default void onDrmSessionReleased(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) {} } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java index 6092f3911f..5b4c9daac7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java @@ -24,6 +24,7 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; +import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MediaSourceEventDispatcher; @@ -156,22 +157,23 @@ public final class OfflineLicenseHelper { DrmSessionEventListener eventListener = new DrmSessionEventListener() { @Override - public void onDrmKeysLoaded() { + public void onDrmKeysLoaded(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { conditionVariable.open(); } @Override - public void onDrmSessionManagerError(Exception e) { + public void onDrmSessionManagerError( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, Exception e) { conditionVariable.open(); } @Override - public void onDrmKeysRestored() { + public void onDrmKeysRestored(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { conditionVariable.open(); } @Override - public void onDrmKeysRemoved() { + public void onDrmKeysRemoved(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { conditionVariable.open(); } }; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java index 5cc75e8e0b..b742d3b431 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java @@ -324,45 +324,54 @@ public abstract class CompositeMediaSource extends BaseMediaSource { // DrmSessionEventListener implementation @Override - public void onDrmSessionAcquired() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionAcquired(), - DrmSessionEventListener.class); + public void onDrmSessionAcquired(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmSessionAcquired, DrmSessionEventListener.class); + } } @Override - public void onDrmKeysLoaded() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysLoaded(), - DrmSessionEventListener.class); + public void onDrmKeysLoaded(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmKeysLoaded, DrmSessionEventListener.class); + } } @Override - public void onDrmSessionManagerError(Exception error) { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionManagerError(error), - DrmSessionEventListener.class); + public void onDrmSessionManagerError( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, Exception error) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + (listener, innerWindowIndex, innerMediaPeriodId) -> + listener.onDrmSessionManagerError(innerWindowIndex, innerMediaPeriodId, error), + DrmSessionEventListener.class); + } } @Override - public void onDrmKeysRestored() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRestored(), - DrmSessionEventListener.class); + public void onDrmKeysRestored(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmKeysRestored, DrmSessionEventListener.class); + } } @Override - public void onDrmKeysRemoved() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRemoved(), - DrmSessionEventListener.class); + public void onDrmKeysRemoved(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmKeysRemoved, DrmSessionEventListener.class); + } } @Override - public void onDrmSessionReleased() { - eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionReleased(), - DrmSessionEventListener.class); + public void onDrmSessionReleased(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.dispatch( + DrmSessionEventListener::onDrmSessionReleased, DrmSessionEventListener.class); + } } /** Updates the event dispatcher and returns whether the event should be dispatched. */ diff --git a/library/core/src/test/java/com/google/android/exoplayer2/util/MediaSourceEventDispatcherTest.java b/library/core/src/test/java/com/google/android/exoplayer2/util/MediaSourceEventDispatcherTest.java index 5e5a6be7c6..8d110a8776 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/util/MediaSourceEventDispatcherTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/util/MediaSourceEventDispatcherTest.java @@ -100,11 +100,10 @@ public class MediaSourceEventDispatcherTest { eventDispatcher.dispatch( MediaSourceEventListener::onMediaPeriodCreated, MediaSourceEventListener.class); eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysLoaded(), - DrmSessionEventListener.class); + DrmSessionEventListener::onDrmKeysLoaded, DrmSessionEventListener.class); verify(mediaAndDrmEventListener).onMediaPeriodCreated(WINDOW_INDEX, MEDIA_PERIOD_ID); - verify(mediaAndDrmEventListener).onDrmKeysLoaded(); + verify(mediaAndDrmEventListener).onDrmKeysLoaded(WINDOW_INDEX, MEDIA_PERIOD_ID); } // If a listener is added that implements multiple types, it should only receive events for the @@ -119,11 +118,10 @@ public class MediaSourceEventDispatcherTest { eventDispatcher.dispatch( MediaSourceEventListener::onMediaPeriodCreated, MediaSourceEventListener.class); eventDispatcher.dispatch( - (listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysLoaded(), - DrmSessionEventListener.class); + DrmSessionEventListener::onDrmKeysLoaded, DrmSessionEventListener.class); verify(mediaAndDrmEventListener).onMediaPeriodCreated(WINDOW_INDEX, MEDIA_PERIOD_ID); - verify(mediaAndDrmEventListener, never()).onDrmKeysLoaded(); + verify(mediaAndDrmEventListener, never()).onDrmKeysLoaded(WINDOW_INDEX, MEDIA_PERIOD_ID); } @Test