Most visited

Recently visited

Added in API level 18

MediaDrm

public final class MediaDrm
extends Object

java.lang.Object
   ↳ android.media.MediaDrm


MediaDrm can be used to obtain keys for decrypting protected media streams, in conjunction with MediaCrypto. The MediaDrm APIs are designed to support the ISO/IEC 23001-7: Common Encryption standard, but may also be used to implement other encryption schemes.

Encrypted content is prepared using an encryption server and stored in a content library. The encrypted content is streamed or downloaded from the content library to client devices via content servers. Licenses to view the content are obtained from a License Server.

MediaDrm Overview diagram

Keys are requested from the license server using a key request. The key response is delivered to the client app, which provides the response to the MediaDrm API.

A Provisioning server may be required to distribute device-unique credentials to the devices.

Enforcing requirements related to the number of devices that may play content simultaneously can be performed either through key renewal or using the secure stop methods.

The following sequence diagram shows the interactions between the objects involved while playing back encrypted content:

MediaDrm Overview diagram

The app first constructs MediaExtractor and MediaCodec objects. It accesses the DRM-scheme-identifying UUID, typically from metadata in the content, and uses this UUID to construct an instance of a MediaDrm object that is able to support the DRM scheme required by the content. Crypto schemes are assigned 16 byte UUIDs. The method isCryptoSchemeSupported(UUID) can be used to query if a given scheme is supported on the device.

The app calls openSession() to generate a sessionId that will uniquely identify the session in subsequent interactions. The app next uses the MediaDrm object to obtain a key request message and send it to the license server, then provide the server's response to the MediaDrm object.

Once the app has a sessionId, it can construct a MediaCrypto object from the UUID and sessionId. The MediaCrypto object is registered with the MediaCodec in the configure(MediaFormat, Surface, MediaCrypto, int) method to enable the codec to decrypt content.

When the app has constructed MediaExtractor, MediaCodec and MediaCrypto objects, it proceeds to pull samples from the extractor and queue them into the decoder. For encrypted content, the samples returned from the extractor remain encrypted, they are only decrypted when the samples are delivered to the decoder.

MediaDrm methods throw MediaDrm.MediaDrmStateException when a method is called on a MediaDrm object that has had an unrecoverable failure in the DRM plugin or security hardware. MediaDrm.MediaDrmStateException extends IllegalStateException with the addition of a developer-readable diagnostic information string associated with the exception.

In the event of a mediaserver process crash or restart while a MediaDrm object is active, MediaDrm methods may throw MediaDrmResetException. To recover, the app must release the MediaDrm object, then create and initialize a new one.

As MediaDrmResetException and MediaDrm.MediaDrmStateException both extend IllegalStateException, they should be in an earlier catch() block than IllegalStateException if handled separately.

Callbacks

Applications should register for informational events in order to be informed of key state updates during playback or streaming. Registration for these events is done via a call to setOnEventListener(MediaDrm.OnEventListener). In order to receive the respective callback associated with this listener, applications are required to create MediaDrm objects on a thread with its own Looper running (main UI thread by default has a Looper running).

Summary

Nested classes

class MediaDrm.CryptoSession

In addition to supporting decryption of DASH Common Encrypted Media, the MediaDrm APIs provide the ability to securely deliver session keys from an operator's session key server to a client device, based on the factory-installed root of trust, and then perform encrypt, decrypt, sign and verify operations with the session key on arbitrary user data. 

class MediaDrm.KeyRequest

Contains the opaque data an app uses to request keys from a license server  

class MediaDrm.KeyStatus

Defines the status of a key. 

class MediaDrm.MediaDrmStateException

Thrown when an unrecoverable failure occurs during a MediaDrm operation. 

interface MediaDrm.OnEventListener

Interface definition for a callback to be invoked when a drm event occurs  

interface MediaDrm.OnExpirationUpdateListener

