/*
 * Copyright 2013, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaDrm-JNI"
#include <utils/Log.h>

#include "android_media_MediaDrm.h"
#include "android_media_MediaMetricsJNI.h"
#include "android_os_Parcel.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "android_os_Parcel.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>

#include <android/hardware/drm/1.3/IDrmFactory.h>
#include <binder/Parcel.h>
#include <binder/PersistableBundle.h>
#include <cutils/properties.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaErrors.h>
#include <mediadrm/DrmMetricsConsumer.h>
#include <mediadrm/DrmUtils.h>
#include <mediadrm/IDrmMetricsConsumer.h>
#include <mediadrm/IDrm.h>
#include <utils/Vector.h>
#include <map>
#include <string>

using ::android::os::PersistableBundle;
namespace drm = ::android::hardware::drm;

namespace android {

#define FIND_CLASS(var, className) \
    var = env->FindClass(className); \
    LOG_FATAL_IF(! (var), "Unable to find class %s", className);

#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
    var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
    LOG_FATAL_IF(! (var), "Unable to find field %s", fieldName);

#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
    var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
    LOG_FATAL_IF(! (var), "Unable to find method %s", fieldName);

#define GET_STATIC_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
    var = env->GetStaticFieldID(clazz, fieldName, fieldDescriptor); \
    LOG_FATAL_IF(! (var), "Unable to find field %s", fieldName);

#define GET_STATIC_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
    var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
    LOG_FATAL_IF(! (var), "Unable to find static method %s", fieldName);

#define GET_STATIC_OBJECT_FIELD(var, clazz, fieldId) \
    var = env->GetStaticObjectField(clazz, fieldId); \
    LOG_FATAL_IF(! (var), "Unable to find static object field %p", fieldId);


struct RequestFields {
    jfieldID data;
    jfieldID defaultUrl;
    jfieldID requestType;
};

struct ArrayListFields {
    jmethodID init;
    jmethodID add;
};

struct HashmapFields {
    jmethodID init;
    jmethodID get;
    jmethodID put;
    jmethodID entrySet;
};

struct SetFields {
    jmethodID iterator;
};

struct IteratorFields {
    jmethodID next;
    jmethodID hasNext;
};

struct EntryFields {
    jmethodID getKey;
    jmethodID getValue;
};

struct EventTypes {
    jint kEventProvisionRequired;
    jint kEventKeyRequired;
    jint kEventKeyExpired;
    jint kEventVendorDefined;
    jint kEventSessionReclaimed;
} gEventTypes;

struct EventWhat {
    jint kWhatDrmEvent;
    jint kWhatExpirationUpdate;
    jint kWhatKeyStatusChange;
    jint kWhatSessionLostState;
} gEventWhat;

struct KeyTypes {
    jint kKeyTypeStreaming;
    jint kKeyTypeOffline;
    jint kKeyTypeRelease;
} gKeyTypes;

struct KeyRequestTypes {
    jint kKeyRequestTypeInitial;
    jint kKeyRequestTypeRenewal;
    jint kKeyRequestTypeRelease;
    jint kKeyRequestTypeNone;
    jint kKeyRequestTypeUpdate;
} gKeyRequestTypes;

struct CertificateTypes {
    jint kCertificateTypeNone;
    jint kCertificateTypeX509;
} gCertificateTypes;

struct CertificateFields {
    jfieldID wrappedPrivateKey;
    jfieldID certificateData;
};

struct StateExceptionFields {
    jmethodID init;
    jclass classId;
};

struct SessionExceptionFields {
    jmethodID init;
    jclass classId;
    jfieldID errorCode;
};

struct SessionExceptionErrorCodes {
    jint kErrorUnknown;
    jint kResourceContention;
} gSessionExceptionErrorCodes;

struct HDCPLevels {
    jint kHdcpLevelUnknown;
    jint kHdcpNone;
    jint kHdcpV1;
    jint kHdcpV2;
    jint kHdcpV2_1;
    jint kHdcpV2_2;
    jint kHdcpV2_3;
    jint kHdcpNoOutput;
} gHdcpLevels;

struct SecurityLevels {
    jint kSecurityLevelUnknown;
    jint kSecurityLevelMax;
    jint kSecurityLevelSwSecureCrypto;
    jint kSecurityLevelSwSecureDecode;
    jint kSecurityLevelHwSecureCrypto;
    jint kSecurityLevelHwSecureDecode;
    jint kSecurityLevelHwSecureAll;
} gSecurityLevels;

struct OfflineLicenseState {
    jint kOfflineLicenseStateUsable;
    jint kOfflineLicenseStateReleased;
    jint kOfflineLicenseStateUnknown;
} gOfflineLicenseStates;

struct KeyStatusFields {
    jmethodID init;
    jclass classId;
};

struct LogMessageFields {
    jmethodID init;
    jclass classId;
};

struct DrmExceptionFields {
    jmethodID init;
    jclass classId;
};

struct fields_t {
    jfieldID context;
    jmethodID post_event;
    RequestFields keyRequest;
    RequestFields provisionRequest;
    ArrayListFields arraylist;
    HashmapFields hashmap;
    SetFields set;
    IteratorFields iterator;
    EntryFields entry;
    CertificateFields certificate;
    StateExceptionFields stateException;
    SessionExceptionFields sessionException;
    jclass certificateClassId;
    jclass hashmapClassId;
    jclass arraylistClassId;
    jclass stringClassId;
    jobject bundleCreator;
    jmethodID createFromParcelId;
    jclass parcelCreatorClassId;
    KeyStatusFields keyStatus;
    LogMessageFields logMessage;
    std::map<std::string, DrmExceptionFields> exceptionCtors;
};

static fields_t gFields;

namespace {

jbyteArray hidlVectorToJByteArray(const hardware::hidl_vec<uint8_t> &vector) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    size_t length = vector.size();
    jbyteArray result = env->NewByteArray(length);
    if (result != NULL) {
        env->SetByteArrayRegion(result, 0, length, reinterpret_cast<const jbyte *>(vector.data()));
    }
    return result;
}

jobject hidlLogMessagesToJavaList(JNIEnv *env, const Vector<drm::V1_4::LogMessage> &logs) {
    jclass clazz = gFields.arraylistClassId;
    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
    clazz = gFields.logMessage.classId;
    for (auto log: logs) {
        jobject jLog = env->NewObject(clazz, gFields.logMessage.init,
                static_cast<jlong>(log.timeMs),
                static_cast<jint>(log.priority),
                env->NewStringUTF(log.message.c_str()));
        env->CallBooleanMethod(arrayList, gFields.arraylist.add, jLog);
    }
    return arrayList;
}

void resolveDrmExceptionCtor(JNIEnv *env, const char *className) {
    jclass clazz;
    jmethodID init;
    FIND_CLASS(clazz, className);
    GET_METHOD_ID(init, clazz, "<init>", "(Ljava/lang/String;III)V");
    gFields.exceptionCtors[std::string(className)] = {
        .init = init,
        .classId = static_cast<jclass>(env->NewGlobalRef(clazz))
        };
}

void drmThrowException(JNIEnv* env, const char *className, const DrmStatus &err, const char *msg) {
    using namespace android::jnihelp;

    if (gFields.exceptionCtors.count(std::string(className)) == 0) {
        jniThrowException(env, className, msg);
    } else {
        jstring _detailMessage = CreateExceptionMsg(env, msg);
        jobject exception = env->NewObject(gFields.exceptionCtors[std::string(className)].classId,
            gFields.exceptionCtors[std::string(className)].init, _detailMessage,
            err.getCdmErr(), err.getOemErr(), err.getContext());
        env->Throw(static_cast<jthrowable>(exception));
        if (_detailMessage != NULL) {
            env->DeleteLocalRef(_detailMessage);
        }
    }
}
}  // namespace anonymous

// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class JNIDrmListener: public DrmListener
{
public:
    JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
    ~JNIDrmListener();
    virtual void notify(DrmPlugin::EventType eventType, int extra, const ListenerArgs *arg = NULL);
private:
    JNIDrmListener();
    jclass      mClass;     // Reference to MediaDrm class
    jobject     mObject;    // Weak ref to MediaDrm Java object to call on
};

JNIDrmListener::JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
{
    // Hold onto the MediaDrm class for use in calling the static method
    // that posts events to the application thread.
    jclass clazz = env->GetObjectClass(thiz);
    if (clazz == NULL) {
        ALOGE("Can't find android/media/MediaDrm");
        jniThrowException(env, "java/lang/Exception",
                          "Can't find android/media/MediaDrm");
        return;
    }
    mClass = (jclass)env->NewGlobalRef(clazz);

    // We use a weak reference so the MediaDrm object can be garbage collected.
    // The reference is only used as a proxy for callbacks.
    mObject  = env->NewGlobalRef(weak_thiz);
}

JNIDrmListener::~JNIDrmListener()
{
    // remove global references
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    env->DeleteGlobalRef(mObject);
    env->DeleteGlobalRef(mClass);
}

void JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra,
                            const ListenerArgs *args)
{
    jint jwhat;
    jint jeventType = 0;

    // translate DrmPlugin event types into their java equivalents
    switch (eventType) {
        case DrmPlugin::kDrmPluginEventProvisionRequired:
            jwhat = gEventWhat.kWhatDrmEvent;
            jeventType = gEventTypes.kEventProvisionRequired;
            break;
        case DrmPlugin::kDrmPluginEventKeyNeeded:
            jwhat = gEventWhat.kWhatDrmEvent;
            jeventType = gEventTypes.kEventKeyRequired;
            break;
        case DrmPlugin::kDrmPluginEventKeyExpired:
            jwhat = gEventWhat.kWhatDrmEvent;
            jeventType = gEventTypes.kEventKeyExpired;
            break;
        case DrmPlugin::kDrmPluginEventVendorDefined:
            jwhat = gEventWhat.kWhatDrmEvent;
            jeventType = gEventTypes.kEventVendorDefined;
            break;
        case DrmPlugin::kDrmPluginEventSessionReclaimed:
            jwhat = gEventWhat.kWhatDrmEvent;
            jeventType = gEventTypes.kEventSessionReclaimed;
            break;
        case DrmPlugin::kDrmPluginEventExpirationUpdate:
            jwhat = gEventWhat.kWhatExpirationUpdate;
            break;
         case DrmPlugin::kDrmPluginEventKeysChange:
            jwhat = gEventWhat.kWhatKeyStatusChange;
            break;
         case DrmPlugin::kDrmPluginEventSessionLostState:
            jwhat = gEventWhat.kWhatSessionLostState;
            break;
        default:
            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
            return;
    }

    JNIEnv *env = AndroidRuntime::getJNIEnv();
    if (args) {
        env->CallStaticVoidMethod(mClass, gFields.post_event, mObject,
                jwhat, jeventType, extra,
                args->jSessionId, args->jData, args->jExpirationTime,
                args->jKeyStatusList, args->jHasNewUsableKey);
    }

    if (env->ExceptionCheck()) {
        ALOGW("An exception occurred while notifying an event.");
        LOGW_EX(env);
        env->ExceptionClear();
    }
}

jint MediaErrorToJavaError(status_t err) {
#define STATUS_CASE(status) \
    case status: \
        return J##status

    switch (err) {
        STATUS_CASE(ERROR_DRM_UNKNOWN);
        STATUS_CASE(ERROR_DRM_NO_LICENSE);
        STATUS_CASE(ERROR_DRM_LICENSE_EXPIRED);
        STATUS_CASE(ERROR_DRM_RESOURCE_BUSY);
        STATUS_CASE(ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION);
        STATUS_CASE(ERROR_DRM_SESSION_NOT_OPENED);
        STATUS_CASE(ERROR_DRM_CANNOT_HANDLE);
        STATUS_CASE(ERROR_DRM_INSUFFICIENT_SECURITY);
        STATUS_CASE(ERROR_DRM_FRAME_TOO_LARGE);
        STATUS_CASE(ERROR_DRM_SESSION_LOST_STATE);
        STATUS_CASE(ERROR_DRM_CERTIFICATE_MALFORMED);
        STATUS_CASE(ERROR_DRM_CERTIFICATE_MISSING);
        STATUS_CASE(ERROR_DRM_CRYPTO_LIBRARY);
        STATUS_CASE(ERROR_DRM_GENERIC_OEM);
        STATUS_CASE(ERROR_DRM_GENERIC_PLUGIN);
        STATUS_CASE(ERROR_DRM_INIT_DATA);
        STATUS_CASE(ERROR_DRM_KEY_NOT_LOADED);
        STATUS_CASE(ERROR_DRM_LICENSE_PARSE);
        STATUS_CASE(ERROR_DRM_LICENSE_POLICY);
        STATUS_CASE(ERROR_DRM_LICENSE_RELEASE);
        STATUS_CASE(ERROR_DRM_LICENSE_REQUEST_REJECTED);
        STATUS_CASE(ERROR_DRM_LICENSE_RESTORE);
        STATUS_CASE(ERROR_DRM_LICENSE_STATE);
        STATUS_CASE(ERROR_DRM_MEDIA_FRAMEWORK);
        STATUS_CASE(ERROR_DRM_PROVISIONING_CERTIFICATE);
        STATUS_CASE(ERROR_DRM_PROVISIONING_CONFIG);
        STATUS_CASE(ERROR_DRM_PROVISIONING_PARSE);
        STATUS_CASE(ERROR_DRM_PROVISIONING_REQUEST_REJECTED);
        STATUS_CASE(ERROR_DRM_PROVISIONING_RETRY);
        STATUS_CASE(ERROR_DRM_RESOURCE_CONTENTION);
        STATUS_CASE(ERROR_DRM_SECURE_STOP_RELEASE);
        STATUS_CASE(ERROR_DRM_STORAGE_READ);
        STATUS_CASE(ERROR_DRM_STORAGE_WRITE);
        STATUS_CASE(ERROR_DRM_ZERO_SUBSAMPLES);
#undef STATUS_CASE
    }
    return static_cast<jint>(err);
}

static void throwStateException(JNIEnv *env, const char *msg, const DrmStatus &err) {
    ALOGE("Illegal state exception: %s (%d)", msg, static_cast<status_t>(err));

    jint jerr = MediaErrorToJavaError(err);
    jobject exception = env->NewObject(gFields.stateException.classId,
            gFields.stateException.init, env->NewStringUTF(msg), static_cast<int>(jerr),
            err.getCdmErr(), err.getOemErr(), err.getContext());
    env->Throw(static_cast<jthrowable>(exception));
}

static void throwSessionException(JNIEnv *env, const char *msg, const DrmStatus &err) {
    ALOGE("Session exception: %s (%d)", msg, static_cast<status_t>(err));

    jint jErrorCode = 0;
    switch(err) {
        case ERROR_DRM_RESOURCE_CONTENTION:
            jErrorCode = gSessionExceptionErrorCodes.kResourceContention;
            break;
        default:
            break;
    }

    jobject exception = env->NewObject(gFields.sessionException.classId,
            gFields.sessionException.init,
            env->NewStringUTF(msg),
            jErrorCode,
            err.getCdmErr(),
            err.getOemErr(),
            err.getContext());

    env->Throw(static_cast<jthrowable>(exception));
}

static bool isSessionException(status_t err) {
    return err == ERROR_DRM_RESOURCE_CONTENTION;
}

static bool throwExceptionAsNecessary(
        JNIEnv *env, const sp<IDrm> &drm, const DrmStatus &err, const char *msg = NULL) {
    std::string msgStr;
    if (drm != NULL && err != OK) {
        msgStr = DrmUtils::GetExceptionMessage(err, msg, drm);
        msg = msgStr.c_str();
    }

    if (err == BAD_VALUE || err == ERROR_DRM_CANNOT_HANDLE) {
        jniThrowException(env, "java/lang/IllegalArgumentException", msg);
        return true;
    } else if (err == ERROR_UNSUPPORTED) {
        jniThrowException(env, "java/lang/UnsupportedOperationException", msg);
        return true;
    } else if (err == ERROR_DRM_NOT_PROVISIONED) {
        drmThrowException(env, "android/media/NotProvisionedException", err, msg);
        return true;
    } else if (err == ERROR_DRM_RESOURCE_BUSY) {
        drmThrowException(env, "android/media/ResourceBusyException", err, msg);
        return true;
    } else if (err == ERROR_DRM_DEVICE_REVOKED) {
        drmThrowException(env, "android/media/DeniedByServerException", err, msg);
        return true;
    } else if (err == DEAD_OBJECT) {
        jniThrowException(env, "android/media/MediaDrmResetException", msg);
        return true;
    } else if (isSessionException(err)) {
        throwSessionException(env, msg, err);
        return true;
    } else if (err != OK) {
        throwStateException(env, msg, err);
        return true;
    }
    return false;
}

static sp<IDrm> GetDrm(JNIEnv *env, jobject thiz) {
    JDrm *jdrm = (JDrm *)env->GetLongField(thiz, gFields.context);
    return jdrm ? jdrm->getDrm() : NULL;
}

JDrm::JDrm(
        JNIEnv *env, jobject thiz, const uint8_t uuid[16],
        const String8 &appPackageName) {
    mObject = env->NewWeakGlobalRef(thiz);
    mDrm = MakeDrm(uuid, appPackageName);
    if (mDrm != NULL) {
        mDrm->setListener(this);
    }
}

JDrm::~JDrm() {
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->DeleteWeakGlobalRef(mObject);
    mObject = NULL;
}

// static
sp<IDrm> JDrm::MakeDrm() {
    return DrmUtils::MakeDrm();
}

// static
sp<IDrm> JDrm::MakeDrm(const uint8_t uuid[16], const String8 &appPackageName) {
    sp<IDrm> drm = MakeDrm();

    if (drm == NULL) {
        return NULL;
    }

    DrmStatus err = drm->createPlugin(uuid, appPackageName);

    if (err != OK) {
        return NULL;
    }

    return drm;
}

status_t JDrm::setListener(const sp<DrmListener>& listener) {
    Mutex::Autolock lock(mLock);
    mListener = listener;
    return OK;
}

void JDrm::notify(DrmPlugin::EventType eventType, int extra, const ListenerArgs *args) {
    sp<DrmListener> listener;
    mLock.lock();
    listener = mListener;
    mLock.unlock();

    if (listener != NULL) {
        Mutex::Autolock lock(mNotifyLock);
        listener->notify(eventType, extra, args);
    }
}

void JDrm::sendEvent(
        DrmPlugin::EventType eventType,
        const hardware::hidl_vec<uint8_t> &sessionId,
        const hardware::hidl_vec<uint8_t> &data) {
    ListenerArgs args{
        .jSessionId = hidlVectorToJByteArray(sessionId),
        .jData = hidlVectorToJByteArray(data),
    };
    notify(eventType, 0, &args);
}

void JDrm::sendExpirationUpdate(
        const hardware::hidl_vec<uint8_t> &sessionId,
        int64_t expiryTimeInMS) {
    ListenerArgs args{
        .jSessionId = hidlVectorToJByteArray(sessionId),
        .jExpirationTime = expiryTimeInMS,
    };
    notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &args);
}

void JDrm::sendKeysChange(
        const hardware::hidl_vec<uint8_t> &sessionId,
        const std::vector<DrmKeyStatus> &keyStatusList,
        bool hasNewUsableKey) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass clazz = gFields.arraylistClassId;
    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
    clazz = gFields.keyStatus.classId;
    for (const auto &keyStatus : keyStatusList) {
        jbyteArray jKeyId(hidlVectorToJByteArray(keyStatus.keyId));
        jint jStatusCode(keyStatus.type);
        jobject jKeyStatus = env->NewObject(clazz, gFields.keyStatus.init, jKeyId, jStatusCode);
        env->CallBooleanMethod(arrayList, gFields.arraylist.add, jKeyStatus);
    }
    ListenerArgs args{
        .jSessionId = hidlVectorToJByteArray(sessionId),
        .jKeyStatusList = arrayList,
        .jHasNewUsableKey = hasNewUsableKey,
    };
    notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &args);
}

void JDrm::sendSessionLostState(
        const hardware::hidl_vec<uint8_t> &sessionId) {
    ListenerArgs args{
        .jSessionId = hidlVectorToJByteArray(sessionId),
    };
    notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &args);
}

void JDrm::disconnect() {
    if (mDrm != NULL) {
        mDrm->destroyPlugin();
        mDrm.clear();
    }
}


// static
status_t JDrm::IsCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType,
                                       DrmPlugin::SecurityLevel securityLevel, bool *isSupported) {
    sp<IDrm> drm = MakeDrm();

    if (drm == NULL) {
        return BAD_VALUE;
    }

    return drm->isCryptoSchemeSupported(uuid, mimeType, securityLevel, isSupported);
}

status_t JDrm::initCheck() const {
    return mDrm == NULL ? NO_INIT : OK;
}

// JNI conversion utilities
static Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray) {
    Vector<uint8_t> vector;
    size_t length = env->GetArrayLength(byteArray);
    vector.insertAt((size_t)0, length);
    env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
    return vector;
}

static jbyteArray VectorToJByteArray(JNIEnv *env, Vector<uint8_t> const &vector) {
    size_t length = vector.size();
    jbyteArray result = env->NewByteArray(length);
    if (result != NULL) {
        env->SetByteArrayRegion(result, 0, length, (jbyte *)vector.array());
    }
    return result;
}

static String8 JStringToString8(JNIEnv *env, jstring const &jstr) {
    String8 result;

    const char *s = env->GetStringUTFChars(jstr, NULL);
    if (s) {
        result = s;
        env->ReleaseStringUTFChars(jstr, s);
    }
    return result;
}

/*
    import java.util.HashMap;
    import java.util.Set;
    import java.Map.Entry;
    import jav.util.Iterator;

    HashMap<k, v> hm;
    Set<Entry<k, v>> s = hm.entrySet();
    Iterator i = s.iterator();
    Entry e = s.next();
*/

