blob: 191648cb8e47f260c7f3df719d27bb75725c6f1d [file] [log] [blame]
aimitakeshid074e302010-07-29 10:12:27 +09001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Takeshi Aimidc549d62010-09-20 23:40:41 +090017//#define LOG_NDEBUG 0
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +090018#define LOG_TAG "android_drm_DrmManagerClient"
aimitakeshid074e302010-07-29 10:12:27 +090019#include <utils/Log.h>
20
21#include <jni.h>
22#include <JNIHelp.h>
23#include <android_runtime/AndroidRuntime.h>
24
25#include <drm/DrmInfo.h>
26#include <drm/DrmRights.h>
27#include <drm/DrmInfoEvent.h>
28#include <drm/DrmInfoStatus.h>
29#include <drm/DrmInfoRequest.h>
30#include <drm/DrmSupportInfo.h>
31#include <drm/DrmConstraints.h>
Takeshi Aimidc9186562010-11-16 13:56:11 +090032#include <drm/DrmMetadata.h>
aimitakeshid074e302010-07-29 10:12:27 +090033#include <drm/DrmConvertedStatus.h>
34#include <drm/drm_framework_common.h>
35
36#include <DrmManagerClientImpl.h>
37
38using namespace android;
39
40/**
41 * Utility class used to extract the value from the provided java object.
42 * May need to add some utility function to create java object.
43 */
44class Utility {
45public:
46 static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName);
47
48 static char* getByteArrayValue(
49 JNIEnv* env, jobject object, const char* fieldName, int* dataLength);
50
51 static char* getByteArrayValue(
52 JNIEnv* env, jbyteArray byteArray, int* dataLength);
53
54 static String8 getStringValue(JNIEnv* env, jstring string);
55
56 static int getIntValue(JNIEnv* env, jobject object, const char* fieldName);
57};
58
59String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
aimitakeshid074e302010-07-29 10:12:27 +090060 /* Look for the instance field with the name fieldName */
61 jfieldID fieldID
62 = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");
63
64 if (NULL != fieldID) {
65 jstring valueString = (jstring) env->GetObjectField(object, fieldID);
James Dongf16a2722012-03-02 16:49:35 -080066 return Utility::getStringValue(env, valueString);
aimitakeshid074e302010-07-29 10:12:27 +090067 }
James Dongf16a2722012-03-02 16:49:35 -080068
69 String8 dataString("");
aimitakeshid074e302010-07-29 10:12:27 +090070 return dataString;
71}
72
73String8 Utility::getStringValue(JNIEnv* env, jstring string) {
74 String8 dataString("");
75
76 if (NULL != string && string != env->NewStringUTF("")) {
77 char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));
78
79 const int length = strlen(bytes) + 1;
80 char *data = new char[length];
81 strncpy(data, bytes, length);
82 dataString = String8(data);
83
84 env->ReleaseStringUTFChars(string, bytes);
85 delete [] data; data = NULL;
86 }
87 return dataString;
88}
89
90char* Utility::getByteArrayValue(
91 JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
James Dongf16a2722012-03-02 16:49:35 -080092
aimitakeshid074e302010-07-29 10:12:27 +090093 *dataLength = 0;
94
95 jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
96
97 if (NULL != fieldID) {
98 jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
James Dongf16a2722012-03-02 16:49:35 -080099 return Utility::getByteArrayValue(env, byteArray, dataLength);
aimitakeshid074e302010-07-29 10:12:27 +0900100 }
James Dongf16a2722012-03-02 16:49:35 -0800101 return NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900102}
103
104char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {
105 char* data = NULL;
106 if (NULL != byteArray) {
107 jint length = env->GetArrayLength(byteArray);
108
109 *dataLength = length;
110 if (0 < *dataLength) {
111 data = new char[length];
112 env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
113 }
114 }
115 return data;
116}
117
118int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {
119 jfieldID fieldID;
120 int intValue = -1;
121
122 /* Get a reference to obj’s class */
123 jclass clazz = env->GetObjectClass(object);
124 /* Look for the instance field with the name fieldName */
125 fieldID = env->GetFieldID(clazz, fieldName , "I");
126
127 if (NULL != fieldID) {
128 intValue = (int) env->GetIntField(object, fieldID);
129 }
130
131 return intValue;
132}
133
134class JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
135public:
136 JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
137
138 virtual ~JNIOnInfoListener();
139 void onInfo(const DrmInfoEvent& event);
140
141private:
142 JNIOnInfoListener();
143 jclass mClass;
144 jobject mObject;
145};
146
147JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
148 jclass clazz = env->GetObjectClass(thiz);
149
150 if (clazz == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000151 ALOGE("Can't find android/drm/DrmManagerClient");
aimitakeshid074e302010-07-29 10:12:27 +0900152 jniThrowException(env, "java/lang/Exception", NULL);
153 return;
154 }
155 mClass = (jclass)env->NewGlobalRef(clazz);
156 mObject = env->NewGlobalRef(weak_thiz);
157}
158
159JNIOnInfoListener::~JNIOnInfoListener() {
160 JNIEnv *env = AndroidRuntime::getJNIEnv();
161 env->DeleteGlobalRef(mObject);
162 env->DeleteGlobalRef(mClass);
163}
164
165void JNIOnInfoListener::onInfo(const DrmInfoEvent& event) {
166 jint uniqueId = event.getUniqueId();
167 jint type = event.getType();
168 JNIEnv *env = AndroidRuntime::getJNIEnv();
169 jstring message = env->NewStringUTF(event.getMessage().string());
Steve Block06ade6a2011-10-20 11:56:00 +0100170 ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
aimitakeshid074e302010-07-29 10:12:27 +0900171
172 env->CallStaticVoidMethod(
173 mClass,
174 env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
175 mObject, uniqueId, type, message);
176}
177
178static Mutex sLock;
179
180static sp<DrmManagerClientImpl> setDrmManagerClientImpl(
181 JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
182 Mutex::Autolock l(sLock);
183 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
184 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
185
186 sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
187 if (client.get()) {
188 client->incStrong(thiz);
189 }
190 if (old != 0) {
191 old->decStrong(thiz);
192 }
193 env->SetIntField(thiz, fieldId, (int)client.get());
194 return old;
195}
196
197static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
198 Mutex::Autolock l(sLock);
199 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
200 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
201
202 DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
203 return sp<DrmManagerClientImpl>(client);
204}
205
Gloria Wanga17d4542011-07-21 15:10:22 -0700206static jint android_drm_DrmManagerClient_initialize(
Kei Takahashi6225df02012-01-31 13:18:45 +0900207 JNIEnv* env, jobject thiz) {
Steve Block06ade6a2011-10-20 11:56:00 +0100208 ALOGV("initialize - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900209
Gloria Wanga17d4542011-07-21 15:10:22 -0700210 int uniqueId = 0;
211 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900212 drmManager->addClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900213
aimitakeshid074e302010-07-29 10:12:27 +0900214 setDrmManagerClientImpl(env, thiz, drmManager);
Steve Block06ade6a2011-10-20 11:56:00 +0100215 ALOGV("initialize - Exit");
Gloria Wanga17d4542011-07-21 15:10:22 -0700216 return uniqueId;
aimitakeshid074e302010-07-29 10:12:27 +0900217}
218
Kei Takahashi6225df02012-01-31 13:18:45 +0900219static void android_drm_DrmManagerClient_setListeners(
220 JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
221 ALOGV("setListeners - Enter");
222
223 // Set the listener to DrmManager
224 sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
225 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
226
227 ALOGV("setListeners - Exit");
228}
229
230static void android_drm_DrmManagerClient_release(
231 JNIEnv* env, jobject thiz, jint uniqueId) {
232 ALOGV("release - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900233 DrmManagerClientImpl::remove(uniqueId);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900234 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
aimitakeshid074e302010-07-29 10:12:27 +0900235
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900236 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
237 if (oldClient != NULL) {
238 oldClient->setOnInfoListener(uniqueId, NULL);
239 oldClient->removeClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900240 }
Kei Takahashi6225df02012-01-31 13:18:45 +0900241 ALOGV("release - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900242}
243
244static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
245 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
Steve Block06ade6a2011-10-20 11:56:00 +0100246 ALOGV("GetConstraints - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900247
248 const String8 pathString = Utility::getStringValue(env, jpath);
249 DrmConstraints* pConstraints
250 = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
251
252 jclass localRef = env->FindClass("android/content/ContentValues");
253 jobject constraints = NULL;
254
255 if (NULL != localRef && NULL != pConstraints) {
256 // Get the constructor id
257 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
258 // create the java DrmConstraints object
259 constraints = env->NewObject(localRef, constructorId);
260
261 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
262
263 while (keyIt.hasNext()) {
264 String8 key = keyIt.next();
265
266 // insert the entry<constraintKey, constraintValue> to newly created java object
267 if (DrmConstraints::EXTENDED_METADATA == key) {
268 const char* value = pConstraints->getAsByteArray(&key);
269 if (NULL != value) {
270 jbyteArray dataArray = env->NewByteArray(strlen(value));
271 env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
272 env->CallVoidMethod(
273 constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
274 env->NewStringUTF(key.string()), dataArray);
275 }
276 } else {
277 String8 value = pConstraints->get(key);
278 env->CallVoidMethod(
279 constraints,
280 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
281 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
282 }
283 }
284 }
285
286 delete pConstraints; pConstraints = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100287 ALOGV("GetConstraints - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900288 return constraints;
289}
290
Takeshi Aimidc9186562010-11-16 13:56:11 +0900291static jobject android_drm_DrmManagerClient_getMetadataFromContent(
292 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100293 ALOGV("GetMetadata - Enter");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900294 const String8 pathString = Utility::getStringValue(env, jpath);
295 DrmMetadata* pMetadata =
296 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
297
298 jobject metadata = NULL;
299
300 jclass localRef = NULL;
301 localRef = env->FindClass("android/content/ContentValues");
302 if (NULL != localRef && NULL != pMetadata) {
303 // Get the constructor id
304 jmethodID constructorId = NULL;
305 constructorId = env->GetMethodID(localRef, "<init>", "()V");
306 if (NULL != constructorId) {
307 // create the java DrmMetadata object
308 metadata = env->NewObject(localRef, constructorId);
309 if (NULL != metadata) {
310 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
311 while (keyIt.hasNext()) {
312 String8 key = keyIt.next();
313 // insert the entry<constraintKey, constraintValue>
314 // to newly created java object
315 String8 value = pMetadata->get(key);
316 env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
317 "(Ljava/lang/String;Ljava/lang/String;)V"),
318 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
319 }
320 }
321 }
322 }
323 delete pMetadata; pMetadata = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100324 ALOGV("GetMetadata - Exit");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900325 return metadata;
326}
327
aimitakeshid074e302010-07-29 10:12:27 +0900328static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
329 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100330 ALOGV("GetAllSupportInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900331 DrmSupportInfo* drmSupportInfoArray = NULL;
332
333 int length = 0;
334 getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
335
336 jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
337
338 jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
339
340 for (int i = 0; i < length; i++) {
341 DrmSupportInfo info = drmSupportInfoArray[i];
342
343 jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
344
345 jmethodID addMimeTypeId
346 = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
347 jmethodID addFileSuffixId
348 = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
349
350 env->CallVoidMethod(
351 drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
352 env->NewStringUTF(info.getDescription().string()));
353
354 DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
355 while (iterator.hasNext()) {
356 String8 value = iterator.next();
357 env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
358 }
359
360 DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
361 while (it.hasNext()) {
362 String8 value = it.next();
363 env->CallVoidMethod(
364 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
365 }
366
367 env->SetObjectArrayElement(array, i, drmSupportInfo);
368 }
369
370 delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100371 ALOGV("GetAllSupportInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900372 return array;
373}
374
375static void android_drm_DrmManagerClient_installDrmEngine(
376 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100377 ALOGV("installDrmEngine - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900378 //getDrmManagerClient(env, thiz)
379 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
Steve Block06ade6a2011-10-20 11:56:00 +0100380 ALOGV("installDrmEngine - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900381}
382
Takeshi Aimidc549d62010-09-20 23:40:41 +0900383static jint android_drm_DrmManagerClient_saveRights(
aimitakeshid074e302010-07-29 10:12:27 +0900384 JNIEnv* env, jobject thiz, jint uniqueId,
385 jobject drmRights, jstring rightsPath, jstring contentPath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100386 ALOGV("saveRights - Enter");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900387 int result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900388 int dataLength = 0;
389 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
390
391 if (NULL != mData) {
392 DrmRights rights(DrmBuffer(mData, dataLength),
393 Utility::getStringValue(env, drmRights, "mMimeType"),
394 Utility::getStringValue(env, drmRights, "mAccountId"),
395 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900396 result = getDrmManagerClientImpl(env, thiz)
aimitakeshid074e302010-07-29 10:12:27 +0900397 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
398 Utility::getStringValue(env, contentPath));
399 }
400
James Dongf16a2722012-03-02 16:49:35 -0800401 delete[] mData; mData = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100402 ALOGV("saveRights - Exit");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900403 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900404}
405
406static jboolean android_drm_DrmManagerClient_canHandle(
407 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100408 ALOGV("canHandle - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900409 jboolean result
410 = getDrmManagerClientImpl(env, thiz)
411 ->canHandle(uniqueId, Utility::getStringValue(env, path),
412 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100413 ALOGV("canHandle - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900414 return result;
415}
416
417static jobject android_drm_DrmManagerClient_processDrmInfo(
418 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
Steve Block06ade6a2011-10-20 11:56:00 +0100419 ALOGV("processDrmInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900420 int dataLength = 0;
421 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType");
422 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
423 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
424
425 const DrmBuffer buffer(mData, dataLength);
426 DrmInfo drmInfo(mInfoType, buffer, mMimeType);
427
428 jclass clazz = env->FindClass("android/drm/DrmInfo");
429 jobject keyIterator
430 = env->CallObjectMethod(drmInfoObject,
431 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
432
433 jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
434
435 while (env->CallBooleanMethod(keyIterator, hasNextId)) {
436 jstring key = (jstring) env->CallObjectMethod(keyIterator,
437 env->GetMethodID(env->FindClass("java/util/Iterator"),
438 "next", "()Ljava/lang/Object;"));
439
440 jobject valueObject = env->CallObjectMethod(drmInfoObject,
441 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
442
443 jstring valString = NULL;
444 if (NULL != valueObject) {
445 valString = (jstring) env->CallObjectMethod(valueObject,
446 env->GetMethodID(env->FindClass("java/lang/Object"),
447 "toString", "()Ljava/lang/String;"));
448 }
449
450 String8 keyString = Utility::getStringValue(env, key);
451 String8 valueString = Utility::getStringValue(env, valString);
Steve Block06ade6a2011-10-20 11:56:00 +0100452 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900453
454 drmInfo.put(keyString, valueString);
455 }
456
457 DrmInfoStatus* pDrmInfoStatus
458 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
459
460 jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
461 jobject drmInfoStatus = NULL;
462
463 if (NULL != localRef && NULL != pDrmInfoStatus) {
464 int statusCode = pDrmInfoStatus->statusCode;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900465 int infoType = pDrmInfoStatus->infoType;
aimitakeshid074e302010-07-29 10:12:27 +0900466
467 jbyteArray dataArray = NULL;
468 if (NULL != pDrmInfoStatus->drmBuffer) {
469 int length = pDrmInfoStatus->drmBuffer->length;
470 dataArray = env->NewByteArray(length);
471 env->SetByteArrayRegion(
472 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
473
474 delete [] pDrmInfoStatus->drmBuffer->data;
475 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
476 }
477 jclass clazz = env->FindClass("android/drm/ProcessedData");
478 jmethodID constructorId
479 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
480 jobject processedData = env->NewObject(clazz, constructorId, dataArray,
481 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
482 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
483
484 constructorId
485 = env->GetMethodID(localRef,
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900486 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
aimitakeshid074e302010-07-29 10:12:27 +0900487
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900488 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
489 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900490 }
491
James Dongf16a2722012-03-02 16:49:35 -0800492 delete[] mData; mData = NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900493 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
494
Steve Block06ade6a2011-10-20 11:56:00 +0100495 ALOGV("processDrmInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900496 return drmInfoStatus;
497}
498
499static jobject android_drm_DrmManagerClient_acquireDrmInfo(
500 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
Steve Block06ade6a2011-10-20 11:56:00 +0100501 ALOGV("acquireDrmInfo Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900502 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType");
503 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
504
505 DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
506
507 jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
508 jobject keyIterator
509 = env->CallObjectMethod(drmInfoRequest,
510 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
511
512 jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
513
514 while (env->CallBooleanMethod(keyIterator, hasNextId)) {
515 jstring key
516 = (jstring) env->CallObjectMethod(keyIterator,
517 env->GetMethodID(env->FindClass("java/util/Iterator"),
518 "next", "()Ljava/lang/Object;"));
519
520 jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
521 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
522
523 String8 keyString = Utility::getStringValue(env, key);
524 String8 valueString = Utility::getStringValue(env, value);
Steve Block06ade6a2011-10-20 11:56:00 +0100525 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900526
527 drmInfoReq.put(keyString, valueString);
528 }
529
530 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
531
532 jobject drmInfoObject = NULL;
533
534 if (NULL != pDrmInfo) {
535 jclass localRef = env->FindClass("android/drm/DrmInfo");
536
537 if (NULL != localRef) {
538 int length = pDrmInfo->getData().length;
539
540 jbyteArray dataArray = env->NewByteArray(length);
541 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
542
543 drmInfoObject
544 = env->NewObject(localRef,
545 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
546 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
547
548 DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
549 jmethodID putMethodId
550 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
551
552 while (it.hasNext()) {
553 String8 key = it.next();
554 String8 value = pDrmInfo->get(key);
555
556 env->CallVoidMethod(drmInfoObject, putMethodId,
557 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
558 }
559 }
560 delete [] pDrmInfo->getData().data;
561 }
562
563 delete pDrmInfo; pDrmInfo = NULL;
564
Steve Block06ade6a2011-10-20 11:56:00 +0100565 ALOGV("acquireDrmInfo Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900566 return drmInfoObject;
567}
568
569static jint android_drm_DrmManagerClient_getDrmObjectType(
570 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100571 ALOGV("getDrmObjectType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900572 int drmObjectType
573 = getDrmManagerClientImpl(env, thiz)
574 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
575 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100576 ALOGV("getDrmObjectType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900577 return drmObjectType;
578}
579
580static jstring android_drm_DrmManagerClient_getOriginalMimeType(
581 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100582 ALOGV("getOriginalMimeType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900583 String8 mimeType
584 = getDrmManagerClientImpl(env, thiz)
585 ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
Steve Block06ade6a2011-10-20 11:56:00 +0100586 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900587 return env->NewStringUTF(mimeType.string());
588}
589
590static jint android_drm_DrmManagerClient_checkRightsStatus(
591 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
Steve Block06ade6a2011-10-20 11:56:00 +0100592 ALOGV("getOriginalMimeType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900593 int rightsStatus
594 = getDrmManagerClientImpl(env, thiz)
595 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
Steve Block06ade6a2011-10-20 11:56:00 +0100596 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900597 return rightsStatus;
598}
599
Takeshi Aimidc549d62010-09-20 23:40:41 +0900600static jint android_drm_DrmManagerClient_removeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900601 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100602 ALOGV("removeRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900603 return getDrmManagerClientImpl(env, thiz)
604 ->removeRights(uniqueId, Utility::getStringValue(env, path));
aimitakeshid074e302010-07-29 10:12:27 +0900605}
606
Takeshi Aimidc549d62010-09-20 23:40:41 +0900607static jint android_drm_DrmManagerClient_removeAllRights(
aimitakeshid074e302010-07-29 10:12:27 +0900608 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100609 ALOGV("removeAllRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900610 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900611}
612
613static jint android_drm_DrmManagerClient_openConvertSession(
614 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100615 ALOGV("openConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900616 int convertId
617 = getDrmManagerClientImpl(env, thiz)
618 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100619 ALOGV("openConvertSession Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900620 return convertId;
621}
622
623static jobject android_drm_DrmManagerClient_convertData(
624 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
Steve Block06ade6a2011-10-20 11:56:00 +0100625 ALOGV("convertData Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900626
627 int dataLength = 0;
628 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
629 const DrmBuffer buffer(mData, dataLength);
630
631 DrmConvertedStatus* pDrmConvertedStatus
632 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
633
634 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
635
636 jobject drmConvertedStatus = NULL;
637
638 if (NULL != localRef && NULL != pDrmConvertedStatus) {
639 int statusCode = pDrmConvertedStatus->statusCode;
640
641 jbyteArray dataArray = NULL;
642 if (NULL != pDrmConvertedStatus->convertedData) {
643 int length = pDrmConvertedStatus->convertedData->length;
644 dataArray = env->NewByteArray(length);
645 env->SetByteArrayRegion(dataArray, 0, length,
646 (jbyte*) pDrmConvertedStatus->convertedData->data);
647
648 delete [] pDrmConvertedStatus->convertedData->data;
649 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
650 }
651 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
652 drmConvertedStatus
653 = env->NewObject(localRef, constructorId,
654 statusCode, dataArray, pDrmConvertedStatus->offset);
655 }
656
James Dongf16a2722012-03-02 16:49:35 -0800657 delete[] mData; mData = NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900658 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
659
Steve Block06ade6a2011-10-20 11:56:00 +0100660 ALOGV("convertData - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900661 return drmConvertedStatus;
662}
663
664static jobject android_drm_DrmManagerClient_closeConvertSession(
665 JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
666
Steve Block06ade6a2011-10-20 11:56:00 +0100667 ALOGV("closeConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900668
669 DrmConvertedStatus* pDrmConvertedStatus
670 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
671
672 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
673
674 jobject drmConvertedStatus = NULL;
675
676 if (NULL != localRef && NULL != pDrmConvertedStatus) {
677 int statusCode = pDrmConvertedStatus->statusCode;
678
679 jbyteArray dataArray = NULL;
680 if (NULL != pDrmConvertedStatus->convertedData) {
681 int length = pDrmConvertedStatus->convertedData->length;
682 dataArray = env->NewByteArray(length);
683 env->SetByteArrayRegion(
684 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
685
686 delete [] pDrmConvertedStatus->convertedData->data;
687 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
688 }
689 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
690 drmConvertedStatus
691 = env->NewObject(localRef, constructorId,
692 statusCode, dataArray, pDrmConvertedStatus->offset);
693 }
694
695 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
696
Steve Block06ade6a2011-10-20 11:56:00 +0100697 ALOGV("closeConvertSession - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900698 return drmConvertedStatus;
699}
700
701static JNINativeMethod nativeMethods[] = {
702
Kei Takahashi6225df02012-01-31 13:18:45 +0900703 {"_initialize", "()I",
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900704 (void*)android_drm_DrmManagerClient_initialize},
aimitakeshid074e302010-07-29 10:12:27 +0900705
Kei Takahashi6225df02012-01-31 13:18:45 +0900706 {"_setListeners", "(ILjava/lang/Object;)V",
707 (void*)android_drm_DrmManagerClient_setListeners},
708
709 {"_release", "(I)V",
710 (void*)android_drm_DrmManagerClient_release},
aimitakeshid074e302010-07-29 10:12:27 +0900711
712 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
713 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
714
Takeshi Aimidc9186562010-11-16 13:56:11 +0900715 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
716 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
717
aimitakeshid074e302010-07-29 10:12:27 +0900718 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
719 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
720
721 {"_installDrmEngine", "(ILjava/lang/String;)V",
722 (void*)android_drm_DrmManagerClient_installDrmEngine},
723
724 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
725 (void*)android_drm_DrmManagerClient_canHandle},
726
727 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
728 (void*)android_drm_DrmManagerClient_processDrmInfo},
729
730 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
731 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
732
Takeshi Aimidc549d62010-09-20 23:40:41 +0900733 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900734 (void*)android_drm_DrmManagerClient_saveRights},
735
736 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
737 (void*)android_drm_DrmManagerClient_getDrmObjectType},
738
739 {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
740 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
741
742 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
743 (void*)android_drm_DrmManagerClient_checkRightsStatus},
744
Takeshi Aimidc549d62010-09-20 23:40:41 +0900745 {"_removeRights", "(ILjava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900746 (void*)android_drm_DrmManagerClient_removeRights},
747
Takeshi Aimidc549d62010-09-20 23:40:41 +0900748 {"_removeAllRights", "(I)I",
aimitakeshid074e302010-07-29 10:12:27 +0900749 (void*)android_drm_DrmManagerClient_removeAllRights},
750
751 {"_openConvertSession", "(ILjava/lang/String;)I",
752 (void*)android_drm_DrmManagerClient_openConvertSession},
753
754 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
755 (void*)android_drm_DrmManagerClient_convertData},
756
757 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
758 (void*)android_drm_DrmManagerClient_closeConvertSession},
759};
760
761static int registerNativeMethods(JNIEnv* env) {
762 int result = -1;
763
764 /* look up the class */
765 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
766
767 if (NULL != clazz) {
768 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
769 / sizeof(nativeMethods[0])) == JNI_OK) {
770 result = 0;
771 }
772 }
773 return result;
774}
775
776jint JNI_OnLoad(JavaVM* vm, void* reserved) {
777 JNIEnv* env = NULL;
778 jint result = -1;
779
780 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
781 if (NULL != env && registerNativeMethods(env) == 0) {
782 result = JNI_VERSION_1_4;
783 }
784 }
785 return result;
786}
787