2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * This file implement the Java Native Interface
21 * for supporting OMA DRM 1.0
24 #include <jni/drm1_jni.h>
25 #include <objmng/svc_drm.h>
29 #define MS_PER_SECOND 1000 /* Milliseconds per second */
30 #define MS_PER_MINUTE 60 * MS_PER_SECOND /* Milliseconds per minute */
31 #define MS_PER_HOUR 60 * MS_PER_MINUTE /* Milliseconds per hour */
32 #define MS_PER_DAY 24 * MS_PER_HOUR /* Milliseconds per day */
34 #define SECONDS_PER_MINUTE 60 /* Seconds per minute*/
35 #define SECONDS_PER_HOUR 60 * SECONDS_PER_MINUTE /* Seconds per hour */
36 #define SECONDS_PER_DAY 24 * SECONDS_PER_HOUR /* Seconds per day */
38 #define DAY_PER_MONTH 30 /* Days per month */
39 #define DAY_PER_YEAR 365 /* Days per year */
41 /** Nonzero if 'y' is a leap year, else zero. */
42 #define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
44 /** Number of leap years from 1970 to 'y' (not including 'y' itself). */
45 #define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
47 /** Accumulated number of days from 01-Jan up to start of current month. */
48 static const int32_t ydays[] = {
49 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
52 #define int64_const(s) (s)
53 #define int64_add(dst, s1, s2) ((void)((dst) = (s1) + (s2)))
54 #define int64_mul(dst, s1, s2) ((void)((dst) = (int64_t)(s1) * (int64_t)(s2)))
59 typedef struct _DrmData {
61 * The id of the DRM content.
66 * The pointer of JNI interface.
71 * The pointer of DRM raw content InputStream object.
76 * The len of the InputStream object.
83 struct _DrmData *next;
86 /** The table to hold all the DRM data. */
87 static DrmData *drmTable = NULL;
90 * Allocate a new item of DrmData.
92 * \return a pointer to a DrmData item if allocate successfully,
93 * otherwise return NULL
95 static DrmData * newItem(void)
97 DrmData *d = (DrmData *)malloc(sizeof(DrmData));
108 * Free the memory of the specified DrmData item <code>d</code>.
110 * \param d - a pointer to DrmData
112 static void freeItem(DrmData *d)
120 * Insert a DrmData item with given <code>name</code> into the head of
123 * @param d - the pointer of the JNI interface
124 * @param pInData - the pointer of the DRM content InputStream object.
126 * @return <code>JNI_DRM_SUCCESS</code> if insert successfully, otherwise
127 * return <code>JNI_DRM_FAILURE</code>
129 static int32_t addItem(DrmData* d)
132 return JNI_DRM_FAILURE;
134 if (NULL == drmTable) {
136 return JNI_DRM_SUCCESS;
142 return JNI_DRM_SUCCESS;
146 * Get the item from the DrmData list by the specified <code>
149 * @param p - the pointer of the DRM content InputStream object.
151 * @return a pointer to the DrmData item if find it successfuly,
152 * otherwise return NULL
154 static DrmData * getItem(int32_t id)
158 if (NULL == drmTable)
161 for (d = drmTable; d != NULL; d = d->next) {
170 * Remove the specified DrmData item <code>d</code>.
172 * @param p - the pointer of the DRM content InputStream object.
174 * @return <code>JNI_DRM_SUCCESS</code> if remove successfuly,
175 * otherwise return <code>JNI_DRM_FAILURE</code>
177 static int32_t removeItem(int32_t id)
179 DrmData *curItem, *preItem, *dstItem;
181 if (NULL == drmTable)
182 return JNI_DRM_FAILURE;
185 for (curItem = drmTable; curItem != NULL; curItem = curItem->next) {
186 if (id == curItem->id) {
187 if (curItem == drmTable)
188 drmTable = curItem->next;
190 preItem->next = curItem->next;
194 return JNI_DRM_SUCCESS;
200 return JNI_DRM_FAILURE;
204 static int32_t getInputStreamDataLength(int32_t handle)
207 jobject* pInputStream;
213 p = (DrmData *)handle;
219 pInputStream = p->pInData;
222 if (NULL == env || p->len <= 0 || NULL == pInputStream)
225 /* check the original InputStream is available or not */
226 cls = (*env)->GetObjectClass(env, *pInputStream);
227 mid = (*env)->GetMethodID(env, cls, "available", "()I");
228 (*env)->DeleteLocalRef(env, cls);
233 if (0 > (*env)->CallIntMethod(env, *pInputStream, mid))
239 static int32_t readInputStreamData(int32_t handle, uint8_t* buf, int32_t bufLen)
242 jobject* pInputStream;
251 p = (DrmData *)handle;
253 if (NULL == p || NULL == buf || bufLen <- 0)
257 pInputStream = p->pInData;
260 if (NULL == env || p->len <= 0 || NULL == pInputStream)
263 cls = (*env)->GetObjectClass(env, *pInputStream);
264 mid = (*env)->GetMethodID(env, cls, "read", "([BII)I");
265 tmp = (*env)->NewByteArray(env, bufLen);
266 bufLen = (*env)->CallIntMethod(env, *pInputStream, mid, tmp, 0, bufLen);
268 (*env)->DeleteLocalRef(env, cls);
273 pNativeBuf = (*env)->GetByteArrayElements(env, tmp, NULL);
274 memcpy(buf, pNativeBuf, bufLen);
275 (*env)->ReleaseByteArrayElements(env, tmp, pNativeBuf, 0);
276 (*env)->DeleteLocalRef(env, tmp);
281 static const T_DRM_Rights_Info_Node *searchRightsObject(const jbyte* roId, const T_DRM_Rights_Info_Node* pRightsList)
283 const T_DRM_Rights_Info_Node *pTmp;
285 if (NULL == roId || NULL == pRightsList)
290 while (NULL != pTmp) {
291 if(0 == strcmp((char *)roId, (char *)pTmp->roInfo.roId))
300 * Returns the difference in seconds between the given GMT time
301 * and 1970-01-01 00:00:00 GMT.
303 * \param year the year (since 1970)
304 * \param month the month (1 - 12)
305 * \param day the day (1 - 31)
306 * \param hour the hour (0 - 23)
307 * \param minute the minute (0 - 59)
308 * \param second the second (0 - 59)
310 * \return the difference in seconds between the given GMT time
311 * and 1970-01-01 00:00:00 GMT.
313 static int64_t mkgmtime(
314 uint32_t year, uint32_t month, uint32_t day,
315 uint32_t hour, uint32_t minute, uint32_t second)
320 * FIXME: It does not check whether the specified days
321 * is valid based on the specified months.
324 && month > 0 && month <= 12
325 && day > 0 && day <= 31
326 && hour < 24 && minute < 60
329 /* Set 'day' to the number of days into the year. */
330 day += ydays[month - 1] + (month > 2 && leap (year)) - 1;
332 /* Now calculate 'day' to the number of days since Jan 1, 1970. */
333 day = day + 365 * (year - 1970) + nleap(year);
335 int64_mul(result, int64_const(day), int64_const(SECONDS_PER_DAY));
336 int64_add(result, result, int64_const(
337 SECONDS_PER_HOUR * hour + SECONDS_PER_MINUTE * minute + second));
343 * Compute the milliseconds by the specified <code>date</code>
344 * and <code>time</code>.
346 * @param date - the specified date,
347 * <code>date = year * 10000 + month * 100 + day</code>
348 * @param time - the specified time,
349 * <code>time = hour * 10000 + minute * 100 + second</code>
351 * @return the related milliseconds
353 static int64_t computeTime(int32_t date, int32_t time)
355 int32_t year, month, day, hour, minute, second;
358 month = (date / 100) % 100;
361 minute = (time / 100) % 100;
364 /* Adjust the invalid parameters. */
365 if (year < 1970) year = 1970;
366 if (month < 1) month = 1;
367 if (month > 12) month = 12;
368 if (day < 1) day = 1;
369 if (day > 31) day = 31;
370 if (hour < 0) hour = 0;
371 if (hour > 23) hour = 23;
372 if (minute < 0) minute = 0;
373 if (minute > 59) minute = 59;
374 if (second < 0) second = 0;
375 if (second > 59) second = 59;
377 return mkgmtime(year, month, day, hour, minute, second) * 1000;
381 * Compute the milliseconds by the specified <code>date</code>
382 * and <code>time</code>.
383 * Note that here we always treat 1 year as 365 days and 1 month as 30 days
384 * that is not precise. But it should not be a problem since OMA DRM 2.0
385 * already restricts the interval representation to be day-based,
386 * i.e. there will not be an interval with year or month any more in the
389 * @param date - the specified date,
390 * <code>date = year * 10000 + month * 100 + day</code>
391 * @param time - the specified time,
392 * <code>time = hour * 10000 + minute * 100 + second</code>
394 * @return the related milliseconds
396 static int64_t computeInterval(int32_t date, int32_t time)
398 int32_t year, month, day, hour, minute, second;
399 int64_t milliseconds;
402 month = (date / 100) % 100;
405 minute = (time / 100) % 100;
408 /* milliseconds = ((((year * 365 + month * 30 + day) * 24
409 * + hour) * 60 + minute) * 60 + second) * 1000;
411 int64_mul(milliseconds,
412 int64_const(year * DAY_PER_YEAR + month * DAY_PER_MONTH + day),
413 int64_const(MS_PER_DAY));
414 int64_add(milliseconds, milliseconds,
415 int64_const(hour * MS_PER_HOUR + minute * MS_PER_MINUTE +
416 second * MS_PER_SECOND));
421 static jint getObjectIntField(JNIEnv * env, jobject obj, const char *name, jint * value)
426 clazz = (*env)->GetObjectClass(env, obj);
428 return JNI_DRM_FAILURE;
430 field = (*env)->GetFieldID(env, clazz, name, "I");
431 (*env)->DeleteLocalRef(env, clazz);
434 return JNI_DRM_FAILURE;
436 *value = (*env)->GetIntField(env, obj, field);
438 return JNI_DRM_SUCCESS;
441 static jint setObjectIntField(JNIEnv * env, jobject obj, const char *name, jint value)
446 clazz = (*env)->GetObjectClass(env, obj);
448 return JNI_DRM_FAILURE;
450 field = (*env)->GetFieldID(env, clazz, name, "I");
451 (*env)->DeleteLocalRef(env, clazz);
454 return JNI_DRM_FAILURE;
456 (*env)->SetIntField(env, obj, field, value);
458 return JNI_DRM_SUCCESS;
461 static jint setObjectLongField(JNIEnv * env, jobject obj, const char *name, jlong value)
466 clazz = (*env)->GetObjectClass(env, obj);
468 return JNI_DRM_FAILURE;
470 field = (*env)->GetFieldID(env, clazz, name, "J");
471 (*env)->DeleteLocalRef(env, clazz);
474 return JNI_DRM_FAILURE;
476 (*env)->SetLongField(env, obj, field, value);
478 return JNI_DRM_SUCCESS;
481 static jint setConstraintFields(JNIEnv * env, jobject constraint, T_DRM_Constraint_Info * pConstraint)
483 /* if no this permission */
484 if (pConstraint->indicator == (uint8_t)DRM_NO_RIGHTS) {
485 if (JNI_DRM_FAILURE == setObjectIntField(env, constraint, "count", 0))
486 return JNI_DRM_FAILURE;
488 return JNI_DRM_SUCCESS;
491 /* set count field */
492 if (pConstraint->indicator & DRM_COUNT_CONSTRAINT) {
493 if (JNI_DRM_FAILURE == setObjectIntField(env, constraint, "count", pConstraint->count))
494 return JNI_DRM_FAILURE;
497 /* set start time field */
498 if (pConstraint->indicator & DRM_START_TIME_CONSTRAINT) {
501 startTime = computeTime(pConstraint->startDate, pConstraint->startTime);
503 if (JNI_DRM_FAILURE == setObjectLongField(env, constraint, "startDate", startTime))
504 return JNI_DRM_FAILURE;
507 /* set end time field */
508 if (pConstraint->indicator & DRM_END_TIME_CONSTRAINT) {
511 endTime = computeTime(pConstraint->endDate, pConstraint->endTime);
513 if (JNI_DRM_FAILURE == setObjectLongField(env, constraint, "endDate", endTime))
514 return JNI_DRM_FAILURE;
517 /* set interval field */
518 if (pConstraint->indicator & DRM_INTERVAL_CONSTRAINT) {
521 interval = computeInterval(pConstraint->intervalDate, pConstraint->intervalTime);
523 if (JNI_DRM_FAILURE == setObjectLongField(env, constraint, "interval", interval))
524 return JNI_DRM_FAILURE;
527 return JNI_DRM_SUCCESS;
530 static jint setRightsFields(JNIEnv * env, jobject rights, T_DRM_Rights_Info* pRoInfo)
537 clazz = (*env)->GetObjectClass(env, rights);
539 return JNI_DRM_FAILURE;
542 field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
543 (*env)->DeleteLocalRef(env, clazz);
546 return JNI_DRM_FAILURE;
548 str = (*env)->NewStringUTF(env, (char *)pRoInfo->roId);
550 return JNI_DRM_FAILURE;
552 (*env)->SetObjectField(env, rights, field, str);
553 (*env)->DeleteLocalRef(env, str);
555 return JNI_DRM_SUCCESS;
558 /* native interface */
559 JNIEXPORT jint JNICALL
560 Java_android_drm_mobile1_DrmRawContent_nativeConstructDrmContent
561 (JNIEnv * env, jobject rawContent, jobject data, jint len, jint mimeType)
564 T_DRM_Input_Data inData;
568 case JNI_DRM_MIMETYPE_MESSAGE:
569 mimeType = TYPE_DRM_MESSAGE;
571 case JNI_DRM_MIMETYPE_CONTENT:
572 mimeType = TYPE_DRM_CONTENT;
575 return JNI_DRM_FAILURE;
578 drmInData = newItem();
579 if (NULL == drmInData)
580 return JNI_DRM_FAILURE;
582 drmInData->env = env;
583 drmInData->pInData = &data;
584 drmInData->len = len;
586 if (JNI_DRM_FAILURE == addItem(drmInData))
587 return JNI_DRM_FAILURE;
589 inData.inputHandle = (int32_t)drmInData;
590 inData.mimeType = mimeType;
591 inData.getInputDataLength = getInputStreamDataLength;
592 inData.readInputData = readInputStreamData;
594 id = SVC_drm_openSession(inData);
596 return JNI_DRM_FAILURE;
603 /* native interface */
604 JNIEXPORT jstring JNICALL
605 Java_android_drm_mobile1_DrmRawContent_nativeGetRightsAddress
606 (JNIEnv * env, jobject rawContent)
609 uint8_t rightsIssuer[256] = {0};
612 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
615 if (DRM_SUCCESS == SVC_drm_getRightsIssuer(id, rightsIssuer))
616 str = (*env)->NewStringUTF(env, (char *)rightsIssuer);
621 /* native interface */
622 JNIEXPORT jint JNICALL
623 Java_android_drm_mobile1_DrmRawContent_nativeGetDeliveryMethod
624 (JNIEnv * env, jobject rawContent)
629 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
630 return JNI_DRM_FAILURE;
632 res = SVC_drm_getDeliveryMethod(id);
636 return JNI_DRM_FORWARD_LOCK;
637 case COMBINED_DELIVERY:
638 return JNI_DRM_COMBINED_DELIVERY;
639 case SEPARATE_DELIVERY:
640 return JNI_DRM_SEPARATE_DELIVERY;
641 case SEPARATE_DELIVERY_FL:
642 return JNI_DRM_SEPARATE_DELIVERY_DM;
644 return JNI_DRM_FAILURE;
648 /* native interface */
649 JNIEXPORT jint JNICALL
650 Java_android_drm_mobile1_DrmRawContent_nativeReadContent
651 (JNIEnv * env, jobject rawContent, jbyteArray buf, jint bufOff, jint len, jint mediaOff)
662 jclass newExcCls = (*env)->FindClass(env, "java/lang/NullPointerException");
664 if (newExcCls == NULL)
665 /* Unable to find the exception class, give up. */
666 return JNI_DRM_FAILURE;
668 (*env)->ThrowNew(env, newExcCls, "b is null");
671 if (len < 0 || bufOff < 0 || len + bufOff > (*env)->GetArrayLength(env, buf)) {
672 jclass newExcCls = (*env)->FindClass(env, "java/lang/IndexOutOfBoundsException");
674 if (newExcCls == NULL)
675 /* Unable to find the exception class, give up. */
676 return JNI_DRM_FAILURE;
678 (*env)->ThrowNew(env, newExcCls, NULL);
681 if (mediaOff < 0 || len == 0)
682 return JNI_DRM_FAILURE;
684 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
685 return JNI_DRM_FAILURE;
689 return JNI_DRM_FAILURE;
691 cls = (*env)->GetObjectClass(env, rawContent);
693 return JNI_DRM_FAILURE;
695 field = (*env)->GetFieldID(env, cls, "inData", "Ljava/io/BufferedInputStream;");
696 (*env)->DeleteLocalRef(env, cls);
699 return JNI_DRM_FAILURE;
701 inputStream = (*env)->GetObjectField(env, rawContent, field);
704 p->pInData = &inputStream;
706 nativeBuf = (*env)->GetByteArrayElements(env, buf, NULL);
708 len = SVC_drm_getContent(id, mediaOff, (uint8_t *)nativeBuf + bufOff, len);
710 (*env)->ReleaseByteArrayElements(env, buf, nativeBuf, 0);
712 if (DRM_MEDIA_EOF == len)
715 return JNI_DRM_FAILURE;
720 /* native interface */
721 JNIEXPORT jstring JNICALL
722 Java_android_drm_mobile1_DrmRawContent_nativeGetContentType
723 (JNIEnv * env, jobject rawContent)
726 uint8_t contentType[64] = {0};
729 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
732 if (DRM_SUCCESS == SVC_drm_getContentType(id, contentType))
733 str = (*env)->NewStringUTF(env, (char *)contentType);
738 /* native interface */
739 JNIEXPORT jint JNICALL
740 Java_android_drm_mobile1_DrmRawContent_nativeGetContentLength
741 (JNIEnv * env, jobject rawContent)
746 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
747 return JNI_DRM_FAILURE;
749 len = SVC_drm_getContentLength(id);
751 if (DRM_UNKNOWN_DATA_LEN == len)
752 return JNI_DRM_UNKNOWN_DATA_LEN;
755 return JNI_DRM_FAILURE;
760 /* native interface */
761 JNIEXPORT void JNICALL
762 Java_android_drm_mobile1_DrmRawContent_finalize
763 (JNIEnv * env, jobject rawContent)
767 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
772 SVC_drm_closeSession(id);
775 /* native interface */
776 JNIEXPORT jint JNICALL
777 Java_android_drm_mobile1_DrmRights_nativeGetConstraintInfo
778 (JNIEnv * env, jobject rights, jint permission, jobject constraint)
784 T_DRM_Rights_Info_Node *pRightsList;
785 T_DRM_Rights_Info_Node *pCurNode;
786 T_DRM_Constraint_Info *pConstraint;
788 clazz = (*env)->GetObjectClass(env, rights);
790 return JNI_DRM_FAILURE;
792 field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
793 (*env)->DeleteLocalRef(env, clazz);
796 return JNI_DRM_FAILURE;
798 str = (*env)->GetObjectField(env, rights, field);
800 nativeStr = (uint8_t *)(*env)->GetStringUTFChars(env, str, NULL);
801 if (NULL == nativeStr)
802 return JNI_DRM_FAILURE;
804 /* this means forward-lock rights */
805 if (0 == strcmp((char *)nativeStr, "ForwardLock")) {
806 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
807 return JNI_DRM_SUCCESS;
810 if (DRM_FAILURE == SVC_drm_viewAllRights(&pRightsList)) {
811 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
812 return JNI_DRM_FAILURE;
815 pCurNode = searchRightsObject((jbyte *)nativeStr, pRightsList);
816 if (NULL == pCurNode) {
817 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
818 SVC_drm_freeRightsInfoList(pRightsList);
819 return JNI_DRM_FAILURE;
821 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
823 switch (permission) {
824 case JNI_DRM_PERMISSION_PLAY:
825 pConstraint = &(pCurNode->roInfo.playRights);
827 case JNI_DRM_PERMISSION_DISPLAY:
828 pConstraint = &(pCurNode->roInfo.displayRights);
830 case JNI_DRM_PERMISSION_EXECUTE:
831 pConstraint = &(pCurNode->roInfo.executeRights);
833 case JNI_DRM_PERMISSION_PRINT:
834 pConstraint = &(pCurNode->roInfo.printRights);
837 SVC_drm_freeRightsInfoList(pRightsList);
838 return JNI_DRM_FAILURE;
841 /* set constraint field */
842 if (JNI_DRM_FAILURE == setConstraintFields(env, constraint, pConstraint)) {
843 SVC_drm_freeRightsInfoList(pRightsList);
844 return JNI_DRM_FAILURE;
847 SVC_drm_freeRightsInfoList(pRightsList);
849 return JNI_DRM_SUCCESS;
852 /* native interface */
853 JNIEXPORT jint JNICALL
854 Java_android_drm_mobile1_DrmRights_nativeConsumeRights
855 (JNIEnv * env, jobject rights, jint permission)
863 switch (permission) {
864 case JNI_DRM_PERMISSION_PLAY:
865 permission = DRM_PERMISSION_PLAY;
867 case JNI_DRM_PERMISSION_DISPLAY:
868 permission = DRM_PERMISSION_DISPLAY;
870 case JNI_DRM_PERMISSION_EXECUTE:
871 permission = DRM_PERMISSION_EXECUTE;
873 case JNI_DRM_PERMISSION_PRINT:
874 permission = DRM_PERMISSION_PRINT;
877 return JNI_DRM_FAILURE;
880 clazz = (*env)->GetObjectClass(env, rights);
882 return JNI_DRM_FAILURE;
884 field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
885 (*env)->DeleteLocalRef(env, clazz);
888 return JNI_DRM_FAILURE;
890 str = (*env)->GetObjectField(env, rights, field);
892 nativeStr = (uint8_t *)(*env)->GetStringUTFChars(env, str, NULL);
893 if (NULL == nativeStr)
894 return JNI_DRM_FAILURE;
896 if (0 == strcmp("ForwardLock", (char *)nativeStr)) {
897 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
898 return JNI_DRM_SUCCESS;
901 if (DRM_SUCCESS != SVC_drm_updateRights(nativeStr, permission)) {
902 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
903 return JNI_DRM_FAILURE;
906 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
908 return JNI_DRM_SUCCESS;
911 /* native interface */
912 JNIEXPORT jint JNICALL
913 Java_android_drm_mobile1_DrmRightsManager_nativeInstallDrmRights
914 (JNIEnv * env, jobject rightsManager, jobject data, jint len, jint mimeType, jobject rights)
917 T_DRM_Input_Data inData;
921 T_DRM_Rights_Info rightsInfo;
924 case JNI_DRM_MIMETYPE_RIGHTS_XML:
925 mimeType = TYPE_DRM_RIGHTS_XML;
927 case JNI_DRM_MIMETYPE_RIGHTS_WBXML:
928 mimeType = TYPE_DRM_RIGHTS_WBXML;
930 case JNI_DRM_MIMETYPE_MESSAGE:
931 mimeType = TYPE_DRM_MESSAGE;
934 return JNI_DRM_FAILURE;
937 drmInData = newItem();
938 if (NULL == drmInData)
939 return JNI_DRM_FAILURE;
941 drmInData->env = env;
942 drmInData->pInData = &data;
943 drmInData->len = len;
945 inData.inputHandle = (int32_t)drmInData;
946 inData.mimeType = mimeType;
947 inData.getInputDataLength = getInputStreamDataLength;
948 inData.readInputData = readInputStreamData;
950 memset(&rightsInfo, 0, sizeof(T_DRM_Rights_Info));
951 if (DRM_FAILURE == SVC_drm_installRights(inData, &rightsInfo))
952 return JNI_DRM_FAILURE;
956 return setRightsFields(env, rights, &rightsInfo);
959 /* native interface */
960 JNIEXPORT jint JNICALL
961 Java_android_drm_mobile1_DrmRightsManager_nativeQueryRights
962 (JNIEnv * env, jobject rightsManager, jobject rawContent, jobject rights)
965 T_DRM_Rights_Info rightsInfo;
967 if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
968 return JNI_DRM_FAILURE;
970 memset(&rightsInfo, 0, sizeof(T_DRM_Rights_Info));
971 if (DRM_SUCCESS != SVC_drm_getRightsInfo(id, &rightsInfo))
972 return JNI_DRM_FAILURE;
974 return setRightsFields(env, rights, &rightsInfo);
977 /* native interface */
978 JNIEXPORT jint JNICALL
979 Java_android_drm_mobile1_DrmRightsManager_nativeGetNumOfRights
980 (JNIEnv * env, jobject rightsManager)
982 T_DRM_Rights_Info_Node *pRightsList;
983 T_DRM_Rights_Info_Node *pCurNode;
986 if (DRM_FAILURE == SVC_drm_viewAllRights(&pRightsList))
987 return JNI_DRM_FAILURE;
989 pCurNode = pRightsList;
990 while (pCurNode != NULL) {
992 pCurNode = pCurNode->next;
995 SVC_drm_freeRightsInfoList(pRightsList);
1000 /* native interface */
1001 JNIEXPORT jint JNICALL
1002 Java_android_drm_mobile1_DrmRightsManager_nativeGetRightsList
1003 (JNIEnv * env, jobject rightsManager, jobjectArray rightsArray, jint num)
1005 T_DRM_Rights_Info_Node *pRightsList;
1006 T_DRM_Rights_Info_Node *pCurNode;
1009 if (DRM_FAILURE == SVC_drm_viewAllRights(&pRightsList))
1010 return JNI_DRM_FAILURE;
1012 pCurNode = pRightsList;
1013 for (index = 0; NULL != pCurNode; index++) {
1014 jobject rights = (*env)->GetObjectArrayElement(env, rightsArray, index);
1018 if (JNI_DRM_FAILURE == setRightsFields(env, rights, &(pCurNode->roInfo)))
1021 (*env)->SetObjectArrayElement(env, rightsArray, index, rights);
1023 pCurNode = pCurNode->next;
1026 SVC_drm_freeRightsInfoList(pRightsList);
1031 /* native interface */
1032 JNIEXPORT jint JNICALL
1033 Java_android_drm_mobile1_DrmRightsManager_nativeDeleteRights
1034 (JNIEnv * env, jobject rightsManager, jobject rights)
1041 clazz = (*env)->GetObjectClass(env, rights);
1043 return JNI_DRM_FAILURE;
1045 field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
1047 return JNI_DRM_FAILURE;
1049 str = (*env)->GetObjectField(env, rights, field);
1051 nativeStr = (uint8_t *)(*env)->GetStringUTFChars(env, str, NULL);
1052 if (NULL == nativeStr)
1053 return JNI_DRM_FAILURE;
1055 if (0 == strcmp("ForwardLock", (char *)nativeStr))
1056 return JNI_DRM_SUCCESS;
1058 if (DRM_SUCCESS != SVC_drm_deleteRights(nativeStr)) {
1059 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
1060 return JNI_DRM_FAILURE;
1063 (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
1064 return JNI_DRM_SUCCESS;
1068 * Table of methods associated with the DrmRawContent class.
1070 static JNINativeMethod gDrmRawContentMethods[] = {
1071 /* name, signature, funcPtr */
1072 {"nativeConstructDrmContent", "(Ljava/io/InputStream;II)I",
1073 (void*)Java_android_drm_mobile1_DrmRawContent_nativeConstructDrmContent},
1074 {"nativeGetRightsAddress", "()Ljava/lang/String;",
1075 (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetRightsAddress},
1076 {"nativeGetDeliveryMethod", "()I",
1077 (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetDeliveryMethod},
1078 {"nativeReadContent", "([BIII)I",
1079 (void*)Java_android_drm_mobile1_DrmRawContent_nativeReadContent},
1080 {"nativeGetContentType", "()Ljava/lang/String;",
1081 (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetContentType},
1082 {"nativeGetContentLength", "()I",
1083 (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetContentLength},
1085 (void*)Java_android_drm_mobile1_DrmRawContent_finalize},
1089 * Table of methods associated with the DrmRights class.
1091 static JNINativeMethod gDrmRightsMethods[] = {
1092 /* name, signature, funcPtr */
1093 {"nativeGetConstraintInfo", "(ILandroid/drm/mobile1/DrmConstraintInfo;)I",
1094 (void*)Java_android_drm_mobile1_DrmRights_nativeGetConstraintInfo},
1095 {"nativeConsumeRights", "(I)I",
1096 (void*)Java_android_drm_mobile1_DrmRights_nativeConsumeRights},
1100 * Table of methods associated with the DrmRightsManager class.
1102 static JNINativeMethod gDrmRightsManagerMethods[] = {
1103 /* name, signature, funcPtr */
1104 {"nativeInstallDrmRights", "(Ljava/io/InputStream;IILandroid/drm/mobile1/DrmRights;)I",
1105 (void*)Java_android_drm_mobile1_DrmRightsManager_nativeInstallDrmRights},
1106 {"nativeQueryRights", "(Landroid/drm/mobile1/DrmRawContent;Landroid/drm/mobile1/DrmRights;)I",
1107 (void*)Java_android_drm_mobile1_DrmRightsManager_nativeQueryRights},
1108 {"nativeGetNumOfRights", "()I",
1109 (void*)Java_android_drm_mobile1_DrmRightsManager_nativeGetNumOfRights},
1110 {"nativeGetRightsList", "([Landroid/drm/mobile1/DrmRights;I)I",
1111 (void*)Java_android_drm_mobile1_DrmRightsManager_nativeGetRightsList},
1112 {"nativeDeleteRights", "(Landroid/drm/mobile1/DrmRights;)I",
1113 (void*)Java_android_drm_mobile1_DrmRightsManager_nativeDeleteRights},
1117 * Register several native methods for one class.
1119 static int registerNativeMethods(JNIEnv* env, const char* className,
1120 JNINativeMethod* gMethods, int numMethods)
1124 clazz = (*env)->FindClass(env, className);
1128 if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0)
1135 * Register native methods for all classes we know about.
1137 static int registerNatives(JNIEnv* env)
1139 if (!registerNativeMethods(env, "android/drm/mobile1/DrmRawContent",
1140 gDrmRawContentMethods, sizeof(gDrmRawContentMethods) / sizeof(gDrmRawContentMethods[0])))
1143 if (!registerNativeMethods(env, "android/drm/mobile1/DrmRights",
1144 gDrmRightsMethods, sizeof(gDrmRightsMethods) / sizeof(gDrmRightsMethods[0])))
1147 if (!registerNativeMethods(env, "android/drm/mobile1/DrmRightsManager",
1148 gDrmRightsManagerMethods, sizeof(gDrmRightsManagerMethods) / sizeof(gDrmRightsManagerMethods[0])))
1154 jint JNI_OnLoad(JavaVM* vm, void* reserved)
1159 printf("Entering JNI_OnLoad\n");
1161 if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
1164 assert(env != NULL);
1166 if (!registerNatives(env))
1169 /* success -- return valid version number */
1170 result = JNI_VERSION_1_4;
1173 printf("Leaving JNI_OnLoad (result=0x%x)\n", result);