static KeyedVector<String8, String8> HashMapToKeyedVector(
    JNIEnv *env, jobject &hashMap, bool* pIsOK) {
    jclass clazz = gFields.stringClassId;
    KeyedVector<String8, String8> keyedVector;
    *pIsOK = true;

    jobject entrySet = env->CallObjectMethod(hashMap, gFields.hashmap.entrySet);
    if (entrySet) {
        jobject iterator = env->CallObjectMethod(entrySet, gFields.set.iterator);
        if (iterator) {
            jboolean hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
            while (hasNext) {
                jobject entry = env->CallObjectMethod(iterator, gFields.iterator.next);
                if (entry) {
                    jobject obj = env->CallObjectMethod(entry, gFields.entry.getKey);
                    if (obj == NULL || !env->IsInstanceOf(obj, clazz)) {
                        jniThrowException(env, "java/lang/IllegalArgumentException",
                                          "HashMap key is not a String");
                        env->DeleteLocalRef(entry);
                        *pIsOK = false;
                        break;
                    }
                    jstring jkey = static_cast<jstring>(obj);

                    obj = env->CallObjectMethod(entry, gFields.entry.getValue);
                    if (obj == NULL || !env->IsInstanceOf(obj, clazz)) {
                        jniThrowException(env, "java/lang/IllegalArgumentException",
                                          "HashMap value is not a String");
                        env->DeleteLocalRef(entry);
                        *pIsOK = false;
                        break;
                    }
                    jstring jvalue = static_cast<jstring>(obj);

                    String8 key = JStringToString8(env, jkey);
                    String8 value = JStringToString8(env, jvalue);
                    keyedVector.add(key, value);

                    env->DeleteLocalRef(jkey);
                    env->DeleteLocalRef(jvalue);
                    hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
                }
                env->DeleteLocalRef(entry);
            }
            env->DeleteLocalRef(iterator);
        }
        env->DeleteLocalRef(entrySet);
    }
    return keyedVector;
}

