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