diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/ExoMediaDrm.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/ExoMediaDrm.java index 25b065c543..1930e11f06 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/ExoMediaDrm.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/ExoMediaDrm.java @@ -21,7 +21,9 @@ import android.media.MediaCryptoException; import android.media.MediaDrm; import android.media.MediaDrmException; import android.media.NotProvisionedException; +import android.os.Handler; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -80,6 +82,31 @@ public interface ExoMediaDrm { byte[] data); } + /** + * @see android.media.MediaDrm.KeyStatus + */ + interface ExoKeyStatus { + int getStatusCode(); + byte[] getKeyId(); + } + + /** + * @see android.media.MediaDrm.OnKeyStatusChangeListener + */ + interface OnKeyStatusChangeListener { + /** + * Called when the keys in a session change status, such as when the license is renewed or + * expires. + * + * @param mediaDrm the {@link ExoMediaDrm} object on which the event occurred. + * @param sessionId the DRM session ID on which the event occurred. + * @param exoKeyInfo a list of {@link ExoKeyStatus} that contains key ID and status. + * @param hasNewUsableKey true if new key becomes usable. + */ + void onKeyStatusChange(ExoMediaDrm mediaDrm, byte[] sessionId, + List exoKeyInfo, boolean hasNewUsableKey); + } + /** * @see android.media.MediaDrm.KeyRequest */ @@ -101,6 +128,11 @@ public interface ExoMediaDrm { */ void setOnEventListener(OnEventListener listener); + /** + * @see MediaDrm#setOnKeyStatusChangeListener(MediaDrm.OnKeyStatusChangeListener, Handler) + */ + void setOnKeyStatusChangeListener(OnKeyStatusChangeListener listener); + /** * @see MediaDrm#openSession() */ diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/FrameworkMediaDrm.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/FrameworkMediaDrm.java index 2edd6ff254..c3ab3462d9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/FrameworkMediaDrm.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/FrameworkMediaDrm.java @@ -20,6 +20,7 @@ import android.media.DeniedByServerException; import android.media.MediaCrypto; import android.media.MediaCryptoException; import android.media.MediaDrm; +import android.media.MediaDrm.KeyStatus; import android.media.MediaDrmException; import android.media.NotProvisionedException; import android.media.UnsupportedSchemeException; @@ -27,14 +28,16 @@ import android.support.annotation.NonNull; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; /** * An {@link ExoMediaDrm} implementation that wraps the framework {@link MediaDrm}. */ -@TargetApi(18) +@TargetApi(23) public final class FrameworkMediaDrm implements ExoMediaDrm { private final UUID uuid; @@ -71,13 +74,36 @@ public final class FrameworkMediaDrm implements ExoMediaDrm listener) { mediaDrm.setOnEventListener(listener == null ? null : new MediaDrm.OnEventListener() { @Override - public void onEvent(@NonNull MediaDrm md, byte[] sessionId, int event, int extra, + public void onEvent(@NonNull MediaDrm md, @NonNull byte[] sessionId, int event, int extra, byte[] data) { listener.onEvent(FrameworkMediaDrm.this, sessionId, event, extra, data); } }); } + @Override + public void setOnKeyStatusChangeListener( + final ExoMediaDrm.OnKeyStatusChangeListener listener) { + if (Util.SDK_INT < 23) { + throw new UnsupportedOperationException(); + } + + mediaDrm.setOnKeyStatusChangeListener(listener == null ? null + : new MediaDrm.OnKeyStatusChangeListener() { + @Override + public void onKeyStatusChange(@NonNull MediaDrm md, @NonNull byte[] sessionId, + @NonNull List keyInfo, boolean hasNewUsableKey) { + List exoKeyInfo = new ArrayList<>(); + for (KeyStatus keyStatus : keyInfo) { + exoKeyInfo.add(new FrameworkKeyStatus(keyStatus)); + } + + listener.onKeyStatusChange(FrameworkMediaDrm.this, sessionId, exoKeyInfo, + hasNewUsableKey); + } + }, null); + } + @Override public byte[] openSession() throws MediaDrmException { return mediaDrm.openSession(); @@ -178,4 +204,22 @@ public final class FrameworkMediaDrm implements ExoMediaDrm