android_drm_DrmManagerClient.cpp revision c7b3ccc564448cb4b918728421f9402bc18278c5
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/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 void android_drm_DrmManagerClient_initialize(
227        JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
228    LOGV("initialize - Enter");
229
230    sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId);
231    drmManager->addClient(uniqueId);
232
233    // Set the listener to DrmManager
234    sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
235    drmManager->setOnInfoListener(uniqueId, listener);
236
237    setDrmManagerClientImpl(env, thiz, drmManager);
238    LOGV("initialize - Exit");
239}
240
241static void android_drm_DrmManagerClient_finalize(JNIEnv* env, jobject thiz, jint uniqueId) {
242    LOGV("finalize - Enter");
243    DrmManagerClientImpl::remove(uniqueId);
244    getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
245
246    sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
247    if (oldClient != NULL) {
248        oldClient->setOnInfoListener(uniqueId, NULL);
249        oldClient->removeClient(uniqueId);
250    }
251    LOGV("finalize - Exit");
252}
253
254static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
255            JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
256    LOGV("GetConstraints - Enter");
257
258    const String8 pathString = Utility::getStringValue(env, jpath);
259    DrmConstraints* pConstraints
260        = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
261
262    jclass localRef = env->FindClass("android/content/ContentValues");
263    jobject constraints = NULL;
264
265    if (NULL != localRef && NULL != pConstraints) {
266        // Get the constructor id
267        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
268        // create the java DrmConstraints object
269        constraints = env->NewObject(localRef, constructorId);
270
271        DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
272
273        while (keyIt.hasNext()) {
274            String8 key = keyIt.next();
275
276            // insert the entry<constraintKey, constraintValue> to newly created java object
277            if (DrmConstraints::EXTENDED_METADATA == key) {
278                const char* value = pConstraints->getAsByteArray(&key);
279                if (NULL != value) {
280                    jbyteArray dataArray = env->NewByteArray(strlen(value));
281                    env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
282                    env->CallVoidMethod(
283                        constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
284                                     env->NewStringUTF(key.string()), dataArray);
285                }
286            } else {
287                String8 value = pConstraints->get(key);
288                env->CallVoidMethod(
289                    constraints,
290                    env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
291                env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
292            }
293        }
294    }
295
296    delete pConstraints; pConstraints = NULL;
297    LOGV("GetConstraints - Exit");
298    return constraints;
299}
300
301static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
302            JNIEnv* env, jobject thiz, jint uniqueId) {
303    LOGV("GetAllSupportInfo - Enter");
304    DrmSupportInfo* drmSupportInfoArray = NULL;
305
306    int length = 0;
307    getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
308
309    jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
310
311    jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
312
313    for (int i = 0; i < length; i++) {
314        DrmSupportInfo info = drmSupportInfoArray[i];
315
316        jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
317
318        jmethodID addMimeTypeId
319            = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
320        jmethodID addFileSuffixId
321            = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
322
323        env->CallVoidMethod(
324            drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
325            env->NewStringUTF(info.getDescription().string()));
326
327        DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
328        while (iterator.hasNext()) {
329            String8  value = iterator.next();
330            env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
331        }
332
333        DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
334        while (it.hasNext()) {
335            String8 value = it.next();
336            env->CallVoidMethod(
337                drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
338        }
339
340        env->SetObjectArrayElement(array, i, drmSupportInfo);
341    }
342
343    delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
344    LOGV("GetAllSupportInfo - Exit");
345    return array;
346}
347
348static void android_drm_DrmManagerClient_installDrmEngine(
349            JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
350    LOGV("installDrmEngine - Enter");
351    //getDrmManagerClient(env, thiz)
352    //  ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
353    LOGV("installDrmEngine - Exit");
354}
355
356static jint android_drm_DrmManagerClient_saveRights(
357            JNIEnv* env, jobject thiz, jint uniqueId,
358            jobject drmRights, jstring rightsPath, jstring contentPath) {
359    LOGV("saveRights - Enter");
360    int result = DRM_ERROR_UNKNOWN;
361    int dataLength = 0;
362    char* mData =  Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
363
364    if (NULL != mData) {
365        DrmRights rights(DrmBuffer(mData, dataLength),
366                Utility::getStringValue(env, drmRights, "mMimeType"),
367                Utility::getStringValue(env, drmRights, "mAccountId"),
368                Utility::getStringValue(env, drmRights, "mSubscriptionId"));
369        result = getDrmManagerClientImpl(env, thiz)
370            ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
371                                Utility::getStringValue(env, contentPath));
372    }
373
374    delete mData; mData = NULL;
375    LOGV("saveRights - Exit");
376    return result;
377}
378
379static jboolean android_drm_DrmManagerClient_canHandle(
380            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
381    LOGV("canHandle - Enter");
382    jboolean result
383        = getDrmManagerClientImpl(env, thiz)
384            ->canHandle(uniqueId, Utility::getStringValue(env, path),
385                    Utility::getStringValue(env, mimeType));
386    LOGV("canHandle - Exit");
387    return result;
388}
389
390static jobject android_drm_DrmManagerClient_processDrmInfo(
391            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
392    LOGV("processDrmInfo - Enter");
393    int dataLength = 0;
394    const String8 mMimeType =  Utility::getStringValue(env, drmInfoObject, "mMimeType");
395    char* mData =  Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
396    int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
397
398    const DrmBuffer buffer(mData, dataLength);
399    DrmInfo drmInfo(mInfoType, buffer, mMimeType);
400
401    jclass clazz = env->FindClass("android/drm/DrmInfo");
402    jobject keyIterator
403        = env->CallObjectMethod(drmInfoObject,
404                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
405
406    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
407
408    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
409        jstring key = (jstring) env->CallObjectMethod(keyIterator,
410                env->GetMethodID(env->FindClass("java/util/Iterator"),
411                "next", "()Ljava/lang/Object;"));
412
413        jobject valueObject = env->CallObjectMethod(drmInfoObject,
414                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
415
416        jstring valString = NULL;
417        if (NULL != valueObject) {
418            valString = (jstring) env->CallObjectMethod(valueObject,
419                env->GetMethodID(env->FindClass("java/lang/Object"),
420                "toString", "()Ljava/lang/String;"));
421        }
422
423        String8 keyString = Utility::getStringValue(env, key);
424        String8 valueString = Utility::getStringValue(env, valString);
425        LOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
426
427        drmInfo.put(keyString, valueString);
428    }
429
430    DrmInfoStatus* pDrmInfoStatus
431        = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
432
433    jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
434    jobject drmInfoStatus = NULL;
435
436    if (NULL != localRef && NULL != pDrmInfoStatus) {
437        int statusCode = pDrmInfoStatus->statusCode;
438        int infoType = pDrmInfoStatus->infoType;
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>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
460
461        drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
462                processedData, 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        LOGV("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 jint android_drm_DrmManagerClient_removeRights(
574            JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
575    LOGV("removeRights");
576    return getDrmManagerClientImpl(env, thiz)
577               ->removeRights(uniqueId, Utility::getStringValue(env, path));
578}
579
580static jint android_drm_DrmManagerClient_removeAllRights(
581            JNIEnv* env, jobject thiz, jint uniqueId) {
582    LOGV("removeAllRights");
583    return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
584}
585
586static jint android_drm_DrmManagerClient_openConvertSession(
587            JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
588    LOGV("openConvertSession Enter");
589    int convertId
590        = getDrmManagerClientImpl(env, thiz)
591            ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
592    LOGV("openConvertSession Exit");
593    return convertId;
594}
595
596static jobject android_drm_DrmManagerClient_convertData(
597            JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
598    LOGV("convertData Enter");
599
600    int dataLength = 0;
601    char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
602    const DrmBuffer buffer(mData, dataLength);
603
604    DrmConvertedStatus* pDrmConvertedStatus
605            = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
606
607    jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
608
609    jobject drmConvertedStatus = NULL;
610
611    if (NULL != localRef && NULL != pDrmConvertedStatus) {
612        int statusCode = pDrmConvertedStatus->statusCode;
613
614        jbyteArray dataArray = NULL;
615        if (NULL != pDrmConvertedStatus->convertedData) {
616            int length = pDrmConvertedStatus->convertedData->length;
617            dataArray = env->NewByteArray(length);
618            env->SetByteArrayRegion(dataArray, 0, length,
619                            (jbyte*) pDrmConvertedStatus->convertedData->data);
620
621            delete [] pDrmConvertedStatus->convertedData->data;
622            delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
623        }
624        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
625        drmConvertedStatus
626            = env->NewObject(localRef, constructorId,
627                             statusCode, dataArray, pDrmConvertedStatus->offset);
628    }
629
630    delete mData; mData = NULL;
631    delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
632
633    LOGV("convertData - Exit");
634    return drmConvertedStatus;
635}
636
637static jobject android_drm_DrmManagerClient_closeConvertSession(
638            JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
639
640    LOGV("closeConvertSession Enter");
641
642    DrmConvertedStatus* pDrmConvertedStatus
643                = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
644
645    jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
646
647    jobject drmConvertedStatus = NULL;
648
649    if (NULL != localRef && NULL != pDrmConvertedStatus) {
650        int statusCode = pDrmConvertedStatus->statusCode;
651
652        jbyteArray dataArray = NULL;
653        if (NULL != pDrmConvertedStatus->convertedData) {
654            int length = pDrmConvertedStatus->convertedData->length;
655            dataArray = env->NewByteArray(length);
656            env->SetByteArrayRegion(
657                dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
658
659            delete [] pDrmConvertedStatus->convertedData->data;
660            delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
661        }
662        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
663        drmConvertedStatus
664            = env->NewObject(localRef, constructorId,
665                             statusCode, dataArray, pDrmConvertedStatus->offset);
666    }
667
668    delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
669
670    LOGV("closeConvertSession - Exit");
671    return drmConvertedStatus;
672}
673
674static JNINativeMethod nativeMethods[] = {
675
676    {"_initialize", "(ILjava/lang/Object;)V",
677                                    (void*)android_drm_DrmManagerClient_initialize},
678
679    {"_finalize", "(I)V",
680                                    (void*)android_drm_DrmManagerClient_finalize},
681
682    {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
683                                    (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
684
685    {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
686                                    (void*)android_drm_DrmManagerClient_getAllSupportInfo},
687
688    {"_installDrmEngine", "(ILjava/lang/String;)V",
689                                    (void*)android_drm_DrmManagerClient_installDrmEngine},
690
691    {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
692                                    (void*)android_drm_DrmManagerClient_canHandle},
693
694    {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
695                                    (void*)android_drm_DrmManagerClient_processDrmInfo},
696
697    {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
698                                    (void*)android_drm_DrmManagerClient_acquireDrmInfo},
699
700    {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
701                                    (void*)android_drm_DrmManagerClient_saveRights},
702
703    {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
704                                    (void*)android_drm_DrmManagerClient_getDrmObjectType},
705
706    {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
707                                    (void*)android_drm_DrmManagerClient_getOriginalMimeType},
708
709    {"_checkRightsStatus", "(ILjava/lang/String;I)I",
710                                    (void*)android_drm_DrmManagerClient_checkRightsStatus},
711
712    {"_removeRights", "(ILjava/lang/String;)I",
713                                    (void*)android_drm_DrmManagerClient_removeRights},
714
715    {"_removeAllRights", "(I)I",
716                                    (void*)android_drm_DrmManagerClient_removeAllRights},
717
718    {"_openConvertSession", "(ILjava/lang/String;)I",
719                                    (void*)android_drm_DrmManagerClient_openConvertSession},
720
721    {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
722                                    (void*)android_drm_DrmManagerClient_convertData},
723
724    {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
725                                    (void*)android_drm_DrmManagerClient_closeConvertSession},
726};
727
728static int registerNativeMethods(JNIEnv* env) {
729    int result = -1;
730
731    /* look up the class */
732    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
733
734    if (NULL != clazz) {
735        if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
736                / sizeof(nativeMethods[0])) == JNI_OK) {
737            result = 0;
738        }
739    }
740    return result;
741}
742
743jint JNI_OnLoad(JavaVM* vm, void* reserved) {
744    JNIEnv* env = NULL;
745    jint result = -1;
746
747    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
748        if (NULL != env && registerNativeMethods(env) == 0) {
749            result = JNI_VERSION_1_4;
750        }
751    }
752    return result;
753}
754
755