Use MediaSourceEventDispatcher in DefaultDrmSession(Manager)

Remove add/removeEventListener methods & associated listener plumbing.

Part of issue:#6765

PiperOrigin-RevId: 302411347
This commit is contained in:
ibaker 2020-03-23 12:13:28 +00:00 committed by Oliver Woodman
parent 1fa9dbc31e
commit adae53c787
3 changed files with 37 additions and 36 deletions

View File

@ -31,7 +31,7 @@ import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest; import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.EventDispatcher; import com.google.android.exoplayer2.util.CopyOnWriteMultiset;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher; import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
@ -109,7 +109,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private final boolean playClearSamplesWithoutKeys; private final boolean playClearSamplesWithoutKeys;
private final boolean isPlaceholderSession; private final boolean isPlaceholderSession;
private final HashMap<String, String> keyRequestParameters; private final HashMap<String, String> keyRequestParameters;
private final EventDispatcher<DrmSessionEventListener> eventDispatcher; private final CopyOnWriteMultiset<MediaSourceEventDispatcher> eventDispatchers;
private final LoadErrorHandlingPolicy loadErrorHandlingPolicy; private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
/* package */ final MediaDrmCallback callback; /* package */ final MediaDrmCallback callback;
@ -144,7 +144,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* @param keyRequestParameters Key request parameters. * @param keyRequestParameters Key request parameters.
* @param callback The media DRM callback. * @param callback The media DRM callback.
* @param playbackLooper The playback looper. * @param playbackLooper The playback looper.
* @param eventDispatcher The dispatcher for DRM session manager events.
* @param loadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy} for key and provisioning * @param loadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy} for key and provisioning
* requests. * requests.
*/ */
@ -161,7 +160,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
HashMap<String, String> keyRequestParameters, HashMap<String, String> keyRequestParameters,
MediaDrmCallback callback, MediaDrmCallback callback,
Looper playbackLooper, Looper playbackLooper,
EventDispatcher<DrmSessionEventListener> eventDispatcher,
LoadErrorHandlingPolicy loadErrorHandlingPolicy) { LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
if (mode == DefaultDrmSessionManager.MODE_QUERY if (mode == DefaultDrmSessionManager.MODE_QUERY
|| mode == DefaultDrmSessionManager.MODE_RELEASE) { || mode == DefaultDrmSessionManager.MODE_RELEASE) {
@ -182,7 +180,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
} }
this.keyRequestParameters = keyRequestParameters; this.keyRequestParameters = keyRequestParameters;
this.callback = callback; this.callback = callback;
this.eventDispatcher = eventDispatcher; this.eventDispatchers = new CopyOnWriteMultiset<>();
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy; this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
state = STATE_OPENING; state = STATE_OPENING;
responseHandler = new ResponseHandler(playbackLooper); responseHandler = new ResponseHandler(playbackLooper);
@ -261,6 +259,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
@Override @Override
public void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher) { public void acquire(@Nullable MediaSourceEventDispatcher eventDispatcher) {
Assertions.checkState(referenceCount >= 0); Assertions.checkState(referenceCount >= 0);
if (eventDispatcher != null) {
eventDispatchers.add(eventDispatcher);
}
if (++referenceCount == 1) { if (++referenceCount == 1) {
Assertions.checkState(state == STATE_OPENING); Assertions.checkState(state == STATE_OPENING);
requestHandlerThread = new HandlerThread("DrmRequestHandler"); requestHandlerThread = new HandlerThread("DrmRequestHandler");
@ -269,6 +270,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
if (openInternal(true)) { if (openInternal(true)) {
doLicense(true); doLicense(true);
} }
} else {
// TODO: Add a parameter to onDrmSessionAcquired to indicate whether the session is being
// re-used or not.
if (eventDispatcher != null) {
eventDispatcher.dispatch(
(listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionAcquired(),
DrmSessionEventListener.class);
}
} }
} }
@ -289,10 +298,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
if (sessionId != null) { if (sessionId != null) {
mediaDrm.closeSession(sessionId); mediaDrm.closeSession(sessionId);
sessionId = null; sessionId = null;
this.eventDispatcher.dispatch(DrmSessionEventListener::onDrmSessionReleased);
} }
releaseCallback.onSessionReleased(this); releaseCallback.onSessionReleased(this);
} }
dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionReleased());
if (eventDispatcher != null) {
eventDispatchers.remove(eventDispatcher);
}
} }
// Internal methods. // Internal methods.
@ -314,7 +326,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
try { try {
sessionId = mediaDrm.openSession(); sessionId = mediaDrm.openSession();
mediaCrypto = mediaDrm.createMediaCrypto(sessionId); mediaCrypto = mediaDrm.createMediaCrypto(sessionId);
eventDispatcher.dispatch(DrmSessionEventListener::onDrmSessionAcquired); dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionAcquired());
state = STATE_OPENED; state = STATE_OPENED;
Assertions.checkNotNull(sessionId); Assertions.checkNotNull(sessionId);
return true; return true;
@ -378,7 +390,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
onError(new KeysExpiredException()); onError(new KeysExpiredException());
} else { } else {
state = STATE_OPENED_WITH_KEYS; state = STATE_OPENED_WITH_KEYS;
eventDispatcher.dispatch(DrmSessionEventListener::onDrmKeysRestored); dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRestored());
} }
} }
break; break;
@ -448,7 +460,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
byte[] responseData = (byte[]) response; byte[] responseData = (byte[]) response;
if (mode == DefaultDrmSessionManager.MODE_RELEASE) { if (mode == DefaultDrmSessionManager.MODE_RELEASE) {
mediaDrm.provideKeyResponse(Util.castNonNull(offlineLicenseKeySetId), responseData); mediaDrm.provideKeyResponse(Util.castNonNull(offlineLicenseKeySetId), responseData);
eventDispatcher.dispatch(DrmSessionEventListener::onDrmKeysRestored); dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysRestored());
} else { } else {
byte[] keySetId = mediaDrm.provideKeyResponse(sessionId, responseData); byte[] keySetId = mediaDrm.provideKeyResponse(sessionId, responseData);
if ((mode == DefaultDrmSessionManager.MODE_DOWNLOAD if ((mode == DefaultDrmSessionManager.MODE_DOWNLOAD
@ -459,7 +471,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
offlineLicenseKeySetId = keySetId; offlineLicenseKeySetId = keySetId;
} }
state = STATE_OPENED_WITH_KEYS; state = STATE_OPENED_WITH_KEYS;
eventDispatcher.dispatch(DrmSessionEventListener::onDrmKeysLoaded); dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmKeysLoaded());
} }
} catch (Exception e) { } catch (Exception e) {
onKeysError(e); onKeysError(e);
@ -483,7 +495,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private void onError(final Exception e) { private void onError(final Exception e) {
lastException = new DrmSessionException(e); lastException = new DrmSessionException(e);
eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(e)); dispatchEvent((listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionManagerError(e));
if (state != STATE_OPENED_WITH_KEYS) { if (state != STATE_OPENED_WITH_KEYS) {
state = STATE_ERROR; state = STATE_ERROR;
} }
@ -495,6 +507,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
return state == STATE_OPENED || state == STATE_OPENED_WITH_KEYS; return state == STATE_OPENED || state == STATE_OPENED_WITH_KEYS;
} }
private void dispatchEvent(
MediaSourceEventDispatcher.EventWithPeriodId<DrmSessionEventListener> event) {
for (MediaSourceEventDispatcher eventDispatcher : eventDispatchers.elementSet()) {
eventDispatcher.dispatch(event, DrmSessionEventListener.class);
}
}
// Internal classes. // Internal classes.
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")

View File

@ -29,7 +29,6 @@ import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.EventDispatcher;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher; import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
@ -240,7 +239,6 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
private final ExoMediaDrm.Provider exoMediaDrmProvider; private final ExoMediaDrm.Provider exoMediaDrmProvider;
private final MediaDrmCallback callback; private final MediaDrmCallback callback;
private final HashMap<String, String> keyRequestParameters; private final HashMap<String, String> keyRequestParameters;
private final EventDispatcher<DrmSessionEventListener> eventDispatcher;
private final boolean multiSession; private final boolean multiSession;
private final int[] useDrmSessionsForClearContentTrackTypes; private final int[] useDrmSessionsForClearContentTrackTypes;
private final boolean playClearSamplesWithoutKeys; private final boolean playClearSamplesWithoutKeys;
@ -356,7 +354,6 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
this.exoMediaDrmProvider = exoMediaDrmProvider; this.exoMediaDrmProvider = exoMediaDrmProvider;
this.callback = callback; this.callback = callback;
this.keyRequestParameters = keyRequestParameters; this.keyRequestParameters = keyRequestParameters;
this.eventDispatcher = new EventDispatcher<>();
this.multiSession = multiSession; this.multiSession = multiSession;
this.useDrmSessionsForClearContentTrackTypes = useDrmSessionsForClearContentTrackTypes; this.useDrmSessionsForClearContentTrackTypes = useDrmSessionsForClearContentTrackTypes;
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys; this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
@ -367,25 +364,6 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
provisioningSessions = new ArrayList<>(); provisioningSessions = new ArrayList<>();
} }
/**
* Adds a {@link DrmSessionEventListener} to listen to drm session events.
*
* @param handler A handler to use when delivering events to {@code eventListener}.
* @param eventListener A listener of events.
*/
public final void addListener(Handler handler, DrmSessionEventListener eventListener) {
eventDispatcher.addListener(handler, eventListener);
}
/**
* Removes a {@link DrmSessionEventListener} from the list of drm session event listeners.
*
* @param eventListener The listener to remove.
*/
public final void removeListener(DrmSessionEventListener eventListener) {
eventDispatcher.removeListener(eventListener);
}
/** /**
* Sets the mode, which determines the role of sessions acquired from the instance. This must be * Sets the mode, which determines the role of sessions acquired from the instance. This must be
* called before {@link #acquireSession(Looper, MediaSourceEventDispatcher, DrmInitData)} or * called before {@link #acquireSession(Looper, MediaSourceEventDispatcher, DrmInitData)} or
@ -509,7 +487,11 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
schemeDatas = getSchemeDatas(drmInitData, uuid, false); schemeDatas = getSchemeDatas(drmInitData, uuid, false);
if (schemeDatas.isEmpty()) { if (schemeDatas.isEmpty()) {
final MissingSchemeDataException error = new MissingSchemeDataException(uuid); final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
this.eventDispatcher.dispatch(listener -> listener.onDrmSessionManagerError(error)); if (eventDispatcher != null) {
eventDispatcher.dispatch(
(listener, windowIndex, mediaPeriodId) -> listener.onDrmSessionManagerError(error),
DrmSessionEventListener.class);
}
return new ErrorStateDrmSession(new DrmSessionException(error)); return new ErrorStateDrmSession(new DrmSessionException(error));
} }
} }
@ -579,7 +561,6 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
keyRequestParameters, keyRequestParameters,
callback, callback,
Assertions.checkNotNull(playbackLooper), Assertions.checkNotNull(playbackLooper),
eventDispatcher,
loadErrorHandlingPolicy); loadErrorHandlingPolicy);
} }

View File

@ -177,7 +177,8 @@ public final class OfflineLicenseHelper {
conditionVariable.open(); conditionVariable.open();
} }
}; };
drmSessionManager.addListener(new Handler(handlerThread.getLooper()), eventListener); eventDispatcher.addEventListener(
new Handler(handlerThread.getLooper()), eventListener, DrmSessionEventListener.class);
} }
/** /**