Interface definition for a callback to be invoked when a drm session expiration update occurs  

interface MediaDrm.OnKeyStatusChangeListener

Interface definition for a callback to be invoked when the keys in a drm session change states. 

class MediaDrm.ProvisionRequest

Contains the opaque data an app uses to request a certificate from a provisioning server  

Constants

int EVENT_KEY_EXPIRED

This event type indicates that the licensed usage duration for keys in a session has expired.

int EVENT_KEY_REQUIRED

This event type indicates that the app needs to request keys from a license server.

int EVENT_PROVISION_REQUIRED

This constant was deprecated in API level 23. Handle provisioning via NotProvisionedException instead.

int EVENT_SESSION_RECLAIMED

This event indicates that a session opened by the app has been reclaimed by the resource manager.

int EVENT_VENDOR_DEFINED

This event may indicate some specific vendor-defined condition, see your DRM provider documentation for details

int KEY_TYPE_OFFLINE

This key request type specifies that the keys will be for offline use, they will be saved to the device for use when the device is not connected to a network.

int KEY_TYPE_RELEASE

This key request type specifies that previously saved offline keys should be released.

int KEY_TYPE_STREAMING

This key request type species that the keys will be for online use, they will not be saved to the device for subsequent use when the device is not connected to a network.

String PROPERTY_ALGORITHMS

String property name: a comma-separated list of cipher and mac algorithms supported by CryptoSession.

String PROPERTY_DESCRIPTION

String property name: describes the DRM engine plugin

String PROPERTY_DEVICE_UNIQUE_ID

Byte array property name: the device unique identifier is established during device provisioning and provides a means of uniquely identifying each device.

String PROPERTY_VENDOR

String property name: identifies the maker of the DRM engine plugin

String PROPERTY_VERSION

String property name: identifies the version of the DRM engine plugin

Public constructors

MediaDrm(UUID uuid)

Instantiate a MediaDrm object

Public methods

void closeSession(byte[] sessionId)

Close a session on the MediaDrm object that was previously opened with openSession().

MediaDrm.CryptoSession getCryptoSession(byte[] sessionId, String cipherAlgorithm, String macAlgorithm)

Obtain a CryptoSession object which can be used to encrypt, decrypt, sign and verify messages or data using the session keys established for the session using methods getKeyRequest(byte[], byte[], String, int, HashMap) and provideKeyResponse(byte[], byte[]) using a session key server.

MediaDrm.KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType, HashMap<StringString> optionalParameters)

A key request/response exchange occurs between the app and a license server to obtain or release keys used to decrypt encrypted content.

byte[] getPropertyByteArray(String propertyName)

Read a DRM engine plugin byte array property value, given the property name string.

String getPropertyString(String propertyName)

Read a DRM engine plugin String property value, given the property name string.

MediaDrm.ProvisionRequest getProvisionRequest()

A provision request/response exchange occurs between the app and a provisioning server to retrieve a device certificate.

byte[] getSecureStop(byte[] ssid)

Access secure stop by secure stop ID.

List<byte[]> getSecureStops()

A means of enforcing limits on the number of concurrent streams per subscriber across devices is provided via SecureStop.

static final boolean isCryptoSchemeSupported(UUID uuid, String mimeType)

Query if the given scheme identified by its UUID is supported on this device, and whether the drm plugin is able to handle the media container format specified by mimeType.

static final boolean isCryptoSchemeSupported(UUID uuid)

Query if the given scheme identified by its UUID is supported on this device.

byte[] openSession()

Open a new session with the MediaDrm object.

byte[] provideKeyResponse(byte[] scope, byte[] response)

A key response is received from the license server by the app, then it is provided to the DRM engine plugin using provideKeyResponse.

void provideProvisionResponse(byte[] response)

After a provision response is received by the app, it is provided to the DRM engine plugin using this method.

HashMap<StringString> queryKeyStatus(byte[] sessionId)