static jobject KeyedVectorToHashMap (JNIEnv *env, KeyedVector<String8, String8> const &map) {
    jclass clazz = gFields.hashmapClassId;
    jobject hashMap = env->NewObject(clazz, gFields.hashmap.init);
    for (size_t i = 0; i < map.size(); ++i) {
        jstring jkey = env->NewStringUTF(map.keyAt(i).c_str());
        jstring jvalue = env->NewStringUTF(map.valueAt(i).c_str());
        env->CallObjectMethod(hashMap, gFields.hashmap.put, jkey, jvalue);
        env->DeleteLocalRef(jkey);
        env->DeleteLocalRef(jvalue);
    }
    return hashMap;
}

static jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
                                                   List<Vector<uint8_t>> list) {
    jclass clazz = gFields.arraylistClassId;
    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
    List<Vector<uint8_t>>::iterator iter = list.begin();
    while (iter != list.end()) {
        jbyteArray byteArray = VectorToJByteArray(env, *iter);
        env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
        env->DeleteLocalRef(byteArray);
        iter++;
    }

    return arrayList;
}

}  // namespace android

using namespace android;

static sp<JDrm> setDrm(
        JNIEnv *env, jobject thiz, const sp<JDrm> &drm) {
    sp<JDrm> old = (JDrm *)env->GetLongField(thiz, gFields.context);
    if (drm != NULL) {
        drm->incStrong(thiz);
    }
    if (old != NULL) {
        old->decStrong(thiz);
    }
    env->SetLongField(thiz, gFields.context, reinterpret_cast<jlong>(drm.get()));

    return old;
}

