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