Request an informative description of the key status for the session.

final void release()
void releaseAllSecureStops()

Remove all secure stops without requiring interaction with the server.

void releaseSecureStops(byte[] ssRelease)

Process the SecureStop server response message ssRelease.

void removeKeys(byte[] sessionId)

Remove the current keys from a session.

void restoreKeys(byte[] sessionId, byte[] keySetId)

Restore persisted offline keys into a new session.

void setOnEventListener(MediaDrm.OnEventListener listener)

Register a callback to be invoked when an event occurs

void setOnExpirationUpdateListener(MediaDrm.OnExpirationUpdateListener listener, Handler handler)

Register a callback to be invoked when a session expiration update occurs.

void setOnKeyStatusChangeListener(MediaDrm.OnKeyStatusChangeListener listener, Handler handler)

Register a callback to be invoked when the state of keys in a session change, e.g.

void setPropertyByteArray(String propertyName, byte[] value)

Set a DRM engine plugin byte array property value.

void setPropertyString(String propertyName, String value)

Set a DRM engine plugin String property value.

Protected methods

void finalize()

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

Inherited methods

From class java.lang.Object

Constants

EVENT_KEY_EXPIRED

Added in API level 18
int EVENT_KEY_EXPIRED

This event type indicates that the licensed usage duration for keys in a session has expired. The keys are no longer valid.

Constant Value: 3 (0x00000003)

EVENT_KEY_REQUIRED

Added in API level 18
int EVENT_KEY_REQUIRED

This event type indicates that the app needs to request keys from a license server. The request message data is obtained using getKeyRequest(byte[], byte[], String, int, HashMap).

Constant Value: 2 (0x00000002)

EVENT_PROVISION_REQUIRED

Added in API level 18
int EVENT_PROVISION_REQUIRED

This constant was deprecated in API level 23.
Handle provisioning via NotProvisionedException instead.

This event type indicates that the app needs to request a certificate from the provisioning server. The request message data is obtained using getProvisionRequest()

Constant Value: 1 (0x00000001)

EVENT_SESSION_RECLAIMED

Added in API level 23
int EVENT_SESSION_RECLAIMED

This event indicates that a session opened by the app has been reclaimed by the resource manager.

Constant Value: 5 (0x00000005)

EVENT_VENDOR_DEFINED

Added in API level 18
int EVENT_VENDOR_DEFINED

This event may indicate some specific vendor-defined condition, see your DRM provider documentation for details

Constant Value: 4 (0x00000004)

KEY_TYPE_OFFLINE

Added in API level 18
int KEY_TYPE_OFFLINE

This key request type specifies that the keys will be for offline use, they will be saved to the device for use when the device is not connected to a network.

Constant Value: 2 (0x00000002)

KEY_TYPE_RELEASE

Added in API level 18
int KEY_TYPE_RELEASE

This key request type specifies that previously saved offline keys should be released.

Constant Value: 3 (0x00000003)

KEY_TYPE_STREAMING

Added in API level 18
int KEY_TYPE_STREAMING

This key request type species that the keys will be for online use, they will not be saved to the device for subsequent use when the device is not connected to a network.

Constant Value: 1 (0x00000001)

PROPERTY_ALGORITHMS

Added in API level 18
String PROPERTY_ALGORITHMS

String property name: a comma-separated list of cipher and mac algorithms supported by CryptoSession. The list may be empty if the DRM engine plugin does not support CryptoSession operations.

Constant Value: "algorithms"

PROPERTY_DESCRIPTION

Added in API level 18
String PROPERTY_DESCRIPTION

String property name: describes the DRM engine plugin

Constant Value: "description"

PROPERTY_DEVICE_UNIQUE_ID

Added in API level 18
String PROPERTY_DEVICE_UNIQUE_ID

Byte array property name: the device unique identifier is established during device provisioning and provides a means of uniquely identifying each device.

Constant Value: "deviceUniqueId"

