android_drm_DrmManagerClient.cpp revision d074e30ce44b9e33da43b67a4515b8986ca72b26
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            LOGD("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 void 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    getDrmManagerClientImpl(env, thiz)->loadPlugIns(uniqueId);
239    LOGV("load plugins - Exit");
240}
241
242static void android_drm_DrmManagerClient_unloadPlugIns(JNIEnv* env, jobject thiz, jint uniqueId) {
243    LOGV("unload plugins - Enter");
244    sp<DrmManagerClientImpl> client = getDrmManagerClientImpl(env, thiz);
245    client->unloadPlugIns(uniqueId);
246    client->setOnInfoListener(uniqueId, NULL);
247    DrmManagerClientImpl::remove(uniqueId);
248
249    sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
250    if (oldClient != NULL) {
251        oldClient->setOnInfoListener(uniqueId, NULL);
252    }
253
254    LOGV("unload plugins - Exit");
255}
256
257static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
258            JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
259    LOGV("GetConstraints - Enter");
260
261    const String8 pathString = Utility::getStringValue(env, jpath);
262    DrmConstraints* pConstraints
263        = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
264
265    jclass localRef = env->FindClass("android/content/ContentValues");
266    jobject constraints = NULL;
267
268    if (NULL != localRef && NULL != pConstraints) {
269        // Get the constructor id
270        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
271        // create the java DrmConstraints object
272        constraints = env->NewObject(localRef, constructorId);
273
274        DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
275
276        while (keyIt.hasNext()) {
277            String8 key = keyIt.next();
278
279            // insert the entry<constraintKey, constraintValue> to newly created java object
280            if (DrmConstraints::EXTENDED_METADATA == key) {
281                const char* value = pConstraints->getAsByteArray(&key);
282                if (NULL != value) {
283                    jbyteArray dataArray = env->NewByteArray(strlen(value));
284                    env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
285                    env->CallVoidMethod(
286                        constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
287                                     env->NewStringUTF(key.string()), dataArray);
288                }
289            } else {
290                String8 value = pConstraints->get(key);
291                env->CallVoidMethod(
292                    constraints,
293                    env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
294                env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
295            }
296        }
297    }
298
299    delete pConstraints; pConstraints = NULL;
300    LOGV("GetConstraints - Exit");
301    return constraints;
302}
303
304static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
305            JNIEnv* env, jobject thiz, jint uniqueId) {
306    LOGV("GetAllSupportInfo - Enter");
307    DrmSupportInfo* drmSupportInfoArray = NULL;
308
309    int length = 0;
310    getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
311
312    jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
313
314    jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
315
316    for (int i = 0; i < length; i++) {
317        DrmSupportInfo info = drmSupportInfoArray[i];
318
319        jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
320
321        jmethodID addMimeTypeId
322            = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
323        jmethodID addFileSuffixId
324            = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
325
326        env->CallVoidMethod(
327            drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
328            env->NewStringUTF(info.getDescription().string()));
329
330        DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
331        while (iterator.hasNext()) {
332            String8  value = iterator.next();
333            env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
334        }
335
336        DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
337        while (it.hasNext()) {
338            String8 value = it.next();
339            env->CallVoidMethod(
340                drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
341        }
342
343        env->SetObjectArrayElement(array, i, drmSupportInfo);
344    }
345
346    delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
347    LOGV("GetAllSupportInfo - Exit");
348    return array;
349}
350
351static void android_drm_DrmManagerClient_installDrmEngine(
352            JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
353    LOGV("installDrmEngine - Enter");
354    //getDrmManagerClient(env, thiz)
355    //  ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
356    LOGV("installDrmEngine - Exit");
357}
358
359static void android_drm_DrmManagerClient_saveRights(
360            JNIEnv* env, jobject thiz, jint uniqueId,
361            jobject drmRights, jstring rightsPath, jstring contentPath) {
362    LOGV("saveRights - Enter");
363    int dataLength = 0;
364    char* mData =  Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
365
366    if (NULL != mData) {
367        DrmRights rights(DrmBuffer(mData, dataLength),
368                Utility::getStringValue(env, drmRights, "mMimeType"),
369                Utility::getStringValue(env, drmRights, "mAccountId"),
370                Utility::getStringValue(env, drmRights, "mSubscriptionId"));
371        getDrmManagerClientImpl(env, thiz)
372            ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
373                                Utility::getStringValue(env, contentPath));
374    }
375
376    delete mData; mData = NULL;
377    LOGV("saveRights - Exit");
378}
379
380static jboolean android_drm_DrmManagerClient_canHandle(
381            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
382    LOGV("canHandle - Enter");
383    jboolean result
384        = getDrmManagerClientImpl(env, thiz)
385            ->canHandle(uniqueId, Utility::getStringValue(env, path),
386                    Utility::getStringValue(env, mimeType));
387    LOGV("canHandle - Exit");
388    return result;
389}
390
391static jobject android_drm_DrmManagerClient_processDrmInfo(
392            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
393    LOGV("processDrmInfo - Enter");
394    int dataLength = 0;
395    const String8 mMimeType =  Utility::getStringValue(env, drmInfoObject, "mMimeType");
396    char* mData =  Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
397    int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
398
399    const DrmBuffer buffer(mData, dataLength);
400    DrmInfo drmInfo(mInfoType, buffer, mMimeType);
401
402    jclass clazz = env->FindClass("android/drm/DrmInfo");
403    jobject keyIterator
404        = env->CallObjectMethod(drmInfoObject,
405                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
406
407    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
408
409    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
410        jstring key = (jstring) env->CallObjectMethod(keyIterator,
411                env->GetMethodID(env->FindClass("java/util/Iterator"),
412                "next", "()Ljava/lang/Object;"));
413
414        jobject valueObject = env->CallObjectMethod(drmInfoObject,
415                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
416
417        jstring valString = NULL;
418        if (NULL != valueObject) {
419            valString = (jstring) env->CallObjectMethod(valueObject,
420                env->GetMethodID(env->FindClass("java/lang/Object"),
421                "toString", "()Ljava/lang/String;"));
422        }
423
424        String8 keyString = Utility::getStringValue(env, key);
425        String8 valueString = Utility::getStringValue(env, valString);
426        LOGD("Key: %s | Value: %s", keyString.string(), valueString.string());
427
428        drmInfo.put(keyString, valueString);
429    }
430
431    DrmInfoStatus* pDrmInfoStatus
432        = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
433
434    jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
435    jobject drmInfoStatus = NULL;
436
437    if (NULL != localRef && NULL != pDrmInfoStatus) {
438        int statusCode = pDrmInfoStatus->statusCode;
439
440        jbyteArray dataArray = NULL;
441        if (NULL != pDrmInfoStatus->drmBuffer) {
442            int length = pDrmInfoStatus->drmBuffer->length;
443            dataArray = env->NewByteArray(length);
444            env->SetByteArrayRegion(
445                dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
446
447            delete [] pDrmInfoStatus->drmBuffer->data;
448            delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
449        }
450        jclass clazz = env->FindClass("android/drm/ProcessedData");
451        jmethodID constructorId
452            = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
453        jobject processedData = env->NewObject(clazz, constructorId, dataArray,
454                    env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
455                    env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
456
457        constructorId
458            = env->GetMethodID(localRef,
459                "<init>", "(ILandroid/drm/ProcessedData;Ljava/lang/String;)V");
460
461        drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, processedData,
462                                env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
463    }
464
465    delete mData; mData = NULL;
466    delete pDrmInfoStatus; pDrmInfoStatus = NULL;
467
468    LOGV("processDrmInfo - Exit");
469    return drmInfoStatus;
470}
471
472static jobject android_drm_DrmManagerClient_acquireDrmInfo(
473            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
474    LOGV("acquireDrmInfo Enter");
475    const String8 mMimeType =  Utility::getStringValue(env, drmInfoRequest, "mMimeType");
476    int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
477
478    DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
479
480    jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
481    jobject keyIterator
482        = env->CallObjectMethod(drmInfoRequest,
483                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
484
485    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
486
487    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
488        jstring key
489            = (jstring) env->CallObjectMethod(keyIterator,
490                env->GetMethodID(env->FindClass("java/util/Iterator"),
491                                "next", "()Ljava/lang/Object;"));
492
493        jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
494                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
495
496        String8 keyString = Utility::getStringValue(env, key);
497        String8 valueString = Utility::getStringValue(env, value);
498        LOGD("Key: %s | Value: %s", keyString.string(), valueString.string());
499
500        drmInfoReq.put(keyString, valueString);
501    }
502
503    DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
504
505    jobject drmInfoObject = NULL;
506
507    if (NULL != pDrmInfo) {
508        jclass localRef = env->FindClass("android/drm/DrmInfo");
509
510        if (NULL != localRef) {
511            int length = pDrmInfo->getData().length;
512
513            jbyteArray dataArray = env->NewByteArray(length);
514            env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
515
516            drmInfoObject
517                = env->NewObject(localRef,
518                    env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
519                    mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
520
521            DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
522            jmethodID putMethodId
523                = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
524
525            while (it.hasNext()) {
526                String8 key = it.next();
527                String8 value = pDrmInfo->get(key);
528
529                env->CallVoidMethod(drmInfoObject, putMethodId,
530                    env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
531            }
532        }
533        delete [] pDrmInfo->getData().data;
534    }
535
536    delete pDrmInfo; pDrmInfo = NULL;
537
538    LOGV("acquireDrmInfo Exit");
539    return drmInfoObject;
540}
541
542static jint android_drm_DrmManagerClient_getDrmObjectType(
543            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
544    LOGV("getDrmObjectType Enter");
545    int drmObjectType
546        = getDrmManagerClientImpl(env, thiz)
547            ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
548                                Utility::getStringValue(env, mimeType));
549    LOGV("getDrmObjectType Exit");
550    return drmObjectType;
551}
552
553static jstring android_drm_DrmManagerClient_getOriginalMimeType(
554            JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
555    LOGV("getOriginalMimeType Enter");
556    String8 mimeType
557        = getDrmManagerClientImpl(env, thiz)
558            ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
559    LOGV("getOriginalMimeType Exit");
560    return env->NewStringUTF(mimeType.string());
561}
562
563static jint android_drm_DrmManagerClient_checkRightsStatus(
564            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
565    LOGV("getOriginalMimeType Enter");
566    int rightsStatus
567        = getDrmManagerClientImpl(env, thiz)
568            ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
569    LOGV("getOriginalMimeType Exit");
570    return rightsStatus;
571}
572
573static void android_drm_DrmManagerClient_removeRights(
574            JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
575    LOGV("removeRights Enter");
576    getDrmManagerClientImpl(env, thiz)->removeRights(uniqueId, Utility::getStringValue(env, path));
577    LOGV("removeRights Exit");
578}
579
580static void android_drm_DrmManagerClient_removeAllRights(
581            JNIEnv* env, jobject thiz, jint uniqueId) {
582    LOGV("removeAllRights Enter");
583    getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
584    LOGV("removeAllRights Exit");
585}
586
587static jint android_drm_DrmManagerClient_openConvertSession(
588            JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
589    LOGV("openConvertSession Enter");
590    int convertId
591        = getDrmManagerClientImpl(env, thiz)
592            ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
593    LOGV("openConvertSession Exit");
594    return convertId;
595}
596
597static jobject android_drm_DrmManagerClient_convertData(
598            JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
599    LOGV("convertData Enter");
600
601    int dataLength = 0;
602    char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
603    const DrmBuffer buffer(mData, dataLength);
604
605    DrmConvertedStatus* pDrmConvertedStatus
606            = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
607
608    jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
609
610    jobject drmConvertedStatus = NULL;
611
612    if (NULL != localRef && NULL != pDrmConvertedStatus) {
613        int statusCode = pDrmConvertedStatus->statusCode;
614
615        jbyteArray dataArray = NULL;
616        if (NULL != pDrmConvertedStatus->convertedData) {
617            int length = pDrmConvertedStatus->convertedData->length;
618            dataArray = env->NewByteArray(length);
619            env->SetByteArrayRegion(dataArray, 0, length,
620                            (jbyte*) pDrmConvertedStatus->convertedData->data);
621
622            delete [] pDrmConvertedStatus->convertedData->data;
623            delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
624        }
625        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
626        drmConvertedStatus
627            = env->NewObject(localRef, constructorId,
628                             statusCode, dataArray, pDrmConvertedStatus->offset);
629    }
630
631    delete mData; mData = NULL;
632    delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
633
634    LOGV("convertData - Exit");
635    return drmConvertedStatus;
636}
637
638static jobject android_drm_DrmManagerClient_closeConvertSession(
639            JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
640
641    LOGV("closeConvertSession Enter");
642
643    DrmConvertedStatus* pDrmConvertedStatus
644                = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
645
646    jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
647
648    jobject drmConvertedStatus = NULL;
649
650    if (NULL != localRef && NULL != pDrmConvertedStatus) {
651        int statusCode = pDrmConvertedStatus->statusCode;
652
653        jbyteArray dataArray = NULL;
654        if (NULL != pDrmConvertedStatus->convertedData) {
655            int length = pDrmConvertedStatus->convertedData->length;
656            dataArray = env->NewByteArray(length);
657            env->SetByteArrayRegion(
658                dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
659
660            delete [] pDrmConvertedStatus->convertedData->data;
661            delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
662        }
663        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
664        drmConvertedStatus
665            = env->NewObject(localRef, constructorId,
666                             statusCode, dataArray, pDrmConvertedStatus->offset);
667    }
668
669    delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
670
671    LOGV("closeConvertSession - Exit");
672    return drmConvertedStatus;
673}
674
675static JNINativeMethod nativeMethods[] = {
676
677    {"_loadPlugIns", "(ILjava/lang/Object;)V",
678                                    (void*)android_drm_DrmManagerClient_loadPlugIns},
679
680    {"_unloadPlugIns", "(I)V",
681                                    (void*)android_drm_DrmManagerClient_unloadPlugIns},
682
683    {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
684                                    (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
685
686    {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
687                                    (void*)android_drm_DrmManagerClient_getAllSupportInfo},
688
689    {"_installDrmEngine", "(ILjava/lang/String;)V",
690                                    (void*)android_drm_DrmManagerClient_installDrmEngine},
691
692    {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
693                                    (void*)android_drm_DrmManagerClient_canHandle},
694
695    {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
696                                    (void*)android_drm_DrmManagerClient_processDrmInfo},
697
698    {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
699                                    (void*)android_drm_DrmManagerClient_acquireDrmInfo},
700
701    {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)V",
702                                    (void*)android_drm_DrmManagerClient_saveRights},
703
704    {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
705                                    (void*)android_drm_DrmManagerClient_getDrmObjectType},
706
707    {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
708                                    (void*)android_drm_DrmManagerClient_getOriginalMimeType},
709
710    {"_checkRightsStatus", "(ILjava/lang/String;I)I",
711                                    (void*)android_drm_DrmManagerClient_checkRightsStatus},
712
713    {"_removeRights", "(ILjava/lang/String;)V",
714                                    (void*)android_drm_DrmManagerClient_removeRights},
715
716    {"_removeAllRights", "(I)V",
717                                    (void*)android_drm_DrmManagerClient_removeAllRights},
718
719    {"_openConvertSession", "(ILjava/lang/String;)I",
720                                    (void*)android_drm_DrmManagerClient_openConvertSession},
721
722    {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
723                                    (void*)android_drm_DrmManagerClient_convertData},
724
725    {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
726                                    (void*)android_drm_DrmManagerClient_closeConvertSession},
727};
728
729static int registerNativeMethods(JNIEnv* env) {
730    int result = -1;
731
732    /* look up the class */
733    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
734
735    if (NULL != clazz) {
736        if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
737                / sizeof(nativeMethods[0])) == JNI_OK) {
738            result = 0;
739        }
740    }
741    return result;
742}
743
744jint JNI_OnLoad(JavaVM* vm, void* reserved) {
745    JNIEnv* env = NULL;
746    jint result = -1;
747
748    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
749        if (NULL != env && registerNativeMethods(env) == 0) {
750            result = JNI_VERSION_1_4;
751        }
752    }
753    return result;
754}
755
756