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