1 /*
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
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "android_drm_DrmManagerClient"
19 #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>
32 #include <drm/DrmMetadata.h>
33 #include <drm/DrmConvertedStatus.h>
34 #include <drm/drm_framework_common.h>
35
36 #include <DrmManagerClientImpl.h>
37
38 using 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 */
44 class Utility {
45 public:
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
getStringValue(JNIEnv * env,jobject object,const char * fieldName)59 String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
60 /* 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);
66 return Utility::getStringValue(env, valueString);
67 }
68
69 String8 dataString("");
70 return dataString;
71 }
72
getStringValue(JNIEnv * env,jstring string)73 String8 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
getByteArrayValue(JNIEnv * env,jobject object,const char * fieldName,int * dataLength)90 char* Utility::getByteArrayValue(
91 JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
92
93 *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);
99 return Utility::getByteArrayValue(env, byteArray, dataLength);
100 }
101 return NULL;
102 }
103
getByteArrayValue(JNIEnv * env,jbyteArray byteArray,int * dataLength)104 char* 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
getIntValue(JNIEnv * env,jobject object,const char * fieldName)118 int 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
134 class JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
135 public:
136 JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
137
138 virtual ~JNIOnInfoListener();
139 void onInfo(const DrmInfoEvent& event);
140
141 private:
142 JNIOnInfoListener();
143 jclass mClass;
144 jobject mObject;
145 };
146
JNIOnInfoListener(JNIEnv * env,jobject thiz,jobject weak_thiz)147 JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
148 jclass clazz = env->GetObjectClass(thiz);
149
150 if (clazz == NULL) {
151 ALOGE("Can't find android/drm/DrmManagerClient");
152 jniThrowException(env, "java/lang/Exception", NULL);
153 return;
154 }
155 mClass = (jclass)env->NewGlobalRef(clazz);
156 mObject = env->NewGlobalRef(weak_thiz);
157 }
158
~JNIOnInfoListener()159 JNIOnInfoListener::~JNIOnInfoListener() {
160 JNIEnv *env = AndroidRuntime::getJNIEnv();
161 env->DeleteGlobalRef(mObject);
162 env->DeleteGlobalRef(mClass);
163 }
164
onInfo(const DrmInfoEvent & event)165 void 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());
170 ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
171
172 env->CallStaticVoidMethod(
173 mClass,
174 env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
175 mObject, uniqueId, type, message);
176 }
177
178 static Mutex sLock;
179
setDrmManagerClientImpl(JNIEnv * env,jobject thiz,const sp<DrmManagerClientImpl> & client)180 static 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
getDrmManagerClientImpl(JNIEnv * env,jobject thiz)197 static 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
android_drm_DrmManagerClient_initialize(JNIEnv * env,jobject thiz)206 static jint android_drm_DrmManagerClient_initialize(
207 JNIEnv* env, jobject thiz) {
208 ALOGV("initialize - Enter");
209
210 int uniqueId = 0;
211 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
212 drmManager->addClient(uniqueId);
213
214 setDrmManagerClientImpl(env, thiz, drmManager);
215 ALOGV("initialize - Exit");
216 return uniqueId;
217 }
218
android_drm_DrmManagerClient_setListeners(JNIEnv * env,jobject thiz,jint uniqueId,jobject weak_thiz)219 static 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
android_drm_DrmManagerClient_release(JNIEnv * env,jobject thiz,jint uniqueId)230 static void android_drm_DrmManagerClient_release(
231 JNIEnv* env, jobject thiz, jint uniqueId) {
232 ALOGV("release - Enter");
233 DrmManagerClientImpl::remove(uniqueId);
234 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
235
236 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
237 if (oldClient != NULL) {
238 oldClient->setOnInfoListener(uniqueId, NULL);
239 oldClient->removeClient(uniqueId);
240 }
241 ALOGV("release - Exit");
242 }
243
android_drm_DrmManagerClient_getConstraintsFromContent(JNIEnv * env,jobject thiz,jint uniqueId,jstring jpath,jint usage)244 static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
245 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
246 ALOGV("GetConstraints - Enter");
247
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;
287 ALOGV("GetConstraints - Exit");
288 return constraints;
289 }
290
android_drm_DrmManagerClient_getMetadataFromContent(JNIEnv * env,jobject thiz,jint uniqueId,jstring jpath)291 static jobject android_drm_DrmManagerClient_getMetadataFromContent(
292 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
293 ALOGV("GetMetadata - Enter");
294 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;
324 ALOGV("GetMetadata - Exit");
325 return metadata;
326 }
327
android_drm_DrmManagerClient_getAllSupportInfo(JNIEnv * env,jobject thiz,jint uniqueId)328 static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
329 JNIEnv* env, jobject thiz, jint uniqueId) {
330 ALOGV("GetAllSupportInfo - Enter");
331 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;
371 ALOGV("GetAllSupportInfo - Exit");
372 return array;
373 }
374
android_drm_DrmManagerClient_installDrmEngine(JNIEnv * env,jobject thiz,jint uniqueId,jstring engineFilePath)375 static void android_drm_DrmManagerClient_installDrmEngine(
376 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
377 ALOGV("installDrmEngine - Enter");
378 //getDrmManagerClient(env, thiz)
379 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
380 ALOGV("installDrmEngine - Exit");
381 }
382
android_drm_DrmManagerClient_saveRights(JNIEnv * env,jobject thiz,jint uniqueId,jobject drmRights,jstring rightsPath,jstring contentPath)383 static jint android_drm_DrmManagerClient_saveRights(
384 JNIEnv* env, jobject thiz, jint uniqueId,
385 jobject drmRights, jstring rightsPath, jstring contentPath) {
386 ALOGV("saveRights - Enter");
387 int result = DRM_ERROR_UNKNOWN;
388 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"));
396 result = getDrmManagerClientImpl(env, thiz)
397 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
398 Utility::getStringValue(env, contentPath));
399 }
400
401 delete[] mData; mData = NULL;
402 ALOGV("saveRights - Exit");
403 return result;
404 }
405
android_drm_DrmManagerClient_canHandle(JNIEnv * env,jobject thiz,jint uniqueId,jstring path,jstring mimeType)406 static jboolean android_drm_DrmManagerClient_canHandle(
407 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
408 ALOGV("canHandle - Enter");
409 jboolean result
410 = getDrmManagerClientImpl(env, thiz)
411 ->canHandle(uniqueId, Utility::getStringValue(env, path),
412 Utility::getStringValue(env, mimeType));
413 ALOGV("canHandle - Exit");
414 return result;
415 }
416
android_drm_DrmManagerClient_processDrmInfo(JNIEnv * env,jobject thiz,jint uniqueId,jobject drmInfoObject)417 static jobject android_drm_DrmManagerClient_processDrmInfo(
418 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
419 ALOGV("processDrmInfo - Enter");
420 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);
452 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
453
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;
465 int infoType = pDrmInfoStatus->infoType;
466
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,
486 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
487
488 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
489 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
490 }
491
492 delete[] mData; mData = NULL;
493 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
494
495 ALOGV("processDrmInfo - Exit");
496 return drmInfoStatus;
497 }
498
android_drm_DrmManagerClient_acquireDrmInfo(JNIEnv * env,jobject thiz,jint uniqueId,jobject drmInfoRequest)499 static jobject android_drm_DrmManagerClient_acquireDrmInfo(
500 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
501 ALOGV("acquireDrmInfo Enter");
502 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);
525 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
526
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
565 ALOGV("acquireDrmInfo Exit");
566 return drmInfoObject;
567 }
568
android_drm_DrmManagerClient_getDrmObjectType(JNIEnv * env,jobject thiz,jint uniqueId,jstring path,jstring mimeType)569 static jint android_drm_DrmManagerClient_getDrmObjectType(
570 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
571 ALOGV("getDrmObjectType Enter");
572 int drmObjectType
573 = getDrmManagerClientImpl(env, thiz)
574 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
575 Utility::getStringValue(env, mimeType));
576 ALOGV("getDrmObjectType Exit");
577 return drmObjectType;
578 }
579
android_drm_DrmManagerClient_getOriginalMimeType(JNIEnv * env,jobject thiz,jint uniqueId,jstring path)580 static jstring android_drm_DrmManagerClient_getOriginalMimeType(
581 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
582 ALOGV("getOriginalMimeType Enter");
583 String8 mimeType
584 = getDrmManagerClientImpl(env, thiz)
585 ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
586 ALOGV("getOriginalMimeType Exit");
587 return env->NewStringUTF(mimeType.string());
588 }
589
android_drm_DrmManagerClient_checkRightsStatus(JNIEnv * env,jobject thiz,jint uniqueId,jstring path,int action)590 static jint android_drm_DrmManagerClient_checkRightsStatus(
591 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
592 ALOGV("getOriginalMimeType Enter");
593 int rightsStatus
594 = getDrmManagerClientImpl(env, thiz)
595 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
596 ALOGV("getOriginalMimeType Exit");
597 return rightsStatus;
598 }
599
android_drm_DrmManagerClient_removeRights(JNIEnv * env,jobject thiz,jint uniqueId,jstring path)600 static jint android_drm_DrmManagerClient_removeRights(
601 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
602 ALOGV("removeRights");
603 return getDrmManagerClientImpl(env, thiz)
604 ->removeRights(uniqueId, Utility::getStringValue(env, path));
605 }
606
android_drm_DrmManagerClient_removeAllRights(JNIEnv * env,jobject thiz,jint uniqueId)607 static jint android_drm_DrmManagerClient_removeAllRights(
608 JNIEnv* env, jobject thiz, jint uniqueId) {
609 ALOGV("removeAllRights");
610 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
611 }
612
android_drm_DrmManagerClient_openConvertSession(JNIEnv * env,jobject thiz,jint uniqueId,jstring mimeType)613 static jint android_drm_DrmManagerClient_openConvertSession(
614 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
615 ALOGV("openConvertSession Enter");
616 int convertId
617 = getDrmManagerClientImpl(env, thiz)
618 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
619 ALOGV("openConvertSession Exit");
620 return convertId;
621 }
622
GetConvertedStatus(JNIEnv * env,DrmConvertedStatus * pDrmConvertedStatus)623 static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) {
624 ALOGV("GetConvertedStatus - Enter");
625 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
626
627 jobject drmConvertedStatus = NULL;
628
629 if (NULL != localRef && NULL != pDrmConvertedStatus) {
630 int statusCode = pDrmConvertedStatus->statusCode;
631
632 jbyteArray dataArray = NULL;
633 if (NULL != pDrmConvertedStatus->convertedData) {
634 int length = pDrmConvertedStatus->convertedData->length;
635 dataArray = env->NewByteArray(length);
636 env->SetByteArrayRegion(
637 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
638
639 delete [] pDrmConvertedStatus->convertedData->data;
640 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
641 }
642 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
643 drmConvertedStatus
644 = env->NewObject(localRef, constructorId,
645 statusCode, dataArray, pDrmConvertedStatus->offset);
646 }
647
648 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
649
650 ALOGV("GetConvertedStatus - Exit");
651 return drmConvertedStatus;
652 }
653
android_drm_DrmManagerClient_convertData(JNIEnv * env,jobject thiz,jint uniqueId,jint convertId,jbyteArray inputData)654 static jobject android_drm_DrmManagerClient_convertData(
655 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
656 ALOGV("convertData Enter");
657
658 int dataLength = 0;
659 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
660 const DrmBuffer buffer(mData, dataLength);
661
662 DrmConvertedStatus* pDrmConvertedStatus
663 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
664 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
665
666 delete[] mData;
667 mData = NULL;
668
669 ALOGV("convertData - Exit");
670 return status;
671 }
672
android_drm_DrmManagerClient_closeConvertSession(JNIEnv * env,jobject thiz,int uniqueId,jint convertId)673 static jobject android_drm_DrmManagerClient_closeConvertSession(
674 JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
675
676 ALOGV("closeConvertSession Enter");
677
678 DrmConvertedStatus* pDrmConvertedStatus
679 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
680 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
681
682 ALOGV("closeConvertSession - Exit");
683 return status;
684 }
685
686 static JNINativeMethod nativeMethods[] = {
687
688 {"_initialize", "()I",
689 (void*)android_drm_DrmManagerClient_initialize},
690
691 {"_setListeners", "(ILjava/lang/Object;)V",
692 (void*)android_drm_DrmManagerClient_setListeners},
693
694 {"_release", "(I)V",
695 (void*)android_drm_DrmManagerClient_release},
696
697 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
698 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
699
700 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
701 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
702
703 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
704 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
705
706 {"_installDrmEngine", "(ILjava/lang/String;)V",
707 (void*)android_drm_DrmManagerClient_installDrmEngine},
708
709 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
710 (void*)android_drm_DrmManagerClient_canHandle},
711
712 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
713 (void*)android_drm_DrmManagerClient_processDrmInfo},
714
715 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
716 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
717
718 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
719 (void*)android_drm_DrmManagerClient_saveRights},
720
721 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
722 (void*)android_drm_DrmManagerClient_getDrmObjectType},
723
724 {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
725 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
726
727 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
728 (void*)android_drm_DrmManagerClient_checkRightsStatus},
729
730 {"_removeRights", "(ILjava/lang/String;)I",
731 (void*)android_drm_DrmManagerClient_removeRights},
732
733 {"_removeAllRights", "(I)I",
734 (void*)android_drm_DrmManagerClient_removeAllRights},
735
736 {"_openConvertSession", "(ILjava/lang/String;)I",
737 (void*)android_drm_DrmManagerClient_openConvertSession},
738
739 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
740 (void*)android_drm_DrmManagerClient_convertData},
741
742 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
743 (void*)android_drm_DrmManagerClient_closeConvertSession},
744 };
745
registerNativeMethods(JNIEnv * env)746 static int registerNativeMethods(JNIEnv* env) {
747 int result = -1;
748
749 /* look up the class */
750 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
751
752 if (NULL != clazz) {
753 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
754 / sizeof(nativeMethods[0])) == JNI_OK) {
755 result = 0;
756 }
757 }
758 return result;
759 }
760
JNI_OnLoad(JavaVM * vm,void * reserved)761 jint JNI_OnLoad(JavaVM* vm, void* reserved) {
762 JNIEnv* env = NULL;
763 jint result = -1;
764
765 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
766 if (NULL != env && registerNativeMethods(env) == 0) {
767 result = JNI_VERSION_1_4;
768 }
769 }
770 return result;
771 }
772
773