Skip to content

Commit

Permalink
Add warning logs if DefaultDrmSessionManager is used on wrong thread
Browse files Browse the repository at this point in the history
Issue: google/ExoPlayer#11008
PiperOrigin-RevId: 520864579
(cherry picked from commit 7ca9668)
  • Loading branch information
icbaker authored and rohitjoins committed Apr 18, 2023
1 parent 3daaad7 commit 3480a27
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ public interface ReferenceCountListener {
private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final PlayerId playerId;

/* package */ final MediaDrmCallback callback;
/* package */ final UUID uuid;
/* package */ final ResponseHandler responseHandler;
private final MediaDrmCallback callback;
private final UUID uuid;
private final Looper playbackLooper;
private final ResponseHandler responseHandler;

private @DrmSession.State int state;
private int referenceCount;
Expand Down Expand Up @@ -209,10 +210,12 @@ public DefaultDrmSession(
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
this.playerId = playerId;
state = STATE_OPENING;
this.playbackLooper = playbackLooper;
responseHandler = new ResponseHandler(playbackLooper);
}

public boolean hasSessionId(byte[] sessionId) {
verifyPlaybackThread();
return Arrays.equals(this.sessionId, sessionId);
}

Expand Down Expand Up @@ -255,50 +258,59 @@ public void onProvisionError(Exception error, boolean thrownByExoMediaDrm) {

@Override
public final @DrmSession.State int getState() {
verifyPlaybackThread();
return state;
}

@Override
public boolean playClearSamplesWithoutKeys() {
verifyPlaybackThread();
return playClearSamplesWithoutKeys;
}

@Override
@Nullable
public final DrmSessionException getError() {
verifyPlaybackThread();
return state == STATE_ERROR ? lastException : null;
}

@Override
public final UUID getSchemeUuid() {
verifyPlaybackThread();
return uuid;
}

@Override
@Nullable
public final CryptoConfig getCryptoConfig() {
verifyPlaybackThread();
return cryptoConfig;
}

@Override
@Nullable
public Map<String, String> queryKeyStatus() {
verifyPlaybackThread();
return sessionId == null ? null : mediaDrm.queryKeyStatus(sessionId);
}

@Override
@Nullable
public byte[] getOfflineLicenseKeySetId() {
verifyPlaybackThread();
return offlineLicenseKeySetId;
}

@Override
public boolean requiresSecureDecoder(String mimeType) {
verifyPlaybackThread();
return mediaDrm.requiresSecureDecoder(checkStateNotNull(sessionId), mimeType);
}

@Override
public void acquire(@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) {
verifyPlaybackThread();
if (referenceCount < 0) {
Log.e(TAG, "Session reference count less than zero: " + referenceCount);
referenceCount = 0;
Expand Down Expand Up @@ -326,6 +338,7 @@ && isOpen()

@Override
public void release(@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher) {
verifyPlaybackThread();
if (referenceCount <= 0) {
Log.e(TAG, "release() called on a session that's already fully released.");
return;
Expand Down Expand Up @@ -561,6 +574,18 @@ private void dispatchEvent(Consumer<DrmSessionEventListener.EventDispatcher> eve
}
}

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.

@SuppressLint("HandlerLeak")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ public void setMode(@Mode int mode, @Nullable byte[] offlineLicenseKeySetId) {

@Override
public final void prepare() {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ true);
if (prepareCallsCount++ != 0) {
return;
}
Expand All @@ -487,6 +488,7 @@ public final void prepare() {

@Override
public final void release() {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ true);
if (--prepareCallsCount != 0) {
return;
}
Expand All @@ -513,6 +515,7 @@ public void setPlayer(Looper playbackLooper, PlayerId playerId) {
@Override
public DrmSessionReference preacquireSession(
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
// Don't verify the playback thread, preacquireSession can be called from any thread.
checkState(prepareCallsCount > 0);
checkStateNotNull(playbackLooper);
PreacquiredSessionReference preacquiredSessionReference =
Expand All @@ -525,6 +528,7 @@ public DrmSessionReference preacquireSession(
@Nullable
public DrmSession acquireSession(
@Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format) {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ false);
checkState(prepareCallsCount > 0);
checkStateNotNull(playbackLooper);
return acquireSession(
Expand Down Expand Up @@ -599,6 +603,7 @@ private DrmSession acquireSession(

@Override
public @C.CryptoType int getCryptoType(Format format) {
verifyPlaybackThread(/* allowBeforeSetPlayer= */ false);
@C.CryptoType int cryptoType = checkNotNull(exoMediaDrm).getCryptoType();
if (format.drmInitData == null) {
int trackType = MimeTypes.getTrackType(format.sampleMimeType);
Expand Down Expand Up @@ -817,6 +822,23 @@ private void maybeReleaseMediaDrm() {
}
}

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}.
*
Expand Down

0 comments on commit 3480a27

Please sign in to comment.