summaryrefslogtreecommitdiffstats
path: root/drm/jni
diff options
context:
space:
mode:
authoraimitakeshi <aimitakeshi@gmail.com>2010-07-29 10:12:27 +0900
committeraimitakeshi <aimitakeshi@gmail.com>2010-09-01 15:40:00 +0900
commitd074e30ce44b9e33da43b67a4515b8986ca72b26 (patch)
treecea9a809ad3b678713d10b938eb21f0d792a89d8 /drm/jni
parentf470ed8630e9e648727443b065b9f1c69fee34d6 (diff)
downloadframeworks_base-d074e30ce44b9e33da43b67a4515b8986ca72b26.zip
frameworks_base-d074e30ce44b9e33da43b67a4515b8986ca72b26.tar.gz
frameworks_base-d074e30ce44b9e33da43b67a4515b8986ca72b26.tar.bz2
Initial contribution from Sony Corporation.
Add DRM Framework to support DRM content playback together with StageFright. - DRM Framework code is added - include/drm - drm - api/current.xml is updated to include DRM Framework Java APIs - cmds/servicemanager/service_manager.c is modified to add drmManager and drmIOService. Change-Id: I6d7bc9c7067362b500e530988a9ce241761866fb
Diffstat (limited to 'drm/jni')
-rw-r--r--drm/jni/Android.mk43
-rw-r--r--drm/jni/android_drm_DrmManagerClient.cpp755
2 files changed, 798 insertions, 0 deletions
diff --git a/drm/jni/Android.mk b/drm/jni/Android.mk
new file mode 100644
index 0000000..0731755
--- /dev/null
+++ b/drm/jni/Android.mk
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ android_drm_DrmManagerClient.cpp
+
+LOCAL_MODULE:= libdrmframework_jni
+
+LOCAL_SHARED_LIBRARIES := \
+ libdrmframework \
+ libutils \
+ libandroid_runtime \
+ libnativehelper \
+ libbinder \
+ libdl
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE) \
+ $(TOP)/frameworks/base/drm/libdrmframework/include \
+ $(TOP)/frameworks/base/drm/libdrmframework/plugins/common/include \
+ $(TOP)/frameworks/base/include
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp
new file mode 100644
index 0000000..bc5a7bf
--- /dev/null
+++ b/drm/jni/android_drm_DrmManagerClient.cpp
@@ -0,0 +1,755 @@
+/*
+ * 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 "DrmManager-JNI"
+#include <utils/Log.h>
+
+#include <jni.h>
+#include <JNIHelp.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/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) {
+ String8 dataString("");
+
+ /* 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);
+
+ if (NULL != valueString && valueString != env->NewStringUTF("")) {
+ char* bytes = const_cast< char* > (env->GetStringUTFChars(valueString, NULL));
+
+ const int length = strlen(bytes) + 1;
+ char *data = new char[length];
+ strncpy(data, bytes, length);
+ dataString = String8(data);
+
+ env->ReleaseStringUTFChars(valueString, bytes);
+ delete [] data; data = NULL;
+ } else {
+ LOGD("Failed to retrieve the data from the field %s", fieldName);
+ }
+ }
+ 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) {
+ char* data = NULL;
+ *dataLength = 0;
+
+ jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
+
+ if (NULL != fieldID) {
+ jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
+ 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;
+}
+
+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) {
+ LOGE("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());
+ LOGV("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", "I");
+
+ sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
+ if (client.get()) {
+ client->incStrong(thiz);
+ }
+ if (old != 0) {
+ old->decStrong(thiz);
+ }
+ env->SetIntField(thiz, fieldId, (int)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", "I");
+
+ DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
+ return sp<DrmManagerClientImpl>(client);
+}
+
+static void android_drm_DrmManagerClient_loadPlugIns(
+ JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
+ LOGV("load plugins - Enter");
+
+ sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId);
+
+ // Set the listener to DrmManager
+ sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
+ drmManager->setOnInfoListener(uniqueId, listener);
+
+ setDrmManagerClientImpl(env, thiz, drmManager);
+
+ getDrmManagerClientImpl(env, thiz)->loadPlugIns(uniqueId);
+ LOGV("load plugins - Exit");
+}
+
+static void android_drm_DrmManagerClient_unloadPlugIns(JNIEnv* env, jobject thiz, jint uniqueId) {
+ LOGV("unload plugins - Enter");
+ sp<DrmManagerClientImpl> client = getDrmManagerClientImpl(env, thiz);
+ client->unloadPlugIns(uniqueId);
+ client->setOnInfoListener(uniqueId, NULL);
+ DrmManagerClientImpl::remove(uniqueId);
+
+ sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
+ if (oldClient != NULL) {
+ oldClient->setOnInfoListener(uniqueId, NULL);
+ }
+
+ LOGV("unload plugins - Exit");
+}
+
+static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
+ LOGV("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");
+ jobject constraints = NULL;
+
+ if (NULL != localRef && NULL != pConstraints) {
+ // Get the constructor id
+ jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
+ // create the java DrmConstraints object
+ constraints = env->NewObject(localRef, constructorId);
+
+ 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) {
+ jbyteArray dataArray = env->NewByteArray(strlen(value));
+ env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
+ env->CallVoidMethod(
+ constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
+ env->NewStringUTF(key.string()), dataArray);
+ }
+ } else {
+ String8 value = pConstraints->get(key);
+ env->CallVoidMethod(
+ constraints,
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
+ env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ }
+ }
+ }
+
+ delete pConstraints; pConstraints = NULL;
+ LOGV("GetConstraints - Exit");
+ return constraints;
+}
+
+static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
+ JNIEnv* env, jobject thiz, jint uniqueId) {
+ LOGV("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;
+ LOGV("GetAllSupportInfo - Exit");
+ return array;
+}
+
+static void android_drm_DrmManagerClient_installDrmEngine(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
+ LOGV("installDrmEngine - Enter");
+ //getDrmManagerClient(env, thiz)
+ // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
+ LOGV("installDrmEngine - Exit");
+}
+
+static void android_drm_DrmManagerClient_saveRights(
+ JNIEnv* env, jobject thiz, jint uniqueId,
+ jobject drmRights, jstring rightsPath, jstring contentPath) {
+ LOGV("saveRights - Enter");
+ 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"));
+ getDrmManagerClientImpl(env, thiz)
+ ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
+ Utility::getStringValue(env, contentPath));
+ }
+
+ delete mData; mData = NULL;
+ LOGV("saveRights - Exit");
+}
+
+static jboolean android_drm_DrmManagerClient_canHandle(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
+ LOGV("canHandle - Enter");
+ jboolean result
+ = getDrmManagerClientImpl(env, thiz)
+ ->canHandle(uniqueId, Utility::getStringValue(env, path),
+ Utility::getStringValue(env, mimeType));
+ LOGV("canHandle - Exit");
+ return result;
+}
+
+static jobject android_drm_DrmManagerClient_processDrmInfo(
+ JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
+ LOGV("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");
+ jobject keyIterator
+ = env->CallObjectMethod(drmInfoObject,
+ env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
+
+ jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+
+ while (env->CallBooleanMethod(keyIterator, hasNextId)) {
+ jstring key = (jstring) env->CallObjectMethod(keyIterator,
+ env->GetMethodID(env->FindClass("java/util/Iterator"),
+ "next", "()Ljava/lang/Object;"));
+
+ jobject valueObject = env->CallObjectMethod(drmInfoObject,
+ env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
+
+ jstring valString = NULL;
+ if (NULL != valueObject) {
+ valString = (jstring) env->CallObjectMethod(valueObject,
+ env->GetMethodID(env->FindClass("java/lang/Object"),
+ "toString", "()Ljava/lang/String;"));
+ }
+
+ String8 keyString = Utility::getStringValue(env, key);
+ String8 valueString = Utility::getStringValue(env, valString);
+ LOGD("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;
+
+ 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>", "(ILandroid/drm/ProcessedData;Ljava/lang/String;)V");
+
+ drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, processedData,
+ env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
+ }
+
+ delete mData; mData = NULL;
+ delete pDrmInfoStatus; pDrmInfoStatus = NULL;
+
+ LOGV("processDrmInfo - Exit");
+ return drmInfoStatus;
+}
+
+static jobject android_drm_DrmManagerClient_acquireDrmInfo(
+ JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
+ LOGV("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 hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+
+ while (env->CallBooleanMethod(keyIterator, hasNextId)) {
+ jstring key
+ = (jstring) env->CallObjectMethod(keyIterator,
+ env->GetMethodID(env->FindClass("java/util/Iterator"),
+ "next", "()Ljava/lang/Object;"));
+
+ jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
+ env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
+
+ String8 keyString = Utility::getStringValue(env, key);
+ String8 valueString = Utility::getStringValue(env, value);
+ LOGD("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);
+
+ env->CallVoidMethod(drmInfoObject, putMethodId,
+ env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ }
+ }
+ delete [] pDrmInfo->getData().data;
+ }
+
+ delete pDrmInfo; pDrmInfo = NULL;
+
+ LOGV("acquireDrmInfo Exit");
+ return drmInfoObject;
+}
+
+static jint android_drm_DrmManagerClient_getDrmObjectType(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
+ LOGV("getDrmObjectType Enter");
+ int drmObjectType
+ = getDrmManagerClientImpl(env, thiz)
+ ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
+ Utility::getStringValue(env, mimeType));
+ LOGV("getDrmObjectType Exit");
+ return drmObjectType;
+}
+
+static jstring android_drm_DrmManagerClient_getOriginalMimeType(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
+ LOGV("getOriginalMimeType Enter");
+ String8 mimeType
+ = getDrmManagerClientImpl(env, thiz)
+ ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
+ LOGV("getOriginalMimeType Exit");
+ return env->NewStringUTF(mimeType.string());
+}
+
+static jint android_drm_DrmManagerClient_checkRightsStatus(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
+ LOGV("getOriginalMimeType Enter");
+ int rightsStatus
+ = getDrmManagerClientImpl(env, thiz)
+ ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
+ LOGV("getOriginalMimeType Exit");
+ return rightsStatus;
+}
+
+static void android_drm_DrmManagerClient_removeRights(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
+ LOGV("removeRights Enter");
+ getDrmManagerClientImpl(env, thiz)->removeRights(uniqueId, Utility::getStringValue(env, path));
+ LOGV("removeRights Exit");
+}
+
+static void android_drm_DrmManagerClient_removeAllRights(
+ JNIEnv* env, jobject thiz, jint uniqueId) {
+ LOGV("removeAllRights Enter");
+ getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
+ LOGV("removeAllRights Exit");
+}
+
+static jint android_drm_DrmManagerClient_openConvertSession(
+ JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
+ LOGV("openConvertSession Enter");
+ int convertId
+ = getDrmManagerClientImpl(env, thiz)
+ ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
+ LOGV("openConvertSession Exit");
+ return convertId;
+}
+
+static jobject android_drm_DrmManagerClient_convertData(
+ JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
+ LOGV("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);
+
+ 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 mData; mData = NULL;
+ delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
+
+ LOGV("convertData - Exit");
+ return drmConvertedStatus;
+}
+
+static jobject android_drm_DrmManagerClient_closeConvertSession(
+ JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
+
+ LOGV("closeConvertSession Enter");
+
+ DrmConvertedStatus* pDrmConvertedStatus
+ = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
+
+ 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;
+
+ LOGV("closeConvertSession - Exit");
+ return drmConvertedStatus;
+}
+
+static JNINativeMethod nativeMethods[] = {
+
+ {"_loadPlugIns", "(ILjava/lang/Object;)V",
+ (void*)android_drm_DrmManagerClient_loadPlugIns},
+
+ {"_unloadPlugIns", "(I)V",
+ (void*)android_drm_DrmManagerClient_unloadPlugIns},
+
+ {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
+ (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
+
+ {"_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;)V",
+ (void*)android_drm_DrmManagerClient_saveRights},
+
+ {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
+ (void*)android_drm_DrmManagerClient_getDrmObjectType},
+
+ {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
+ (void*)android_drm_DrmManagerClient_getOriginalMimeType},
+
+ {"_checkRightsStatus", "(ILjava/lang/String;I)I",
+ (void*)android_drm_DrmManagerClient_checkRightsStatus},
+
+ {"_removeRights", "(ILjava/lang/String;)V",
+ (void*)android_drm_DrmManagerClient_removeRights},
+
+ {"_removeAllRights", "(I)V",
+ (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;
+}
+