android_media_MediaDrm.cpp revision 8a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906
18a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/*
28a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Copyright 2013, The Android Open Source Project
38a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *
48a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
58a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * you may not use this file except in compliance with the License.
68a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * You may obtain a copy of the License at
78a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *
88a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *     http://www.apache.org/licenses/LICENSE-2.0
98a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *
108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Unless required by applicable law or agreed to in writing, software
118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * See the License for the specific language governing permissions and
148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * limitations under the License.
158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */
168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker//#define LOG_NDEBUG 0
188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define LOG_TAG "MediaDrm-JNI"
198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <utils/Log.h>
208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "android_media_MediaDrm.h"
228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "android_runtime/AndroidRuntime.h"
248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "jni.h"
258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "JNIHelp.h"
268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <binder/IServiceManager.h>
288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/IDrm.h>
298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/IMediaPlayerService.h>
308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/stagefright/foundation/ADebug.h>
318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkernamespace android {
338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define FIND_CLASS(var, className) \
358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->FindClass(className); \
368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find class " className);
378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find field " fieldName);
418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find method " fieldName);
458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct RequestFields {
478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID data;
488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID defaultUrl;
498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct ArrayListFields {
528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID init;
538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID add;
548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct HashmapFields {
578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID init;
588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID get;
598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID put;
608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID entrySet;
618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct SetFields {
648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID iterator;
658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct IteratorFields {
688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID next;
698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID hasNext;
708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct EntryFields {
738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID getKey;
748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID getValue;
758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct fields_t {
788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID context;
798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    RequestFields licenseRequest;
808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    RequestFields provisionRequest;
818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    ArrayListFields arraylist;
828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    HashmapFields hashmap;
838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    SetFields set;
848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    IteratorFields iterator;
858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    EntryFields entry;
868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic fields_t gFields;
898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic bool throwExceptionAsNecessary(
918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, status_t err, const char *msg = NULL) {
928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err == BAD_VALUE) {
948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", msg);
958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return true;
968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    } else if (err != OK) {
978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", msg);
988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return true;
998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return false;
1018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic sp<IDrm> GetDrm(JNIEnv *env, jobject thiz) {
1048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JDrm *jdrm = (JDrm *)env->GetIntField(thiz, gFields.context);
1058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return jdrm ? jdrm->getDrm() : NULL;
1068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff TinkerJDrm::JDrm(
1098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, const uint8_t uuid[16]) {
1108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mObject = env->NewWeakGlobalRef(thiz);
1118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mDrm = MakeDrm(uuid);
1128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff TinkerJDrm::~JDrm() {
1158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mDrm.clear();
1168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
1188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->DeleteWeakGlobalRef(mObject);
1208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mObject = NULL;
1218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
1248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkersp<IDrm> JDrm::MakeDrm() {
1258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IServiceManager> sm = defaultServiceManager();
1268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IBinder> binder =
1288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        sm->getService(String16("media.player"));
1298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IMediaPlayerService> service =
1318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        interface_cast<IMediaPlayerService>(binder);
1328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (service == NULL) {
1348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
1358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = service->makeDrm();
1388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
1408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
1418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm;
1448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
1478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkersp<IDrm> JDrm::MakeDrm(const uint8_t uuid[16]) {
1488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = MakeDrm();
1498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
1518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
1528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->createPlugin(uuid);
1558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err != OK) {
1578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
1588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm;
1618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
1648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerbool JDrm::IsCryptoSchemeSupported(const uint8_t uuid[16]) {
1658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = MakeDrm();
1668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
1688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
1698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm->isCryptoSchemeSupported(uuid);
1728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatus_t JDrm::initCheck() const {
1758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return mDrm == NULL ? NO_INIT : OK;
1768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// JNI conversion utilities
1798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray) {
1808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> vector;
1818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    size_t length = env->GetArrayLength(byteArray);
1828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    vector.insertAt((size_t)0, length);
1838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
1848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return vector;
1858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray VectorToJByteArray(JNIEnv *env, Vector<uint8_t> const &vector) {
1888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    size_t length = vector.size();
1898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jbyteArray result = env->NewByteArray(length);
1908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (result != NULL) {
1918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetByteArrayRegion(result, 0, length, (jbyte *)vector.array());
1928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
1938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return result;
1948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
1958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic String8 JStringToString8(JNIEnv *env, jstring const &jstr) {
1978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jboolean isCopy;
1988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 result;
1998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    const char *s = env->GetStringUTFChars(jstr, &isCopy);
2018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (s) {
2028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        result = s;
2038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->ReleaseStringUTFChars(jstr, s);
2048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return result;
2068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/*
2088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.util.HashMap;
2098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.util.Set;
2108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.Map.Entry;
2118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import jav.util.Iterator;
2128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    HashMap<k, v> hm;
2148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Set<Entry<k, v> > s = hm.entrySet();
2158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Iterator i = s.iterator();
2168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Entry e = s.next();
2178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker*/
2188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic KeyedVector<String8, String8> HashMapToKeyedVector(JNIEnv *env, jobject &hashMap) {
2208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
2218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/lang/String");
2228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> keyedVector;
2238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject entrySet = env->CallObjectMethod(hashMap, gFields.hashmap.entrySet);
2258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (entrySet) {
2268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jobject iterator = env->CallObjectMethod(entrySet, gFields.set.iterator);
2278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        if (iterator) {
2288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            jboolean hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
2298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            while (hasNext) {
2308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                jobject entry = env->CallObjectMethod(iterator, gFields.iterator.next);
2318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                if (entry) {
2328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jobject obj = env->CallObjectMethod(entry, gFields.entry.getKey);
2338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    if (!env->IsInstanceOf(obj, clazz)) {
2348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
2358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    }
2368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jstring jkey = static_cast<jstring>(obj);
2378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    obj = env->CallObjectMethod(entry, gFields.entry.getValue);
2398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    if (!env->IsInstanceOf(obj, clazz)) {
2408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
2418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    }
2428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jstring jvalue = static_cast<jstring>(obj);
2438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    String8 key = JStringToString8(env, jkey);
2458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    String8 value = JStringToString8(env, jvalue);
2468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    keyedVector.add(key, value);
2478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    env->DeleteLocalRef(jkey);
2498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    env->DeleteLocalRef(jvalue);
2508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
2518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                }
2528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env->DeleteLocalRef(entry);
2538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            }
2548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            env->DeleteLocalRef(iterator);
2558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        }
2568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(entrySet);
2578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return keyedVector;
2598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject KeyedVectorToHashMap (JNIEnv *env, KeyedVector<String8, String8> const &map) {
2628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
2638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/HashMap");
2648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject hashMap = env->NewObject(clazz, gFields.hashmap.init);
2658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    for (size_t i = 0; i < map.size(); ++i) {
2668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jkey = env->NewStringUTF(map.keyAt(i).string());
2678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jvalue = env->NewStringUTF(map.valueAt(i).string());
2688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->CallObjectMethod(hashMap, gFields.hashmap.put, jkey, jvalue);
2698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(jkey);
2708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(jvalue);
2718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return hashMap;
2738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
2768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                                                   List<Vector<uint8_t> > list) {
2778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
2788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/ArrayList");
2798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
2808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    List<Vector<uint8_t> >::iterator iter = list.begin();
2818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    while (iter != list.end()) {
2828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray byteArray = VectorToJByteArray(env, *iter);
2838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
2848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(byteArray);
2858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        iter++;
2868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return arrayList;
2898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}  // namespace android
2928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerusing namespace android;
2948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic sp<JDrm> setDrm(
2968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, const sp<JDrm> &drm) {
2978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<JDrm> old = (JDrm *)env->GetIntField(thiz, gFields.context);
2988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm != NULL) {
2998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        drm->incStrong(thiz);
3008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (old != NULL) {
3028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        old->decStrong(thiz);
3038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->SetIntField(thiz, gFields.context, (int)drm.get());
3058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return old;
3078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic bool CheckSession(JNIEnv *env, const sp<IDrm> &drm, jbyteArray const &jsessionId)
3108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker{
3118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
3128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
3138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
3148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jsessionId == NULL) {
3178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
3188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
3198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return true;
3218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_release(JNIEnv *env, jobject thiz) {
3248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    setDrm(env, thiz, NULL);
3258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_init(JNIEnv *env) {
3288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
3298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm");
3308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_FIELD_ID(gFields.context, clazz, "mNativeContext", "I");
3318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$LicenseRequest");
3338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_FIELD_ID(gFields.licenseRequest.data, clazz, "data", "[B");
3348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_FIELD_ID(gFields.licenseRequest.defaultUrl, clazz, "defaultUrl", "Ljava/lang/String;");
3358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
3378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_FIELD_ID(gFields.provisionRequest.data, clazz, "data", "[B");
3388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "defaultUrl", "Ljava/lang/String;");
3398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/ArrayList");
3418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V");
3428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.arraylist.add, clazz, "add", "(Ljava/lang/Object;)Z");
3438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/HashMap");
3458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.init, clazz, "<init>", "()V");
3468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.get, clazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
3478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.put, clazz, "put",
3488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.entrySet, clazz, "entrySet", "()Ljava/util/Set;");
3508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Set");
3528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.set.iterator, clazz, "iterator", "()Ljava/util/Iterator;");
3538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Iterator");
3558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.iterator.next, clazz, "next", "()Ljava/lang/Object;");
3568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.iterator.hasNext, clazz, "hasNext", "()Z");
3578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Map$Entry");
3598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.entry.getKey, clazz, "getKey", "()Ljava/lang/Object;");
3608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.entry.getValue, clazz, "getValue", "()Ljava/lang/Object;");
3618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_setup(
3648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz,
3658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jobject weak_this, jbyteArray uuidObj) {
3668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuidObj == NULL) {
3688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
3698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
3708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
3738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuid.size() != 16) {
3758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
3768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
3778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<JDrm> drm = new JDrm(env, thiz, uuid.array());
3808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->initCheck();
3828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err != OK) {
3848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(
3858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env,
3868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "android/media/MediaDrmException",
3878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "Failed to instantiate drm object.");
3888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
3898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    setDrm(env, thiz, drm);
3928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_finalize(
3958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz) {
3968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    android_media_MediaDrm_release(env, thiz);
3978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
4008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, jbyteArray uuidObj) {
4018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuidObj == NULL) {
4038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
4048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
4058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
4088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuid.size() != 16) {
4108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(
4118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env,
4128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "java/lang/IllegalArgumentException",
4138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                NULL);
4148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
4158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return JDrm::IsCryptoSchemeSupported(uuid.array());
4188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray android_media_MediaDrm_openSession(
4218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
4228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
4238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
4258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
4268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
4278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId;
4308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->openSession(sessionId);
4318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to open session")) {
4338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
4348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return VectorToJByteArray(env, sessionId);
4378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_closeSession(
4408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
4418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
4428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
4448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
4458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
4488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->closeSession(sessionId);
4508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to close session");
4528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_getLicenseRequest(
4558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jinitData,
4568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jstring jmimeType, jint jlicenseType, jobject joptParams) {
4578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
4588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
4608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
4618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
4648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> initData;
4668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jinitData != NULL) {
4678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        initData = JByteArrayToVector(env, jinitData);
4688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 mimeType;
4718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jmimeType != NULL) {
4728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        mimeType = JStringToString8(env, jmimeType);
4738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    DrmPlugin::LicenseType licenseType = (DrmPlugin::LicenseType)jlicenseType;
4768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> optParams;
4788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (joptParams != NULL) {
4798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        optParams = HashMapToKeyedVector(env, joptParams);
4808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> request;
4838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 defaultUrl;
4848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getLicenseRequest(sessionId, initData, mimeType,
4868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                                          licenseType, optParams, request, defaultUrl);
4878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get license request")) {
4898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
4908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    // Fill out return obj
4938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
4948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$LicenseRequest");
4958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject licenseObj = NULL;
4978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (clazz) {
4998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        licenseObj = env->AllocObject(clazz);
5008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray jrequest = VectorToJByteArray(env, request);
5018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(licenseObj, gFields.licenseRequest.data, jrequest);
5028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
5048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(licenseObj, gFields.licenseRequest.defaultUrl, jdefaultUrl);
5058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return licenseObj;
5088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_provideLicenseResponse(
5118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jresponse) {
5128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
5138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
5158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
5168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
5198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jresponse == NULL) {
5218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
5228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
5238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
5258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->provideLicenseResponse(sessionId, response);
5278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to handle license response");
5298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_removeLicense(
5328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
5338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
5348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
5368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
5378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
5408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->removeLicense(sessionId);
5428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to remove license");
5448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_queryLicenseStatus(
5478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
5488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
5498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
5518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
5528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
5548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> infoMap;
5568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->queryLicenseStatus(sessionId, infoMap);
5588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to query license")) {
5608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
5618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return KeyedVectorToHashMap(env, infoMap);
5648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_getProvisionRequest(
5678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
5688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
5698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
5718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
5728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
5738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> request;
5768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 defaultUrl;
5778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getProvisionRequest(request, defaultUrl);
5798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get provision request")) {
5818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
5828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    // Fill out return obj
5858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
5868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
5878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject provisionObj = NULL;
5898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (clazz) {
5918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        provisionObj = env->AllocObject(clazz);
5928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray jrequest = VectorToJByteArray(env, request);
5938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(provisionObj, gFields.provisionRequest.data, jrequest);
5948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
5968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(provisionObj, gFields.provisionRequest.defaultUrl, jdefaultUrl);
5978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return provisionObj;
6008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_provideProvisionResponse(
6038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jresponse) {
6048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
6078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
6088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jresponse == NULL) {
6128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
6178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->provideProvisionResponse(response);
6198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to handle provision response");
6218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_getSecureStops(
6248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
6258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
6288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
6298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    List<Vector<uint8_t> > secureStops;
6338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getSecureStops(secureStops);
6358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get secure stops")) {
6378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return ListOfVectorsToArrayListOfByteArray(env, secureStops);
6418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_releaseSecureStops(
6448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jssRelease) {
6458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
6488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
6498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> ssRelease(JByteArrayToVector(env, jssRelease));
6538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->releaseSecureStops(ssRelease);
6558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to release secure stops");
6578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jstring android_media_MediaDrm_getPropertyString(
6608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname) {
6618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
6648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
6658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL) {
6698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
6748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 value;
6758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getPropertyString(name, value);
6778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get property")) {
6798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return env->NewStringUTF(value.string());
6838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray android_media_MediaDrm_getPropertyByteArray(
6868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname) {
6878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
6908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
6918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL) {
6958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
7008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> value;
7018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getPropertyByteArray(name, value);
7038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get property")) {
7058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
7068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return VectorToJByteArray(env, value);
7098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_setPropertyString(
7128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname, jstring jvalue) {
7138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
7168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
7178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
7188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL || jvalue == NULL) {
7218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
7228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
7238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
7268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 value = JStringToString8(env, jvalue);
7278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->setPropertyString(name, value);
7298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set property");
7318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_setPropertyByteArray(
7348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname, jbyteArray jvalue) {
7358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
7388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", NULL);
7398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
7408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL || jvalue == NULL) {
7438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
7448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
7458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
7488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> value = JByteArrayToVector(env, jvalue);
7498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->setPropertyByteArray(name, value);
7518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set property");
7538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic JNINativeMethod gMethods[] = {
7578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "release", "()V", (void *)android_media_MediaDrm_release },
7588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_init", "()V", (void *)android_media_MediaDrm_native_init },
7598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_setup", "(Ljava/lang/Object;[B)V",
7618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_native_setup },
7628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_finalize", "()V",
7648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_native_finalize },
7658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "isCryptoSchemeSupportedNative", "([B)Z",
7678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },
7688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "openSession", "()[B",
7708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_openSession },
7718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "closeSession", "([B)V",
7738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_closeSession },
7748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getLicenseRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
7768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      "Landroid/media/MediaDrm$LicenseRequest;",
7778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getLicenseRequest },
7788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "provideLicenseResponse", "([B[B)V",
7808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_provideLicenseResponse },
7818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "removeLicense", "([B)V",
7838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_removeLicense },
7848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "queryLicenseStatus", "([B)Ljava/util/HashMap;",
7868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_queryLicenseStatus },
7878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getProvisionRequest", "()Landroid/media/MediaDrm$ProvisionRequest;",
7898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getProvisionRequest },
7908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "provideProvisionResponse", "([B)V",
7928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_provideProvisionResponse },
7938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getSecureStops", "()Ljava/util/List;",
7958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getSecureStops },
7968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "releaseSecureStops", "([B)V",
7988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_releaseSecureStops },
7998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
8018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getPropertyString },
8028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getPropertyByteArray", "(Ljava/lang/String;)[B",
8048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getPropertyByteArray },
8058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "setPropertyString", "(Ljava/lang/String;Ljava/lang/String;)V",
8078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_setPropertyString },
8088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "setPropertyByteArray", "(Ljava/lang/String;[B)V",
8108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_setPropertyByteArray },
8118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
8128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerint register_android_media_Drm(JNIEnv *env) {
8148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return AndroidRuntime::registerNativeMethods(env,
8158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "android/media/MediaDrm", gMethods, NELEM(gMethods));
8168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
818