static bool CheckDrm(JNIEnv *env, const sp<IDrm> &drm) {
    if (drm == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "MediaDrm obj is null");
        return false;
    }
    return true;
}

static bool CheckSession(JNIEnv *env, const sp<IDrm> &drm, jbyteArray const &jsessionId)
{
    if (!CheckDrm(env, drm)) {
        return false;
    }

    if (jsessionId == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "sessionId is null");
        return false;
    }
    return true;
}

static void android_media_MediaDrm_native_release(JNIEnv *env, jobject thiz) {
    sp<JDrm> drm = setDrm(env, thiz, NULL);
    if (drm != NULL) {
        drm->setListener(NULL);
        drm->disconnect();
    }
}

static void android_media_MediaDrm_native_init(JNIEnv *env) {
    jclass clazz;
    FIND_CLASS(clazz, "android/media/MediaDrm");
    GET_FIELD_ID(gFields.context, clazz, "mNativeContext", "J");
    GET_STATIC_METHOD_ID(gFields.post_event, clazz, "postEventFromNative",
                         "(Ljava/lang/Object;III[B[BJLjava/util/List;Z)V");

    jfieldID field;
    GET_STATIC_FIELD_ID(field, clazz, "EVENT_PROVISION_REQUIRED", "I");
    gEventTypes.kEventProvisionRequired = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_REQUIRED", "I");
    gEventTypes.kEventKeyRequired = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_EXPIRED", "I");
    gEventTypes.kEventKeyExpired = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "EVENT_VENDOR_DEFINED", "I");
    gEventTypes.kEventVendorDefined = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "EVENT_SESSION_RECLAIMED", "I");
    gEventTypes.kEventSessionReclaimed = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "DRM_EVENT", "I");
    gEventWhat.kWhatDrmEvent = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "EXPIRATION_UPDATE", "I");
    gEventWhat.kWhatExpirationUpdate = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "KEY_STATUS_CHANGE", "I");
    gEventWhat.kWhatKeyStatusChange = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "SESSION_LOST_STATE", "I");
    gEventWhat.kWhatSessionLostState = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I");
    gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_OFFLINE", "I");
    gKeyTypes.kKeyTypeOffline = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
    gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I");
    gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I");
    gCertificateTypes.kCertificateTypeX509 = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "HDCP_LEVEL_UNKNOWN", "I");
    gHdcpLevels.kHdcpLevelUnknown = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_NONE", "I");
    gHdcpLevels.kHdcpNone = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_V1", "I");
    gHdcpLevels.kHdcpV1 = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_V2", "I");
    gHdcpLevels.kHdcpV2 = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_V2_1", "I");
    gHdcpLevels.kHdcpV2_1 = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_V2_2", "I");
    gHdcpLevels.kHdcpV2_2 = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_V2_3", "I");
    gHdcpLevels.kHdcpV2_3 = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "HDCP_NO_DIGITAL_OUTPUT", "I");
    gHdcpLevels.kHdcpNoOutput = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_UNKNOWN", "I");
    gSecurityLevels.kSecurityLevelUnknown = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_SW_SECURE_CRYPTO", "I");
    gSecurityLevels.kSecurityLevelSwSecureCrypto = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_SW_SECURE_DECODE", "I");
    gSecurityLevels.kSecurityLevelSwSecureDecode = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_HW_SECURE_CRYPTO", "I");
    gSecurityLevels.kSecurityLevelHwSecureCrypto = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_HW_SECURE_DECODE", "I");
    gSecurityLevels.kSecurityLevelHwSecureDecode = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_HW_SECURE_ALL", "I");
    gSecurityLevels.kSecurityLevelHwSecureAll = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "OFFLINE_LICENSE_STATE_USABLE", "I");
    gOfflineLicenseStates.kOfflineLicenseStateUsable = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "OFFLINE_LICENSE_STATE_RELEASED", "I");
    gOfflineLicenseStates.kOfflineLicenseStateReleased = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "OFFLINE_LICENSE_STATE_UNKNOWN", "I");
    gOfflineLicenseStates.kOfflineLicenseStateUnknown = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_HW_SECURE_CRYPTO", "I");

    jmethodID getMaxSecurityLevel;
    GET_STATIC_METHOD_ID(getMaxSecurityLevel, clazz, "getMaxSecurityLevel", "()I");
    gSecurityLevels.kSecurityLevelMax = env->CallStaticIntMethod(clazz, getMaxSecurityLevel);

    FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
    GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
    GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
    GET_FIELD_ID(gFields.keyRequest.requestType, clazz, "mRequestType", "I");

    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I");
    gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I");
    gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I");
    gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_NONE", "I");
    gKeyRequestTypes.kKeyRequestTypeNone = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_UPDATE", "I");
    gKeyRequestTypes.kKeyRequestTypeUpdate = env->GetStaticIntField(clazz, field);

    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
    GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
    GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");

    FIND_CLASS(clazz, "android/media/MediaDrm$Certificate");
    GET_FIELD_ID(gFields.certificate.wrappedPrivateKey, clazz, "mWrappedKey", "[B");
    GET_FIELD_ID(gFields.certificate.certificateData, clazz, "mCertificateData", "[B");
    gFields.certificateClassId = static_cast<jclass>(env->NewGlobalRef(clazz));

    // Metrics-related fields and classes.
    FIND_CLASS(clazz, "android/os/PersistableBundle");
    jfieldID bundleCreatorId;
    GET_STATIC_FIELD_ID(bundleCreatorId, clazz, "CREATOR",
                        "Landroid/os/Parcelable$Creator;");
    jobject bundleCreator;
    GET_STATIC_OBJECT_FIELD(bundleCreator, clazz, bundleCreatorId);
    gFields.bundleCreator = static_cast<jobject>(env->NewGlobalRef(bundleCreator));
    FIND_CLASS(clazz, "android/os/Parcelable$Creator");
    GET_METHOD_ID(gFields.createFromParcelId, clazz, "createFromParcel",
                  "(Landroid/os/Parcel;)Ljava/lang/Object;");
    gFields.parcelCreatorClassId = static_cast<jclass>(env->NewGlobalRef(clazz));

    FIND_CLASS(clazz, "java/util/ArrayList");
    GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V");
    GET_METHOD_ID(gFields.arraylist.add, clazz, "add", "(Ljava/lang/Object;)Z");

    FIND_CLASS(clazz, "java/util/HashMap");
    GET_METHOD_ID(gFields.hashmap.init, clazz, "<init>", "()V");
    GET_METHOD_ID(gFields.hashmap.get, clazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
    GET_METHOD_ID(gFields.hashmap.put, clazz, "put",
                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    GET_METHOD_ID(gFields.hashmap.entrySet, clazz, "entrySet", "()Ljava/util/Set;");

    FIND_CLASS(clazz, "java/util/Set");
    GET_METHOD_ID(gFields.set.iterator, clazz, "iterator", "()Ljava/util/Iterator;");

    FIND_CLASS(clazz, "java/util/Iterator");
    GET_METHOD_ID(gFields.iterator.next, clazz, "next", "()Ljava/lang/Object;");
    GET_METHOD_ID(gFields.iterator.hasNext, clazz, "hasNext", "()Z");

    FIND_CLASS(clazz, "java/util/Map$Entry");
    GET_METHOD_ID(gFields.entry.getKey, clazz, "getKey", "()Ljava/lang/Object;");
    GET_METHOD_ID(gFields.entry.getValue, clazz, "getValue", "()Ljava/lang/Object;");

    FIND_CLASS(clazz, "java/util/HashMap");
    gFields.hashmapClassId = static_cast<jclass>(env->NewGlobalRef(clazz));

    FIND_CLASS(clazz, "java/lang/String");
    gFields.stringClassId = static_cast<jclass>(env->NewGlobalRef(clazz));

    FIND_CLASS(clazz, "java/util/ArrayList");
    gFields.arraylistClassId = static_cast<jclass>(env->NewGlobalRef(clazz));

    FIND_CLASS(clazz, "android/media/MediaDrm$MediaDrmStateException");
    GET_METHOD_ID(gFields.stateException.init, clazz, "<init>", "(Ljava/lang/String;IIII)V");
    gFields.stateException.classId = static_cast<jclass>(env->NewGlobalRef(clazz));

    FIND_CLASS(clazz, "android/media/MediaDrm$SessionException");
    GET_METHOD_ID(gFields.sessionException.init, clazz, "<init>", "(Ljava/lang/String;IIII)V");
    gFields.sessionException.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
    GET_FIELD_ID(gFields.sessionException.errorCode, clazz, "mErrorCode", "I");

    GET_STATIC_FIELD_ID(field, clazz, "ERROR_UNKNOWN", "I");
    gSessionExceptionErrorCodes.kErrorUnknown = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "ERROR_RESOURCE_CONTENTION", "I");
    gSessionExceptionErrorCodes.kResourceContention = env->GetStaticIntField(clazz, field);

    FIND_CLASS(clazz, "android/media/MediaDrm$KeyStatus");
    gFields.keyStatus.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
    GET_METHOD_ID(gFields.keyStatus.init, clazz, "<init>", "([BI)V");

    FIND_CLASS(clazz, "android/media/MediaDrm$LogMessage");
    gFields.logMessage.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
    GET_METHOD_ID(gFields.logMessage.init, clazz, "<init>", "(JILjava/lang/String;)V");

    resolveDrmExceptionCtor(env, "android/media/NotProvisionedException");
    resolveDrmExceptionCtor(env, "android/media/ResourceBusyException");
    resolveDrmExceptionCtor(env, "android/media/DeniedByServerException");
}

