android_drm_DrmManagerClient.cpp revision dc549d60f98d809f626c99de614960409a847054
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 "DrmManager-JNI"
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/DrmConvertedStatus.h>
33#include <drm/drm_framework_common.h>
34
35#include <DrmManagerClientImpl.h>
36
37using namespace android;
38
39/**
40 * Utility class used to extract the value from the provided java object.
41 * May need to add some utility function to create java object.
42 */
43class Utility {
44public:
45    static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName);
46
47    static char* getByteArrayValue(
48            JNIEnv* env, jobject object, const char* fieldName, int* dataLength);
49
50    static char* getByteArrayValue(
51            JNIEnv* env, jbyteArray byteArray, int* dataLength);
52
53    static String8 getStringValue(JNIEnv* env, jstring string);
54
55    static int getIntValue(JNIEnv* env, jobject object, const char* fieldName);
56};
57
58String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
59    String8 dataString("");
60
61    /* Look for the instance field with the name fieldName */
62    jfieldID fieldID
63        = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");
64
65    if (NULL != fieldID) {
66        jstring valueString = (jstring) env->GetObjectField(object, fieldID);
67
68        if (NULL != valueString && valueString != env->NewStringUTF("")) {
69            char* bytes = const_cast< char* > (env->GetStringUTFChars(valueString, NULL));
70
71            const int length = strlen(bytes) + 1;
72            char *data = new char[length];
73            strncpy(data, bytes, length);
74            dataString = String8(data);
75
76            env->ReleaseStringUTFChars(valueString, bytes);
77            delete [] data; data = NULL;
78        } else {
79            LOGV("Failed to retrieve the data from the field %s", fieldName);
80        }
81    }
82    return dataString;
83}
84
85String8 Utility::getStringValue(JNIEnv* env, jstring string) {
86    String8 dataString("");
87
88    if (NULL != string && string != env->NewStringUTF("")) {
89        char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));
90
91        const int length = strlen(bytes) + 1;
92        char *data = new char[length];
93        strncpy(data, bytes, length);
94        dataString = String8(data);
95
96        env->ReleaseStringUTFChars(string, bytes);
97        delete [] data; data = NULL;
98    }
99    return dataString;
100}
101
102char* Utility::getByteArrayValue(
103            JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
104    char* data = NULL;
105    *dataLength = 0;
106
107    jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
108
109    if (NULL != fieldID) {
110        jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
111        if (NULL != byteArray) {
112            jint length = env->GetArrayLength(byteArray);
113
114            *dataLength = length;
115            if (0 < *dataLength) {
116                data = new char[length];
117                env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
118            }
119        }
120    }
121    return data;
122}
123
124char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {
125    char* data = NULL;
126    if (NULL != byteArray) {
127        jint length = env->GetArrayLength(byteArray);
128
129        *dataLength = length;
130        if (0 < *dataLength) {
131            data = new char[length];
132            env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
133        }
134    }
135    return data;
136}
137
138int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {
139    jfieldID fieldID;
140    int intValue = -1;
141
142    /* Get a reference to obj’s class */
143    jclass clazz = env->GetObjectClass(object);
144    /* Look for the instance field with the name fieldName */
145    fieldID = env->GetFieldID(clazz, fieldName , "I");
146
147    if (NULL != fieldID) {
148        intValue = (int) env->GetIntField(object, fieldID);
149    }
150
151    return intValue;
152}
153
154class JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
155public:
156    JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
157
158    virtual ~JNIOnInfoListener();
159    void onInfo(const DrmInfoEvent& event);
160
161private:
162    JNIOnInfoListener();
163    jclass mClass;
164    jobject mObject;
165};
166
167JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
168    jclass clazz = env->GetObjectClass(thiz);
169
170    if (clazz == NULL) {
171        LOGE("Can't find android/drm/DrmManagerClient");
172        jniThrowException(env, "java/lang/Exception", NULL);
173        return;
174    }
175    mClass = (jclass)env->NewGlobalRef(clazz);
176    mObject  = env->NewGlobalRef(weak_thiz);
177}
178
179JNIOnInfoListener::~JNIOnInfoListener() {
180    JNIEnv *env = AndroidRuntime::getJNIEnv();
181    env->DeleteGlobalRef(mObject);
182    env->DeleteGlobalRef(mClass);
183}
184
185void JNIOnInfoListener::onInfo(const DrmInfoEvent& event) {
186    jint uniqueId = event.getUniqueId();
187    jint type = event.getType();
188    JNIEnv *env = AndroidRuntime::getJNIEnv();
189    jstring message = env->NewStringUTF(event.getMessage().string());
190    LOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
191
192    env->CallStaticVoidMethod(
193            mClass,
194            env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
195            mObject, uniqueId, type, message);
196}
197
198static Mutex sLock;
199
200static sp<DrmManagerClientImpl> setDrmManagerClientImpl(
201            JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
202    Mutex::Autolock l(sLock);
203    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
204    jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
205
206    sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
207    if (client.get()) {
208        client->incStrong(thiz);
209    }
210    if (old != 0) {
211        old->decStrong(thiz);
212    }
213    env->SetIntField(thiz, fieldId, (int)client.get());
214    return old;
215}
216
217static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
218    Mutex::Autolock l(sLock);
219    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
220    jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
221
222    DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
223    return sp<DrmManagerClientImpl>(client);
224}
225
226static jint android_drm_DrmManagerClient_loadPlugIns(
227        JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
228    LOGV("load plugins - Enter");
229
230    sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId);
231
232    // Set the listener to DrmManager
233    sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
234    drmManager->setOnInfoListener(uniqueId, listener);
235
236    setDrmManagerClientImpl(env, thiz, drmManager);
237
238    LOGV("load plugins - Exit");
239    return getDrmManagerClientImpl(env, thiz)->loadPlugIns(uniqueId);
240}
241
242static jint android_drm_DrmManagerClient_unloadPlugIns(JNIEnv* env, jobject thiz, jint uniqueId) {
243    LOGV("unload plugins - Enter");
244    sp<DrmManagerClientImpl> client = getDrmManagerClientImpl(env, thiz);
245
246    DrmManagerClientImpl::remove(uniqueId);
247    int result = client->unloadPlugIns(uniqueId);
248    if (DRM_NO_ERROR == result) {
249        client->setOnInfoListener(uniqueId, NULL);
250
251        sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
252        if (oldClient != NULL) {
253            oldClient->setOnInfoListener(uniqueId, NULL);
254        }
255    }
256    LOGV("unload plugins - Exit");
257    return result;
258}
259
260static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
261            JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
262    LOGV("GetConstraints - Enter");
263
264    const String8 pathString = Utility::getStringValue(env, jpath);
265    DrmConstraints* pConstraints
266        = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
267
268    jclass localRef = env->FindClass("android/content/ContentValues");
269    jobject constraints = NULL;
270
271    if (NULL != localRef && NULL != pConstraints) {
272        // Get the constructor id
273        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
274        // create the java DrmConstraints object
275        constraints = env->NewObject(localRef, constructorId);
276
277        DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
278
279        while (keyIt.hasNext()) {
280            String8 key = keyIt.next();
281
282            // insert the entry<constraintKey, constraintValue> to newly created java object
283            if (DrmConstraints::EXTENDED_METADATA == key) {
284                const char* value = pConstraints->getAsByteArray(&key);
285                if (NULL != value) {
286                    jbyteArray dataArray = env->NewByteArray(strlen(value));
287                    env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
288                    env->CallVoidMethod(
289                        constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
290                                     env->NewStringUTF(key.string()), dataArray);
291                }
292            } else {
293                String8 value = pConstraints->get(key);
294                env->CallVoidMethod(
295                    constraints,
296                    env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
297                env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
298            }
299        }
300    }
301
302    delete pConstraints; pConstraints = NULL;
303    LOGV("GetConstraints - Exit");
304    return constraints;
305}
306
307static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
308            JNIEnv* env, jobject thiz, jint uniqueId) {
309    LOGV("GetAllSupportInfo - Enter");
310    DrmSupportInfo* drmSupportInfoArray = NULL;
311
312    int length = 0;
313    getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
314
315    jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
316
317    jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
318
319    for (int i = 0; i < length; i++) {
320        DrmSupportInfo info = drmSupportInfoArray[i];
321
322        jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
323
324        jmethodID addMimeTypeId
325            = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
326        jmethodID addFileSuffixId
327            = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
328
329        env->CallVoidMethod(
330            drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
331            env->NewStringUTF(info.getDescription().string()));
332
333        DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
334        while (iterator.hasNext()) {
335            String8  value = iterator.next();
336            env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
337        }
338
339        DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
340        while (it.hasNext()) {
341            String8 value = it.next();
342            env->CallVoidMethod(
343                drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
344        }
345
346        env->SetObjectArrayElement(array, i, drmSupportInfo);
347    }
348
349    delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
350    LOGV("GetAllSupportInfo - Exit");
351    return array;
352}
353
354static void android_drm_DrmManagerClient_installDrmEngine(
355            JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
356    LOGV("installDrmEngine - Enter");
357    //getDrmManagerClient(env, thiz)
358    //  ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
359    LOGV("installDrmEngine - Exit");
360}
361
362static jint android_drm_DrmManagerClient_saveRights(
363            JNIEnv* env, jobject thiz, jint uniqueId,
364            jobject drmRights, jstring rightsPath, jstring contentPath) {
365    LOGV("saveRights - Enter");
366    int result = DRM_ERROR_UNKNOWN;
367    int dataLength = 0;
368    char* mData =  Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
369
370    if (NULL != mData) {
371        DrmRights rights(DrmBuffer(mData, dataLength),
372                Utility::getStringValue(env, drmRights, "mMimeType"),
373                Utility::getStringValue(env, drmRights, "mAccountId"),
374                Utility::getStringValue(env, drmRights, "mSubscriptionId"));
375        result = getDrmManagerClientImpl(env, thiz)
376            ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
377                                Utility::getStringValue(env, contentPath));
378    }
379
380    delete mData; mData = NULL;
381    LOGV("saveRights - Exit");
382    return result;
383}
384
385static jboolean android_drm_DrmManagerClient_canHandle(
386            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
387    LOGV("canHandle - Enter");
388    jboolean result
389        = getDrmManagerClientImpl(env, thiz)
390            ->canHandle(uniqueId, Utility::getStringValue(env, path),
391                    Utility::getStringValue(env, mimeType));
392    LOGV("canHandle - Exit");
393    return result;
394}
395
396static jobject android_drm_DrmManagerClient_processDrmInfo(
397            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
398    LOGV("processDrmInfo - Enter");
399    int dataLength = 0;
400    const String8 mMimeType =  Utility::getStringValue(env, drmInfoObject, "mMimeType");
401    char* mData =  Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
402    int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
403
404    const DrmBuffer buffer(mData, dataLength);
405    DrmInfo drmInfo(mInfoType, buffer, mMimeType);
406
407    jclass clazz = env->FindClass("android/drm/DrmInfo");
408    jobject keyIterator
409        = env->CallObjectMethod(drmInfoObject,
410                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
411
412    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
413
414    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
415        jstring key = (jstring) env->CallObjectMethod(keyIterator,
416                env->GetMethodID(env->FindClass("java/util/Iterator"),
417                "next", "()Ljava/lang/Object;"));
418
419        jobject valueObject = env->CallObjectMethod(drmInfoObject,
420                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
421
422        jstring valString = NULL;
423        if (NULL != valueObject) {
424            valString = (jstring) env->CallObjectMethod(valueObject,
425                env->GetMethodID(env->FindClass("java/lang/Object"),
426                "toString", "()Ljava/lang/String;"));
427        }
428
429        String8 keyString = Utility::getStringValue(env, key);
430        String8 valueString = Utility::getStringValue(env, valString);
431        LOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
432
433        drmInfo.put(keyString, valueString);
434    }
435
436    DrmInfoStatus* pDrmInfoStatus
437        = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
438
439    jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
440    jobject drmInfoStatus = NULL;
441
442    if (NULL != localRef && NULL != pDrmInfoStatus) {
443        int statusCode = pDrmInfoStatus->statusCode;
444
445        jbyteArray dataArray = NULL;
446        if (NULL != pDrmInfoStatus->drmBuffer) {
447            int length = pDrmInfoStatus->drmBuffer->length;
448            dataArray = env->NewByteArray(length);
449            env->SetByteArrayRegion(
450                dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
451
452            delete [] pDrmInfoStatus->drmBuffer->data;
453            delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
454        }
455        jclass clazz = env->FindClass("android/drm/ProcessedData");
456        jmethodID constructorId
457            = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
458        jobject processedData = env->NewObject(clazz, constructorId, dataArray,
459                    env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
460                    env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
461
462        constructorId
463            = env->GetMethodID(localRef,
464                "<init>", "(ILandroid/drm/ProcessedData;Ljava/lang/String;)V");
465
466        drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, processedData,
467                                env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
468    }
469
470    delete mData; mData = NULL;
471    delete pDrmInfoStatus; pDrmInfoStatus = NULL;
472
473    LOGV("processDrmInfo - Exit");
474    return drmInfoStatus;
475}
476
477static jobject android_drm_DrmManagerClient_acquireDrmInfo(
478            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
479    LOGV("acquireDrmInfo Enter");
480    const String8 mMimeType =  Utility::getStringValue(env, drmInfoRequest, "mMimeType");
481    int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
482
483    DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
484
485    jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
486    jobject keyIterator
487        = env->CallObjectMethod(drmInfoRequest,
488                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
489
490    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
491
492    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
493        jstring key
494            = (jstring) env->CallObjectMethod(keyIterator,
495                env->GetMethodID(env->FindClass("java/util/Iterator"),
496                                "next", "()Ljava/lang/Object;"));
497
498        jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
499                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
500
501        String8 keyString = Utility::getStringValue(env, key);
502        String8 valueString = Utility::getStringValue(env, value);
503        LOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
504
505        drmInfoReq.put(keyString, valueString);
506    }
507
508    DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
509
510    jobject drmInfoObject = NULL;
511
512    if (NULL != pDrmInfo) {
513        jclass localRef = env->FindClass("android/drm/DrmInfo");
514
515        if (NULL != localRef) {
516            int length = pDrmInfo->getData().length;
517
518            jbyteArray dataArray = env->NewByteArray(length);
519            env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
520
521            drmInfoObject
522                = env->NewObject(localRef,
523                    env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
524                    mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
525
526            DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
527            jmethodID putMethodId
528                = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
529
530            while (it.hasNext()) {
531                String8 key = it.next();
532                String8 value = pDrmInfo->get(key);
533
534                env->CallVoidMethod(drmInfoObject, putMethodId,
535                    env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
536            }
537        }
538        delete [] pDrmInfo->getData().data;
539    }
540
541    delete pDrmInfo; pDrmInfo = NULL;
542
543    LOGV("acquireDrmInfo Exit");
544    return drmInfoObject;
545}
546
547static jint android_drm_DrmManagerClient_getDrmObjectType(
548            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
549    LOGV("getDrmObjectType Enter");
550    int drmObjectType
551        = getDrmManagerClientImpl(env, thiz)
552            ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
553                                Utility::getStringValue(env, mimeType));
554    LOGV("getDrmObjectType Exit");
555    return drmObjectType;
556}
557
558static jstring android_drm_DrmManagerClient_getOriginalMimeType(
559            JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
560    LOGV("getOriginalMimeType Enter");
561    String8 mimeType
562        = getDrmManagerClientImpl(env, thiz)
563            ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
564    LOGV("getOriginalMimeType Exit");
565    return env->NewStringUTF(mimeType.string());
566}
567
568static jint android_drm_DrmManagerClient_checkRightsStatus(
569            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
570    LOGV("getOriginalMimeType Enter");
571    int rightsStatus
572        = getDrmManagerClientImpl(env, thiz)
573            ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
574    LOGV("getOriginalMimeType Exit");
575    return rightsStatus;
576}
577
578static jint android_drm_DrmManagerClient_removeRights(
579            JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
580    LOGV("removeRights");
581    return getDrmManagerClientImpl(env, thiz)
582               ->removeRights(uniqueId, Utility::getStringValue(env, path));
583}
584
585static jint android_drm_DrmManagerClient_removeAllRights(
586            JNIEnv* env, jobject thiz, jint uniqueId) {
587    LOGV("removeAllRights");
588    return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
589}
590
591static jint android_drm_DrmManagerClient_openConvertSession(
592            JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
593    LOGV("openConvertSession Enter");
594    int convertId
595        = getDrmManagerClientImpl(env, thiz)
596            ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
597    LOGV("openConvertSession Exit");
598    return convertId;
599}
600
601static jobject android_drm_DrmManagerClient_convertData(
602            JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
603    LOGV("convertData Enter");
604
605    int dataLength = 0;
606    char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
607    const DrmBuffer buffer(mData, dataLength);
608
609    DrmConvertedStatus* pDrmConvertedStatus
610            = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
611
612    jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
613
614    jobject drmConvertedStatus = NULL;
615
616    if (NULL != localRef && NULL != pDrmConvertedStatus) {
617        int statusCode = pDrmConvertedStatus->statusCode;
618
619        jbyteArray dataArray = NULL;
620        if (NULL != pDrmConvertedStatus->convertedData) {
621            int length = pDrmConvertedStatus->convertedData->length;
622            dataArray = env->NewByteArray(length);
623            env->SetByteArrayRegion(dataArray, 0, length,
624                            (jbyte*) pDrmConvertedStatus->convertedData->data);
625
626            delete [] pDrmConvertedStatus->convertedData->data;
627            delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
628        }
629        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
630        drmConvertedStatus
631            = env->NewObject(localRef, constructorId,
632                             statusCode, dataArray, pDrmConvertedStatus->offset);
633    }
634
635    delete mData; mData = NULL;
636    delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
637
638    LOGV("convertData - Exit");
639    return drmConvertedStatus;
640}
641
642static jobject android_drm_DrmManagerClient_closeConvertSession(
643            JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
644
645    LOGV("closeConvertSession Enter");
646
647    DrmConvertedStatus* pDrmConvertedStatus
648                = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
649
650    jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
651
652    jobject drmConvertedStatus = NULL;
653
654    if (NULL != localRef && NULL != pDrmConvertedStatus) {
655        int statusCode = pDrmConvertedStatus->statusCode;
656
657        jbyteArray dataArray = NULL;
658        if (NULL != pDrmConvertedStatus->convertedData) {
659            int length = pDrmConvertedStatus->convertedData->length;
660            dataArray = env->NewByteArray(length);
661            env->SetByteArrayRegion(
662                dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
663
664            delete [] pDrmConvertedStatus->convertedData->data;
665            delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
666        }
667        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
668        drmConvertedStatus
669            = env->NewObject(localRef, constructorId,
670                             statusCode, dataArray, pDrmConvertedStatus->offset);
671    }
672
673    delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
674
675    LOGV("closeConvertSession - Exit");
676    return drmConvertedStatus;
677}
678
679static JNINativeMethod nativeMethods[] = {
680
681    {"_loadPlugIns", "(ILjava/lang/Object;)I",
682                                    (void*)android_drm_DrmManagerClient_loadPlugIns},
683
684    {"_unloadPlugIns", "(I)I",
685                                    (void*)android_drm_DrmManagerClient_unloadPlugIns},
686
687    {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
688                                    (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
689
690    {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
691                                    (void*)android_drm_DrmManagerClient_getAllSupportInfo},
692
693    {"_installDrmEngine", "(ILjava/lang/String;)V",
694                                    (void*)android_drm_DrmManagerClient_installDrmEngine},
695
696    {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
697                                    (void*)android_drm_DrmManagerClient_canHandle},
698
699    {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
700                                    (void*)android_drm_DrmManagerClient_processDrmInfo},
701
702    {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
703                                    (void*)android_drm_DrmManagerClient_acquireDrmInfo},
704
705    {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
706                                    (void*)android_drm_DrmManagerClient_saveRights},
707
708    {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
709                                    (void*)android_drm_DrmManagerClient_getDrmObjectType},
710
711    {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
712                                    (void*)android_drm_DrmManagerClient_getOriginalMimeType},
713
714    {"_checkRightsStatus", "(ILjava/lang/String;I)I",
715                                    (void*)android_drm_DrmManagerClient_checkRightsStatus},
716
717    {"_removeRights", "(ILjava/lang/String;)I",
718                                    (void*)android_drm_DrmManagerClient_removeRights},
719
720    {"_removeAllRights", "(I)I",
721                                    (void*)android_drm_DrmManagerClient_removeAllRights},
722
723    {"_openConvertSession", "(ILjava/lang/String;)I",
724                                    (void*)android_drm_DrmManagerClient_openConvertSession},
725
726    {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
727                                    (void*)android_drm_DrmManagerClient_convertData},
728
729    {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
730                                    (void*)android_drm_DrmManagerClient_closeConvertSession},
731};
732
733static int registerNativeMethods(JNIEnv* env) {
734    int result = -1;
735
736    /* look up the class */
737    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
738
739    if (NULL != clazz) {
740        if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
741                / sizeof(nativeMethods[0])) == JNI_OK) {
742            result = 0;
743        }
744    }
745    return result;
746}
747
748jint JNI_OnLoad(JavaVM* vm, void* reserved) {
749    JNIEnv* env = NULL;
750    jint result = -1;
751
752    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
753        if (NULL != env && registerNativeMethods(env) == 0) {
754            result = JNI_VERSION_1_4;
755        }
756    }
757    return result;
758}
759
760