/* * Copyright (C) 2010 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "android_drm_DrmManagerClient" #include <utils/Log.h> #include <jni.h> #include <JNIHelp.h> #include <ScopedLocalRef.h> #include <android_runtime/AndroidRuntime.h> #include <drm/DrmInfo.h> #include <drm/DrmRights.h> #include <drm/DrmInfoEvent.h> #include <drm/DrmInfoStatus.h> #include <drm/DrmInfoRequest.h> #include <drm/DrmSupportInfo.h> #include <drm/DrmConstraints.h> #include <drm/DrmMetadata.h> #include <drm/DrmConvertedStatus.h> #include <drm/drm_framework_common.h> #include <DrmManagerClientImpl.h> using namespace android; /** * Utility class used to extract the value from the provided java object. * May need to add some utility function to create java object. */ class Utility { public: static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName); static char* getByteArrayValue( JNIEnv* env, jobject object, const char* fieldName, int* dataLength); static char* getByteArrayValue( JNIEnv* env, jbyteArray byteArray, int* dataLength); static String8 getStringValue(JNIEnv* env, jstring string); static int getIntValue(JNIEnv* env, jobject object, const char* fieldName); }; String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) { /* Look for the instance field with the name fieldName */ jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;"); if (NULL != fieldID) { jstring valueString = (jstring) env->GetObjectField(object, fieldID); return Utility::getStringValue(env, valueString); } String8 dataString(""); return dataString; } String8 Utility::getStringValue(JNIEnv* env, jstring string) { String8 dataString(""); if (NULL != string && string != env->NewStringUTF("")) { char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL)); const int length = strlen(bytes) + 1; char *data = new char[length]; strncpy(data, bytes, length); dataString = String8(data); env->ReleaseStringUTFChars(string, bytes); delete [] data; data = NULL; } return dataString; } char* Utility::getByteArrayValue( JNIEnv* env, jobject object, const char* fieldName, int* dataLength) { *dataLength = 0; jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B"); if (NULL != fieldID) { jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID); return Utility::getByteArrayValue(env, byteArray, dataLength); } return NULL; } char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) { char* data = NULL; if (NULL != byteArray) { jint length = env->GetArrayLength(byteArray); *dataLength = length; if (0 < *dataLength) { data = new char[length]; env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data); } } return data; } int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) { jfieldID fieldID; int intValue = -1; /* Get a reference to obj’s class */ jclass clazz = env->GetObjectClass(object); /* Look for the instance field with the name fieldName */ fieldID = env->GetFieldID(clazz, fieldName , "I"); if (NULL != fieldID) { intValue = (int) env->GetIntField(object, fieldID); } return intValue; } class JNIOnInfoListener : public DrmManagerClient::OnInfoListener { public: JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz); virtual ~JNIOnInfoListener(); void onInfo(const DrmInfoEvent& event); private: JNIOnInfoListener(); jclass mClass; jobject mObject; }; JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) { jclass clazz = env->GetObjectClass(thiz); if (clazz == NULL) { ALOGE("Can't find android/drm/DrmManagerClient"); jniThrowException(env, "java/lang/Exception", NULL); return; } mClass = (jclass)env->NewGlobalRef(clazz); mObject = env->NewGlobalRef(weak_thiz); } JNIOnInfoListener::~JNIOnInfoListener() { JNIEnv *env = AndroidRuntime::getJNIEnv(); env->DeleteGlobalRef(mObject); env->DeleteGlobalRef(mClass); } void JNIOnInfoListener::onInfo(const DrmInfoEvent& event) { jint uniqueId = event.getUniqueId(); jint type = event.getType(); JNIEnv *env = AndroidRuntime::getJNIEnv(); jstring message = env->NewStringUTF(event.getMessage().string()); ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string()); env->CallStaticVoidMethod( mClass, env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"), mObject, uniqueId, type, message); } static Mutex sLock; static sp<DrmManagerClientImpl> setDrmManagerClientImpl( JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) { Mutex::Autolock l(sLock); jclass clazz = env->FindClass("android/drm/DrmManagerClient"); jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J"); jlong oldHandle = env->GetLongField(thiz, fieldId); sp<DrmManagerClientImpl> old = reinterpret_cast<DrmManagerClientImpl*>(oldHandle); if (client.get()) { client->incStrong(thiz); } if (old != 0) { old->decStrong(thiz); } env->SetLongField(thiz, fieldId, reinterpret_cast<jlong>(client.get())); return old; } static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) { Mutex::Autolock l(sLock); jclass clazz = env->FindClass("android/drm/DrmManagerClient"); jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J"); jlong clientHandle = env->GetLongField(thiz, fieldId); DrmManagerClientImpl* const client = reinterpret_cast<DrmManagerClientImpl*>(clientHandle); return sp<DrmManagerClientImpl>(client); } static jint android_drm_DrmManagerClient_initialize( JNIEnv* env, jobject thiz) { ALOGV("initialize - Enter"); int uniqueId = 0; sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false); drmManager->addClient(uniqueId); setDrmManagerClientImpl(env, thiz, drmManager); ALOGV("initialize - Exit"); return static_cast<jint>(uniqueId); } static void android_drm_DrmManagerClient_setListeners( JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) { ALOGV("setListeners - Enter"); // Set the listener to DrmManager sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz); getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener); ALOGV("setListeners - Exit"); } static void android_drm_DrmManagerClient_release( JNIEnv* env, jobject thiz, jint uniqueId) { ALOGV("release - Enter"); getDrmManagerClientImpl(env, thiz)->remove(uniqueId); getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL); sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL); if (oldClient != NULL) { oldClient->setOnInfoListener(uniqueId, NULL); oldClient->removeClient(uniqueId); } ALOGV("release - Exit"); } static jobject android_drm_DrmManagerClient_getConstraintsFromContent( JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) { ALOGV("GetConstraints - Enter"); const String8 pathString = Utility::getStringValue(env, jpath); DrmConstraints* pConstraints = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage); jclass localRef = env->FindClass("android/content/ContentValues"); jmethodID ContentValues_putByteArray = env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"); jmethodID ContentValues_putString = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"); jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V"); jobject constraints = NULL; if (NULL != localRef && NULL != pConstraints) { // create the java DrmConstraints object constraints = env->NewObject(localRef, ContentValues_constructor); DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator(); while (keyIt.hasNext()) { String8 key = keyIt.next(); // insert the entry<constraintKey, constraintValue> to newly created java object if (DrmConstraints::EXTENDED_METADATA == key) { const char* value = pConstraints->getAsByteArray(&key); if (NULL != value) { ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value))); ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string())); env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value); env->CallVoidMethod(constraints, ContentValues_putByteArray, keyString.get(), dataArray.get()); } } else { String8 value = pConstraints->get(key); ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string())); ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string())); env->CallVoidMethod(constraints, ContentValues_putString, keyString.get(), valueString.get()); } } } delete pConstraints; pConstraints = NULL; ALOGV("GetConstraints - Exit"); return constraints; } static jobject android_drm_DrmManagerClient_getMetadataFromContent( JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) { ALOGV("GetMetadata - Enter"); const String8 pathString = Utility::getStringValue(env, jpath); DrmMetadata* pMetadata = getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString); jobject metadata = NULL; jclass localRef = env->FindClass("android/content/ContentValues"); jmethodID ContentValues_putString = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"); if (NULL != localRef && NULL != pMetadata) { // Get the constructor id jmethodID constructorId = NULL; constructorId = env->GetMethodID(localRef, "<init>", "()V"); if (NULL != constructorId) { // create the java DrmMetadata object metadata = env->NewObject(localRef, constructorId); if (NULL != metadata) { DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator(); while (keyIt.hasNext()) { String8 key = keyIt.next(); // insert the entry<constraintKey, constraintValue> // to newly created java object String8 value = pMetadata->get(key); ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string())); ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string())); env->CallVoidMethod(metadata, ContentValues_putString, keyString.get(), valueString.get()); } } } } delete pMetadata; pMetadata = NULL; ALOGV("GetMetadata - Exit"); return metadata; } static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo( JNIEnv* env, jobject thiz, jint uniqueId) { ALOGV("GetAllSupportInfo - Enter"); DrmSupportInfo* drmSupportInfoArray = NULL; int length = 0; getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray); jclass clazz = env->FindClass("android/drm/DrmSupportInfo"); jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL); for (int i = 0; i < length; i++) { DrmSupportInfo info = drmSupportInfoArray[i]; jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V")); jmethodID addMimeTypeId = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V"); jmethodID addFileSuffixId = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V"); env->CallVoidMethod( drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"), env->NewStringUTF(info.getDescription().string())); DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator(); while (iterator.hasNext()) { String8 value = iterator.next(); env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string())); } DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator(); while (it.hasNext()) { String8 value = it.next(); env->CallVoidMethod( drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string())); } env->SetObjectArrayElement(array, i, drmSupportInfo); } delete [] drmSupportInfoArray; drmSupportInfoArray = NULL; ALOGV("GetAllSupportInfo - Exit"); return array; } static void android_drm_DrmManagerClient_installDrmEngine( JNIEnv* /* env */, jobject /* thiz */, jint /* uniqueId */, jstring /* engineFilePath */) { ALOGV("installDrmEngine - Enter"); //getDrmManagerClient(env, thiz) // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath)); ALOGV("installDrmEngine - Exit"); } static jint android_drm_DrmManagerClient_saveRights( JNIEnv* env, jobject thiz, jint uniqueId, jobject drmRights, jstring rightsPath, jstring contentPath) { ALOGV("saveRights - Enter"); int result = DRM_ERROR_UNKNOWN; int dataLength = 0; char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength); if (NULL != mData) { DrmRights rights(DrmBuffer(mData, dataLength), Utility::getStringValue(env, drmRights, "mMimeType"), Utility::getStringValue(env, drmRights, "mAccountId"), Utility::getStringValue(env, drmRights, "mSubscriptionId")); result = getDrmManagerClientImpl(env, thiz) ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath), Utility::getStringValue(env, contentPath)); } delete[] mData; mData = NULL; ALOGV("saveRights - Exit"); return static_cast<jint>(result); } static jboolean android_drm_DrmManagerClient_canHandle( JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) { ALOGV("canHandle - Enter"); jboolean result = getDrmManagerClientImpl(env, thiz) ->canHandle(uniqueId, Utility::getStringValue(env, path), Utility::getStringValue(env, mimeType)); ALOGV("canHandle - Exit"); return result; } static jobject android_drm_DrmManagerClient_processDrmInfo( JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) { ALOGV("processDrmInfo - Enter"); int dataLength = 0; const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType"); char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength); int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType"); const DrmBuffer buffer(mData, dataLength); DrmInfo drmInfo(mInfoType, buffer, mMimeType); jclass clazz = env->FindClass("android/drm/DrmInfo"); jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"); jobject keyIterator = env->CallObjectMethod(drmInfoObject, env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;")); jclass Iterator_class = env->FindClass("java/util/Iterator"); jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z"); jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;"); jclass Object_class = env->FindClass("java/lang/Object"); jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;"); while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) { ScopedLocalRef<jstring> key(env, (jstring) env->CallObjectMethod(keyIterator, Iterator_next)); ScopedLocalRef<jobject> valueObject(env, env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get())); ScopedLocalRef<jstring> valString(env, NULL); if (NULL != valueObject.get()) { valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString)); } String8 keyString = Utility::getStringValue(env, key.get()); String8 valueString = Utility::getStringValue(env, valString.get()); ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string()); drmInfo.put(keyString, valueString); } DrmInfoStatus* pDrmInfoStatus = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo); jclass localRef = env->FindClass("android/drm/DrmInfoStatus"); jobject drmInfoStatus = NULL; if (NULL != localRef && NULL != pDrmInfoStatus) { int statusCode = pDrmInfoStatus->statusCode; int infoType = pDrmInfoStatus->infoType; jbyteArray dataArray = NULL; if (NULL != pDrmInfoStatus->drmBuffer) { int length = pDrmInfoStatus->drmBuffer->length; dataArray = env->NewByteArray(length); env->SetByteArrayRegion( dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data); delete [] pDrmInfoStatus->drmBuffer->data; delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL; } jclass clazz = env->FindClass("android/drm/ProcessedData"); jmethodID constructorId = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V"); jobject processedData = env->NewObject(clazz, constructorId, dataArray, env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()), env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string())); constructorId = env->GetMethodID(localRef, "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V"); drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType, processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string())); } delete[] mData; mData = NULL; delete pDrmInfoStatus; pDrmInfoStatus = NULL; ALOGV("processDrmInfo - Exit"); return drmInfoStatus; } static jobject android_drm_DrmManagerClient_acquireDrmInfo( JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) { ALOGV("acquireDrmInfo Enter"); const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType"); int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType"); DrmInfoRequest drmInfoReq(mInfoType, mMimeType); jclass clazz = env->FindClass("android/drm/DrmInfoRequest"); jobject keyIterator = env->CallObjectMethod(drmInfoRequest, env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;")); jmethodID DrmInfoRequest_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"); jclass Iterator_class = env->FindClass("java/util/Iterator"); jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z"); jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;"); while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) { ScopedLocalRef<jstring> key(env, (jstring) env->CallObjectMethod(keyIterator, Iterator_next)); ScopedLocalRef<jstring> value(env, (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get())); String8 keyString = Utility::getStringValue(env, key.get()); String8 valueString = Utility::getStringValue(env, value.get()); ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string()); drmInfoReq.put(keyString, valueString); } DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq); jobject drmInfoObject = NULL; if (NULL != pDrmInfo) { jclass localRef = env->FindClass("android/drm/DrmInfo"); if (NULL != localRef) { int length = pDrmInfo->getData().length; jbyteArray dataArray = env->NewByteArray(length); env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data); drmInfoObject = env->NewObject(localRef, env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"), mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string())); DrmInfo::KeyIterator it = pDrmInfo->keyIterator(); jmethodID putMethodId = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V"); while (it.hasNext()) { String8 key = it.next(); String8 value = pDrmInfo->get(key); ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string())); ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string())); env->CallVoidMethod(drmInfoObject, putMethodId, keyString.get(), valueString.get()); } } delete [] pDrmInfo->getData().data; } delete pDrmInfo; pDrmInfo = NULL; ALOGV("acquireDrmInfo Exit"); return drmInfoObject; } static jint android_drm_DrmManagerClient_getDrmObjectType( JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) { ALOGV("getDrmObjectType Enter"); int drmObjectType = getDrmManagerClientImpl(env, thiz) ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path), Utility::getStringValue(env, mimeType)); ALOGV("getDrmObjectType Exit"); return static_cast<jint>(drmObjectType); } static jstring android_drm_DrmManagerClient_getOriginalMimeType( JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jobject fileDescriptor) { ALOGV("getOriginalMimeType Enter"); int fd = (fileDescriptor == NULL) ? -1 : jniGetFDFromFileDescriptor(env, fileDescriptor); String8 mimeType = getDrmManagerClientImpl(env, thiz) ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path), fd); ALOGV("getOriginalMimeType Exit"); return env->NewStringUTF(mimeType.string()); } static jint android_drm_DrmManagerClient_checkRightsStatus( JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) { ALOGV("checkRightsStatus Enter"); int rightsStatus = getDrmManagerClientImpl(env, thiz) ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action); ALOGV("checkRightsStatus Exit"); return static_cast<jint>(rightsStatus); } static jint android_drm_DrmManagerClient_removeRights( JNIEnv* env, jobject thiz, jint uniqueId, jstring path) { ALOGV("removeRights"); return static_cast<jint>(getDrmManagerClientImpl(env, thiz) ->removeRights(uniqueId, Utility::getStringValue(env, path))); } static jint android_drm_DrmManagerClient_removeAllRights( JNIEnv* env, jobject thiz, jint uniqueId) { ALOGV("removeAllRights"); return static_cast<jint>(getDrmManagerClientImpl(env, thiz) ->removeAllRights(uniqueId)); } static jint android_drm_DrmManagerClient_openConvertSession( JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) { ALOGV("openConvertSession Enter"); int convertId = getDrmManagerClientImpl(env, thiz) ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType)); ALOGV("openConvertSession Exit"); return static_cast<jint>(convertId); } static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) { ALOGV("GetConvertedStatus - Enter"); jclass localRef = env->FindClass("android/drm/DrmConvertedStatus"); jobject drmConvertedStatus = NULL; if (NULL != localRef && NULL != pDrmConvertedStatus) { int statusCode = pDrmConvertedStatus->statusCode; jbyteArray dataArray = NULL; if (NULL != pDrmConvertedStatus->convertedData) { int length = pDrmConvertedStatus->convertedData->length; dataArray = env->NewByteArray(length); env->SetByteArrayRegion( dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data); delete [] pDrmConvertedStatus->convertedData->data; delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL; } jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V"); drmConvertedStatus = env->NewObject(localRef, constructorId, statusCode, dataArray, pDrmConvertedStatus->offset); } delete pDrmConvertedStatus; pDrmConvertedStatus = NULL; ALOGV("GetConvertedStatus - Exit"); return drmConvertedStatus; } static jobject android_drm_DrmManagerClient_convertData( JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) { ALOGV("convertData Enter"); int dataLength = 0; char* mData = Utility::getByteArrayValue(env, inputData, &dataLength); const DrmBuffer buffer(mData, dataLength); DrmConvertedStatus* pDrmConvertedStatus = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer); jobject status = GetConvertedStatus(env, pDrmConvertedStatus); delete[] mData; mData = NULL; ALOGV("convertData - Exit"); return status; } static jobject android_drm_DrmManagerClient_closeConvertSession( JNIEnv* env, jobject thiz, jint uniqueId, jint convertId) { ALOGV("closeConvertSession Enter"); DrmConvertedStatus* pDrmConvertedStatus = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId); jobject status = GetConvertedStatus(env, pDrmConvertedStatus); ALOGV("closeConvertSession - Exit"); return status; } static JNINativeMethod nativeMethods[] = { {"_initialize", "()I", (void*)android_drm_DrmManagerClient_initialize}, {"_setListeners", "(ILjava/lang/Object;)V", (void*)android_drm_DrmManagerClient_setListeners}, {"_release", "(I)V", (void*)android_drm_DrmManagerClient_release}, {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;", (void*)android_drm_DrmManagerClient_getConstraintsFromContent}, {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;", (void*)android_drm_DrmManagerClient_getMetadataFromContent}, {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;", (void*)android_drm_DrmManagerClient_getAllSupportInfo}, {"_installDrmEngine", "(ILjava/lang/String;)V", (void*)android_drm_DrmManagerClient_installDrmEngine}, {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z", (void*)android_drm_DrmManagerClient_canHandle}, {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;", (void*)android_drm_DrmManagerClient_processDrmInfo}, {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;", (void*)android_drm_DrmManagerClient_acquireDrmInfo}, {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I", (void*)android_drm_DrmManagerClient_saveRights}, {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I", (void*)android_drm_DrmManagerClient_getDrmObjectType}, {"_getOriginalMimeType", "(ILjava/lang/String;Ljava/io/FileDescriptor;)Ljava/lang/String;", (void*)android_drm_DrmManagerClient_getOriginalMimeType}, {"_checkRightsStatus", "(ILjava/lang/String;I)I", (void*)android_drm_DrmManagerClient_checkRightsStatus}, {"_removeRights", "(ILjava/lang/String;)I", (void*)android_drm_DrmManagerClient_removeRights}, {"_removeAllRights", "(I)I", (void*)android_drm_DrmManagerClient_removeAllRights}, {"_openConvertSession", "(ILjava/lang/String;)I", (void*)android_drm_DrmManagerClient_openConvertSession}, {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;", (void*)android_drm_DrmManagerClient_convertData}, {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;", (void*)android_drm_DrmManagerClient_closeConvertSession}, }; static int registerNativeMethods(JNIEnv* env) { int result = -1; /* look up the class */ jclass clazz = env->FindClass("android/drm/DrmManagerClient"); if (NULL != clazz) { if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods) / sizeof(nativeMethods[0])) == JNI_OK) { result = 0; } } return result; } jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { if (NULL != env && registerNativeMethods(env) == 0) { result = JNI_VERSION_1_4; } } return result; }