PROPERTY_VENDOR

Added in API level 18
String PROPERTY_VENDOR

String property name: identifies the maker of the DRM engine plugin

Constant Value: "vendor"

PROPERTY_VERSION

Added in API level 18
String PROPERTY_VERSION

String property name: identifies the version of the DRM engine plugin

Constant Value: "version"

Public constructors

MediaDrm

Added in API level 18
MediaDrm (UUID uuid)

Instantiate a MediaDrm object

Parameters
uuid UUID: The UUID of the crypto scheme.
Throws
UnsupportedSchemeException if the device does not support the specified scheme UUID

Public methods

closeSession

Added in API level 18
void closeSession (byte[] sessionId)

Close a session on the MediaDrm object that was previously opened with openSession().

Parameters
sessionId byte

getCryptoSession

Added in API level 18
MediaDrm.CryptoSession getCryptoSession (byte[] sessionId, 
                String cipherAlgorithm, 
                String macAlgorithm)

Obtain a CryptoSession object which can be used to encrypt, decrypt, sign and verify messages or data using the session keys established for the session using methods getKeyRequest(byte[], byte[], String, int, HashMap) and provideKeyResponse(byte[], byte[]) using a session key server.

Parameters
sessionId byte: the session ID for the session containing keys to be used for encrypt, decrypt, sign and/or verify
cipherAlgorithm String: the algorithm to use for encryption and decryption ciphers. The algorithm string conforms to JCA Standard Names for Cipher Transforms and is case insensitive. For example "AES/CBC/NoPadding".
macAlgorithm String: the algorithm to use for sign and verify The algorithm string conforms to JCA Standard Names for Mac Algorithms and is case insensitive. For example "HmacSHA256".

The list of supported algorithms for a DRM engine plugin can be obtained using the method getPropertyString(String) with the property name "algorithms".

Returns
MediaDrm.CryptoSession

getKeyRequest

Added in API level 18
MediaDrm.KeyRequest getKeyRequest (byte[] scope, 
                byte[] init, 
                String mimeType, 
                int keyType, 
                HashMap<StringString> optionalParameters)

A key request/response exchange occurs between the app and a license server to obtain or release keys used to decrypt encrypted content.

getKeyRequest() is used to obtain an opaque key request byte array that is delivered to the license server. The opaque key request byte array is returned in KeyRequest.data. The recommended URL to deliver the key request to is returned in KeyRequest.defaultUrl.

After the app has received the key request response from the server, it should deliver to the response to the DRM engine plugin using the method provideKeyResponse(byte[], byte[]).

Parameters
scope byte: may be a sessionId or a keySetId, depending on the specified keyType. When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, scope should be set to the sessionId the keys will be provided to. When the keyType is KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys being released. Releasing keys from a device invalidates them for all sessions.
init byte: container-specific data, its meaning is interpreted based on the mime type provided in the mimeType parameter. It could contain, for example, the content ID, key ID or other data obtained from the content metadata that is required in generating the key request. init may be null when keyType is KEY_TYPE_RELEASE.
mimeType String: identifies the mime type of the content
keyType int: specifes the type of the request. The request may be to acquire keys for streaming or offline content, or to release previously acquired keys, which are identified by a keySetId.
optionalParameters HashMap: are included in the key request message to allow a client application to provide additional message parameters to the server. This may be null if no additional parameters are to be sent.
Returns
MediaDrm.KeyRequest
Throws
NotProvisionedException if reprovisioning is needed, due to a problem with the certifcate

getPropertyByteArray

Added in API level 18
byte[] getPropertyByteArray (String propertyName)

Read a DRM engine plugin byte array property value, given the property name string.

Standard fields names are PROPERTY_DEVICE_UNIQUE_ID

Parameters
propertyName String
Returns
byte[]

getPropertyString

Added in API level 18
String getPropertyString (String propertyName)

Read a DRM engine plugin String property value, given the property name string.