static void android_media_MediaDrm_native_setup(
        JNIEnv *env, jobject thiz,
        jobject weak_this, jbyteArray uuidObj, jstring jappPackageName) {

    if (uuidObj == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "uuid is null");
        return;
    }

    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);

    if (uuid.size() != 16) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "invalid UUID size, expected 16 bytes");
        return;
    }

    String8 packageName;
    if (jappPackageName == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "application package name cannot be null");
        return;
    }

    packageName = JStringToString8(env, jappPackageName);
    sp<JDrm> drm = new JDrm(env, thiz, uuid.array(), packageName);

    status_t err = drm->initCheck();

    if (err != OK) {
        auto logs(DrmUtils::gLogBuf.getLogs());
        auto msg(DrmUtils::GetExceptionMessage(err, "Failed to instantiate drm object", logs));
        jniThrowException(
                env,
                "android/media/UnsupportedSchemeException",
                msg.c_str());
        return;
    }

    sp<JNIDrmListener> listener = new JNIDrmListener(env, thiz, weak_this);
    drm->setListener(listener);
    setDrm(env, thiz, drm);
}

DrmPlugin::SecurityLevel jintToSecurityLevel(jint jlevel) {
    DrmPlugin::SecurityLevel level;

    if (jlevel == gSecurityLevels.kSecurityLevelMax) {
        level = DrmPlugin::kSecurityLevelMax;
    }  else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureCrypto) {
        level = DrmPlugin::kSecurityLevelSwSecureCrypto;
    } else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureDecode) {
        level = DrmPlugin::kSecurityLevelSwSecureDecode;
    } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureCrypto) {
        level = DrmPlugin::kSecurityLevelHwSecureCrypto;
    } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureDecode) {
        level = DrmPlugin::kSecurityLevelHwSecureDecode;
    } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureAll) {
        level = DrmPlugin::kSecurityLevelHwSecureAll;
    } else {
        level = DrmPlugin::kSecurityLevelUnknown;
    }
    return level;
}

static jbyteArray android_media_MediaDrm_getSupportedCryptoSchemesNative(JNIEnv *env) {
    sp<IDrm> drm = android::DrmUtils::MakeDrm();
    if (drm == NULL) return env->NewByteArray(0);

    std::vector<uint8_t> bv;
    drm->getSupportedSchemes(bv);
    jbyteArray jUuidBytes = env->NewByteArray(bv.size());
    env->SetByteArrayRegion(jUuidBytes, 0, bv.size(), reinterpret_cast<const jbyte *>(bv.data()));
    return jUuidBytes;
}

static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
        JNIEnv *env, jobject /* thiz */, jbyteArray uuidObj, jstring jmimeType,
        jint jSecurityLevel) {

    if (uuidObj == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return false;
    }

    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);

    if (uuid.size() != 16) {
        jniThrowException(
                env,
                "java/lang/IllegalArgumentException",
                "invalid UUID size, expected 16 bytes");
        return false;
    }

    String8 mimeType;
    if (jmimeType != NULL) {
        mimeType = JStringToString8(env, jmimeType);
    }
    DrmPlugin::SecurityLevel securityLevel = jintToSecurityLevel(jSecurityLevel);

    bool isSupported;
    status_t err = JDrm::IsCryptoSchemeSupported(uuid.array(), mimeType,
            securityLevel, &isSupported);

    if (throwExceptionAsNecessary(env, NULL, err, "Failed to query crypto scheme support")) {
        return false;
    }
    return isSupported;
}

static jbyteArray android_media_MediaDrm_openSession(
        JNIEnv *env, jobject thiz, jint jlevel) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    Vector<uint8_t> sessionId;
    DrmPlugin::SecurityLevel level = jintToSecurityLevel(jlevel);
    if (level == DrmPlugin::kSecurityLevelUnknown) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid security level");
        return NULL;
    }

    DrmStatus err = drm->openSession(level, sessionId);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to open session")) {
        return NULL;
    }

    return VectorToJByteArray(env, sessionId);
}

static void android_media_MediaDrm_closeSession(
    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckSession(env, drm, jsessionId)) {
        return;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    DrmStatus err = drm->closeSession(sessionId);

    throwExceptionAsNecessary(env, drm, err, "Failed to close session");
}

static jobject android_media_MediaDrm_getKeyRequest(
    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jinitData,
    jstring jmimeType, jint jkeyType, jobject joptParams) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    Vector<uint8_t> initData;
    if (jinitData != NULL) {
        initData = JByteArrayToVector(env, jinitData);
    }

    String8 mimeType;
    if (jmimeType != NULL) {
        mimeType = JStringToString8(env, jmimeType);
    }

    DrmPlugin::KeyType keyType;
    if (jkeyType == gKeyTypes.kKeyTypeStreaming) {
        keyType = DrmPlugin::kKeyType_Streaming;
    } else if (jkeyType == gKeyTypes.kKeyTypeOffline) {
        keyType = DrmPlugin::kKeyType_Offline;
    } else if (jkeyType == gKeyTypes.kKeyTypeRelease) {
        keyType = DrmPlugin::kKeyType_Release;
    } else {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "invalid keyType");
        return NULL;
    }

    KeyedVector<String8, String8> optParams;
    if (joptParams != NULL) {
        bool isOK;
        optParams = HashMapToKeyedVector(env, joptParams, &isOK);
        if (!isOK) {
            return NULL;
        }
    }

    Vector<uint8_t> request;
    String8 defaultUrl;
    DrmPlugin::KeyRequestType keyRequestType;

    DrmStatus err = drm->getKeyRequest(sessionId, initData, mimeType, keyType, optParams, request,
                                       defaultUrl, &keyRequestType);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get key request")) {
        return NULL;
    }

    // Fill out return obj
    jclass clazz;
    FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");

    jobject keyObj = NULL;

    if (clazz) {
        keyObj = env->AllocObject(clazz);
        jbyteArray jrequest = VectorToJByteArray(env, request);
        env->SetObjectField(keyObj, gFields.keyRequest.data, jrequest);

        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.c_str());
        env->SetObjectField(keyObj, gFields.keyRequest.defaultUrl, jdefaultUrl);

        switch (keyRequestType) {
            case DrmPlugin::kKeyRequestType_Initial:
                env->SetIntField(keyObj, gFields.keyRequest.requestType,
                        gKeyRequestTypes.kKeyRequestTypeInitial);
                break;
            case DrmPlugin::kKeyRequestType_Renewal:
                env->SetIntField(keyObj, gFields.keyRequest.requestType,
                        gKeyRequestTypes.kKeyRequestTypeRenewal);
                break;
            case DrmPlugin::kKeyRequestType_Release:
                env->SetIntField(keyObj, gFields.keyRequest.requestType,
                        gKeyRequestTypes.kKeyRequestTypeRelease);
                break;
            case DrmPlugin::kKeyRequestType_None:
                env->SetIntField(keyObj, gFields.keyRequest.requestType,
                        gKeyRequestTypes.kKeyRequestTypeNone);
                break;
            case DrmPlugin::kKeyRequestType_Update:
                env->SetIntField(keyObj, gFields.keyRequest.requestType,
                        gKeyRequestTypes.kKeyRequestTypeUpdate);
                break;

            default:
                throwStateException(env, "DRM plugin failure: unknown key request type",
                        ERROR_DRM_UNKNOWN);
                break;
        }
    }

    return keyObj;
}

