diff --git a/library/common/src/main/java/com/google/android/exoplayer2/drm/ExoMediaCrypto.java b/library/common/src/main/java/com/google/android/exoplayer2/drm/ExoMediaCrypto.java index feba7eaaf4..27730c14b3 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/drm/ExoMediaCrypto.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/drm/ExoMediaCrypto.java @@ -15,5 +15,5 @@ */ package com.google.android.exoplayer2.drm; -/** An opaque {@link android.media.MediaCrypto} equivalent. */ +/** Enables decoding of encrypted data using keys in a DRM session. */ public interface ExoMediaCrypto {} 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 b5fe62f6cf..6a5dffc6b8 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 @@ -20,6 +20,7 @@ import android.media.MediaCryptoException; import android.media.MediaDrm; import android.media.MediaDrmException; import android.media.NotProvisionedException; +import android.media.ResourceBusyException; import android.os.Handler; import android.os.PersistableBundle; import androidx.annotation.IntDef; @@ -34,7 +35,7 @@ import java.util.Map; import java.util.UUID; /** - * Used to obtain keys for decrypting protected media streams. See {@link android.media.MediaDrm}. + * Used to obtain keys for decrypting protected media streams. * *

Reference counting

* @@ -45,16 +46,18 @@ import java.util.UUID; *

Each new instance has an initial reference count of 1. Hence application code that creates a * new instance does not normally need to call {@link #acquire()}, and must call {@link #release()} * when the instance is no longer required. + * + * @see MediaDrm */ public interface ExoMediaDrm { - /** {@link ExoMediaDrm} instances provider. */ + /** Provider for {@link ExoMediaDrm} instances. */ interface Provider { /** * Returns an {@link ExoMediaDrm} instance with an incremented reference count. When the caller - * no longer needs to use the instance, it must call {@link ExoMediaDrm#release()} to decrement - * the reference count. + * no longer needs the instance, it must call {@link ExoMediaDrm#release()} to decrement the + * reference count. */ ExoMediaDrm acquireExoMediaDrm(UUID uuid); } @@ -82,37 +85,37 @@ public interface ExoMediaDrm { } } - /** @see MediaDrm#EVENT_KEY_REQUIRED */ + /** Event indicating that keys need to be requested from the license server. */ @SuppressWarnings("InlinedApi") int EVENT_KEY_REQUIRED = MediaDrm.EVENT_KEY_REQUIRED; - /** - * @see MediaDrm#EVENT_KEY_EXPIRED - */ + /** Event indicating that keys have expired, and are no longer usable. */ @SuppressWarnings("InlinedApi") int EVENT_KEY_EXPIRED = MediaDrm.EVENT_KEY_EXPIRED; - /** - * @see MediaDrm#EVENT_PROVISION_REQUIRED - */ + /** Event indicating that a certificate needs to be requested from the provisioning server. */ @SuppressWarnings("InlinedApi") int EVENT_PROVISION_REQUIRED = MediaDrm.EVENT_PROVISION_REQUIRED; /** - * @see MediaDrm#KEY_TYPE_STREAMING + * Key request type for keys that will be used for online use. Streaming keys will not be saved to + * the device for subsequent use when the device is not connected to a network. */ @SuppressWarnings("InlinedApi") int KEY_TYPE_STREAMING = MediaDrm.KEY_TYPE_STREAMING; /** - * @see MediaDrm#KEY_TYPE_OFFLINE + * Key request type for keys that will be used for offline use. They will be saved to the device + * for subsequent use when the device is not connected to a network. */ @SuppressWarnings("InlinedApi") int KEY_TYPE_OFFLINE = MediaDrm.KEY_TYPE_OFFLINE; - /** - * @see MediaDrm#KEY_TYPE_RELEASE - */ + /** Key request type indicating that saved offline keys should be released. */ @SuppressWarnings("InlinedApi") int KEY_TYPE_RELEASE = MediaDrm.KEY_TYPE_RELEASE; - /** @see android.media.MediaDrm.OnEventListener */ + /** + * Called when a DRM event occurs. + * + * @see MediaDrm.OnEventListener + */ interface OnEventListener { /** * Called when an event occurs that requires the app to be notified @@ -131,7 +134,11 @@ public interface ExoMediaDrm { @Nullable byte[] data); } - /** @see android.media.MediaDrm.OnKeyStatusChangeListener */ + /** + * Called when the keys in a DRM session change state. + * + * @see MediaDrm.OnKeyStatusChangeListener + */ interface OnKeyStatusChangeListener { /** * Called when the keys in a session change status, such as when the license is renewed or @@ -149,12 +156,16 @@ public interface ExoMediaDrm { boolean hasNewUsableKey); } - /** @see android.media.MediaDrm.OnExpirationUpdateListener */ + /** + * Called when a session expiration update occurs. + * + * @see MediaDrm.OnExpirationUpdateListener + */ interface OnExpirationUpdateListener { /** * Called when a session expiration update occurs, to inform the app about the change in - * expiration time + * expiration time. * * @param mediaDrm The {@link ExoMediaDrm} object on which the event occurred. * @param sessionId The DRM session ID on which the event occurred @@ -165,31 +176,43 @@ public interface ExoMediaDrm { void onExpirationUpdate(ExoMediaDrm mediaDrm, byte[] sessionId, long expirationTimeMs); } - /** @see android.media.MediaDrm.KeyStatus */ + /** + * Defines the status of a key. + * + * @see MediaDrm.KeyStatus + */ final class KeyStatus { private final int statusCode; private final byte[] keyId; + /** + * Creates an instance. + * + * @param statusCode The status code of the key, as defined by {@link + * MediaDrm.KeyStatus#getStatusCode()}. + * @param keyId The ID of the key. + */ public KeyStatus(int statusCode, byte[] keyId) { this.statusCode = statusCode; this.keyId = keyId; } + /** Returns the status of the key, as defined by {@link MediaDrm.KeyStatus#getStatusCode()}. */ public int getStatusCode() { return statusCode; } + /** Returns the ID of the key. */ public byte[] getKeyId() { return keyId; } - } /** * Contains data used to request keys from a license server. * - * @see android.media.MediaDrm.KeyRequest + * @see MediaDrm.KeyRequest */ final class KeyRequest { @@ -281,25 +304,40 @@ public interface ExoMediaDrm { } } - /** @see android.media.MediaDrm.ProvisionRequest */ + /** + * Contains data to request a certificate from a provisioning server. + * + * @see MediaDrm.ProvisionRequest + */ final class ProvisionRequest { private final byte[] data; private final String defaultUrl; + /** + * Creates an instance. + * + * @param data The opaque provisioning request data. + * @param defaultUrl The default URL of the provisioning server to which the request can be + * made, or the empty string if not known. + */ public ProvisionRequest(byte[] data, String defaultUrl) { this.data = data; this.defaultUrl = defaultUrl; } + /** Returns the opaque provisioning request data. */ public byte[] getData() { return data; } + /** + * Returns the default URL of the provisioning server to which the request can be made, or the + * empty string if not known. + */ public String getDefaultUrl() { return defaultUrl; } - } /** @@ -338,11 +376,20 @@ public interface ExoMediaDrm { */ void setOnExpirationUpdateListener(@Nullable OnExpirationUpdateListener listener); - /** @see MediaDrm#openSession() */ + /** + * Opens a new DRM session. A session ID is returned. + * + * @return The session ID. + * @throws NotProvisionedException If provisioning is needed. + * @throws ResourceBusyException If required resources are in use. + * @throws MediaDrmException If the session could not be opened. + */ byte[] openSession() throws MediaDrmException; /** - * @see MediaDrm#closeSession(byte[]) + * Closes a DRM session. + * + * @param sessionId The ID of the session to close. */ void closeSession(byte[] sessionId); @@ -350,8 +397,8 @@ public interface ExoMediaDrm { * Generates a key request. * * @param scope If {@code keyType} is {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE}, - * the session id that the keys will be provided to. If {@code keyType} is {@link - * #KEY_TYPE_RELEASE}, the keySetId of the keys to release. + * the ID of the session that the keys will be provided to. If {@code keyType} is {@link + * #KEY_TYPE_RELEASE}, the {@code keySetId} of the keys to release. * @param schemeDatas If key type is {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE}, a * list of {@link SchemeData} instances extracted from the media. Null otherwise. * @param keyType The type of the request. Either {@link #KEY_TYPE_STREAMING} to acquire keys for @@ -371,23 +418,45 @@ public interface ExoMediaDrm { @Nullable HashMap optionalParameters) throws NotProvisionedException; - /** @see MediaDrm#provideKeyResponse(byte[], byte[]) */ + /** + * Provides a key response for the last request to be generated using {@link #getKeyRequest}. + * + * @param scope If the request had type {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE}, + * the ID of the session to provide the keys to. If {@code keyType} is {@link + * #KEY_TYPE_RELEASE}, the {@code keySetId} of the keys being released. + * @param response The response data from the server. + * @return If the request had type {@link #KEY_TYPE_OFFLINE}, the {@code keySetId} for the offline + * keys. An empty byte array or {@code null} may be returned for other cases. + * @throws NotProvisionedException If the response indicates that provisioning is needed. + * @throws DeniedByServerException If the response indicates that the server rejected the request. + */ @Nullable byte[] provideKeyResponse(byte[] scope, byte[] response) throws NotProvisionedException, DeniedByServerException; /** - * @see MediaDrm#getProvisionRequest() + * Generates a provisioning request. + * + * @return The generated provisioning request. */ ProvisionRequest getProvisionRequest(); /** - * @see MediaDrm#provideProvisionResponse(byte[]) + * Provides a provisioning response for the last request to be generated using {@link + * #getProvisionRequest()}. + * + * @param response The response data from the server. + * @throws DeniedByServerException If the response indicates that the server rejected the request. */ void provideProvisionResponse(byte[] response) throws DeniedByServerException; /** - * @see MediaDrm#queryKeyStatus(byte[]) + * Returns the key status for a given session, as {name, value} pairs. Since DRM license policies + * vary by vendor, the returned entries depend on the DRM plugin being used. Refer to your DRM + * provider's documentation for more information. + * + * @param sessionId The ID of the session being queried. + * @return The key status for the session. */ Map queryKeyStatus(byte[] sessionId); @@ -407,43 +476,64 @@ public interface ExoMediaDrm { void release(); /** - * @see MediaDrm#restoreKeys(byte[], byte[]) + * Restores persisted offline keys into a session. + * + * @param sessionId The ID of the session into which the keys will be restored. + * @param keySetId The {@code keySetId} of the keys to restore, as provided by the call to {@link + * #provideKeyResponse} that persisted them. */ void restoreKeys(byte[] sessionId, byte[] keySetId); /** - * Returns drm metrics. May be null if unavailable. - * - * @see MediaDrm#getMetrics() + * Returns metrics data for this ExoMediaDrm instance, or {@code null} if metrics are unavailable. */ @Nullable PersistableBundle getMetrics(); /** - * @see MediaDrm#getPropertyString(String) + * Returns the value of a string property. For standard property names, see {@link + * MediaDrm#getPropertyString}. + * + * @param propertyName The property name. + * @return The property value. + * @throws IllegalArgumentException If the underlying DRM plugin does not support the property. */ String getPropertyString(String propertyName); /** - * @see MediaDrm#getPropertyByteArray(String) + * Returns the value of a byte array property. For standard property names, see {@link + * MediaDrm#getPropertyByteArray}. + * + * @param propertyName The property name. + * @return The property value. + * @throws IllegalArgumentException If the underlying DRM plugin does not support the property. */ byte[] getPropertyByteArray(String propertyName); /** - * @see MediaDrm#setPropertyString(String, String) + * Sets the value of a string property. + * + * @param propertyName The property name. + * @param value The value. + * @throws IllegalArgumentException If the underlying DRM plugin does not support the property. */ void setPropertyString(String propertyName, String value); /** - * @see MediaDrm#setPropertyByteArray(String, byte[]) + * Sets the value of a byte array property. + * + * @param propertyName The property name. + * @param value The value. + * @throws IllegalArgumentException If the underlying DRM plugin does not support the property. */ void setPropertyByteArray(String propertyName, byte[] value); /** - * @see android.media.MediaCrypto#MediaCrypto(UUID, byte[]) - * @param sessionId The DRM session ID. - * @return An object extends {@link ExoMediaCrypto}, using opaque crypto scheme specific data. - * @throws MediaCryptoException If the instance can't be created. + * Creates an {@link ExoMediaCrypto} for a given session. + * + * @param sessionId The ID of the session. + * @return An {@link ExoMediaCrypto} for the given session. + * @throws MediaCryptoException If an {@link ExoMediaCrypto} could not be created. */ ExoMediaCrypto createMediaCrypto(byte[] sessionId) throws MediaCryptoException;