Standard fields names are: PROPERTY_VENDOR, PROPERTY_VERSION, PROPERTY_DESCRIPTION, PROPERTY_ALGORITHMS

Parameters
propertyName String
Returns
String

getProvisionRequest

Added in API level 18
MediaDrm.ProvisionRequest getProvisionRequest ()

A provision request/response exchange occurs between the app and a provisioning server to retrieve a device certificate. If provisionining is required, the EVENT_PROVISION_REQUIRED event will be sent to the event handler. getProvisionRequest is used to obtain the opaque provision request byte array that should be delivered to the provisioning server. The provision request byte array is returned in ProvisionRequest.data. The recommended URL to deliver the provision request to is returned in ProvisionRequest.defaultUrl.

Returns
MediaDrm.ProvisionRequest

getSecureStop

Added in API level 22
byte[] getSecureStop (byte[] ssid)

Access secure stop by secure stop ID.

Parameters
ssid byte: - The secure stop ID provided by the license server.
Returns
byte[]

getSecureStops

Added in API level 18
List<byte[]> getSecureStops ()

A means of enforcing limits on the number of concurrent streams per subscriber across devices is provided via SecureStop. This is achieved by securely monitoring the lifetime of sessions.

Information from the server related to the current playback session is written to persistent storage on the device when each MediaCrypto object is created.

In the normal case, playback will be completed, the session destroyed and the Secure Stops will be queried. The app queries secure stops and forwards the secure stop message to the server which verifies the signature and notifies the server side database that the session destruction has been confirmed. The persisted record on the client is only removed after positive confirmation that the server received the message using releaseSecureStops().

Returns
List<byte[]>

isCryptoSchemeSupported

Added in API level 19
boolean isCryptoSchemeSupported (UUID uuid, 
                String mimeType)

Query if the given scheme identified by its UUID is supported on this device, and whether the drm plugin is able to handle the media container format specified by mimeType.

Parameters
uuid UUID: The UUID of the crypto scheme.
mimeType String: The MIME type of the media container, e.g. "video/mp4" or "video/webm"
Returns
boolean

isCryptoSchemeSupported

Added in API level 18
boolean isCryptoSchemeSupported (UUID uuid)

Query if the given scheme identified by its UUID is supported on this device.

Parameters
uuid UUID: The UUID of the crypto scheme.
Returns
boolean

openSession

Added in API level 18
byte[] openSession ()

Open a new session with the MediaDrm object. A session ID is returned.

Returns
byte[]
Throws
NotProvisionedException if provisioning is needed
ResourceBusyException if required resources are in use

provideKeyResponse

Added in API level 18
byte[] provideKeyResponse (byte[] scope, 
                byte[] response)

A key response is received from the license server by the app, then it is provided to the DRM engine plugin using provideKeyResponse. When the response is for an offline key request, a keySetId is returned that can be used to later restore the keys to a new session with the method restoreKeys(byte[], byte[]). When the response is for a streaming or release request, null is returned.

Parameters
scope byte: may be a sessionId or keySetId depending on the type of the response. Scope should be set to the sessionId when the response is for either streaming or offline key requests. Scope should be set to the keySetId when the response is for a release request.
response byte: the byte array response from the server
Returns
byte[]
Throws
NotProvisionedException if the response indicates that reprovisioning is required
DeniedByServerException if the response indicates that the server rejected the request

provideProvisionResponse

Added in API level 18
void provideProvisionResponse (byte[] response)

After a provision response is received by the app, it is provided to the DRM engine plugin using this method.

Parameters
response byte: the opaque provisioning response byte array to provide to the DRM engine plugin.
Throws
DeniedByServerException if the response indicates that the server rejected the request

queryKeyStatus

Added in API level 18
HashMap<StringString> queryKeyStatus (byte[] sessionId)