static jbyteArray android_media_MediaDrm_provideKeyResponse(
    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jresponse) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    if (jresponse == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "key response is null");
        return NULL;
    }
    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
    Vector<uint8_t> keySetId;

    DrmStatus err = drm->provideKeyResponse(sessionId, response, keySetId);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to handle key response")) {
        return NULL;
    }
    return VectorToJByteArray(env, keySetId);
}

static void android_media_MediaDrm_removeKeys(
    JNIEnv *env, jobject thiz, jbyteArray jkeysetId) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    if (jkeysetId == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "keySetId is null");
        return;
    }

    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));

    DrmStatus err = drm->removeKeys(keySetId);

    throwExceptionAsNecessary(env, drm, err, "Failed to remove keys");
}

static void android_media_MediaDrm_restoreKeys(
    JNIEnv *env, jobject thiz, jbyteArray jsessionId,
    jbyteArray jkeysetId) {

    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckSession(env, drm, jsessionId)) {
        return;
    }

    if (jkeysetId == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));

    DrmStatus err = drm->restoreKeys(sessionId, keySetId);

    throwExceptionAsNecessary(env, drm, err, "Failed to restore keys");
}

static jobject android_media_MediaDrm_queryKeyStatus(
    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }
    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    KeyedVector<String8, String8> infoMap;

    DrmStatus err = drm->queryKeyStatus(sessionId, infoMap);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to query key status")) {
        return NULL;
    }

    return KeyedVectorToHashMap(env, infoMap);
}

static jobject android_media_MediaDrm_getProvisionRequestNative(
    JNIEnv *env, jobject thiz, jint jcertType, jstring jcertAuthority) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    Vector<uint8_t> request;
    String8 defaultUrl;

    String8 certType;
    if (jcertType == gCertificateTypes.kCertificateTypeX509) {
        certType = "X.509";
    } else if (jcertType == gCertificateTypes.kCertificateTypeNone) {
        certType = "none";
    } else {
        certType = "invalid";
    }

    String8 certAuthority = JStringToString8(env, jcertAuthority);
    DrmStatus err = drm->getProvisionRequest(certType, certAuthority, request, defaultUrl);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get provision request")) {
        return NULL;
    }

    // Fill out return obj
    jclass clazz;
    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");

    jobject provisionObj = NULL;

    if (clazz) {
        provisionObj = env->AllocObject(clazz);
        jbyteArray jrequest = VectorToJByteArray(env, request);
        env->SetObjectField(provisionObj, gFields.provisionRequest.data, jrequest);

        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.c_str());
        env->SetObjectField(provisionObj, gFields.provisionRequest.defaultUrl, jdefaultUrl);
    }

    return provisionObj;
}

static jobject android_media_MediaDrm_provideProvisionResponseNative(
    JNIEnv *env, jobject thiz, jbyteArray jresponse) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    if (jresponse == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "provision response is null");
        return NULL;
    }

    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
    Vector<uint8_t> certificate, wrappedKey;

    DrmStatus err = drm->provideProvisionResponse(response, certificate, wrappedKey);

    // Fill out return obj
    jclass clazz = gFields.certificateClassId;

    jobject certificateObj = NULL;

    if (clazz && certificate.size() && wrappedKey.size()) {
        certificateObj = env->AllocObject(clazz);
        jbyteArray jcertificate = VectorToJByteArray(env, certificate);
        env->SetObjectField(certificateObj, gFields.certificate.certificateData, jcertificate);

        jbyteArray jwrappedKey = VectorToJByteArray(env, wrappedKey);
        env->SetObjectField(certificateObj, gFields.certificate.wrappedPrivateKey, jwrappedKey);
    }

    throwExceptionAsNecessary(env, drm, err, "Failed to handle provision response");
    return certificateObj;
}

static jobject android_media_MediaDrm_getSecureStops(
    JNIEnv *env, jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    List<Vector<uint8_t>> secureStops;

    DrmStatus err = drm->getSecureStops(secureStops);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get secure stops")) {
        return NULL;
    }

    return ListOfVectorsToArrayListOfByteArray(env, secureStops);
}

static jobject android_media_MediaDrm_getSecureStopIds(
    JNIEnv *env, jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    List<Vector<uint8_t>> secureStopIds;

    DrmStatus err = drm->getSecureStopIds(secureStopIds);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get secure stop Ids")) {
        return NULL;
    }

    return ListOfVectorsToArrayListOfByteArray(env, secureStopIds);
}

static jbyteArray android_media_MediaDrm_getSecureStop(
    JNIEnv *env, jobject thiz, jbyteArray ssid) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    Vector<uint8_t> secureStop;

    DrmStatus err = drm->getSecureStop(JByteArrayToVector(env, ssid), secureStop);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get secure stop")) {
        return NULL;
    }

    return VectorToJByteArray(env, secureStop);
}

static void android_media_MediaDrm_releaseSecureStops(
    JNIEnv *env, jobject thiz, jbyteArray jssRelease) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    Vector<uint8_t> ssRelease(JByteArrayToVector(env, jssRelease));

    DrmStatus err = drm->releaseSecureStops(ssRelease);

    throwExceptionAsNecessary(env, drm, err, "Failed to release secure stops");
}

static void android_media_MediaDrm_removeSecureStop(
        JNIEnv *env, jobject thiz, jbyteArray ssid) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    DrmStatus err = drm->removeSecureStop(JByteArrayToVector(env, ssid));

    throwExceptionAsNecessary(env, drm, err, "Failed to remove secure stop");
}

static void android_media_MediaDrm_removeAllSecureStops(
    JNIEnv *env, jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    DrmStatus err = drm->removeAllSecureStops();

    throwExceptionAsNecessary(env, drm, err, "Failed to remove all secure stops");
}


static jint HdcpLevelTojint(DrmPlugin::HdcpLevel level) {
    switch(level) {
    case DrmPlugin::kHdcpLevelUnknown:
        return gHdcpLevels.kHdcpLevelUnknown;
    case DrmPlugin::kHdcpNone:
        return gHdcpLevels.kHdcpNone;
    case DrmPlugin::kHdcpV1:
        return gHdcpLevels.kHdcpV1;
    case DrmPlugin::kHdcpV2:
        return gHdcpLevels.kHdcpV2;
    case DrmPlugin::kHdcpV2_1:
        return gHdcpLevels.kHdcpV2_1;
    case DrmPlugin::kHdcpV2_2:
        return gHdcpLevels.kHdcpV2_2;
    case DrmPlugin::kHdcpV2_3:
        return gHdcpLevels.kHdcpV2_3;
    case DrmPlugin::kHdcpNoOutput:
        return gHdcpLevels.kHdcpNoOutput;
    }
    return gHdcpLevels.kHdcpNone;
}

static jint android_media_MediaDrm_getConnectedHdcpLevel(JNIEnv *env,
        jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return gHdcpLevels.kHdcpNone;
    }

    DrmPlugin::HdcpLevel connected = DrmPlugin::kHdcpNone;
    DrmPlugin::HdcpLevel max = DrmPlugin::kHdcpNone;

    DrmStatus err = drm->getHdcpLevels(&connected, &max);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get HDCP levels")) {
        return gHdcpLevels.kHdcpLevelUnknown;
    }
    return HdcpLevelTojint(connected);
}

static jint android_media_MediaDrm_getMaxHdcpLevel(JNIEnv *env,
        jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return gHdcpLevels.kHdcpLevelUnknown;
    }

    DrmPlugin::HdcpLevel connected = DrmPlugin::kHdcpLevelUnknown;
    DrmPlugin::HdcpLevel max = DrmPlugin::kHdcpLevelUnknown;

    DrmStatus err = drm->getHdcpLevels(&connected, &max);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get HDCP levels")) {
        return gHdcpLevels.kHdcpLevelUnknown;
    }
    return HdcpLevelTojint(max);
}

static jint android_media_MediaDrm_getOpenSessionCount(JNIEnv *env,
        jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return 0;
    }

    uint32_t open = 0, max = 0;
    DrmStatus err = drm->getNumberOfSessions(&open, &max);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get number of sessions")) {
        return 0;
    }
    return open;
}

static jint android_media_MediaDrm_getMaxSessionCount(JNIEnv *env,
        jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return 0;
    }

    uint32_t open = 0, max = 0;
    DrmStatus err = drm->getNumberOfSessions(&open, &max);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get number of sessions")) {
        return 0;
    }
    return max;
}

