Fix potential NPE/ThreadSafety issues with MediaDrm listener

- MediaDrmEventListener.onEvent is typically called on the
  app's main thread. mediaDrmHandler is instantiated on the
  playback thread. Hence mediaDrmHandler should be volatile
  to ensure visibility.
- Nulling mediaDrmHandler could result in a NPE in onEvent.
  Instantiate mediaDrmHandler (and don't null it again) to
  avoid this. MediaDrmHandler.handleMessage will correctly
  discard any events for sessions that are now closed.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=168707938
This commit is contained in:
olly 2017-09-14 10:34:30 -07:00 committed by Oliver Woodman
parent 58293abc11
commit a479afff5f

View File

@ -98,21 +98,22 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
/** Releases an existing offline license. */
public static final int MODE_RELEASE = 3;
private final UUID uuid;
private final ExoMediaDrm<T> mediaDrm;
private final MediaDrmCallback callback;
private final HashMap<String, String> optionalKeyRequestParameters;
private final Handler eventHandler;
private final EventListener eventListener;
private final ExoMediaDrm<T> mediaDrm;
private final HashMap<String, String> optionalKeyRequestParameters;
private final MediaDrmCallback callback;
private final UUID uuid;
private final boolean multiSession;
private final List<DefaultDrmSession<T>> sessions;
private final AtomicBoolean provisioningInProgress;
private Looper playbackLooper;
private int mode;
private byte[] offlineLicenseKeySetId;
private final List<DefaultDrmSession<T>> sessions;
private final AtomicBoolean provisioningInProgress;
/* package */ MediaDrmHandler mediaDrmHandler;
/* package */ volatile MediaDrmHandler mediaDrmHandler;
/**
* Instantiates a new instance using the Widevine scheme.
@ -226,6 +227,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
if (multiSession) {
mediaDrm.setPropertyString("sessionSharing", "enable");
}
mediaDrm.setOnEventListener(new MediaDrmEventListener());
}
/**
@ -334,8 +336,9 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
if (sessions.isEmpty()) {
this.playbackLooper = playbackLooper;
if (mediaDrmHandler == null) {
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
mediaDrm.setOnEventListener(new MediaDrmEventListener());
}
}
DefaultDrmSession<T> session = null;
@ -383,13 +386,6 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
if (drmSession.release()) {
sessions.remove(drmSession);
}
if (sessions.isEmpty()) {
mediaDrm.setOnEventListener(null);
mediaDrmHandler.removeCallbacksAndMessages(null);
mediaDrmHandler = null;
playbackLooper = null;
}
}
@Override