From 99d3773eb90ff449009bb1f163f190e3432a955c Mon Sep 17 00:00:00 2001 From: ibaker Date: Wed, 26 May 2021 11:29:18 +0100 Subject: [PATCH] Throw from (pre)acquireSession if the DrmSessionManager isn't prepared Currently acquireSession() fails with an NPE from checkNotNull(exoMediaDrm). A follow-up change will result in exoMediaDrm sometimes being non-null while prepareCount==0 (and in this case we still want acquireSession() to fail). preacquireSession() doesn't currently fail in a way the caller can observe - the same NPE is thrown, but asynchronously and it doesn't propagate out of the background thread. Throwing directly seems preferable since it's a clear bug to be trying to preacquire sessions from an unprepared/released manager. PiperOrigin-RevId: 375906450 --- .../drm/DefaultDrmSessionManager.java | 2 ++ .../drm/DefaultDrmSessionManagerTest.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) 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 ebc08641fb..559f333d48 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 @@ -487,6 +487,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) { + checkState(prepareCallsCount > 0); initPlaybackLooper(playbackLooper); PreacquiredSessionReference preacquiredSessionReference = new PreacquiredSessionReference(eventDispatcher); @@ -500,6 +501,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) { + checkState(prepareCallsCount > 0); initPlaybackLooper(playbackLooper); return acquireSession( playbackLooper, diff --git a/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java index 07398e0bf1..b29c82e61e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.drm; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.Assert.assertThrows; import android.os.Looper; import androidx.annotation.Nullable; @@ -407,6 +408,31 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.release(); } + @Test + public void managerNotPrepared_acquireSessionAndPreacquireSessionFail() throws Exception { + FakeExoMediaDrm.LicenseServer licenseServer = + FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS); + DefaultDrmSessionManager drmSessionManager = + new DefaultDrmSessionManager.Builder() + .setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()) + .build(/* mediaDrmCallback= */ licenseServer); + + assertThrows( + Exception.class, + () -> + drmSessionManager.acquireSession( + /* playbackLooper= */ checkNotNull(Looper.myLooper()), + /* eventDispatcher= */ null, + FORMAT_WITH_DRM_INIT_DATA)); + assertThrows( + Exception.class, + () -> + drmSessionManager.preacquireSession( + /* playbackLooper= */ checkNotNull(Looper.myLooper()), + /* eventDispatcher= */ null, + FORMAT_WITH_DRM_INIT_DATA)); + } + private static void waitForOpenedWithKeys(DrmSession drmSession) { // Check the error first, so we get a meaningful failure if there's been an error. assertThat(drmSession.getError()).isNull();