static jint android_media_MediaDrm_getSecurityLevel(JNIEnv *env,
        jobject thiz, jbyteArray jsessionId) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckSession(env, drm, jsessionId)) {
        return gSecurityLevels.kSecurityLevelUnknown;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    DrmPlugin::SecurityLevel level = DrmPlugin::kSecurityLevelUnknown;

    DrmStatus err = drm->getSecurityLevel(sessionId, &level);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get security level")) {
        return gSecurityLevels.kSecurityLevelUnknown;
    }

    switch(level) {
    case DrmPlugin::kSecurityLevelSwSecureCrypto:
        return gSecurityLevels.kSecurityLevelSwSecureCrypto;
    case DrmPlugin::kSecurityLevelSwSecureDecode:
        return gSecurityLevels.kSecurityLevelSwSecureDecode;
    case DrmPlugin::kSecurityLevelHwSecureCrypto:
        return gSecurityLevels.kSecurityLevelHwSecureCrypto;
    case DrmPlugin::kSecurityLevelHwSecureDecode:
        return gSecurityLevels.kSecurityLevelHwSecureDecode;
    case DrmPlugin::kSecurityLevelHwSecureAll:
        return gSecurityLevels.kSecurityLevelHwSecureAll;
    default:
        return gSecurityLevels.kSecurityLevelUnknown;
    }
}

static jobject android_media_MediaDrm_getOfflineLicenseKeySetIds(
    JNIEnv *env, jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    List<Vector<uint8_t> > keySetIds;

    DrmStatus err = drm->getOfflineLicenseKeySetIds(keySetIds);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get offline key set Ids")) {
        return NULL;
    }

    return ListOfVectorsToArrayListOfByteArray(env, keySetIds);
}

static void android_media_MediaDrm_removeOfflineLicense(
        JNIEnv *env, jobject thiz, jbyteArray keySetId) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    DrmStatus err = drm->removeOfflineLicense(JByteArrayToVector(env, keySetId));

    throwExceptionAsNecessary(env, drm, err, "Failed to remove offline license");
}

static jint android_media_MediaDrm_getOfflineLicenseState(JNIEnv *env,
        jobject thiz, jbyteArray jkeySetId) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return gOfflineLicenseStates.kOfflineLicenseStateUnknown;
    }

    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeySetId));

    DrmPlugin::OfflineLicenseState state = DrmPlugin::kOfflineLicenseStateUnknown;

    DrmStatus err = drm->getOfflineLicenseState(keySetId, &state);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get offline license state")) {
        return gOfflineLicenseStates.kOfflineLicenseStateUnknown;
    }

    switch(state) {
    case DrmPlugin::kOfflineLicenseStateUsable:
        return gOfflineLicenseStates.kOfflineLicenseStateUsable;
    case DrmPlugin::kOfflineLicenseStateReleased:
        return gOfflineLicenseStates.kOfflineLicenseStateReleased;
    default:
        return gOfflineLicenseStates.kOfflineLicenseStateUnknown;
    }
}

static jstring android_media_MediaDrm_getPropertyString(
    JNIEnv *env, jobject thiz, jstring jname) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    if (jname == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "property name String is null");
        return NULL;
    }

    String8 name = JStringToString8(env, jname);
    String8 value;

    DrmStatus err = drm->getPropertyString(name, value);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get property")) {
        return NULL;
    }

    return env->NewStringUTF(value.c_str());
}

static jbyteArray android_media_MediaDrm_getPropertyByteArray(
    JNIEnv *env, jobject thiz, jstring jname) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    if (jname == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "property name String is null");
        return NULL;
    }

    String8 name = JStringToString8(env, jname);
    Vector<uint8_t> value;

    DrmStatus err = drm->getPropertyByteArray(name, value);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to get property")) {
        return NULL;
    }

    return VectorToJByteArray(env, value);
}

static void android_media_MediaDrm_setPropertyString(
    JNIEnv *env, jobject thiz, jstring jname, jstring jvalue) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    if (jname == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "property name String is null");
        return;
    }

    if (jvalue == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "property value String is null");
        return;
    }

    String8 name = JStringToString8(env, jname);
    String8 value = JStringToString8(env, jvalue);

    DrmStatus err = drm->setPropertyString(name, value);

    throwExceptionAsNecessary(env, drm, err, "Failed to set property");
}

static void android_media_MediaDrm_setPropertyByteArray(
    JNIEnv *env, jobject thiz, jstring jname, jbyteArray jvalue) {
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return;
    }

    if (jname == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "property name String is null");
        return;
    }

    if (jvalue == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "property value byte array is null");
        return;
    }

    String8 name = JStringToString8(env, jname);
    Vector<uint8_t> value = JByteArrayToVector(env, jvalue);

    DrmStatus err = drm->setPropertyByteArray(name, value);

    throwExceptionAsNecessary(env, drm, err, "Failed to set property");
}

static void android_media_MediaDrm_setCipherAlgorithmNative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jstring jalgorithm) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return;
    }

    if (jalgorithm == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "algorithm String is null");
        return;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    String8 algorithm = JStringToString8(env, jalgorithm);

    DrmStatus err = drm->setCipherAlgorithm(sessionId, algorithm);

    throwExceptionAsNecessary(env, drm, err, "Failed to set cipher algorithm");
}

static void android_media_MediaDrm_setMacAlgorithmNative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jstring jalgorithm) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return;
    }

    if (jalgorithm == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "algorithm String is null");
        return;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    String8 algorithm = JStringToString8(env, jalgorithm);

    DrmStatus err = drm->setMacAlgorithm(sessionId, algorithm);

    throwExceptionAsNecessary(env, drm, err, "Failed to set mac algorithm");
}


static jbyteArray android_media_MediaDrm_encryptNative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }

    if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "required argument is null");
        return NULL;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
    Vector<uint8_t> input(JByteArrayToVector(env, jinput));
    Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
    Vector<uint8_t> output;

    DrmStatus err = drm->encrypt(sessionId, keyId, input, iv, output);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to encrypt")) {
        return NULL;
    }

    return VectorToJByteArray(env, output);
}

static jbyteArray android_media_MediaDrm_decryptNative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }

    if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "required argument is null");
        return NULL;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
    Vector<uint8_t> input(JByteArrayToVector(env, jinput));
    Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
    Vector<uint8_t> output;

    DrmStatus err = drm->decrypt(sessionId, keyId, input, iv, output);
    if (throwExceptionAsNecessary(env, drm, err, "Failed to decrypt")) {
        return NULL;
    }

    return VectorToJByteArray(env, output);
}

static jbyteArray android_media_MediaDrm_signNative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jbyteArray jkeyId, jbyteArray jmessage) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }

    if (jkeyId == NULL || jmessage == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "required argument is null");
        return NULL;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
    Vector<uint8_t> signature;

    DrmStatus err = drm->sign(sessionId, keyId, message, signature);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to sign")) {
        return NULL;
    }

    return VectorToJByteArray(env, signature);
}

static jboolean android_media_MediaDrm_verifyNative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jbyteArray jkeyId, jbyteArray jmessage, jbyteArray jsignature) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return false;
    }

    if (jkeyId == NULL || jmessage == NULL || jsignature == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "required argument is null");
        return false;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
    Vector<uint8_t> signature(JByteArrayToVector(env, jsignature));
    bool match;

    DrmStatus err = drm->verify(sessionId, keyId, message, signature, match);

    throwExceptionAsNecessary(env, drm, err, "Failed to verify");
    return match;
}

static jobject
android_media_MediaDrm_native_getMetrics(JNIEnv *env, jobject thiz)
{
    sp<IDrm> drm = GetDrm(env, thiz);

    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    // Retrieve current metrics snapshot from drm.
    PersistableBundle metrics;
    sp<IDrmMetricsConsumer> consumer(new DrmMetricsConsumer(&metrics));
    DrmStatus err = drm->getMetrics(consumer);
    if (err != OK) {
        ALOGE("getMetrics failed: %d", (int)err);
        return (jobject) NULL;
    }

    return MediaMetricsJNI::nativeToJavaPersistableBundle(env, &metrics);
}

static jbyteArray android_media_MediaDrm_signRSANative(
    JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
    jstring jalgorithm, jbyteArray jwrappedKey, jbyteArray jmessage) {

    sp<IDrm> drm = GetDrm(env, jdrm);

    if (!CheckSession(env, drm, jsessionId)) {
        return NULL;
    }

    if (jalgorithm == NULL || jwrappedKey == NULL || jmessage == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException",
                          "required argument is null");
        return NULL;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
    String8 algorithm = JStringToString8(env, jalgorithm);
    Vector<uint8_t> wrappedKey(JByteArrayToVector(env, jwrappedKey));
    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
    Vector<uint8_t> signature;

    DrmStatus err = drm->signRSA(sessionId, algorithm, message, wrappedKey, signature);

    if (throwExceptionAsNecessary(env, drm, err, "Failed to sign")) {
        return NULL;
    }

    return VectorToJByteArray(env, signature);
}

static jboolean android_media_MediaDrm_requiresSecureDecoder(
        JNIEnv *env, jobject thiz, jstring jmimeType,
        jint jSecurityLevel) {
    sp<IDrm> drm = GetDrm(env, thiz);
    if (!CheckDrm(env, drm)) {
        return JNI_FALSE;
    }

    String8 mimeType;
    if (jmimeType != NULL) {
        mimeType = JStringToString8(env, jmimeType);
    }

    DrmPlugin::SecurityLevel securityLevel = jintToSecurityLevel(jSecurityLevel);
    if (securityLevel == DrmPlugin::kSecurityLevelUnknown) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid security level");
        return JNI_FALSE;
    }

    bool required = false;
    DrmStatus err = OK;
    if (securityLevel == DrmPlugin::kSecurityLevelMax) {
        err = drm->requiresSecureDecoder(mimeType.c_str(), &required);
    } else {
        err = drm->requiresSecureDecoder(mimeType.c_str(), securityLevel, &required);
    }
    if (throwExceptionAsNecessary(env, drm, err, "Failed to query secure decoder requirement")) {
        return false;
    }
    return required;
}

static void android_media_MediaDrm_setPlaybackId(
        JNIEnv *env, jobject thiz, jbyteArray jsessionId,
        jstring jplaybackId) {
    sp<IDrm> drm = GetDrm(env, thiz);
    if (!CheckSession(env, drm, jsessionId)) {
        return;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    String8 playbackId;
    if (jplaybackId != NULL) {
        playbackId = JStringToString8(env, jplaybackId);
    }
    DrmStatus err = drm->setPlaybackId(sessionId, playbackId.c_str());
    throwExceptionAsNecessary(env, drm, err, "Failed to set playbackId");
}

static jobject android_media_MediaDrm_getLogMessages(
        JNIEnv *env, jobject thiz) {
    sp<IDrm> drm = GetDrm(env, thiz);
    if (!CheckDrm(env, drm)) {
        return NULL;
    }

    Vector<drm::V1_4::LogMessage> logs;
    DrmStatus err = drm->getLogMessages(logs);
    ALOGI("drm->getLogMessages %zu logs", logs.size());
    if (throwExceptionAsNecessary(env, drm, err, "Failed to get log messages")) {
        return NULL;
    }
    return hidlLogMessagesToJavaList(env, logs);
}

static const JNINativeMethod gMethods[] = {
    { "native_release", "()V", (void *)android_media_MediaDrm_native_release },

    { "native_init", "()V", (void *)android_media_MediaDrm_native_init },

    { "native_setup", "(Ljava/lang/Object;[BLjava/lang/String;)V",
      (void *)android_media_MediaDrm_native_setup },

    { "getSupportedCryptoSchemesNative", "()[B",
      (void *)android_media_MediaDrm_getSupportedCryptoSchemesNative },

    { "isCryptoSchemeSupportedNative", "([BLjava/lang/String;I)Z",
      (void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },

    { "openSessionNative", "(I)[B",
      (void *)android_media_MediaDrm_openSession },

    { "closeSessionNative", "([B)V",
      (void *)android_media_MediaDrm_closeSession },

    { "getKeyRequestNative", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
      "Landroid/media/MediaDrm$KeyRequest;",
      (void *)android_media_MediaDrm_getKeyRequest },

    { "provideKeyResponse", "([B[B)[B",
      (void *)android_media_MediaDrm_provideKeyResponse },

    { "removeKeys", "([B)V",
      (void *)android_media_MediaDrm_removeKeys },

    { "restoreKeys", "([B[B)V",
      (void *)android_media_MediaDrm_restoreKeys },

    { "queryKeyStatus", "([B)Ljava/util/HashMap;",
      (void *)android_media_MediaDrm_queryKeyStatus },

    { "getProvisionRequestNative", "(ILjava/lang/String;)Landroid/media/MediaDrm$ProvisionRequest;",
      (void *)android_media_MediaDrm_getProvisionRequestNative },

    { "provideProvisionResponseNative", "([B)Landroid/media/MediaDrm$Certificate;",
      (void *)android_media_MediaDrm_provideProvisionResponseNative },

    { "getSecureStops", "()Ljava/util/List;",
      (void *)android_media_MediaDrm_getSecureStops },

    { "getSecureStopIds", "()Ljava/util/List;",
      (void *)android_media_MediaDrm_getSecureStopIds },

    { "getSecureStop", "([B)[B",
      (void *)android_media_MediaDrm_getSecureStop },

    { "releaseSecureStops", "([B)V",
      (void *)android_media_MediaDrm_releaseSecureStops },

    { "removeSecureStop", "([B)V",
      (void *)android_media_MediaDrm_removeSecureStop },

    { "removeAllSecureStops", "()V",
      (void *)android_media_MediaDrm_removeAllSecureStops },

    { "getConnectedHdcpLevel", "()I",
      (void *)android_media_MediaDrm_getConnectedHdcpLevel },

    { "getMaxHdcpLevel", "()I",
      (void *)android_media_MediaDrm_getMaxHdcpLevel },

    { "getOpenSessionCount", "()I",
      (void *)android_media_MediaDrm_getOpenSessionCount },

    { "getMaxSessionCount", "()I",
      (void *)android_media_MediaDrm_getMaxSessionCount },

    { "getSecurityLevel", "([B)I",
      (void *)android_media_MediaDrm_getSecurityLevel },

    { "removeOfflineLicense", "([B)V",
      (void *)android_media_MediaDrm_removeOfflineLicense },

    { "getOfflineLicenseKeySetIds", "()Ljava/util/List;",
      (void *)android_media_MediaDrm_getOfflineLicenseKeySetIds },

    { "getOfflineLicenseState", "([B)I",
      (void *)android_media_MediaDrm_getOfflineLicenseState },

    { "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
      (void *)android_media_MediaDrm_getPropertyString },

    { "getPropertyByteArray", "(Ljava/lang/String;)[B",
      (void *)android_media_MediaDrm_getPropertyByteArray },

    { "setPropertyString", "(Ljava/lang/String;Ljava/lang/String;)V",
      (void *)android_media_MediaDrm_setPropertyString },

    { "setPropertyByteArray", "(Ljava/lang/String;[B)V",
      (void *)android_media_MediaDrm_setPropertyByteArray },

    { "setCipherAlgorithmNative",
      "(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
      (void *)android_media_MediaDrm_setCipherAlgorithmNative },

    { "setMacAlgorithmNative",
      "(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
      (void *)android_media_MediaDrm_setMacAlgorithmNative },

    { "encryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
      (void *)android_media_MediaDrm_encryptNative },

    { "decryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
      (void *)android_media_MediaDrm_decryptNative },

    { "signNative", "(Landroid/media/MediaDrm;[B[B[B)[B",
      (void *)android_media_MediaDrm_signNative },

    { "verifyNative", "(Landroid/media/MediaDrm;[B[B[B[B)Z",
      (void *)android_media_MediaDrm_verifyNative },

    { "signRSANative", "(Landroid/media/MediaDrm;[BLjava/lang/String;[B[B)[B",
      (void *)android_media_MediaDrm_signRSANative },

    { "getMetricsNative", "()Landroid/os/PersistableBundle;",
      (void *)android_media_MediaDrm_native_getMetrics },

    { "requiresSecureDecoder", "(Ljava/lang/String;I)Z",
      (void *)android_media_MediaDrm_requiresSecureDecoder },

    { "setPlaybackId", "([BLjava/lang/String;)V",
      (void *)android_media_MediaDrm_setPlaybackId },

    { "getLogMessages", "()Ljava/util/List;",
      (void *)android_media_MediaDrm_getLogMessages },
};

int register_android_media_Drm(JNIEnv *env) {
    return AndroidRuntime::registerNativeMethods(env,
                "android/media/MediaDrm", gMethods, NELEM(gMethods));
}