Merge "MediaDrm API update" into jb-mr2-dev

This commit is contained in:
Jeff Tinker
2013-04-02 22:49:19 +00:00
committed by Android (Google) Code Review
2 changed files with 420 additions and 87 deletions

View File

@@ -28,8 +28,8 @@ import android.os.Bundle;
import android.util.Log;
/**
* MediaDrm class can be used in conjunction with {@link android.media.MediaCrypto}
* to obtain licenses for decoding encrypted media data.
* MediaDrm can be used in conjunction with {@link android.media.MediaCrypto}
* to obtain keys for decrypting protected media data.
*
* Crypto schemes are assigned 16 byte UUIDs,
* the method {@link #isCryptoSchemeSupported} can be used to query if a given
@@ -131,11 +131,15 @@ public final class MediaDrm {
void onEvent(MediaDrm md, byte[] sessionId, int event, int extra, byte[] data);
}
public static final int MEDIA_DRM_EVENT_PROVISION_REQUIRED = 1;
public static final int MEDIA_DRM_EVENT_KEY_REQUIRED = 2;
public static final int MEDIA_DRM_EVENT_KEY_EXPIRED = 3;
public static final int MEDIA_DRM_EVENT_VENDOR_DEFINED = 4;
/* Do not change these values without updating their counterparts
* in include/media/mediadrm.h!
*/
private static final int DRM_EVENT = 200;
private class EventHandler extends Handler
{
private MediaDrm mMediaDrm;
@@ -197,68 +201,88 @@ public final class MediaDrm {
public native byte[] openSession() throws MediaDrmException;
/**
* Close a session on the MediaDrm object.
* Close a session on the MediaDrm object that was previously opened
* with {@link #openSession}.
*/
public native void closeSession(byte[] sessionId) throws MediaDrmException;
public static final int MEDIA_DRM_LICENSE_TYPE_STREAMING = 1;
public static final int MEDIA_DRM_LICENSE_TYPE_OFFLINE = 2;
public static final int MEDIA_DRM_KEY_TYPE_STREAMING = 1;
public static final int MEDIA_DRM_KEY_TYPE_OFFLINE = 2;
public final class LicenseRequest {
public LicenseRequest() {}
public final class KeyRequest {
public KeyRequest() {}
public byte[] data;
public String defaultUrl;
};
/**
* A license request/response exchange occurs between the app and a License
* Server to obtain the keys required to decrypt the content. getLicenseRequest()
* is used to obtain an opaque license request byte array that is delivered to the
* license server. The opaque license request byte array is returned in
* LicenseReqeust.data. The recommended URL to deliver the license request to is
* returned in LicenseRequest.defaultUrl
* A key request/response exchange occurs between the app and a license
* server to obtain the keys 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
* {@link #provideKeyResponse}.
*
* @param sessonId the session ID for the drm session
* @param init 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 license request.
* required in generating the key request.
* @param mimeType identifies the mime type of the content
* @param licenseType specifes if the license is for streaming or offline content
* @param optionalParameters are included in the license server request message to
* @param keyType specifes if the request is for streaming or offline content
* @param optionalParameters are included in the key request message to
* allow a client application to provide additional message parameters to the server.
*/
public native LicenseRequest getLicenseRequest( byte[] sessionId, byte[] init,
String mimeType, int licenseType,
HashMap<String, String> optionalParameters )
public native KeyRequest getKeyRequest(byte[] sessionId, byte[] init,
String mimeType, int keyType,
HashMap<String, String> optionalParameters)
throws MediaDrmException;
/**
* After a license response is received by the app, it is provided to the DRM plugin
* using provideLicenseResponse.
* A key response is received from the license server by the app, then it is
* provided to the DRM engine plugin using provideKeyResponse. The byte array
* returned is a keySetId that can be used to later restore the keys to a new
* session with the method {@link restoreKeys}, enabling offline key use.
*
* @param sessionId the session ID for the DRM session
* @param response the byte array response from the server
*/
public native void provideLicenseResponse( byte[] sessionId, byte[] response )
public native byte[] provideKeyResponse(byte[] sessionId, byte[] response)
throws MediaDrmException;
/**
* Remove the keys associated with a license for a session
* Restore persisted offline keys into a new session. keySetId identifies the
* keys to load, obtained from a prior call to {@link provideKeyResponse}.
*
* @param sessionId the session ID for the DRM session
* @param keySetId identifies the saved key set to restore
*/
public native void removeLicense( byte[] sessionId ) throws MediaDrmException;
public native void restoreKeys(byte[] sessionId, byte[] keySetId)
throws MediaDrmException;
/**
* Request an informative description of the license for the session. The status is
* Remove the persisted keys associated with an offline license. Keys are persisted
* when {@link provideKeyResponse} is called with keys obtained from the method
* {@link getKeyRequest} using keyType = MEDIA_DRM_KEY_TYPE_OFFLINE.
*
* @param keySetId identifies the saved key set to remove
*/
public native void removeKeys(byte[] keySetId) throws MediaDrmException;
/**
* 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
* DrmEngine.
* DRM engine plugin.
*
* @param sessionId the session ID for the DRM session
*/
public native HashMap<String, String> queryLicenseStatus( byte[] sessionId )
public native HashMap<String, String> queryKeyStatus(byte[] sessionId)
throws MediaDrmException;
public final class ProvisionRequest {
@@ -269,22 +293,23 @@ public final class MediaDrm {
/**
* A provision request/response exchange occurs between the app and a provisioning
* server to retrieve a device certificate. getProvisionRequest is used to obtain
* an opaque license request byte array that is delivered to the provisioning server.
* The opaque provision request byte array is returned in ProvisionRequest.data
* The recommended URL to deliver the license request to is returned in
* ProvisionRequest.defaultUrl.
* server to retrieve a device certificate. If provisionining is required, the
* MEDIA_DRM_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.
*/
public native ProvisionRequest getProvisionRequest() throws MediaDrmException;
/**
* After a provision response is received by the app, it is provided to the DRM
* plugin using this method.
* engine plugin using this method.
*
* @param response the opaque provisioning response byte array to provide to the
* DrmEngine.
* DRM engine plugin.
*/
public native void provideProvisionResponse( byte[] response )
public native void provideProvisionResponse(byte[] response)
throws MediaDrmException;
/**
@@ -314,38 +339,140 @@ public final class MediaDrm {
*
* @param ssRelease the server response indicating which secure stops to release
*/
public native void releaseSecureStops( byte[] ssRelease )
public native void releaseSecureStops(byte[] ssRelease)
throws MediaDrmException;
/**
* Read a Drm plugin property value, given the property name string. There are several
* forms of property access functions, depending on the data type returned.
* Read a DRM engine plugin property value, given the property name string. There are
* several forms of property access functions, depending on the data type returned.
*
* Standard fields names are:
* vendor String - identifies the maker of the plugin
* version String - identifies the version of the plugin
* description String - describes the plugin
* vendor String - identifies the maker of the DRM engine plugin
* version String - identifies the version of the DRM engine plugin
* description String - describes the DRM engine plugin
* deviceUniqueId byte[] - The device unique identifier is established during device
* provisioning and provides a means of uniquely identifying
* each device
* provisioning and provides a means of uniquely identifying
* each device
* algorithms String - a comma-separate list of cipher and mac algorithms supported
* by CryptoSession. The list may be empty if the DRM engine
* plugin does not support CryptoSession operations.
*/
public native String getPropertyString( String propertyName )
public native String getPropertyString(String propertyName)
throws MediaDrmException;
public native byte[] getPropertyByteArray( String propertyName )
public native byte[] getPropertyByteArray(String propertyName)
throws MediaDrmException;
/**
* Write a Drm plugin property value. There are several forms of property setting
* functions, depending on the data type being set.
* Write a DRM engine plugin property value. There are several forms of
* property setting functions, depending on the data type being set.
*/
public native void setPropertyString( String propertyName, String value )
public native void setPropertyString(String propertyName, String value)
throws MediaDrmException;
public native void setPropertyByteArray( String propertyName, byte[] value )
public native void setPropertyByteArray(String propertyName, byte[] value)
throws MediaDrmException;
/**
* 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 provide the ability to do encrypt, decrypt, sign and verify
* with the session key on arbitrary user data.
*
* The CryptoSession class implements generic encrypt/decrypt/sign/verify methods
* based on the established session keys. These keys are exchanged using the
* getKeyRequest/provideKeyResponse methods.
*
* Applications of this capability could include securing various types of
* purchased or private content, such as applications, books and other media,
* photos or media delivery protocols.
*
* Operators can create session key servers that are functionally similar to a
* license key server, except that instead of receiving license key requests and
* providing encrypted content keys which are used specifically to decrypt A/V media
* content, the session key server receives session key requests and provides
* encrypted session keys which can be used for general purpose crypto operations.
*/
private static final native void setCipherAlgorithmNative(MediaDrm drm, byte[] sessionId,
String algorithm);
private static final native void setMacAlgorithmNative(MediaDrm drm, byte[] sessionId,
String algorithm);
private static final native byte[] encryptNative(MediaDrm drm, byte[] sessionId,
byte[] keyId, byte[] input, byte[] iv);
private static final native byte[] decryptNative(MediaDrm drm, byte[] sessionId,
byte[] keyId, byte[] input, byte[] iv);
private static final native byte[] signNative(MediaDrm drm, byte[] sessionId,
byte[] keyId, byte[] message);
private static final native boolean verifyNative(MediaDrm drm, byte[] sessionId,
byte[] keyId, byte[] message,
byte[] signature);
public final class CryptoSession {
private MediaDrm mDrm;
private byte[] mSessionId;
/**
* Construct a CryptoSession which can be used to encrypt, decrypt,
* sign and verify messages or data using the session keys established
* for the session using methods {@link getKeyRequest} and
* {@link provideKeyResponse} using a session key server.
*
* @param sessionId the session ID for the session containing keys
* to be used for encrypt, decrypt, sign and/or verify
*
* @param cipherAlgorithm 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/PKCS5Padding".
*
* @param macAlgorithm 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 {@link getPropertyString("algorithms")}
*/
public CryptoSession(MediaDrm drm, byte[] sessionId,
String cipherAlgorithm, String macAlgorithm)
throws MediaDrmException {
mSessionId = sessionId;
mDrm = drm;
setCipherAlgorithmNative(drm, sessionId, cipherAlgorithm);
setMacAlgorithmNative(drm, sessionId, macAlgorithm);
}
public byte[] encrypt(byte[] keyid, byte[] input, byte[] iv) {
return encryptNative(mDrm, mSessionId, keyid, input, iv);
}
public byte[] decrypt(byte[] keyid, byte[] input, byte[] iv) {
return decryptNative(mDrm, mSessionId, keyid, input, iv);
}
public byte[] sign(byte[] keyid, byte[] message) {
return signNative(mDrm, mSessionId, keyid, message);
}
public boolean verify(byte[] keyid, byte[] message, byte[] signature) {
return verifyNative(mDrm, mSessionId, keyid, message, signature);
}
};
public CryptoSession getCryptoSession(byte[] sessionId,
String cipherAlgorithm,
String macAlgorithm)
throws MediaDrmException {
return new CryptoSession(this, sessionId, cipherAlgorithm, macAlgorithm);
}
@Override
protected void finalize() {
native_finalize();

View File

@@ -76,7 +76,7 @@ struct EntryFields {
struct fields_t {
jfieldID context;
RequestFields licenseRequest;
RequestFields keyRequest;
RequestFields provisionRequest;
ArrayListFields arraylist;
HashmapFields hashmap;
@@ -204,6 +204,7 @@ static String8 JStringToString8(JNIEnv *env, jstring const &jstr) {
}
return result;
}
/*
import java.util.HashMap;
import java.util.Set;
@@ -329,9 +330,9 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
FIND_CLASS(clazz, "android/media/MediaDrm");
GET_FIELD_ID(gFields.context, clazz, "mNativeContext", "I");
FIND_CLASS(clazz, "android/media/MediaDrm$LicenseRequest");
GET_FIELD_ID(gFields.licenseRequest.data, clazz, "data", "[B");
GET_FIELD_ID(gFields.licenseRequest.defaultUrl, clazz, "defaultUrl", "Ljava/lang/String;");
FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
GET_FIELD_ID(gFields.keyRequest.data, clazz, "data", "[B");
GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "defaultUrl", "Ljava/lang/String;");
FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
GET_FIELD_ID(gFields.provisionRequest.data, clazz, "data", "[B");
@@ -451,9 +452,9 @@ static void android_media_MediaDrm_closeSession(
throwExceptionAsNecessary(env, err, "Failed to close session");
}
static jobject android_media_MediaDrm_getLicenseRequest(
static jobject android_media_MediaDrm_getKeyRequest(
JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jinitData,
jstring jmimeType, jint jlicenseType, jobject joptParams) {
jstring jmimeType, jint jkeyType, jobject joptParams) {
sp<IDrm> drm = GetDrm(env, thiz);
if (!CheckSession(env, drm, jsessionId)) {
@@ -472,7 +473,7 @@ static jobject android_media_MediaDrm_getLicenseRequest(
mimeType = JStringToString8(env, jmimeType);
}
DrmPlugin::LicenseType licenseType = (DrmPlugin::LicenseType)jlicenseType;
DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)jkeyType;
KeyedVector<String8, String8> optParams;
if (joptParams != NULL) {
@@ -482,68 +483,94 @@ static jobject android_media_MediaDrm_getLicenseRequest(
Vector<uint8_t> request;
String8 defaultUrl;
status_t err = drm->getLicenseRequest(sessionId, initData, mimeType,
licenseType, optParams, request, defaultUrl);
status_t err = drm->getKeyRequest(sessionId, initData, mimeType,
keyType, optParams, request, defaultUrl);
if (throwExceptionAsNecessary(env, err, "Failed to get license request")) {
if (throwExceptionAsNecessary(env, err, "Failed to get key request")) {
return NULL;
}
// Fill out return obj
jclass clazz;
FIND_CLASS(clazz, "android/media/MediaDrm$LicenseRequest");
FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
jobject licenseObj = NULL;
jobject keyObj = NULL;
if (clazz) {
licenseObj = env->AllocObject(clazz);
keyObj = env->AllocObject(clazz);
jbyteArray jrequest = VectorToJByteArray(env, request);
env->SetObjectField(licenseObj, gFields.licenseRequest.data, jrequest);
env->SetObjectField(keyObj, gFields.keyRequest.data, jrequest);
jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
env->SetObjectField(licenseObj, gFields.licenseRequest.defaultUrl, jdefaultUrl);
env->SetObjectField(keyObj, gFields.keyRequest.defaultUrl, jdefaultUrl);
}
return licenseObj;
return keyObj;
}
static void android_media_MediaDrm_provideLicenseResponse(
static jbyteArray android_media_MediaDrm_provideKeyResponse(
JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jresponse) {
sp<IDrm> drm = GetDrm(env, thiz);
if (!CheckSession(env, drm, jsessionId)) {
return;
return NULL;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
if (jresponse == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
return NULL;
}
Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
Vector<uint8_t> keySetId;
status_t err = drm->provideLicenseResponse(sessionId, response);
status_t err = drm->provideKeyResponse(sessionId, response, keySetId);
throwExceptionAsNecessary(env, err, "Failed to handle license response");
throwExceptionAsNecessary(env, err, "Failed to handle key response");
return VectorToJByteArray(env, keySetId);
}
static void android_media_MediaDrm_removeLicense(
JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
static void android_media_MediaDrm_removeKeys(
JNIEnv *env, jobject thiz, jbyteArray jkeysetId) {
sp<IDrm> drm = GetDrm(env, thiz);
if (jkeysetId == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));
status_t err = drm->removeKeys(keySetId);
throwExceptionAsNecessary(env, err, "Failed to remove keys");
}
static void android_media_MediaDrm_restoreKeys(
JNIEnv *env, jobject thiz, jbyteArray jsessionId,
jbyteArray jkeysetId) {
sp<IDrm> drm = GetDrm(env, thiz);
if (!CheckSession(env, drm, jsessionId)) {
return;
}
if (jkeysetId == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));
status_t err = drm->removeLicense(sessionId);
status_t err = drm->restoreKeys(sessionId, keySetId);
throwExceptionAsNecessary(env, err, "Failed to remove license");
throwExceptionAsNecessary(env, err, "Failed to restore keys");
}
static jobject android_media_MediaDrm_queryLicenseStatus(
static jobject android_media_MediaDrm_queryKeyStatus(
JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
sp<IDrm> drm = GetDrm(env, thiz);
@@ -554,9 +581,9 @@ static jobject android_media_MediaDrm_queryLicenseStatus(
KeyedVector<String8, String8> infoMap;
status_t err = drm->queryLicenseStatus(sessionId, infoMap);
status_t err = drm->queryKeyStatus(sessionId, infoMap);
if (throwExceptionAsNecessary(env, err, "Failed to query license")) {
if (throwExceptionAsNecessary(env, err, "Failed to query key status")) {
return NULL;
}
@@ -752,6 +779,162 @@ static void android_media_MediaDrm_setPropertyByteArray(
throwExceptionAsNecessary(env, err, "Failed to set property");
}
static void android_media_MediaDrm_setCipherAlgorithmNative(
JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
jstring jalgorithm) {
sp<IDrm> drm = GetDrm(env, jdrm);
if (!CheckSession(env, drm, jsessionId)) {
return;
}
if (jalgorithm == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
String8 algorithm = JStringToString8(env, jalgorithm);
status_t err = drm->setCipherAlgorithm(sessionId, algorithm);
throwExceptionAsNecessary(env, err, "Failed to set cipher algorithm");
}
static void android_media_MediaDrm_setMacAlgorithmNative(
JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
jstring jalgorithm) {
sp<IDrm> drm = GetDrm(env, jdrm);
if (!CheckSession(env, drm, jsessionId)) {
return;
}
if (jalgorithm == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
String8 algorithm = JStringToString8(env, jalgorithm);
status_t err = drm->setMacAlgorithm(sessionId, algorithm);
throwExceptionAsNecessary(env, err, "Failed to set mac algorithm");
}
static jbyteArray android_media_MediaDrm_encryptNative(
JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
sp<IDrm> drm = GetDrm(env, jdrm);
if (!CheckSession(env, drm, jsessionId)) {
return NULL;
}
if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return NULL;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
Vector<uint8_t> input(JByteArrayToVector(env, jinput));
Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
Vector<uint8_t> output;
status_t err = drm->encrypt(sessionId, keyId, input, iv, output);
throwExceptionAsNecessary(env, err, "Failed to encrypt");
return VectorToJByteArray(env, output);
}
static jbyteArray android_media_MediaDrm_decryptNative(
JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
sp<IDrm> drm = GetDrm(env, jdrm);
if (!CheckSession(env, drm, jsessionId)) {
return NULL;
}
if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return NULL;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
Vector<uint8_t> input(JByteArrayToVector(env, jinput));
Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
Vector<uint8_t> output;
status_t err = drm->decrypt(sessionId, keyId, input, iv, output);
throwExceptionAsNecessary(env, err, "Failed to decrypt");
return VectorToJByteArray(env, output);
}
static jbyteArray android_media_MediaDrm_signNative(
JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jmessage) {
sp<IDrm> drm = GetDrm(env, jdrm);
if (!CheckSession(env, drm, jsessionId)) {
return NULL;
}
if (jkeyId == NULL || jmessage == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return NULL;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
Vector<uint8_t> signature;
status_t err = drm->sign(sessionId, keyId, message, signature);
throwExceptionAsNecessary(env, err, "Failed to sign");
return VectorToJByteArray(env, signature);
}
static jboolean android_media_MediaDrm_verifyNative(
JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jmessage, jbyteArray jsignature) {
sp<IDrm> drm = GetDrm(env, jdrm);
if (!CheckSession(env, drm, jsessionId)) {
return false;
}
if (jkeyId == NULL || jmessage == NULL || jsignature == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return false;
}
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
Vector<uint8_t> signature(JByteArrayToVector(env, jsignature));
bool match;
status_t err = drm->verify(sessionId, keyId, message, signature, match);
throwExceptionAsNecessary(env, err, "Failed to verify");
return match;
}
static JNINativeMethod gMethods[] = {
{ "release", "()V", (void *)android_media_MediaDrm_release },
@@ -772,18 +955,21 @@ static JNINativeMethod gMethods[] = {
{ "closeSession", "([B)V",
(void *)android_media_MediaDrm_closeSession },
{ "getLicenseRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
"Landroid/media/MediaDrm$LicenseRequest;",
(void *)android_media_MediaDrm_getLicenseRequest },
{ "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
"Landroid/media/MediaDrm$KeyRequest;",
(void *)android_media_MediaDrm_getKeyRequest },
{ "provideLicenseResponse", "([B[B)V",
(void *)android_media_MediaDrm_provideLicenseResponse },
{ "provideKeyResponse", "([B[B)[B",
(void *)android_media_MediaDrm_provideKeyResponse },
{ "removeLicense", "([B)V",
(void *)android_media_MediaDrm_removeLicense },
{ "removeKeys", "([B)V",
(void *)android_media_MediaDrm_removeKeys },
{ "queryLicenseStatus", "([B)Ljava/util/HashMap;",
(void *)android_media_MediaDrm_queryLicenseStatus },
{ "restoreKeys", "([B[B)V",
(void *)android_media_MediaDrm_restoreKeys },
{ "queryKeyStatus", "([B)Ljava/util/HashMap;",
(void *)android_media_MediaDrm_queryKeyStatus },
{ "getProvisionRequest", "()Landroid/media/MediaDrm$ProvisionRequest;",
(void *)android_media_MediaDrm_getProvisionRequest },
@@ -808,6 +994,26 @@ static JNINativeMethod gMethods[] = {
{ "setPropertyByteArray", "(Ljava/lang/String;[B)V",
(void *)android_media_MediaDrm_setPropertyByteArray },
{ "setCipherAlgorithmNative",
"(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
(void *)android_media_MediaDrm_setCipherAlgorithmNative },
{ "setMacAlgorithmNative",
"(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
(void *)android_media_MediaDrm_setMacAlgorithmNative },
{ "encryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
(void *)android_media_MediaDrm_encryptNative },
{ "decryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
(void *)android_media_MediaDrm_decryptNative },
{ "signNative", "(Landroid/media/MediaDrm;[B[B[B)[B",
(void *)android_media_MediaDrm_signNative },
{ "verifyNative", "(Landroid/media/MediaDrm;[B[B[B[B)Z",
(void *)android_media_MediaDrm_verifyNative },
};
int register_android_media_Drm(JNIEnv *env) {