Request an informative description of the key status for the session. The status is in the form of {name, value} pairs. Since DRM license policies vary by vendor, the specific status field names are determined by each DRM vendor. Refer to your DRM provider documentation for definitions of the field names for a particular DRM engine plugin.

Parameters
sessionId byte: the session ID for the DRM session
Returns
HashMap<StringString>

release

Added in API level 18
void release ()

releaseAllSecureStops

Added in API level 22
void releaseAllSecureStops ()

Remove all secure stops without requiring interaction with the server.

releaseSecureStops

Added in API level 18
void releaseSecureStops (byte[] ssRelease)

Process the SecureStop server response message ssRelease. After authenticating the message, remove the SecureStops identified in the response.

Parameters
ssRelease byte: the server response indicating which secure stops to release

removeKeys

Added in API level 18
void removeKeys (byte[] sessionId)

Remove the current keys from a session.

Parameters
sessionId byte: the session ID for the DRM session

restoreKeys

Added in API level 18
void restoreKeys (byte[] sessionId, 
                byte[] keySetId)

Restore persisted offline keys into a new session. keySetId identifies the keys to load, obtained from a prior call to provideKeyResponse(byte[], byte[]).

Parameters
sessionId byte: the session ID for the DRM session
keySetId byte: identifies the saved key set to restore

setOnEventListener

Added in API level 18
void setOnEventListener (MediaDrm.OnEventListener listener)

Register a callback to be invoked when an event occurs

Parameters
listener MediaDrm.OnEventListener: the callback that will be run. Use null to stop receiving event callbacks.

setOnExpirationUpdateListener

Added in API level 23
void setOnExpirationUpdateListener (MediaDrm.OnExpirationUpdateListener listener, 
                Handler handler)

Register a callback to be invoked when a session expiration update occurs. The app's OnExpirationUpdateListener will be notified when the expiration time of the keys in the session have changed.

Parameters
listener MediaDrm.OnExpirationUpdateListener: the callback that will be run, or null to unregister the previously registered callback.
handler Handler: the handler on which the listener should be invoked, or null if the listener should be invoked on the calling thread's looper.

setOnKeyStatusChangeListener

Added in API level 23
void setOnKeyStatusChangeListener (MediaDrm.OnKeyStatusChangeListener listener, 
                Handler handler)

Register a callback to be invoked when the state of keys in a session change, e.g. when a license update occurs or when a license expires.

Parameters
listener MediaDrm.OnKeyStatusChangeListener: the callback that will be run when key status changes, or null to unregister the previously registered callback.
handler Handler: the handler on which the listener should be invoked, or null if the listener should be invoked on the calling thread's looper.

setPropertyByteArray

Added in API level 18
void setPropertyByteArray (String propertyName, 
                byte[] value)

Set a DRM engine plugin byte array property value.

Parameters
propertyName String
value byte

setPropertyString

Added in API level 18
void setPropertyString (String propertyName, 
                String value)

Set a DRM engine plugin String property value.

Parameters
propertyName String
value String

Protected methods

finalize

Added in API level 18
void finalize ()

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup.

The general contract of finalize is that it is invoked if and when the JavaTM virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized. The finalize method may take any action, including making this object available again to other threads; the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.

The finalize method of class Object performs no special action; it simply returns normally. Subclasses of Object may override this definition.

The Java programming language does not guarantee which thread will invoke the finalize method for any given object. It is guaranteed, however, that the thread that invokes finalize will not be holding any user-visible synchronization locks when finalize is invoked. If an uncaught exception is thrown by the finalize method, the exception is ignored and finalization of that object terminates.

After the finalize method has been invoked for an object, no further action is taken until the Java virtual machine has again determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, including possible actions by other objects or classes which are ready to be finalized, at which point the object may be discarded.

The finalize method is never invoked more than once by a Java virtual machine for any given object.

Any exception thrown by the finalize method causes the finalization of this object to be halted, but is otherwise ignored.

Hooray!