Commit 9d028b33 by ibaker Committed by Rohit Singh

Add warning logs if `DefaultDrmSessionManager` is used on wrong thread

Issue: google/ExoPlayer#11008
PiperOrigin-RevId: 520864579
(cherry picked from commit 1ac7f3cd)
parent b0ce51ac
...@@ -136,9 +136,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -136,9 +136,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private final LoadErrorHandlingPolicy loadErrorHandlingPolicy; private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final PlayerId playerId; private final PlayerId playerId;
/* package */ final MediaDrmCallback callback; private final MediaDrmCallback callback;
/* package */ final UUID uuid; private final UUID uuid;
/* package */ final ResponseHandler responseHandler; private final Looper playbackLooper;
private final ResponseHandler responseHandler;
private @DrmSession.State int state; private @DrmSession.State int state;
private int referenceCount; private int referenceCount;
...@@ -209,10 +210,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -209,10 +210,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy; this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
this.playerId = playerId; this.playerId = playerId;
state = STATE_OPENING; state = STATE_OPENING;
this.playbackLooper = playbackLooper;
responseHandler = new ResponseHandler(playbackLooper); responseHandler = new ResponseHandler(playbackLooper);
} }
public boolean hasSessionId(byte[] sessionId) { public boolean hasSessionId(byte[] sessionId) {
verifyPlaybackThread();
return Arrays.equals(this.sessionId, sessionId); return Arrays.equals(this.sessionId, sessionId);
} }
...@@ -255,50 +258,59 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -255,50 +258,59 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
@Override @Override
public final @DrmSession.State int getState() { public final @DrmSession.State int getState() {
verifyPlaybackThread();
return state; return state;
} }
@Override @Override
public boolean playClearSamplesWithoutKeys() { public boolean playClearSamplesWithoutKeys() {
verifyPlaybackThread();
return playClearSamplesWithoutKeys; return playClearSamplesWithoutKeys;
} }
@Override @Override
@Nullable @Nullable
public final DrmSessionException getError() { public final DrmSessionException getError() {
verifyPlaybackThread();
return state == STATE_ERROR ? lastException : null; return state == STATE_ERROR ? lastException : null;
} }
@Override @Override
public final UUID getSchemeUuid() { public final UUID getSchemeUuid() {
verifyPlaybackThread();
return uuid; return uuid;
} }
@Override @Override
@Nullable @Nullable
public final CryptoConfig getCryptoConfig() { public final CryptoConfig getCryptoConfig() {
verifyPlaybackThread();
return cryptoConfig; return cryptoConfig;
} }
@Override @Override
@Nullable @Nullable
public Map<String, String> queryKeyStatus() { public Map<String, String> queryKeyStatus() {
verifyPlaybackThread();
return sessionId == null ? null : mediaDrm.queryKeyStatus(sessionId); return sessionId == null ? null : mediaDrm.queryKeyStatus(sessionId);
} }
@Override @Override
@Nullable @Nullable
public byte[] getOfflineLicenseKeySetId() { public byte[] getOfflineLicenseKeySetId() {
verifyPlaybackThread();
return offlineLicenseKeySetId; return offlineLicenseKeySetId;
} }
@Override @Override
public boolean requiresSecureDecoder(String mimeType) { public boolean requiresSecureDecoder(String mimeType) {
verifyPlaybackThread();
return mediaDrm.requiresSecureDecoder(checkStateNotNull(sessionId), mimeType); return mediaDrm.requiresSecureDecoder(checkStateNotNull(sessionId), mimeType);
} }
@Override @Override
public void acquire(@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) { public void acquire(@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) {
verifyPlaybackThread();
if (referenceCount < 0) { if (referenceCount < 0) {
Log.e(TAG, "Session reference count less than zero: " + referenceCount); Log.e(TAG, "Session reference count less than zero: " + referenceCount);
referenceCount = 0; referenceCount = 0;
...@@ -326,6 +338,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -326,6 +338,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
@Override @Override
public void release(@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) { public void release(@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) {
verifyPlaybackThread();
if (referenceCount <= 0) { if (referenceCount <= 0) {
Log.e(TAG, "release() called on a session that's already fully released."); Log.e(TAG, "release() called on a session that's already fully released.");
return; return;
...@@ -561,6 +574,18 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -561,6 +574,18 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
} }
} }
private void verifyPlaybackThread() {
if (Thread.currentThread() != playbackLooper.getThread()) {
Log.w(
TAG,
"DefaultDrmSession accessed on the wrong thread.\nCurrent thread: "
+ Thread.currentThread().getName()
+ "\nExpected thread: "
+ playbackLooper.getThread().getName(),
new IllegalStateException());
}
}
// Internal classes. // Internal classes.
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
......
...@@ -468,6 +468,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -468,6 +468,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
@Override @Override
public final void prepare() { public final void prepare() {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ true);
if (prepareCallsCount++ != 0) { if (prepareCallsCount++ != 0) {
return; return;
} }
...@@ -484,6 +485,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -484,6 +485,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
@Override @Override
public final void release() { public final void release() {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ true);
if (--prepareCallsCount != 0) { if (--prepareCallsCount != 0) {
return; return;
} }
...@@ -510,6 +512,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -510,6 +512,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
@Override @Override
public DrmSessionReference preacquireSession( public DrmSessionReference preacquireSession(
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) { @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
// Don't verify the playback thread, preacquireSession can be called from any thread.
checkState(prepareCallsCount > 0); checkState(prepareCallsCount > 0);
checkStateNotNull(playbackLooper); checkStateNotNull(playbackLooper);
PreacquiredSessionReference preacquiredSessionReference = PreacquiredSessionReference preacquiredSessionReference =
...@@ -522,6 +525,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -522,6 +525,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
@Nullable @Nullable
public DrmSession acquireSession( public DrmSession acquireSession(
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) { @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ false);
checkState(prepareCallsCount > 0); checkState(prepareCallsCount > 0);
checkStateNotNull(playbackLooper); checkStateNotNull(playbackLooper);
return acquireSession( return acquireSession(
...@@ -596,6 +600,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -596,6 +600,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
@Override @Override
public @C.CryptoType int getCryptoType(Format format) { public @C.CryptoType int getCryptoType(Format format) {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ false);
@C.CryptoType int cryptoType = checkNotNull(exoMediaDrm).getCryptoType(); @C.CryptoType int cryptoType = checkNotNull(exoMediaDrm).getCryptoType();
if (format.drmInitData == null) { if (format.drmInitData == null) {
int trackType = MimeTypes.getTrackType(format.sampleMimeType); int trackType = MimeTypes.getTrackType(format.sampleMimeType);
...@@ -814,6 +819,23 @@ public class DefaultDrmSessionManager implements DrmSessionManager { ...@@ -814,6 +819,23 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
} }
} }
private void verifyPlaybackThread(boolean allowBeforeSetPlayer) {
if (allowBeforeSetPlayer && playbackLooper == null) {
Log.w(
TAG,
"DefaultDrmSessionManager accessed before setPlayer(), possibly on the wrong thread.",
new IllegalStateException());
} else if (Thread.currentThread() != checkNotNull(playbackLooper).getThread()) {
Log.w(
TAG,
"DefaultDrmSessionManager accessed on the wrong thread.\nCurrent thread: "
+ Thread.currentThread().getName()
+ "\nExpected thread: "
+ playbackLooper.getThread().getName(),
new IllegalStateException());
}
}
/** /**
* Extracts {@link SchemeData} instances suitable for the given DRM scheme {@link UUID}. * Extracts {@link SchemeData} instances suitable for the given DRM scheme {@link UUID}.
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment