Skip to content

Commit

Permalink
Support multiple DefaultDrmSessionManager listeners.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190236842
  • Loading branch information
tonihei authored and ojw28 committed Mar 27, 2018
1 parent 416e05f commit 40947d5
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 172 deletions.
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* Add release method to Cache interface.
* Prevent multiple instances of SimpleCache in the same folder.
Previous instance must be released.
* DRM: Allow multiple listeners for `DefaultDrmSessionManager`.
* Fix ANR issue on Redmi 4X and Redmi Note 4
([#4006](https://github.com/google/ExoPlayer/issues/4006)).
* Removed default renderer time offset of 60000000 from internal player. The
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,11 @@ private DrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManagerV18(UUID u
keyRequestPropertiesArray[i + 1]);
}
}
return new DefaultDrmSessionManager<>(uuid, FrameworkMediaDrm.newInstance(uuid), drmCallback,
null, mainHandler, eventLogger, multiSession);
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
new DefaultDrmSessionManager<>(
uuid, FrameworkMediaDrm.newInstance(uuid), drmCallback, null, multiSession);
drmSessionManager.addListener(mainHandler, eventLogger);
return drmSessionManager;
}

private void releasePlayer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import android.util.Log;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DefaultDrmSessionEventListener.EventDispatcher;
import com.google.android.exoplayer2.drm.ExoMediaDrm.DefaultKeyRequest;
import com.google.android.exoplayer2.drm.ExoMediaDrm.KeyRequest;
import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
Expand Down Expand Up @@ -80,8 +81,7 @@ public interface ProvisioningManager<T extends ExoMediaCrypto> {
private final String mimeType;
private final @DefaultDrmSessionManager.Mode int mode;
private final HashMap<String, String> optionalKeyRequestParameters;
private final Handler eventHandler;
private final DefaultDrmSessionManager.EventListener eventListener;
private final EventDispatcher eventDispatcher;
private final int initialDrmRequestRetryCount;

/* package */ final MediaDrmCallback callback;
Expand Down Expand Up @@ -109,17 +109,22 @@ public interface ProvisioningManager<T extends ExoMediaCrypto> {
* @param optionalKeyRequestParameters The optional key request parameters.
* @param callback The media DRM callback.
* @param playbackLooper The playback looper.
* @param eventHandler The handler to post listener events.
* @param eventListener The DRM session manager event listener.
* @param eventDispatcher The dispatcher for DRM session manager events.
* @param initialDrmRequestRetryCount The number of times to retry for initial provisioning and
* key request before reporting error.
*/
public DefaultDrmSession(UUID uuid, ExoMediaDrm<T> mediaDrm,
ProvisioningManager<T> provisioningManager, byte[] initData, String mimeType,
@DefaultDrmSessionManager.Mode int mode, byte[] offlineLicenseKeySetId,
HashMap<String, String> optionalKeyRequestParameters, MediaDrmCallback callback,
Looper playbackLooper, Handler eventHandler,
DefaultDrmSessionManager.EventListener eventListener,
public DefaultDrmSession(
UUID uuid,
ExoMediaDrm<T> mediaDrm,
ProvisioningManager<T> provisioningManager,
byte[] initData,
String mimeType,
@DefaultDrmSessionManager.Mode int mode,
byte[] offlineLicenseKeySetId,
HashMap<String, String> optionalKeyRequestParameters,
MediaDrmCallback callback,
Looper playbackLooper,
EventDispatcher eventDispatcher,
int initialDrmRequestRetryCount) {
this.uuid = uuid;
this.provisioningManager = provisioningManager;
Expand All @@ -129,9 +134,7 @@ public DefaultDrmSession(UUID uuid, ExoMediaDrm<T> mediaDrm,
this.optionalKeyRequestParameters = optionalKeyRequestParameters;
this.callback = callback;
this.initialDrmRequestRetryCount = initialDrmRequestRetryCount;

this.eventHandler = eventHandler;
this.eventListener = eventListener;
this.eventDispatcher = eventDispatcher;
state = STATE_OPENING;

postResponseHandler = new PostResponseHandler(playbackLooper);
Expand Down Expand Up @@ -306,14 +309,7 @@ private void doLicense(boolean allowRetry) {
onError(new KeysExpiredException());
} else {
state = STATE_OPENED_WITH_KEYS;
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
eventListener.onDrmKeysRestored();
}
});
}
eventDispatcher.drmKeysRestored();
}
}
break;
Expand Down Expand Up @@ -391,14 +387,7 @@ private void onKeyResponse(Object response) {
}
if (mode == DefaultDrmSessionManager.MODE_RELEASE) {
mediaDrm.provideKeyResponse(offlineLicenseKeySetId, responseData);
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
eventListener.onDrmKeysRemoved();
}
});
}
eventDispatcher.drmKeysRemoved();
} else {
byte[] keySetId = mediaDrm.provideKeyResponse(sessionId, responseData);
if ((mode == DefaultDrmSessionManager.MODE_DOWNLOAD
Expand All @@ -407,14 +396,7 @@ public void run() {
offlineLicenseKeySetId = keySetId;
}
state = STATE_OPENED_WITH_KEYS;
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
eventListener.onDrmKeysLoaded();
}
});
}
eventDispatcher.drmKeysLoaded();
}
} catch (Exception e) {
onKeysError(e);
Expand All @@ -438,14 +420,7 @@ private void onKeysError(Exception e) {

private void onError(final Exception e) {
lastException = new DrmSessionException(e);
if (eventHandler != null && eventListener != null) {
eventHandler.post(new Runnable() {
@Override
public void run() {
eventListener.onDrmSessionManagerError(e);
}
});
}
eventDispatcher.drmSessionManagerError(e);
if (state != STATE_OPENED_WITH_KEYS) {
state = STATE_ERROR;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.drm;

import android.os.Handler;
import com.google.android.exoplayer2.Player;
import java.util.concurrent.CopyOnWriteArrayList;

/** Listener of {@link DefaultDrmSessionManager} events. */
public interface DefaultDrmSessionEventListener {

/** Called each time keys are loaded. */
void onDrmKeysLoaded();

/**
* Called when a drm error occurs.
*
* <p>This method being called does not indicate that playback has failed, or that it will fail.
* The player may be able to recover from the error and continue. Hence applications should
* <em>not</em> implement this method to display a user visible error or initiate an application
* level retry ({@link Player.EventListener#onPlayerError} is the appropriate place to implement
* such behavior). This method is called to provide the application with an opportunity to log the
* error if it wishes to do so.
*
* @param error The corresponding exception.
*/
void onDrmSessionManagerError(Exception error);

/** Called each time offline keys are restored. */
void onDrmKeysRestored();

/** Called each time offline keys are removed. */
void onDrmKeysRemoved();

/** Dispatches drm events to all registered listeners. */
final class EventDispatcher {

private final CopyOnWriteArrayList<HandlerAndListener> listeners;

/** Creates event dispatcher. */
public EventDispatcher() {
listeners = new CopyOnWriteArrayList<>();
}

/** Adds listener to event dispatcher. */
public void addListener(Handler handler, DefaultDrmSessionEventListener eventListener) {
listeners.add(new HandlerAndListener(handler, eventListener));
}

/** Removes listener from event dispatcher. */
public void removeListener(DefaultDrmSessionEventListener eventListener) {
for (HandlerAndListener handlerAndListener : listeners) {
if (handlerAndListener.listener == eventListener) {
listeners.remove(handlerAndListener);
}
}
}

/** Dispatches {@link DefaultDrmSessionEventListener#onDrmKeysLoaded()}. */
public void drmKeysLoaded() {
for (HandlerAndListener handlerAndListener : listeners) {
final DefaultDrmSessionEventListener listener = handlerAndListener.listener;
handlerAndListener.handler.post(
new Runnable() {
@Override
public void run() {
listener.onDrmKeysLoaded();
}
});
}
}

/** Dispatches {@link DefaultDrmSessionEventListener#onDrmSessionManagerError(Exception)}. */
public void drmSessionManagerError(final Exception e) {
for (HandlerAndListener handlerAndListener : listeners) {
final DefaultDrmSessionEventListener listener = handlerAndListener.listener;
handlerAndListener.handler.post(
new Runnable() {
@Override
public void run() {
listener.onDrmSessionManagerError(e);
}
});
}
}

/** Dispatches {@link DefaultDrmSessionEventListener#onDrmKeysRestored()}. */
public void drmKeysRestored() {
for (HandlerAndListener handlerAndListener : listeners) {
final DefaultDrmSessionEventListener listener = handlerAndListener.listener;
handlerAndListener.handler.post(
new Runnable() {
@Override
public void run() {
listener.onDrmKeysRestored();
}
});
}
}

/** Dispatches {@link DefaultDrmSessionEventListener#onDrmKeysRemoved()}. */
public void drmKeysRemoved() {
for (HandlerAndListener handlerAndListener : listeners) {
final DefaultDrmSessionEventListener listener = handlerAndListener.listener;
handlerAndListener.handler.post(
new Runnable() {
@Override
public void run() {
listener.onDrmKeysRemoved();
}
});
}
}

private static final class HandlerAndListener {

public final Handler handler;
public final DefaultDrmSessionEventListener listener;

public HandlerAndListener(Handler handler, DefaultDrmSessionEventListener eventListener) {
this.handler = handler;
this.listener = eventListener;
}
}
}
}
Loading

0 comments on commit 40947d5

Please sign in to comment.