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