/*
 * Copyright 2012, 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 "MediaCodec-JNI"
#include <utils/Log.h>

#include <type_traits>

#include "android_media_MediaCodec.h"

#include "android_media_MediaCodecLinearBlock.h"
#include "android_media_MediaCrypto.h"
#include "android_media_MediaDescrambler.h"
#include "android_media_MediaMetricsJNI.h"
#include "android_media_Streams.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/android_view_Surface.h"
#include "android_util_Binder.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>

#include <C2AllocatorGralloc.h>
#include <C2BlockInternal.h>
#include <C2Buffer.h>

#include <android/hardware/cas/native/1.0/IDescrambler.h>

#include <android_runtime/android_hardware_HardwareBuffer.h>

#include <binder/MemoryHeapBase.h>

#include <cutils/compiler.h>

#include <gui/Surface.h>

#include <hidlmemory/FrameworkUtils.h>

#include <media/MediaCodecBuffer.h>
#include <media/hardware/VideoAPI.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/PersistentSurface.h>
#include <mediadrm/ICrypto.h>

#include <private/android/AHardwareBufferHelpers.h>

#include <system/window.h>

namespace android {

// Keep these in sync with their equivalents in MediaCodec.java !!!
enum {
    DEQUEUE_INFO_TRY_AGAIN_LATER            = -1,
    DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED      = -2,
    DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
};

enum {
    EVENT_CALLBACK = 1,
    EVENT_SET_CALLBACK = 2,
    EVENT_FRAME_RENDERED = 3,
};

static struct CryptoErrorCodes {
    jint cryptoErrorNoKey;
    jint cryptoErrorKeyExpired;
    jint cryptoErrorResourceBusy;
    jint cryptoErrorInsufficientOutputProtection;
    jint cryptoErrorSessionNotOpened;
    jint cryptoErrorInsufficientSecurity;
    jint cryptoErrorUnsupportedOperation;
    jint cryptoErrorFrameTooLarge;
    jint cryptoErrorLostState;
} gCryptoErrorCodes;

static struct CodecActionCodes {
    jint codecActionTransient;
    jint codecActionRecoverable;
} gCodecActionCodes;

static struct CodecErrorCodes {
    jint errorInsufficientResource;
    jint errorReclaimed;
} gCodecErrorCodes;

static struct {
    jclass clazz;
    jfieldID mLock;
    jfieldID mPersistentObject;
    jmethodID ctor;
    jmethodID setNativeObjectLocked;
} gPersistentSurfaceClassInfo;

static struct {
    jint Unencrypted;
    jint AesCtr;
    jint AesCbc;
} gCryptoModes;

static struct {
    jclass capsClazz;
    jmethodID capsCtorId;
    jclass profileLevelClazz;
    jfieldID profileField;
    jfieldID levelField;
} gCodecInfo;

static struct {
    jclass clazz;
    jobject nativeByteOrder;
    jmethodID orderId;
    jmethodID asReadOnlyBufferId;
    jmethodID positionId;
    jmethodID limitId;
} gByteBufferInfo;

static struct {
    jmethodID sizeId;
    jmethodID getId;
    jmethodID addId;
} gArrayListInfo;

static struct {
    jclass clazz;
    jmethodID ctorId;
    jmethodID setInternalStateId;
    jfieldID contextId;
    jfieldID validId;
    jfieldID lockId;
} gLinearBlockInfo;

struct fields_t {
    jmethodID postEventFromNativeID;
    jmethodID lockAndGetContextID;
    jmethodID setAndUnlockContextID;
    jfieldID cryptoInfoNumSubSamplesID;
    jfieldID cryptoInfoNumBytesOfClearDataID;
    jfieldID cryptoInfoNumBytesOfEncryptedDataID;
    jfieldID cryptoInfoKeyID;
    jfieldID cryptoInfoIVID;
    jfieldID cryptoInfoModeID;
    jfieldID cryptoInfoPatternID;
    jfieldID patternEncryptBlocksID;
    jfieldID patternSkipBlocksID;
    jfieldID queueRequestIndexID;
    jfieldID outputFrameLinearBlockID;
    jfieldID outputFrameHardwareBufferID;
    jfieldID outputFrameChangedKeysID;
    jfieldID outputFrameFormatID;
};

static fields_t gFields;
static const void *sRefBaseOwner;


////////////////////////////////////////////////////////////////////////////////

JMediaCodec::JMediaCodec(
        JNIEnv *env, jobject thiz,
        const char *name, bool nameIsType, bool encoder)
    : mClass(NULL),
      mObject(NULL) {
    jclass clazz = env->GetObjectClass(thiz);
    CHECK(clazz != NULL);

    mClass = (jclass)env->NewGlobalRef(clazz);
    mObject = env->NewWeakGlobalRef(thiz);

    mLooper = new ALooper;
    mLooper->setName("MediaCodec_looper");

    mLooper->start(
            false,      // runOnCallingThread
            true,       // canCallJava
            ANDROID_PRIORITY_VIDEO);

    if (nameIsType) {
        mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus);
        if (mCodec == nullptr || mCodec->getName(&mNameAtCreation) != OK) {
            mNameAtCreation = "(null)";
        }
    } else {
        mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus);
        mNameAtCreation = name;
    }
    CHECK((mCodec != NULL) != (mInitStatus != OK));
}

status_t JMediaCodec::initCheck() const {
    return mInitStatus;
}

void JMediaCodec::registerSelf() {
    mLooper->registerHandler(this);
}

void JMediaCodec::release() {
    std::call_once(mReleaseFlag, [this] {
        if (mCodec != NULL) {
            mCodec->release();
            mInitStatus = NO_INIT;
        }

        if (mLooper != NULL) {
            mLooper->unregisterHandler(id());
            mLooper->stop();
            mLooper.clear();
        }
    });
}

JMediaCodec::~JMediaCodec() {
    if (mLooper != NULL) {
        /* MediaCodec and looper should have been released explicitly already
         * in setMediaCodec() (see comments in setMediaCodec()).
         *
         * Otherwise JMediaCodec::~JMediaCodec() might be called from within the
         * message handler, doing release() there risks deadlock as MediaCodec::
         * release() post synchronous message to the same looper.
         *
         * Print a warning and try to proceed with releasing.
         */
        ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()...");
        release();
        ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec().");
    }

    JNIEnv *env = AndroidRuntime::getJNIEnv();

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

status_t JMediaCodec::enableOnFrameRenderedListener(jboolean enable) {
    if (enable) {
        if (mOnFrameRenderedNotification == NULL) {
            mOnFrameRenderedNotification = new AMessage(kWhatFrameRendered, this);
        }
    } else {
        mOnFrameRenderedNotification.clear();
    }

    return mCodec->setOnFrameRenderedNotification(mOnFrameRenderedNotification);
}

status_t JMediaCodec::setCallback(jobject cb) {
    if (cb != NULL) {
        if (mCallbackNotification == NULL) {
            mCallbackNotification = new AMessage(kWhatCallbackNotify, this);
        }
    } else {
        mCallbackNotification.clear();
    }

    return mCodec->setCallback(mCallbackNotification);
}

status_t JMediaCodec::configure(
        const sp<AMessage> &format,
        const sp<IGraphicBufferProducer> &bufferProducer,
        const sp<ICrypto> &crypto,
        const sp<IDescrambler> &descrambler,
        int flags) {
    sp<Surface> client;
    if (bufferProducer != NULL) {
        mSurfaceTextureClient =
            new Surface(bufferProducer, true /* controlledByApp */);
    } else {
        mSurfaceTextureClient.clear();
    }

    constexpr int32_t CONFIGURE_FLAG_ENCODE = 1;
    AString mime;
    CHECK(format->findString("mime", &mime));
    mGraphicOutput = (mime.startsWithIgnoreCase("video/") || mime.startsWithIgnoreCase("image/"))
            && !(flags & CONFIGURE_FLAG_ENCODE);

    return mCodec->configure(
            format, mSurfaceTextureClient, crypto, descrambler, flags);
}

status_t JMediaCodec::setSurface(
        const sp<IGraphicBufferProducer> &bufferProducer) {
    sp<Surface> client;
    if (bufferProducer != NULL) {
        client = new Surface(bufferProducer, true /* controlledByApp */);
    }
    status_t err = mCodec->setSurface(client);
    if (err == OK) {
        mSurfaceTextureClient = client;
    }
    return err;
}

status_t JMediaCodec::createInputSurface(
        sp<IGraphicBufferProducer>* bufferProducer) {
    return mCodec->createInputSurface(bufferProducer);
}

status_t JMediaCodec::setInputSurface(
        const sp<PersistentSurface> &surface) {
    return mCodec->setInputSurface(surface);
}

status_t JMediaCodec::start() {
    return mCodec->start();
}

status_t JMediaCodec::stop() {
    mSurfaceTextureClient.clear();

    return mCodec->stop();
}

status_t JMediaCodec::flush() {
    return mCodec->flush();
}

status_t JMediaCodec::reset() {
    return mCodec->reset();
}

status_t JMediaCodec::queueInputBuffer(
        size_t index,
        size_t offset, size_t size, int64_t timeUs, uint32_t flags,
        AString *errorDetailMsg) {
    return mCodec->queueInputBuffer(
            index, offset, size, timeUs, flags, errorDetailMsg);
}

status_t JMediaCodec::queueSecureInputBuffer(
        size_t index,
        size_t offset,
        const CryptoPlugin::SubSample *subSamples,
        size_t numSubSamples,
        const uint8_t key[16],
        const uint8_t iv[16],
        CryptoPlugin::Mode mode,
        const CryptoPlugin::Pattern &pattern,
        int64_t presentationTimeUs,
        uint32_t flags,
        AString *errorDetailMsg) {
    return mCodec->queueSecureInputBuffer(
            index, offset, subSamples, numSubSamples, key, iv, mode, pattern,
            presentationTimeUs, flags, errorDetailMsg);
}

status_t JMediaCodec::queueBuffer(
        size_t index, const std::shared_ptr<C2Buffer> &buffer, int64_t timeUs,
        uint32_t flags, const sp<AMessage> &tunings, AString *errorDetailMsg) {
    return mCodec->queueBuffer(
            index, buffer, timeUs, flags, tunings, errorDetailMsg);
}

status_t JMediaCodec::queueEncryptedLinearBlock(
        size_t index,
        const sp<hardware::HidlMemory> &buffer,
        size_t offset,
        const CryptoPlugin::SubSample *subSamples,
        size_t numSubSamples,
        const uint8_t key[16],
        const uint8_t iv[16],
        CryptoPlugin::Mode mode,
        const CryptoPlugin::Pattern &pattern,
        int64_t presentationTimeUs,
        uint32_t flags,
        const sp<AMessage> &tunings,
        AString *errorDetailMsg) {
    return mCodec->queueEncryptedBuffer(
            index, buffer, offset, subSamples, numSubSamples, key, iv, mode, pattern,
            presentationTimeUs, flags, tunings, errorDetailMsg);
}

status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
    return mCodec->dequeueInputBuffer(index, timeoutUs);
}

status_t JMediaCodec::dequeueOutputBuffer(
        JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) {
    size_t size, offset;
    int64_t timeUs;
    uint32_t flags;
    status_t err = mCodec->dequeueOutputBuffer(
            index, &offset, &size, &timeUs, &flags, timeoutUs);

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

    ScopedLocalRef<jclass> clazz(
            env, env->FindClass("android/media/MediaCodec$BufferInfo"));

    jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");
    env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags);

    return OK;
}

status_t JMediaCodec::releaseOutputBuffer(
        size_t index, bool render, bool updatePTS, int64_t timestampNs) {
    if (updatePTS) {
        return mCodec->renderOutputBufferAndRelease(index, timestampNs);
    }
    return render
        ? mCodec->renderOutputBufferAndRelease(index)
        : mCodec->releaseOutputBuffer(index);
}

status_t JMediaCodec::signalEndOfInputStream() {
    return mCodec->signalEndOfInputStream();
}

status_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const {
    sp<AMessage> msg;
    status_t err;
    err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg);
    if (err != OK) {
        return err;
    }

    return ConvertMessageToMap(env, msg, format);
}

status_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const {
    sp<AMessage> msg;
    status_t err;
    if ((err = mCodec->getOutputFormat(index, &msg)) != OK) {
        return err;
    }

    return ConvertMessageToMap(env, msg, format);
}

status_t JMediaCodec::getBuffers(
        JNIEnv *env, bool input, jobjectArray *bufArray) const {
    Vector<sp<MediaCodecBuffer> > buffers;

    status_t err =
        input
            ? mCodec->getInputBuffers(&buffers)
            : mCodec->getOutputBuffers(&buffers);

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

    *bufArray = (jobjectArray)env->NewObjectArray(
            buffers.size(), gByteBufferInfo.clazz, NULL);
    if (*bufArray == NULL) {
        return NO_MEMORY;
    }

    for (size_t i = 0; i < buffers.size(); ++i) {
        const sp<MediaCodecBuffer> &buffer = buffers.itemAt(i);

        jobject byteBuffer = NULL;
        err = createByteBufferFromABuffer(
                env, !input /* readOnly */, true /* clearBuffer */, buffer, &byteBuffer);
        if (err != OK) {
            return err;
        }
        if (byteBuffer != NULL) {
            env->SetObjectArrayElement(
                    *bufArray, i, byteBuffer);

            env->DeleteLocalRef(byteBuffer);
            byteBuffer = NULL;
        }
    }

    return OK;
}

template <typename T>
static jobject CreateByteBuffer(
        JNIEnv *env, T *base, size_t capacity, size_t offset, size_t size,
        bool readOnly, bool clearBuffer) {
    jobject byteBuffer =
        env->NewDirectByteBuffer(
                const_cast<typename std::remove_const<T>::type *>(base),
                capacity);
    if (readOnly && byteBuffer != NULL) {
        jobject readOnlyBuffer = env->CallObjectMethod(
                byteBuffer, gByteBufferInfo.asReadOnlyBufferId);
        env->DeleteLocalRef(byteBuffer);
        byteBuffer = readOnlyBuffer;
    }
    if (byteBuffer == NULL) {
        return nullptr;
    }
    jobject me = env->CallObjectMethod(
            byteBuffer, gByteBufferInfo.orderId, gByteBufferInfo.nativeByteOrder);
    env->DeleteLocalRef(me);
    me = env->CallObjectMethod(
            byteBuffer, gByteBufferInfo.limitId,
            clearBuffer ? capacity : offset + size);
    env->DeleteLocalRef(me);
    me = env->CallObjectMethod(
            byteBuffer, gByteBufferInfo.positionId,
            clearBuffer ? 0 : offset);
    env->DeleteLocalRef(me);
    me = NULL;
    return byteBuffer;
}


// static
template <typename T>
status_t JMediaCodec::createByteBufferFromABuffer(
        JNIEnv *env, bool readOnly, bool clearBuffer, const sp<T> &buffer,
        jobject *buf) const {
    // if this is an ABuffer that doesn't actually hold any accessible memory,
    // use a null ByteBuffer
    *buf = NULL;

    if (buffer == NULL) {
        ALOGV("createByteBufferFromABuffer - given NULL, returning NULL");
        return OK;
    }

    if (buffer->base() == NULL) {
        return OK;
    }

    jobject byteBuffer = CreateByteBuffer(
            env, buffer->base(), buffer->capacity(), buffer->offset(), buffer->size(),
            readOnly, clearBuffer);

    *buf = byteBuffer;
    return OK;
}

status_t JMediaCodec::getBuffer(
        JNIEnv *env, bool input, size_t index, jobject *buf) const {
    sp<MediaCodecBuffer> buffer;

    status_t err =
        input
            ? mCodec->getInputBuffer(index, &buffer)
            : mCodec->getOutputBuffer(index, &buffer);

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

    return createByteBufferFromABuffer(
            env, !input /* readOnly */, input /* clearBuffer */, buffer, buf);
}

status_t JMediaCodec::getImage(
        JNIEnv *env, bool input, size_t index, jobject *buf) const {
    sp<MediaCodecBuffer> buffer;

    status_t err =
        input
            ? mCodec->getInputBuffer(index, &buffer)
            : mCodec->getOutputBuffer(index, &buffer);

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

    // if this is an ABuffer that doesn't actually hold any accessible memory,
    // use a null ByteBuffer
    *buf = NULL;
    if (buffer->base() == NULL) {
        return OK;
    }

    // check if buffer is an image
    sp<ABuffer> imageData;
    if (!buffer->meta()->findBuffer("image-data", &imageData)) {
        return OK;
    }

    int64_t timestamp = 0;
    if (!input && buffer->meta()->findInt64("timeUs", &timestamp)) {
        timestamp *= 1000; // adjust to ns
    }

    jobject byteBuffer = NULL;
    err = createByteBufferFromABuffer(
            env, !input /* readOnly */, input /* clearBuffer */, buffer, &byteBuffer);
    if (err != OK) {
        return OK;
    }

    jobject infoBuffer = NULL;
    err = createByteBufferFromABuffer(
            env, true /* readOnly */, true /* clearBuffer */, imageData, &infoBuffer);
    if (err != OK) {
        env->DeleteLocalRef(byteBuffer);
        byteBuffer = NULL;
        return OK;
    }

    jobject cropRect = NULL;
    int32_t left, top, right, bottom;
    if (buffer->meta()->findRect("crop-rect", &left, &top, &right, &bottom)) {
        ScopedLocalRef<jclass> rectClazz(
                env, env->FindClass("android/graphics/Rect"));
        CHECK(rectClazz.get() != NULL);

        jmethodID rectConstructID = env->GetMethodID(
                rectClazz.get(), "<init>", "(IIII)V");

        cropRect = env->NewObject(
                rectClazz.get(), rectConstructID, left, top, right + 1, bottom + 1);
    }

    ScopedLocalRef<jclass> imageClazz(
            env, env->FindClass("android/media/MediaCodec$MediaImage"));
    CHECK(imageClazz.get() != NULL);

    jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>",
            "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ZJIILandroid/graphics/Rect;)V");

    *buf = env->NewObject(imageClazz.get(), imageConstructID,
            byteBuffer, infoBuffer,
            (jboolean)!input /* readOnly */,
            (jlong)timestamp,
            (jint)0 /* xOffset */, (jint)0 /* yOffset */, cropRect);

    // if MediaImage creation fails, return null
    if (env->ExceptionCheck()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
        *buf = NULL;
    }

    if (cropRect != NULL) {
        env->DeleteLocalRef(cropRect);
        cropRect = NULL;
    }

    env->DeleteLocalRef(byteBuffer);
    byteBuffer = NULL;

    env->DeleteLocalRef(infoBuffer);
    infoBuffer = NULL;

    return OK;
}

status_t JMediaCodec::getOutputFrame(
        JNIEnv *env, jobject frame, size_t index) const {
    sp<MediaCodecBuffer> buffer;

    status_t err = mCodec->getOutputBuffer(index, &buffer);
    if (err != OK) {
        return err;
    }

    if (buffer->size() > 0) {
        std::shared_ptr<C2Buffer> c2Buffer = buffer->asC2Buffer();
        if (c2Buffer) {
            switch (c2Buffer->data().type()) {
                case C2BufferData::LINEAR: {
                    std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
                    context->mBuffer = c2Buffer;
                    ScopedLocalRef<jobject> linearBlock{env, env->NewObject(
                            gLinearBlockInfo.clazz, gLinearBlockInfo.ctorId)};
                    env->CallVoidMethod(
                            linearBlock.get(),
                            gLinearBlockInfo.setInternalStateId,
                            (jlong)context.release(),
                            true);
                    env->SetObjectField(frame, gFields.outputFrameLinearBlockID, linearBlock.get());
                    break;
                }
                case C2BufferData::GRAPHIC: {
                    const C2Handle *c2Handle = c2Buffer->data().graphicBlocks().front().handle();
                    uint32_t width, height, format, stride, igbp_slot, generation;
                    uint64_t usage, igbp_id;
                    _UnwrapNativeCodec2GrallocMetadata(
                            c2Handle, &width, &height, &format, &usage, &stride, &generation,
                            &igbp_id, &igbp_slot);
                    native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(c2Handle);
                    GraphicBuffer* graphicBuffer = new GraphicBuffer(
                            grallocHandle, GraphicBuffer::CLONE_HANDLE,
                            width, height, format, 1, usage, stride);
                    ScopedLocalRef<jobject> hardwareBuffer{
                        env,
                        android_hardware_HardwareBuffer_createFromAHardwareBuffer(
                                env, AHardwareBuffer_from_GraphicBuffer(graphicBuffer))};
                    env->SetObjectField(
                            frame, gFields.outputFrameHardwareBufferID, hardwareBuffer.get());
                    break;
                }
                case C2BufferData::LINEAR_CHUNKS:  [[fallthrough]];
                case C2BufferData::GRAPHIC_CHUNKS: [[fallthrough]];
                case C2BufferData::INVALID:        [[fallthrough]];
                default:
                    return INVALID_OPERATION;
            }
        } else {
            if (!mGraphicOutput) {
                std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
                context->mLegacyBuffer = buffer;
                ScopedLocalRef<jobject> linearBlock{env, env->NewObject(
                        gLinearBlockInfo.clazz, gLinearBlockInfo.ctorId)};
                env->CallVoidMethod(
                        linearBlock.get(),
                        gLinearBlockInfo.setInternalStateId,
                        (jlong)context.release(),
                        true);
                env->SetObjectField(frame, gFields.outputFrameLinearBlockID, linearBlock.get());
            } else {
                // No-op.
            }
        }
    }

    jobject format;
    err = getOutputFormat(env, index, &format);
    if (err != OK) {
        return err;
    }
    env->SetObjectField(frame, gFields.outputFrameFormatID, format);
    env->DeleteLocalRef(format);
    format = nullptr;

    sp<RefBase> obj;
    if (buffer->meta()->findObject("changedKeys", &obj) && obj) {
        sp<MediaCodec::WrapperObject<std::set<std::string>>> changedKeys{
            (decltype(changedKeys.get()))obj.get()};
        ScopedLocalRef<jobject> changedKeysObj{env, env->GetObjectField(
                frame, gFields.outputFrameChangedKeysID)};
        for (const std::string &key : changedKeys->value) {
            ScopedLocalRef<jstring> keyStr{env, env->NewStringUTF(key.c_str())};
            (void)env->CallBooleanMethod(changedKeysObj.get(), gArrayListInfo.addId, keyStr.get());
        }
    }
    return OK;
}


status_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const {
    AString name;

    status_t err = mCodec->getName(&name);

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

    *nameStr = env->NewStringUTF(name.c_str());

    return OK;
}

static jobject getCodecCapabilitiesObject(
        JNIEnv *env, const char *mime, bool isEncoder,
        const sp<MediaCodecInfo::Capabilities> &capabilities) {
    Vector<MediaCodecInfo::ProfileLevel> profileLevels;
    Vector<uint32_t> colorFormats;

    sp<AMessage> defaultFormat = new AMessage();
    defaultFormat->setString("mime", mime);

    capabilities->getSupportedColorFormats(&colorFormats);
    capabilities->getSupportedProfileLevels(&profileLevels);
    sp<AMessage> details = capabilities->getDetails();

    jobject defaultFormatObj = NULL;
    if (ConvertMessageToMap(env, defaultFormat, &defaultFormatObj)) {
        return NULL;
    }
    ScopedLocalRef<jobject> defaultFormatRef(env, defaultFormatObj);

    jobject detailsObj = NULL;
    if (ConvertMessageToMap(env, details, &detailsObj)) {
        return NULL;
    }
    ScopedLocalRef<jobject> detailsRef(env, detailsObj);

    ScopedLocalRef<jobjectArray> profileLevelArray(env, env->NewObjectArray(
            profileLevels.size(), gCodecInfo.profileLevelClazz, NULL));

    for (size_t i = 0; i < profileLevels.size(); ++i) {
        const MediaCodecInfo::ProfileLevel &src = profileLevels.itemAt(i);

        ScopedLocalRef<jobject> srcRef(env, env->AllocObject(
                gCodecInfo.profileLevelClazz));

        env->SetIntField(srcRef.get(), gCodecInfo.profileField, src.mProfile);
        env->SetIntField(srcRef.get(), gCodecInfo.levelField, src.mLevel);

        env->SetObjectArrayElement(profileLevelArray.get(), i, srcRef.get());
    }

    ScopedLocalRef<jintArray> colorFormatsArray(
            env, env->NewIntArray(colorFormats.size()));
    for (size_t i = 0; i < colorFormats.size(); ++i) {
        jint val = colorFormats.itemAt(i);
        env->SetIntArrayRegion(colorFormatsArray.get(), i, 1, &val);
    }

    return env->NewObject(
            gCodecInfo.capsClazz, gCodecInfo.capsCtorId,
            profileLevelArray.get(), colorFormatsArray.get(), isEncoder,
            defaultFormatRef.get(), detailsRef.get());
}

status_t JMediaCodec::getCodecInfo(JNIEnv *env, jobject *codecInfoObject) const {
    sp<MediaCodecInfo> codecInfo;

    status_t err = mCodec->getCodecInfo(&codecInfo);

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

    ScopedLocalRef<jstring> nameObject(env,
            env->NewStringUTF(mNameAtCreation.c_str()));

    ScopedLocalRef<jstring> canonicalNameObject(env,
            env->NewStringUTF(codecInfo->getCodecName()));

    MediaCodecInfo::Attributes attributes = codecInfo->getAttributes();
    bool isEncoder = codecInfo->isEncoder();

    Vector<AString> mediaTypes;
    codecInfo->getSupportedMediaTypes(&mediaTypes);

    ScopedLocalRef<jobjectArray> capsArrayObj(env,
        env->NewObjectArray(mediaTypes.size(), gCodecInfo.capsClazz, NULL));

    for (size_t i = 0; i < mediaTypes.size(); i++) {
        const sp<MediaCodecInfo::Capabilities> caps =
                codecInfo->getCapabilitiesFor(mediaTypes[i].c_str());

        ScopedLocalRef<jobject> capsObj(env, getCodecCapabilitiesObject(
                env, mediaTypes[i].c_str(), isEncoder, caps));

        env->SetObjectArrayElement(capsArrayObj.get(), i, capsObj.get());
    }

    ScopedLocalRef<jclass> codecInfoClazz(env,
            env->FindClass("android/media/MediaCodecInfo"));
    CHECK(codecInfoClazz.get() != NULL);

    jmethodID codecInfoCtorID = env->GetMethodID(codecInfoClazz.get(), "<init>",
            "(Ljava/lang/String;Ljava/lang/String;I[Landroid/media/MediaCodecInfo$CodecCapabilities;)V");

    *codecInfoObject = env->NewObject(codecInfoClazz.get(), codecInfoCtorID,
            nameObject.get(), canonicalNameObject.get(), attributes, capsArrayObj.get());

    return OK;
}

status_t JMediaCodec::getMetrics(JNIEnv *, mediametrics::Item * &reply) const {
    mediametrics_handle_t reply2 = mediametrics::Item::convert(reply);
    status_t status = mCodec->getMetrics(reply2);
    // getMetrics() updates reply2, pass the converted update along to our caller.
    reply = mediametrics::Item::convert(reply2);
    return status;
}

status_t JMediaCodec::setParameters(const sp<AMessage> &msg) {
    return mCodec->setParameters(msg);
}

void JMediaCodec::setVideoScalingMode(int mode) {
    if (mSurfaceTextureClient != NULL) {
        // this works for components that queue to surface
        native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode);
        // also signal via param for components that queue to IGBP
        sp<AMessage> msg = new AMessage;
        msg->setInt32("android._video-scaling", mode);
        (void)mCodec->setParameters(msg);
    }
}

void JMediaCodec::selectAudioPresentation(const int32_t presentationId, const int32_t programId) {
    sp<AMessage> msg = new AMessage;
    msg->setInt32("audio-presentation-presentation-id", presentationId);
    msg->setInt32("audio-presentation-program-id", programId);
    (void)mCodec->setParameters(msg);
}

static jthrowable createCodecException(
        JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) {
    ScopedLocalRef<jclass> clazz(
            env, env->FindClass("android/media/MediaCodec$CodecException"));
    CHECK(clazz.get() != NULL);

    const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;)V");
    CHECK(ctor != NULL);

    ScopedLocalRef<jstring> msgObj(
            env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err)));

    // translate action code to Java equivalent
    switch (actionCode) {
    case ACTION_CODE_TRANSIENT:
        actionCode = gCodecActionCodes.codecActionTransient;
        break;
    case ACTION_CODE_RECOVERABLE:
        actionCode = gCodecActionCodes.codecActionRecoverable;
        break;
    default:
        actionCode = 0;  // everything else is fatal
        break;
    }

    /* translate OS errors to Java API CodecException errorCodes */
    switch (err) {
        case NO_MEMORY:
            err = gCodecErrorCodes.errorInsufficientResource;
            break;
        case DEAD_OBJECT:
            err = gCodecErrorCodes.errorReclaimed;
            break;
        default:  /* Other error codes go out as is. */
            break;
    }

    return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get());
}

void JMediaCodec::handleCallback(const sp<AMessage> &msg) {
    int32_t arg1, arg2 = 0;
    jobject obj = NULL;
    CHECK(msg->findInt32("callbackID", &arg1));
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    switch (arg1) {
        case MediaCodec::CB_INPUT_AVAILABLE:
        {
            CHECK(msg->findInt32("index", &arg2));
            break;
        }

        case MediaCodec::CB_OUTPUT_AVAILABLE:
        {
            CHECK(msg->findInt32("index", &arg2));

            size_t size, offset;
            int64_t timeUs;
            uint32_t flags;
            CHECK(msg->findSize("size", &size));
            CHECK(msg->findSize("offset", &offset));
            CHECK(msg->findInt64("timeUs", &timeUs));
            CHECK(msg->findInt32("flags", (int32_t *)&flags));

            ScopedLocalRef<jclass> clazz(
                    env, env->FindClass("android/media/MediaCodec$BufferInfo"));
            jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V");
            jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");

            obj = env->NewObject(clazz.get(), ctor);

            if (obj == NULL) {
                if (env->ExceptionCheck()) {
                    ALOGE("Could not create MediaCodec.BufferInfo.");
                    env->ExceptionClear();
                }
                jniThrowException(env, "java/lang/IllegalStateException", NULL);
                return;
            }

            env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags);
            break;
        }

        case MediaCodec::CB_ERROR:
        {
            int32_t err, actionCode;
            CHECK(msg->findInt32("err", &err));
            CHECK(msg->findInt32("actionCode", &actionCode));

            // note that DRM errors could conceivably alias into a CodecException
            obj = (jobject)createCodecException(env, err, actionCode);

            if (obj == NULL) {
                if (env->ExceptionCheck()) {
                    ALOGE("Could not create CodecException object.");
                    env->ExceptionClear();
                }
                jniThrowException(env, "java/lang/IllegalStateException", NULL);
                return;
            }

            break;
        }

        case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
        {
            sp<AMessage> format;
            CHECK(msg->findMessage("format", &format));

            if (OK != ConvertMessageToMap(env, format, &obj)) {
                jniThrowException(env, "java/lang/IllegalStateException", NULL);
                return;
            }

            break;
        }

        default:
            TRESPASS();
    }

    env->CallVoidMethod(
            mObject,
            gFields.postEventFromNativeID,
            EVENT_CALLBACK,
            arg1,
            arg2,
            obj);

    env->DeleteLocalRef(obj);
}

void JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) {
    int32_t arg1 = 0, arg2 = 0;
    jobject obj = NULL;
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    sp<AMessage> data;
    CHECK(msg->findMessage("data", &data));

    status_t err = ConvertMessageToMap(env, data, &obj);
    if (err != OK) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return;
    }

    env->CallVoidMethod(
            mObject, gFields.postEventFromNativeID,
            EVENT_FRAME_RENDERED, arg1, arg2, obj);

    env->DeleteLocalRef(obj);
}

void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatCallbackNotify:
        {
            handleCallback(msg);
            break;
        }
        case kWhatFrameRendered:
        {
            handleFrameRenderedNotification(msg);
            break;
        }
        default:
            TRESPASS();
    }
}

}  // namespace android

////////////////////////////////////////////////////////////////////////////////

using namespace android;

static sp<JMediaCodec> setMediaCodec(
        JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) {
    sp<JMediaCodec> old = (JMediaCodec *)env->CallLongMethod(thiz, gFields.lockAndGetContextID);
    if (codec != NULL) {
        codec->incStrong(thiz);
    }
    if (old != NULL) {
        /* release MediaCodec and stop the looper now before decStrong.
         * otherwise JMediaCodec::~JMediaCodec() could be called from within
         * its message handler, doing release() from there will deadlock
         * (as MediaCodec::release() post synchronous message to the same looper)
         */
        old->release();
        old->decStrong(thiz);
    }
    env->CallVoidMethod(thiz, gFields.setAndUnlockContextID, (jlong)codec.get());

    return old;
}

static sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) {
    sp<JMediaCodec> codec = (JMediaCodec *)env->CallLongMethod(thiz, gFields.lockAndGetContextID);
    env->CallVoidMethod(thiz, gFields.setAndUnlockContextID, (jlong)codec.get());
    return codec;
}

static void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) {
    setMediaCodec(env, thiz, NULL);
}

static void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, const char *msg) {
    jthrowable exception = createCodecException(env, err, actionCode, msg);
    env->Throw(exception);
}

static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
    ScopedLocalRef<jclass> clazz(
            env, env->FindClass("android/media/MediaCodec$CryptoException"));
    CHECK(clazz.get() != NULL);

    jmethodID constructID =
        env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V");
    CHECK(constructID != NULL);

    const char *defaultMsg = "Unknown Error";

    /* translate OS errors to Java API CryptoException errorCodes (which are positive) */
    switch (err) {
        case ERROR_DRM_NO_LICENSE:
            err = gCryptoErrorCodes.cryptoErrorNoKey;
            defaultMsg = "Crypto key not available";
            break;
        case ERROR_DRM_LICENSE_EXPIRED:
            err = gCryptoErrorCodes.cryptoErrorKeyExpired;
            defaultMsg = "License expired";
            break;
        case ERROR_DRM_RESOURCE_BUSY:
            err = gCryptoErrorCodes.cryptoErrorResourceBusy;
            defaultMsg = "Resource busy or unavailable";
            break;
        case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
            err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
            defaultMsg = "Required output protections are not active";
            break;
        case ERROR_DRM_SESSION_NOT_OPENED:
            err = gCryptoErrorCodes.cryptoErrorSessionNotOpened;
            defaultMsg = "Attempted to use a closed session";
            break;
        case ERROR_DRM_INSUFFICIENT_SECURITY:
            err = gCryptoErrorCodes.cryptoErrorInsufficientSecurity;
            defaultMsg = "Required security level is not met";
            break;
        case ERROR_DRM_CANNOT_HANDLE:
            err = gCryptoErrorCodes.cryptoErrorUnsupportedOperation;
            defaultMsg = "Operation not supported in this configuration";
            break;
        case ERROR_DRM_FRAME_TOO_LARGE:
            err = gCryptoErrorCodes.cryptoErrorFrameTooLarge;
            defaultMsg = "Decrytped frame exceeds size of output buffer";
            break;
        case ERROR_DRM_SESSION_LOST_STATE:
            err = gCryptoErrorCodes.cryptoErrorLostState;
            defaultMsg = "Session state was lost, open a new session and retry";
            break;
        default:  /* Other negative DRM error codes go out as is. */
            break;
    }

    jstring msgObj = env->NewStringUTF(msg != NULL ? msg : defaultMsg);

    jthrowable exception =
        (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj);

    env->Throw(exception);
}

static jint throwExceptionAsNecessary(
        JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL,
        const char *msg = NULL) {
    switch (err) {
        case OK:
            return 0;

        case -EAGAIN:
            return DEQUEUE_INFO_TRY_AGAIN_LATER;

        case INFO_FORMAT_CHANGED:
            return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED;

        case INFO_OUTPUT_BUFFERS_CHANGED:
            return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;

        case INVALID_OPERATION:
            jniThrowException(env, "java/lang/IllegalStateException", msg);
            return 0;

        case BAD_VALUE:
            jniThrowException(env, "java/lang/IllegalArgumentException", msg);
            return 0;

        default:
            if (isCryptoError(err)) {
                throwCryptoException(env, err, msg);
                return 0;
            }
            throwCodecException(env, err, actionCode, msg);
            return 0;
    }
}

static void android_media_MediaCodec_native_enableOnFrameRenderedListener(
        JNIEnv *env,
        jobject thiz,
        jboolean enabled) {
    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->enableOnFrameRenderedListener(enabled);

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_native_setCallback(
        JNIEnv *env,
        jobject thiz,
        jobject cb) {
    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->setCallback(cb);

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_native_configure(
        JNIEnv *env,
        jobject thiz,
        jobjectArray keys, jobjectArray values,
        jobject jsurface,
        jobject jcrypto,
        jobject descramblerBinderObj,
        jint flags) {
    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    sp<AMessage> format;
    status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format);

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

    sp<IGraphicBufferProducer> bufferProducer;
    if (jsurface != NULL) {
        sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
        if (surface != NULL) {
            bufferProducer = surface->getIGraphicBufferProducer();
        } else {
            jniThrowException(
                    env,
                    "java/lang/IllegalArgumentException",
                    "The surface has been released");
            return;
        }
    }

    sp<ICrypto> crypto;
    if (jcrypto != NULL) {
        crypto = JCrypto::GetCrypto(env, jcrypto);
    }

    sp<IDescrambler> descrambler;
    if (descramblerBinderObj != NULL) {
        descrambler = GetDescrambler(env, descramblerBinderObj);
    }

    err = codec->configure(format, bufferProducer, crypto, descrambler, flags);

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_native_setSurface(
        JNIEnv *env,
        jobject thiz,
        jobject jsurface) {
    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    sp<IGraphicBufferProducer> bufferProducer;
    if (jsurface != NULL) {
        sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
        if (surface != NULL) {
            bufferProducer = surface->getIGraphicBufferProducer();
        } else {
            jniThrowException(
                    env,
                    "java/lang/IllegalArgumentException",
                    "The surface has been released");
            return;
        }
    }

    status_t err = codec->setSurface(bufferProducer);
    throwExceptionAsNecessary(env, err);
}

sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface(
        JNIEnv* env, jobject object) {
    sp<PersistentSurface> persistentSurface;

    jobject lock = env->GetObjectField(
            object, gPersistentSurfaceClassInfo.mLock);
    if (env->MonitorEnter(lock) == JNI_OK) {
        persistentSurface = reinterpret_cast<PersistentSurface *>(
                env->GetLongField(object,
                        gPersistentSurfaceClassInfo.mPersistentObject));
        env->MonitorExit(lock);
    }
    env->DeleteLocalRef(lock);

    return persistentSurface;
}

static jobject android_media_MediaCodec_createPersistentInputSurface(
        JNIEnv* env, jclass /* clazz */) {
    ALOGV("android_media_MediaCodec_createPersistentInputSurface");
    sp<PersistentSurface> persistentSurface =
        MediaCodec::CreatePersistentInputSurface();

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

    sp<Surface> surface = new Surface(
            persistentSurface->getBufferProducer(), true);
    if (surface == NULL) {
        return NULL;
    }

    jobject object = env->NewObject(
            gPersistentSurfaceClassInfo.clazz,
            gPersistentSurfaceClassInfo.ctor);

    if (object == NULL) {
        if (env->ExceptionCheck()) {
            ALOGE("Could not create PersistentSurface.");
            env->ExceptionClear();
        }
        return NULL;
    }

    jobject lock = env->GetObjectField(
            object, gPersistentSurfaceClassInfo.mLock);
    if (env->MonitorEnter(lock) == JNI_OK) {
        env->CallVoidMethod(
                object,
                gPersistentSurfaceClassInfo.setNativeObjectLocked,
                (jlong)surface.get());
        env->SetLongField(
                object,
                gPersistentSurfaceClassInfo.mPersistentObject,
                (jlong)persistentSurface.get());
        env->MonitorExit(lock);
    } else {
        env->DeleteLocalRef(object);
        object = NULL;
    }
    env->DeleteLocalRef(lock);

    if (object != NULL) {
        surface->incStrong(&sRefBaseOwner);
        persistentSurface->incStrong(&sRefBaseOwner);
    }

    return object;
}

static void android_media_MediaCodec_releasePersistentInputSurface(
        JNIEnv* env, jclass /* clazz */, jobject object) {
    sp<PersistentSurface> persistentSurface;

    jobject lock = env->GetObjectField(
            object, gPersistentSurfaceClassInfo.mLock);
    if (env->MonitorEnter(lock) == JNI_OK) {
        persistentSurface = reinterpret_cast<PersistentSurface *>(
            env->GetLongField(
                    object, gPersistentSurfaceClassInfo.mPersistentObject));
        env->SetLongField(
                object,
                gPersistentSurfaceClassInfo.mPersistentObject,
                (jlong)0);
        env->MonitorExit(lock);
    }
    env->DeleteLocalRef(lock);

    if (persistentSurface != NULL) {
        persistentSurface->decStrong(&sRefBaseOwner);
    }
    // no need to release surface as it will be released by Surface's jni
}

static void android_media_MediaCodec_setInputSurface(
        JNIEnv* env, jobject thiz, jobject object) {
    ALOGV("android_media_MediaCodec_setInputSurface");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    sp<PersistentSurface> persistentSurface =
        android_media_MediaCodec_getPersistentInputSurface(env, object);

    if (persistentSurface == NULL) {
        throwExceptionAsNecessary(
                env, BAD_VALUE, ACTION_CODE_FATAL, "input surface not valid");
        return;
    }
    status_t err = codec->setInputSurface(persistentSurface);
    if (err != NO_ERROR) {
        throwExceptionAsNecessary(env, err);
    }
}

static jobject android_media_MediaCodec_createInputSurface(JNIEnv* env,
        jobject thiz) {
    ALOGV("android_media_MediaCodec_createInputSurface");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    // Tell the MediaCodec that we want to use a Surface as input.
    sp<IGraphicBufferProducer> bufferProducer;
    status_t err = codec->createInputSurface(&bufferProducer);
    if (err != NO_ERROR) {
        throwExceptionAsNecessary(env, err);
        return NULL;
    }

    // Wrap the IGBP in a Java-language Surface.
    return android_view_Surface_createFromIGraphicBufferProducer(env,
            bufferProducer);
}

static void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_start");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->start();

    throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed");
}

static void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_stop");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->stop();

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_reset");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->reset();
    if (err != OK) {
        // treat all errors as fatal for now, though resource not available
        // errors could be treated as transient.
        // we also should avoid sending INVALID_OPERATION here due to
        // the transitory nature of reset(), it should not inadvertently
        // trigger an IllegalStateException.
        err = UNKNOWN_ERROR;
    }
    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_flush");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->flush();

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_queueInputBuffer(
        JNIEnv *env,
        jobject thiz,
        jint index,
        jint offset,
        jint size,
        jlong timestampUs,
        jint flags) {
    ALOGV("android_media_MediaCodec_queueInputBuffer");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    AString errorDetailMsg;

    status_t err = codec->queueInputBuffer(
            index, offset, size, timestampUs, flags, &errorDetailMsg);

    throwExceptionAsNecessary(
            env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}

struct NativeCryptoInfo {
    NativeCryptoInfo(JNIEnv *env, jobject cryptoInfoObj)
        : mEnv{env},
          mIvObj{env, (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID)},
          mKeyObj{env, (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID)} {
        mNumSubSamples = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);

        ScopedLocalRef<jintArray> numBytesOfClearDataObj{env, (jintArray)env->GetObjectField(
                cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID)};

        ScopedLocalRef<jintArray> numBytesOfEncryptedDataObj{env, (jintArray)env->GetObjectField(
                cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID)};

        jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
        if (jmode == gCryptoModes.Unencrypted) {
            mMode = CryptoPlugin::kMode_Unencrypted;
        } else if (jmode == gCryptoModes.AesCtr) {
            mMode = CryptoPlugin::kMode_AES_CTR;
        } else if (jmode == gCryptoModes.AesCbc) {
            mMode = CryptoPlugin::kMode_AES_CBC;
        }  else {
            throwExceptionAsNecessary(env, INVALID_OPERATION);
            return;
        }

        ScopedLocalRef<jobject> patternObj{
            env, env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID)};

        CryptoPlugin::Pattern pattern;
        if (patternObj.get() == nullptr) {
            pattern.mEncryptBlocks = 0;
            pattern.mSkipBlocks = 0;
        } else {
            pattern.mEncryptBlocks = env->GetIntField(
                    patternObj.get(), gFields.patternEncryptBlocksID);
            pattern.mSkipBlocks = env->GetIntField(
                    patternObj.get(), gFields.patternSkipBlocksID);
        }

        mErr = OK;
        if (mNumSubSamples <= 0) {
            mErr = -EINVAL;
        } else if (numBytesOfClearDataObj == nullptr
                && numBytesOfEncryptedDataObj == nullptr) {
            mErr = -EINVAL;
        } else if (numBytesOfEncryptedDataObj != nullptr
                && env->GetArrayLength(numBytesOfEncryptedDataObj.get()) < mNumSubSamples) {
            mErr = -ERANGE;
        } else if (numBytesOfClearDataObj != nullptr
                && env->GetArrayLength(numBytesOfClearDataObj.get()) < mNumSubSamples) {
            mErr = -ERANGE;
        // subSamples array may silently overflow if number of samples are too large.  Use
        // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms
        } else if (CC_UNLIKELY(mNumSubSamples >= (signed)(INT32_MAX / sizeof(*mSubSamples))) ) {
            mErr = -EINVAL;
        } else {
            jint *numBytesOfClearData =
                (numBytesOfClearDataObj == nullptr)
                    ? nullptr
                    : env->GetIntArrayElements(numBytesOfClearDataObj.get(), nullptr);

            jint *numBytesOfEncryptedData =
                (numBytesOfEncryptedDataObj == nullptr)
                    ? nullptr
                    : env->GetIntArrayElements(numBytesOfEncryptedDataObj.get(), nullptr);

            mSubSamples = new CryptoPlugin::SubSample[mNumSubSamples];

            for (jint i = 0; i < mNumSubSamples; ++i) {
                mSubSamples[i].mNumBytesOfClearData =
                    (numBytesOfClearData == nullptr) ? 0 : numBytesOfClearData[i];

                mSubSamples[i].mNumBytesOfEncryptedData =
                    (numBytesOfEncryptedData == nullptr) ? 0 : numBytesOfEncryptedData[i];
            }

            if (numBytesOfEncryptedData != nullptr) {
                env->ReleaseIntArrayElements(
                        numBytesOfEncryptedDataObj.get(), numBytesOfEncryptedData, 0);
                numBytesOfEncryptedData = nullptr;
            }

            if (numBytesOfClearData != nullptr) {
                env->ReleaseIntArrayElements(
                        numBytesOfClearDataObj.get(), numBytesOfClearData, 0);
                numBytesOfClearData = nullptr;
            }
        }

        if (mErr == OK && mKeyObj.get() != nullptr) {
            if (env->GetArrayLength(mKeyObj.get()) != 16) {
                mErr = -EINVAL;
            } else {
                mKey = env->GetByteArrayElements(mKeyObj.get(), nullptr);
            }
        }

        if (mErr == OK && mIvObj.get() != nullptr) {
            if (env->GetArrayLength(mIvObj.get()) != 16) {
                mErr = -EINVAL;
            } else {
                mIv = env->GetByteArrayElements(mIvObj.get(), nullptr);
            }
        }
    }

    ~NativeCryptoInfo() {
        if (mIv != nullptr) {
            mEnv->ReleaseByteArrayElements(mIvObj.get(), mIv, 0);
        }

        if (mKey != nullptr) {
            mEnv->ReleaseByteArrayElements(mKeyObj.get(), mKey, 0);
        }

        if (mSubSamples != nullptr) {
            delete[] mSubSamples;
        }
    }

    JNIEnv *mEnv{nullptr};
    ScopedLocalRef<jbyteArray> mIvObj;
    ScopedLocalRef<jbyteArray> mKeyObj;
    status_t mErr{OK};

    CryptoPlugin::SubSample *mSubSamples{nullptr};
    int32_t mNumSubSamples{0};
    jbyte *mIv{nullptr};
    jbyte *mKey{nullptr};
    enum CryptoPlugin::Mode mMode;
    CryptoPlugin::Pattern mPattern;
};

static void android_media_MediaCodec_queueSecureInputBuffer(
        JNIEnv *env,
        jobject thiz,
        jint index,
        jint offset,
        jobject cryptoInfoObj,
        jlong timestampUs,
        jint flags) {
    ALOGV("android_media_MediaCodec_queueSecureInputBuffer");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    jint numSubSamples =
        env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);

    jintArray numBytesOfClearDataObj =
        (jintArray)env->GetObjectField(
                cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID);

    jintArray numBytesOfEncryptedDataObj =
        (jintArray)env->GetObjectField(
                cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID);

    jbyteArray keyObj =
        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID);

    jbyteArray ivObj =
        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);

    jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
    enum CryptoPlugin::Mode mode;
    if (jmode == gCryptoModes.Unencrypted) {
        mode = CryptoPlugin::kMode_Unencrypted;
    } else if (jmode == gCryptoModes.AesCtr) {
        mode = CryptoPlugin::kMode_AES_CTR;
    } else if (jmode == gCryptoModes.AesCbc) {
        mode = CryptoPlugin::kMode_AES_CBC;
    }  else {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID);

    CryptoPlugin::Pattern pattern;
    if (patternObj == NULL) {
        pattern.mEncryptBlocks = 0;
        pattern.mSkipBlocks = 0;
    } else {
        pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID);
        pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID);
    }

    status_t err = OK;

    CryptoPlugin::SubSample *subSamples = NULL;
    jbyte *key = NULL;
    jbyte *iv = NULL;

    if (numSubSamples <= 0) {
        err = -EINVAL;
    } else if (numBytesOfClearDataObj == NULL
            && numBytesOfEncryptedDataObj == NULL) {
        err = -EINVAL;
    } else if (numBytesOfEncryptedDataObj != NULL
            && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) {
        err = -ERANGE;
    } else if (numBytesOfClearDataObj != NULL
            && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) {
        err = -ERANGE;
    // subSamples array may silently overflow if number of samples are too large.  Use
    // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms
    } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) {
        err = -EINVAL;
    } else {
        jboolean isCopy;

        jint *numBytesOfClearData =
            (numBytesOfClearDataObj == NULL)
                ? NULL
                : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy);

        jint *numBytesOfEncryptedData =
            (numBytesOfEncryptedDataObj == NULL)
                ? NULL
                : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);

        subSamples = new CryptoPlugin::SubSample[numSubSamples];

        for (jint i = 0; i < numSubSamples; ++i) {
            subSamples[i].mNumBytesOfClearData =
                (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i];

            subSamples[i].mNumBytesOfEncryptedData =
                (numBytesOfEncryptedData == NULL)
                    ? 0 : numBytesOfEncryptedData[i];
        }

        if (numBytesOfEncryptedData != NULL) {
            env->ReleaseIntArrayElements(
                    numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0);
            numBytesOfEncryptedData = NULL;
        }

        if (numBytesOfClearData != NULL) {
            env->ReleaseIntArrayElements(
                    numBytesOfClearDataObj, numBytesOfClearData, 0);
            numBytesOfClearData = NULL;
        }
    }

    if (err == OK && keyObj != NULL) {
        if (env->GetArrayLength(keyObj) != 16) {
            err = -EINVAL;
        } else {
            jboolean isCopy;
            key = env->GetByteArrayElements(keyObj, &isCopy);
        }
    }

    if (err == OK && ivObj != NULL) {
        if (env->GetArrayLength(ivObj) != 16) {
            err = -EINVAL;
        } else {
            jboolean isCopy;
            iv = env->GetByteArrayElements(ivObj, &isCopy);
        }
    }

    AString errorDetailMsg;

    if (err == OK) {
        err = codec->queueSecureInputBuffer(
                index, offset,
                subSamples, numSubSamples,
                (const uint8_t *)key, (const uint8_t *)iv,
                mode,
                pattern,
                timestampUs,
                flags,
                &errorDetailMsg);
    }

    if (iv != NULL) {
        env->ReleaseByteArrayElements(ivObj, iv, 0);
        iv = NULL;
    }

    if (key != NULL) {
        env->ReleaseByteArrayElements(keyObj, key, 0);
        key = NULL;
    }

    delete[] subSamples;
    subSamples = NULL;

    throwExceptionAsNecessary(
            env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}

static jobject android_media_MediaCodec_mapHardwareBuffer(JNIEnv *env, jobject bufferObj) {
    ALOGV("android_media_MediaCodec_mapHardwareBuffer");
    AHardwareBuffer *hardwareBuffer = android_hardware_HardwareBuffer_getNativeHardwareBuffer(
            env, bufferObj);
    AHardwareBuffer_Desc desc;
    AHardwareBuffer_describe(hardwareBuffer, &desc);
    if (desc.format != AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420) {
        ALOGI("mapHardwareBuffer: unmappable format: %d", desc.format);
        return nullptr;
    }
    if ((desc.usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) == 0) {
        ALOGI("mapHardwareBuffer: buffer not CPU readable");
        return nullptr;
    }
    bool readOnly = ((desc.usage & AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK) == 0);

    uint64_t cpuUsage = desc.usage;
    cpuUsage = (cpuUsage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK);
    cpuUsage = (cpuUsage & AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK);

    AHardwareBuffer_Planes planes;
    int err = AHardwareBuffer_lockPlanes(
            hardwareBuffer, cpuUsage, -1 /* fence */, nullptr /* rect */, &planes);
    if (err != 0) {
        ALOGI("mapHardwareBuffer: Failed to lock planes (err=%d)", err);
        return nullptr;
    }

    if (planes.planeCount != 3) {
        ALOGI("mapHardwareBuffer: planeCount expected 3, actual %u", planes.planeCount);
        return nullptr;
    }

    ScopedLocalRef<jclass> planeClazz(
            env, env->FindClass("android/media/MediaCodec$MediaImage$MediaPlane"));
    ScopedLocalRef<jobjectArray> planeArray{
            env, env->NewObjectArray(3, planeClazz.get(), NULL)};
    CHECK(planeClazz.get() != NULL);
    jmethodID planeConstructID = env->GetMethodID(planeClazz.get(), "<init>",
            "([Ljava/nio/ByteBuffer;IIIII)V");

    // plane indices are Y-U-V.
    for (uint32_t i = 0; i < 3; ++i) {
        const AHardwareBuffer_Plane &plane = planes.planes[i];
        ScopedLocalRef<jobject> byteBuffer{env, CreateByteBuffer(
                env,
                plane.data,
                plane.rowStride * (desc.height - 1) + plane.pixelStride * (desc.width - 1) + 1,
                0,
                plane.rowStride * (desc.height - 1) + plane.pixelStride * (desc.width - 1) + 1,
                readOnly,
                true)};

        ScopedLocalRef<jobject> planeObj{env, env->NewObject(
                planeClazz.get(), planeConstructID,
                byteBuffer.get(), plane.rowStride, plane.pixelStride)};

        env->SetObjectArrayElement(planeArray.get(), i, planeObj.get());
    }

    ScopedLocalRef<jclass> imageClazz(
            env, env->FindClass("android/media/MediaCodec$MediaImage"));
    CHECK(imageClazz.get() != NULL);

    jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>",
            "([Landroid/media/Image$Plane;IIIZJIILandroid/graphics/Rect;J)V");

    jobject img = env->NewObject(imageClazz.get(), imageConstructID,
            planeArray.get(),
            desc.width,
            desc.height,
            desc.format, // ???
            (jboolean)readOnly /* readOnly */,
            (jlong)0 /* timestamp */,
            (jint)0 /* xOffset */, (jint)0 /* yOffset */, nullptr /* cropRect */,
            (jlong)hardwareBuffer);

    // if MediaImage creation fails, return null
    if (env->ExceptionCheck()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
        return nullptr;
    }

    AHardwareBuffer_acquire(hardwareBuffer);

    return img;
}

static void android_media_MediaCodec_closeMediaImage(JNIEnv *, jlong context) {
    if (context == 0) {
        return;
    }
    AHardwareBuffer *hardwareBuffer = (AHardwareBuffer *)context;

    int32_t fenceFd = -1;
    int err = AHardwareBuffer_unlock(hardwareBuffer, &fenceFd);
    if (err == 0) {
        sp<Fence> fence{new Fence(fenceFd)};
    } else {
        ALOGI("closeMediaImage: failed to unlock (err=%d)", err);
        // Continue to release the hardwareBuffer
    }

    AHardwareBuffer_release(hardwareBuffer);
}

static status_t ConvertKeyValueListsToAMessage(
        JNIEnv *env, jobject keys, jobject values, sp<AMessage> *msg) {
    static struct Fields {
        explicit Fields(JNIEnv *env) {
            ScopedLocalRef<jclass> clazz{env, env->FindClass("java/lang/String")};
            CHECK(clazz.get() != NULL);
            mStringClass = (jclass)env->NewGlobalRef(clazz.get());

            clazz.reset(env->FindClass("java/lang/Integer"));
            CHECK(clazz.get() != NULL);
            mIntegerClass = (jclass)env->NewGlobalRef(clazz.get());

            mIntegerValueId = env->GetMethodID(clazz.get(), "intValue", "()I");
            CHECK(mIntegerValueId != NULL);

            clazz.reset(env->FindClass("java/lang/Long"));
            CHECK(clazz.get() != NULL);
            mLongClass = (jclass)env->NewGlobalRef(clazz.get());

            mLongValueId = env->GetMethodID(clazz.get(), "longValue", "()J");
            CHECK(mLongValueId != NULL);

            clazz.reset(env->FindClass("java/lang/Float"));
            CHECK(clazz.get() != NULL);
            mFloatClass = (jclass)env->NewGlobalRef(clazz.get());

            mFloatValueId = env->GetMethodID(clazz.get(), "floatValue", "()F");
            CHECK(mFloatValueId != NULL);

            clazz.reset(env->FindClass("java/util/ArrayList"));
            CHECK(clazz.get() != NULL);

            mByteBufferArrayId = env->GetMethodID(gByteBufferInfo.clazz, "array", "()[B");
            CHECK(mByteBufferArrayId != NULL);
        }

        jclass mStringClass;
        jclass mIntegerClass;
        jmethodID mIntegerValueId;
        jclass mLongClass;
        jmethodID mLongValueId;
        jclass mFloatClass;
        jmethodID mFloatValueId;
        jmethodID mByteBufferArrayId;
    } sFields{env};

    jint size = env->CallIntMethod(keys, gArrayListInfo.sizeId);
    if (size != env->CallIntMethod(values, gArrayListInfo.sizeId)) {
        return BAD_VALUE;
    }

    sp<AMessage> result{new AMessage};
    for (jint i = 0; i < size; ++i) {
        ScopedLocalRef<jstring> jkey{
            env, (jstring)env->CallObjectMethod(keys, gArrayListInfo.getId, i)};
        const char *tmp = env->GetStringUTFChars(jkey.get(), nullptr);
        AString key;
        if (tmp) {
            key.setTo(tmp);
        }
        env->ReleaseStringUTFChars(jkey.get(), tmp);
        if (key.empty()) {
            return NO_MEMORY;
        }

        ScopedLocalRef<jobject> jvalue{
            env, env->CallObjectMethod(values, gArrayListInfo.getId, i)};

        if (env->IsInstanceOf(jvalue.get(), sFields.mStringClass)) {
            const char *tmp = env->GetStringUTFChars((jstring)jvalue.get(), nullptr);
            AString value;
            if (tmp) {
                value.setTo(tmp);
            }
            env->ReleaseStringUTFChars((jstring)jvalue.get(), tmp);
            if (value.empty()) {
                return NO_MEMORY;
            }
            result->setString(key.c_str(), value);
        } else if (env->IsInstanceOf(jvalue.get(), sFields.mIntegerClass)) {
            jint value = env->CallIntMethod(jvalue.get(), sFields.mIntegerValueId);
            result->setInt32(key.c_str(), value);
        } else if (env->IsInstanceOf(jvalue.get(), sFields.mLongClass)) {
            jlong value = env->CallLongMethod(jvalue.get(), sFields.mLongValueId);
            result->setInt64(key.c_str(), value);
        } else if (env->IsInstanceOf(jvalue.get(), sFields.mFloatClass)) {
            jfloat value = env->CallFloatMethod(jvalue.get(), sFields.mFloatValueId);
            result->setFloat(key.c_str(), value);
        } else if (env->IsInstanceOf(jvalue.get(), gByteBufferInfo.clazz)) {
            jint position = env->CallIntMethod(jvalue.get(), gByteBufferInfo.positionId);
            jint limit = env->CallIntMethod(jvalue.get(), gByteBufferInfo.limitId);
            sp<ABuffer> buffer{new ABuffer(limit - position)};
            void *data = env->GetDirectBufferAddress(jvalue.get());
            if (data != nullptr) {
                memcpy(buffer->data(),
                       static_cast<const uint8_t *>(data) + position,
                       buffer->size());
            } else {
                ScopedLocalRef<jbyteArray> byteArray{env, (jbyteArray)env->CallObjectMethod(
                        jvalue.get(), sFields.mByteBufferArrayId)};
                env->GetByteArrayRegion(byteArray.get(), position, buffer->size(),
                                        reinterpret_cast<jbyte *>(buffer->data()));
            }
            result->setBuffer(key.c_str(), buffer);
        }
    }

    *msg = result;
    return OK;
}

static void android_media_MediaCodec_native_queueLinearBlock(
        JNIEnv *env, jobject thiz, jint index, jobject bufferObj,
        jint offset, jint size, jobject cryptoInfoObj,
        jlong presentationTimeUs, jint flags, jobject keys, jobject values) {
    ALOGV("android_media_MediaCodec_native_queueLinearBlock");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == nullptr) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    sp<AMessage> tunings;
    status_t err = ConvertKeyValueListsToAMessage(env, keys, values, &tunings);
    if (err != OK) {
        throwExceptionAsNecessary(env, err);
        return;
    }

    std::shared_ptr<C2Buffer> buffer;
    sp<hardware::HidlMemory> memory;
    ScopedLocalRef<jobject> lock{env, env->GetObjectField(bufferObj, gLinearBlockInfo.lockId)};
    if (env->MonitorEnter(lock.get()) == JNI_OK) {
        if (env->GetBooleanField(bufferObj, gLinearBlockInfo.validId)) {
            JMediaCodecLinearBlock *context =
                (JMediaCodecLinearBlock *)env->GetLongField(bufferObj, gLinearBlockInfo.contextId);
            if (cryptoInfoObj != nullptr) {
                memory = context->toHidlMemory();
            } else {
                buffer = context->toC2Buffer(offset, size);
            }
        }
        env->MonitorExit(lock.get());
    } else {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    AString errorDetailMsg;
    if (cryptoInfoObj != nullptr) {
        if (!memory) {
            throwExceptionAsNecessary(env, BAD_VALUE);
            return;
        }

        NativeCryptoInfo cryptoInfo{env, cryptoInfoObj};
        err = codec->queueEncryptedLinearBlock(
                index,
                memory,
                offset,
                cryptoInfo.mSubSamples, cryptoInfo.mNumSubSamples,
                (const uint8_t *)cryptoInfo.mKey, (const uint8_t *)cryptoInfo.mIv,
                cryptoInfo.mMode,
                cryptoInfo.mPattern,
                presentationTimeUs,
                flags,
                tunings,
                &errorDetailMsg);
    } else {
        if (!buffer) {
            throwExceptionAsNecessary(env, BAD_VALUE);
            return;
        }
        err = codec->queueBuffer(
                index, buffer, presentationTimeUs, flags, tunings, &errorDetailMsg);
    }
    throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, errorDetailMsg.c_str());
}

static void android_media_MediaCodec_native_queueHardwareBuffer(
        JNIEnv *env, jobject thiz, jint index, jobject bufferObj,
        jlong presentationTimeUs, jint flags, jobject keys, jobject values) {
    ALOGV("android_media_MediaCodec_native_queueHardwareBuffer");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    sp<AMessage> tunings;
    status_t err = ConvertKeyValueListsToAMessage(env, keys, values, &tunings);
    if (err != OK) {
        throwExceptionAsNecessary(env, err);
        return;
    }

    AHardwareBuffer *hardwareBuffer = android_hardware_HardwareBuffer_getNativeHardwareBuffer(
            env, bufferObj);
    sp<GraphicBuffer> graphicBuffer{AHardwareBuffer_to_GraphicBuffer(hardwareBuffer)};
    C2Handle *handle = WrapNativeCodec2GrallocHandle(
            graphicBuffer->handle, graphicBuffer->format,
            graphicBuffer->width, graphicBuffer->height,
            graphicBuffer->usage, graphicBuffer->stride);
    std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(handle);

    if (!block) {
        throwExceptionAsNecessary(env, BAD_VALUE);
        return;
    }
    std::shared_ptr<C2Buffer> buffer = C2Buffer::CreateGraphicBuffer(block->share(
            block->crop(), C2Fence{}));
    AString errorDetailMsg;
    err = codec->queueBuffer(index, buffer, presentationTimeUs, flags, tunings, &errorDetailMsg);
    throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, errorDetailMsg.c_str());
}

static void android_media_MediaCodec_native_getOutputFrame(
        JNIEnv *env, jobject thiz, jobject frame, jint index) {
    ALOGV("android_media_MediaCodec_native_getOutputFrame");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->getOutputFrame(env, frame, index);
    if (err != OK) {
        throwExceptionAsNecessary(env, err);
    }
}

static jint android_media_MediaCodec_dequeueInputBuffer(
        JNIEnv *env, jobject thiz, jlong timeoutUs) {
    ALOGV("android_media_MediaCodec_dequeueInputBuffer");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return -1;
    }

    size_t index;
    status_t err = codec->dequeueInputBuffer(&index, timeoutUs);

    if (err == OK) {
        return (jint) index;
    }

    return throwExceptionAsNecessary(env, err);
}

static jint android_media_MediaCodec_dequeueOutputBuffer(
        JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) {
    ALOGV("android_media_MediaCodec_dequeueOutputBuffer");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return 0;
    }

    size_t index;
    status_t err = codec->dequeueOutputBuffer(
            env, bufferInfo, &index, timeoutUs);

    if (err == OK) {
        return (jint) index;
    }

    return throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_releaseOutputBuffer(
        JNIEnv *env, jobject thiz,
        jint index, jboolean render, jboolean updatePTS, jlong timestampNs) {
    ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs);

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env,
        jobject thiz) {
    ALOGV("android_media_MediaCodec_signalEndOfInputStream");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->signalEndOfInputStream();

    throwExceptionAsNecessary(env, err);
}

static jobject android_media_MediaCodec_getFormatNative(
        JNIEnv *env, jobject thiz, jboolean input) {
    ALOGV("android_media_MediaCodec_getFormatNative");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobject format;
    status_t err = codec->getFormat(env, input, &format);

    if (err == OK) {
        return format;
    }

    throwExceptionAsNecessary(env, err);

    return NULL;
}

static jobject android_media_MediaCodec_getOutputFormatForIndexNative(
        JNIEnv *env, jobject thiz, jint index) {
    ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobject format;
    status_t err = codec->getOutputFormat(env, index, &format);

    if (err == OK) {
        return format;
    }

    throwExceptionAsNecessary(env, err);

    return NULL;
}

static jobjectArray android_media_MediaCodec_getBuffers(
        JNIEnv *env, jobject thiz, jboolean input) {
    ALOGV("android_media_MediaCodec_getBuffers");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobjectArray buffers;
    status_t err = codec->getBuffers(env, input, &buffers);

    if (err == OK) {
        return buffers;
    }

    // if we're out of memory, an exception was already thrown
    if (err != NO_MEMORY) {
        throwExceptionAsNecessary(env, err);
    }

    return NULL;
}

static jobject android_media_MediaCodec_getBuffer(
        JNIEnv *env, jobject thiz, jboolean input, jint index) {
    ALOGV("android_media_MediaCodec_getBuffer");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobject buffer;
    status_t err = codec->getBuffer(env, input, index, &buffer);

    if (err == OK) {
        return buffer;
    }

    // if we're out of memory, an exception was already thrown
    if (err != NO_MEMORY) {
        throwExceptionAsNecessary(env, err);
    }

    return NULL;
}

static jobject android_media_MediaCodec_getImage(
        JNIEnv *env, jobject thiz, jboolean input, jint index) {
    ALOGV("android_media_MediaCodec_getImage");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobject image;
    status_t err = codec->getImage(env, input, index, &image);

    if (err == OK) {
        return image;
    }

    // if we're out of memory, an exception was already thrown
    if (err != NO_MEMORY) {
        throwExceptionAsNecessary(env, err);
    }

    return NULL;
}

static jobject android_media_MediaCodec_getName(
        JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_getName");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jstring name;
    status_t err = codec->getName(env, &name);

    if (err == OK) {
        return name;
    }

    throwExceptionAsNecessary(env, err);

    return NULL;
}

static jobject android_media_MediaCodec_getOwnCodecInfo(
        JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_getOwnCodecInfo");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobject codecInfoObj;
    status_t err = codec->getCodecInfo(env, &codecInfoObj);

    if (err == OK) {
        return codecInfoObj;
    }

    throwExceptionAsNecessary(env, err);

    return NULL;
}

static jobject
android_media_MediaCodec_native_getMetrics(JNIEnv *env, jobject thiz)
{
    ALOGV("android_media_MediaCodec_native_getMetrics");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
    if (codec == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return 0;
    }

    // get what we have for the metrics from the codec
    mediametrics::Item *item = 0;

    status_t err = codec->getMetrics(env, item);
    if (err != OK) {
        ALOGE("getMetrics failed");
        return (jobject) NULL;
    }

    jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL);

    // housekeeping
    delete item;
    item = 0;

    return mybundle;
}

static void android_media_MediaCodec_setParameters(
        JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) {
    ALOGV("android_media_MediaCodec_setParameters");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    sp<AMessage> params;
    status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, &params);

    if (err == OK) {
        err = codec->setParameters(params);
    }

    throwExceptionAsNecessary(env, err);
}

static void android_media_MediaCodec_setVideoScalingMode(
        JNIEnv *env, jobject thiz, jint mode) {
    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW
            && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return;
    }

    codec->setVideoScalingMode(mode);
}

static void android_media_MediaCodec_setAudioPresentation(
        JNIEnv *env, jobject thiz, jint presentationId, jint programId) {
    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    codec->selectAudioPresentation((int32_t)presentationId, (int32_t)programId);
}

static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) {
    ScopedLocalRef<jclass> clazz(
            env, env->FindClass("android/media/MediaCodec"));
    CHECK(clazz.get() != NULL);

    gFields.postEventFromNativeID =
        env->GetMethodID(
                clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V");
    CHECK(gFields.postEventFromNativeID != NULL);

    gFields.lockAndGetContextID =
        env->GetMethodID(
                clazz.get(), "lockAndGetContext", "()J");
    CHECK(gFields.lockAndGetContextID != NULL);

    gFields.setAndUnlockContextID =
        env->GetMethodID(
                clazz.get(), "setAndUnlockContext", "(J)V");
    CHECK(gFields.setAndUnlockContextID != NULL);

    jfieldID field;
    field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_UNENCRYPTED", "I");
    CHECK(field != NULL);
    gCryptoModes.Unencrypted =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CTR", "I");
    CHECK(field != NULL);
    gCryptoModes.AesCtr =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CBC", "I");
    CHECK(field != NULL);
    gCryptoModes.AesCbc =
        env->GetStaticIntField(clazz.get(), field);

    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
    CHECK(clazz.get() != NULL);

    gFields.cryptoInfoNumSubSamplesID =
        env->GetFieldID(clazz.get(), "numSubSamples", "I");
    CHECK(gFields.cryptoInfoNumSubSamplesID != NULL);

    gFields.cryptoInfoNumBytesOfClearDataID =
        env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I");
    CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL);

    gFields.cryptoInfoNumBytesOfEncryptedDataID =
        env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I");
    CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL);

    gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B");
    CHECK(gFields.cryptoInfoKeyID != NULL);

    gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B");
    CHECK(gFields.cryptoInfoIVID != NULL);

    gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I");
    CHECK(gFields.cryptoInfoModeID != NULL);

    gFields.cryptoInfoPatternID = env->GetFieldID(clazz.get(), "pattern",
        "Landroid/media/MediaCodec$CryptoInfo$Pattern;");
    CHECK(gFields.cryptoInfoPatternID != NULL);

    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo$Pattern"));
    CHECK(clazz.get() != NULL);

    gFields.patternEncryptBlocksID = env->GetFieldID(clazz.get(), "mEncryptBlocks", "I");
    CHECK(gFields.patternEncryptBlocksID != NULL);

    gFields.patternSkipBlocksID = env->GetFieldID(clazz.get(), "mSkipBlocks", "I");
    CHECK(gFields.patternSkipBlocksID != NULL);

    clazz.reset(env->FindClass("android/media/MediaCodec$QueueRequest"));
    CHECK(clazz.get() != NULL);

    gFields.queueRequestIndexID = env->GetFieldID(clazz.get(), "mIndex", "I");
    CHECK(gFields.queueRequestIndexID != NULL);

    clazz.reset(env->FindClass("android/media/MediaCodec$OutputFrame"));
    CHECK(clazz.get() != NULL);

    gFields.outputFrameLinearBlockID =
        env->GetFieldID(clazz.get(), "mLinearBlock", "Landroid/media/MediaCodec$LinearBlock;");
    CHECK(gFields.outputFrameLinearBlockID != NULL);

    gFields.outputFrameHardwareBufferID =
        env->GetFieldID(clazz.get(), "mHardwareBuffer", "Landroid/hardware/HardwareBuffer;");
    CHECK(gFields.outputFrameHardwareBufferID != NULL);

    gFields.outputFrameChangedKeysID =
        env->GetFieldID(clazz.get(), "mChangedKeys", "Ljava/util/ArrayList;");
    CHECK(gFields.outputFrameChangedKeysID != NULL);

    gFields.outputFrameFormatID =
        env->GetFieldID(clazz.get(), "mFormat", "Landroid/media/MediaFormat;");
    CHECK(gFields.outputFrameFormatID != NULL);

    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException"));
    CHECK(clazz.get() != NULL);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorNoKey =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorKeyExpired =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorResourceBusy =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_SESSION_NOT_OPENED", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorSessionNotOpened =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_SECURITY", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorInsufficientSecurity =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_UNSUPPORTED_OPERATION", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorUnsupportedOperation =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_FRAME_TOO_LARGE", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorFrameTooLarge =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_LOST_STATE", "I");
    CHECK(field != NULL);
    gCryptoErrorCodes.cryptoErrorLostState =
        env->GetStaticIntField(clazz.get(), field);

    clazz.reset(env->FindClass("android/media/MediaCodec$CodecException"));
    CHECK(clazz.get() != NULL);
    field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I");
    CHECK(field != NULL);
    gCodecActionCodes.codecActionTransient =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ACTION_RECOVERABLE", "I");
    CHECK(field != NULL);
    gCodecActionCodes.codecActionRecoverable =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_RESOURCE", "I");
    CHECK(field != NULL);
    gCodecErrorCodes.errorInsufficientResource =
        env->GetStaticIntField(clazz.get(), field);

    field = env->GetStaticFieldID(clazz.get(), "ERROR_RECLAIMED", "I");
    CHECK(field != NULL);
    gCodecErrorCodes.errorReclaimed =
        env->GetStaticIntField(clazz.get(), field);

    clazz.reset(env->FindClass("android/view/Surface"));
    CHECK(clazz.get() != NULL);

    field = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;");
    CHECK(field != NULL);
    gPersistentSurfaceClassInfo.mLock = field;

    jmethodID method = env->GetMethodID(clazz.get(), "setNativeObjectLocked", "(J)V");
    CHECK(method != NULL);
    gPersistentSurfaceClassInfo.setNativeObjectLocked = method;

    clazz.reset(env->FindClass("android/media/MediaCodec$PersistentSurface"));
    CHECK(clazz.get() != NULL);
    gPersistentSurfaceClassInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());

    method = env->GetMethodID(clazz.get(), "<init>", "()V");
    CHECK(method != NULL);
    gPersistentSurfaceClassInfo.ctor = method;

    field = env->GetFieldID(clazz.get(), "mPersistentObject", "J");
    CHECK(field != NULL);
    gPersistentSurfaceClassInfo.mPersistentObject = field;

    clazz.reset(env->FindClass("android/media/MediaCodecInfo$CodecCapabilities"));
    CHECK(clazz.get() != NULL);
    gCodecInfo.capsClazz = (jclass)env->NewGlobalRef(clazz.get());

    method = env->GetMethodID(clazz.get(), "<init>",
            "([Landroid/media/MediaCodecInfo$CodecProfileLevel;[IZ"
            "Ljava/util/Map;Ljava/util/Map;)V");
    CHECK(method != NULL);
    gCodecInfo.capsCtorId = method;

    clazz.reset(env->FindClass("android/media/MediaCodecInfo$CodecProfileLevel"));
    CHECK(clazz.get() != NULL);
    gCodecInfo.profileLevelClazz = (jclass)env->NewGlobalRef(clazz.get());

    field = env->GetFieldID(clazz.get(), "profile", "I");
    CHECK(field != NULL);
    gCodecInfo.profileField = field;

    field = env->GetFieldID(clazz.get(), "level", "I");
    CHECK(field != NULL);
    gCodecInfo.levelField = field;

    clazz.reset(env->FindClass("java/nio/ByteBuffer"));
    CHECK(clazz.get() != NULL);
    gByteBufferInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());

    ScopedLocalRef<jclass> byteOrderClass(
            env, env->FindClass("java/nio/ByteOrder"));
    CHECK(byteOrderClass.get() != NULL);

    jmethodID nativeOrderID = env->GetStaticMethodID(
            byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;");
    CHECK(nativeOrderID != NULL);

    ScopedLocalRef<jobject> nativeByteOrderObj{
        env, env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID)};
    gByteBufferInfo.nativeByteOrder = env->NewGlobalRef(nativeByteOrderObj.get());
    CHECK(gByteBufferInfo.nativeByteOrder != NULL);
    nativeByteOrderObj.reset();

    gByteBufferInfo.orderId = env->GetMethodID(
            clazz.get(),
            "order",
            "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
    CHECK(gByteBufferInfo.orderId != NULL);

    gByteBufferInfo.asReadOnlyBufferId = env->GetMethodID(
            clazz.get(), "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;");
    CHECK(gByteBufferInfo.asReadOnlyBufferId != NULL);

    gByteBufferInfo.positionId = env->GetMethodID(
            clazz.get(), "position", "(I)Ljava/nio/Buffer;");
    CHECK(gByteBufferInfo.positionId != NULL);

    gByteBufferInfo.limitId = env->GetMethodID(
            clazz.get(), "limit", "(I)Ljava/nio/Buffer;");
    CHECK(gByteBufferInfo.limitId != NULL);

    clazz.reset(env->FindClass("java/util/ArrayList"));
    CHECK(clazz.get() != NULL);

    gArrayListInfo.sizeId = env->GetMethodID(clazz.get(), "size", "()I");
    CHECK(gArrayListInfo.sizeId != NULL);

    gArrayListInfo.getId = env->GetMethodID(clazz.get(), "get", "(I)Ljava/lang/Object;");
    CHECK(gArrayListInfo.getId != NULL);

    gArrayListInfo.addId = env->GetMethodID(clazz.get(), "add", "(Ljava/lang/Object;)Z");
    CHECK(gArrayListInfo.addId != NULL);

    clazz.reset(env->FindClass("android/media/MediaCodec$LinearBlock"));
    CHECK(clazz.get() != NULL);

    gLinearBlockInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());

    gLinearBlockInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V");
    CHECK(gLinearBlockInfo.ctorId != NULL);

    gLinearBlockInfo.setInternalStateId = env->GetMethodID(
            clazz.get(), "setInternalStateLocked", "(JZ)V");
    CHECK(gLinearBlockInfo.setInternalStateId != NULL);

    gLinearBlockInfo.contextId = env->GetFieldID(clazz.get(), "mNativeContext", "J");
    CHECK(gLinearBlockInfo.contextId != NULL);

    gLinearBlockInfo.validId = env->GetFieldID(clazz.get(), "mValid", "Z");
    CHECK(gLinearBlockInfo.validId != NULL);

    gLinearBlockInfo.lockId = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;");
    CHECK(gLinearBlockInfo.lockId != NULL);
}

static void android_media_MediaCodec_native_setup(
        JNIEnv *env, jobject thiz,
        jstring name, jboolean nameIsType, jboolean encoder) {
    if (name == NULL) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return;
    }

    const char *tmp = env->GetStringUTFChars(name, NULL);

    if (tmp == NULL) {
        return;
    }

    sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder);

    const status_t err = codec->initCheck();
    if (err == NAME_NOT_FOUND) {
        // fail and do not try again.
        jniThrowException(env, "java/lang/IllegalArgumentException",
                String8::format("Failed to initialize %s, error %#x", tmp, err));
        env->ReleaseStringUTFChars(name, tmp);
        return;
    } if (err == NO_MEMORY) {
        throwCodecException(env, err, ACTION_CODE_TRANSIENT,
                String8::format("Failed to initialize %s, error %#x", tmp, err));
        env->ReleaseStringUTFChars(name, tmp);
        return;
    } else if (err != OK) {
        // believed possible to try again
        jniThrowException(env, "java/io/IOException",
                String8::format("Failed to find matching codec %s, error %#x", tmp, err));
        env->ReleaseStringUTFChars(name, tmp);
        return;
    }

    env->ReleaseStringUTFChars(name, tmp);

    codec->registerSelf();

    setMediaCodec(env,thiz, codec);
}

static void android_media_MediaCodec_native_finalize(
        JNIEnv *env, jobject thiz) {
    android_media_MediaCodec_release(env, thiz);
}

// MediaCodec.LinearBlock

static jobject android_media_MediaCodec_LinearBlock_native_map(
        JNIEnv *env, jobject thiz) {
    JMediaCodecLinearBlock *context =
        (JMediaCodecLinearBlock *)env->GetLongField(thiz, gLinearBlockInfo.contextId);
    if (context->mBuffer) {
        std::shared_ptr<C2Buffer> buffer = context->mBuffer;
        if (!context->mReadonlyMapping) {
            const C2BufferData data = buffer->data();
            if (data.type() != C2BufferData::LINEAR) {
                throwExceptionAsNecessary(env, INVALID_OPERATION);
                return nullptr;
            }
            if (data.linearBlocks().size() != 1u) {
                throwExceptionAsNecessary(env, INVALID_OPERATION);
                return nullptr;
            }
            C2ConstLinearBlock block = data.linearBlocks().front();
            context->mReadonlyMapping =
                std::make_shared<C2ReadView>(block.map().get());
        }
        return CreateByteBuffer(
                env,
                context->mReadonlyMapping->data(),  // base
                context->mReadonlyMapping->capacity(),  // capacity
                0u,  // offset
                context->mReadonlyMapping->capacity(),  // size
                true,  // readOnly
                true /* clearBuffer */);
    } else if (context->mBlock) {
        std::shared_ptr<C2LinearBlock> block = context->mBlock;
        if (!context->mReadWriteMapping) {
            context->mReadWriteMapping =
                std::make_shared<C2WriteView>(block->map().get());
        }
        return CreateByteBuffer(
                env,
                context->mReadWriteMapping->base(),
                context->mReadWriteMapping->capacity(),
                context->mReadWriteMapping->offset(),
                context->mReadWriteMapping->size(),
                false,  // readOnly
                true /* clearBuffer */);
    } else if (context->mLegacyBuffer) {
        return CreateByteBuffer(
                env,
                context->mLegacyBuffer->base(),
                context->mLegacyBuffer->capacity(),
                context->mLegacyBuffer->offset(),
                context->mLegacyBuffer->size(),
                true,  // readOnly
                true /* clearBuffer */);
    } else if (context->mHeap) {
        return CreateByteBuffer(
                env,
                static_cast<uint8_t *>(context->mHeap->getBase()) + context->mHeap->getOffset(),
                context->mHeap->getSize(),
                0,
                context->mHeap->getSize(),
                false,  // readOnly
                true /* clearBuffer */);
    }
    throwExceptionAsNecessary(env, INVALID_OPERATION);
    return nullptr;
}

static void android_media_MediaCodec_LinearBlock_native_recycle(
        JNIEnv *env, jobject thiz) {
    JMediaCodecLinearBlock *context =
        (JMediaCodecLinearBlock *)env->GetLongField(thiz, gLinearBlockInfo.contextId);
    env->CallVoidMethod(thiz, gLinearBlockInfo.setInternalStateId, 0, false);
    delete context;
}

static void PopulateNamesVector(
        JNIEnv *env, jobjectArray codecNames, std::vector<std::string> *names) {
    jsize length = env->GetArrayLength(codecNames);
    for (jsize i = 0; i < length; ++i) {
        jstring jstr = static_cast<jstring>(env->GetObjectArrayElement(codecNames, i));
        if (jstr == nullptr) {
            // null entries are ignored
            continue;
        }
        const char *cstr = env->GetStringUTFChars(jstr, nullptr);
        if (cstr == nullptr) {
            throwExceptionAsNecessary(env, BAD_VALUE);
            return;
        }
        names->emplace_back(cstr);
        env->ReleaseStringUTFChars(jstr, cstr);
    }
}

static void android_media_MediaCodec_LinearBlock_native_obtain(
        JNIEnv *env, jobject thiz, jint capacity, jobjectArray codecNames) {
    std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
    std::vector<std::string> names;
    PopulateNamesVector(env, codecNames, &names);
    bool hasSecure = false;
    bool hasNonSecure = false;
    for (const std::string &name : names) {
        if (name.length() >= 7 && name.substr(name.length() - 7) == ".secure") {
            hasSecure = true;
        } else {
            hasNonSecure = true;
        }
    }
    if (hasSecure && !hasNonSecure) {
        context->mHeap = new MemoryHeapBase(capacity);
        context->mMemory = hardware::fromHeap(context->mHeap);
    } else {
        context->mBlock = MediaCodec::FetchLinearBlock(capacity, names);
        if (!context->mBlock) {
            jniThrowException(env, "java/io/IOException", nullptr);
            return;
        }
    }
    env->CallVoidMethod(
            thiz,
            gLinearBlockInfo.setInternalStateId,
            (jlong)context.release(),
            true /* isMappable */);
}

static jboolean android_media_MediaCodec_LinearBlock_checkCompatible(
        JNIEnv *env, jclass, jobjectArray codecNames) {
    std::vector<std::string> names;
    PopulateNamesVector(env, codecNames, &names);
    bool isCompatible = false;
    bool hasSecure = false;
    bool hasNonSecure = false;
    for (const std::string &name : names) {
        if (name.length() >= 7 && name.substr(name.length() - 7) == ".secure") {
            hasSecure = true;
        } else {
            hasNonSecure = true;
        }
    }
    if (hasSecure && hasNonSecure) {
        return false;
    }
    status_t err = MediaCodec::CanFetchLinearBlock(names, &isCompatible);
    if (err != OK) {
        throwExceptionAsNecessary(env, err);
    }
    return isCompatible;
}

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

    { "native_reset", "()V", (void *)android_media_MediaCodec_reset },

    { "native_releasePersistentInputSurface",
      "(Landroid/view/Surface;)V",
       (void *)android_media_MediaCodec_releasePersistentInputSurface},

    { "native_createPersistentInputSurface",
      "()Landroid/media/MediaCodec$PersistentSurface;",
      (void *)android_media_MediaCodec_createPersistentInputSurface },

    { "native_setInputSurface", "(Landroid/view/Surface;)V",
      (void *)android_media_MediaCodec_setInputSurface },

    { "native_enableOnFrameRenderedListener", "(Z)V",
      (void *)android_media_MediaCodec_native_enableOnFrameRenderedListener },

    { "native_setCallback",
      "(Landroid/media/MediaCodec$Callback;)V",
      (void *)android_media_MediaCodec_native_setCallback },

    { "native_configure",
      "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;"
      "Landroid/media/MediaCrypto;Landroid/os/IHwBinder;I)V",
      (void *)android_media_MediaCodec_native_configure },

    { "native_setSurface",
      "(Landroid/view/Surface;)V",
      (void *)android_media_MediaCodec_native_setSurface },

    { "createInputSurface", "()Landroid/view/Surface;",
      (void *)android_media_MediaCodec_createInputSurface },

    { "native_start", "()V", (void *)android_media_MediaCodec_start },
    { "native_stop", "()V", (void *)android_media_MediaCodec_stop },
    { "native_flush", "()V", (void *)android_media_MediaCodec_flush },

    { "native_queueInputBuffer", "(IIIJI)V",
      (void *)android_media_MediaCodec_queueInputBuffer },

    { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V",
      (void *)android_media_MediaCodec_queueSecureInputBuffer },

    { "native_mapHardwareBuffer",
      "(Landroid/hardware/HardwareBuffer;)Landroid/media/Image;",
      (void *)android_media_MediaCodec_mapHardwareBuffer },

    { "native_closeMediaImage", "(J)V", (void *)android_media_MediaCodec_closeMediaImage },

    { "native_queueLinearBlock",
      "(ILandroid/media/MediaCodec$LinearBlock;IILandroid/media/MediaCodec$CryptoInfo;JI"
      "Ljava/util/ArrayList;Ljava/util/ArrayList;)V",
      (void *)android_media_MediaCodec_native_queueLinearBlock },

    { "native_queueHardwareBuffer",
      "(ILandroid/hardware/HardwareBuffer;JILjava/util/ArrayList;Ljava/util/ArrayList;)V",
      (void *)android_media_MediaCodec_native_queueHardwareBuffer },

    { "native_getOutputFrame",
      "(Landroid/media/MediaCodec$OutputFrame;I)V",
      (void *)android_media_MediaCodec_native_getOutputFrame },

    { "native_dequeueInputBuffer", "(J)I",
      (void *)android_media_MediaCodec_dequeueInputBuffer },

    { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I",
      (void *)android_media_MediaCodec_dequeueOutputBuffer },

    { "releaseOutputBuffer", "(IZZJ)V",
      (void *)android_media_MediaCodec_releaseOutputBuffer },

    { "signalEndOfInputStream", "()V",
      (void *)android_media_MediaCodec_signalEndOfInputStream },

    { "getFormatNative", "(Z)Ljava/util/Map;",
      (void *)android_media_MediaCodec_getFormatNative },

    { "getOutputFormatNative", "(I)Ljava/util/Map;",
      (void *)android_media_MediaCodec_getOutputFormatForIndexNative },

    { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;",
      (void *)android_media_MediaCodec_getBuffers },

    { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;",
      (void *)android_media_MediaCodec_getBuffer },

    { "getImage", "(ZI)Landroid/media/Image;",
      (void *)android_media_MediaCodec_getImage },

    { "getCanonicalName", "()Ljava/lang/String;",
      (void *)android_media_MediaCodec_getName },

    { "getOwnCodecInfo", "()Landroid/media/MediaCodecInfo;",
        (void *)android_media_MediaCodec_getOwnCodecInfo },

    { "native_getMetrics", "()Landroid/os/PersistableBundle;",
      (void *)android_media_MediaCodec_native_getMetrics},

    { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V",
      (void *)android_media_MediaCodec_setParameters },

    { "setVideoScalingMode", "(I)V",
      (void *)android_media_MediaCodec_setVideoScalingMode },

    { "native_setAudioPresentation", "(II)V",
      (void *)android_media_MediaCodec_setAudioPresentation },

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

    { "native_setup", "(Ljava/lang/String;ZZ)V",
      (void *)android_media_MediaCodec_native_setup },

    { "native_finalize", "()V",
      (void *)android_media_MediaCodec_native_finalize },
};

static const JNINativeMethod gLinearBlockMethods[] = {
    { "native_map", "()Ljava/nio/ByteBuffer;",
      (void *)android_media_MediaCodec_LinearBlock_native_map },

    { "native_recycle", "()V",
      (void *)android_media_MediaCodec_LinearBlock_native_recycle },

    { "native_obtain", "(I[Ljava/lang/String;)V",
      (void *)android_media_MediaCodec_LinearBlock_native_obtain },

    { "native_checkCompatible", "([Ljava/lang/String;)Z",
      (void *)android_media_MediaCodec_LinearBlock_checkCompatible },
};

int register_android_media_MediaCodec(JNIEnv *env) {
    int result = AndroidRuntime::registerNativeMethods(env,
                "android/media/MediaCodec", gMethods, NELEM(gMethods));
    if (result != JNI_OK) {
        return result;
    }
    result = AndroidRuntime::registerNativeMethods(env,
                "android/media/MediaCodec$LinearBlock",
                gLinearBlockMethods,
                NELEM(gLinearBlockMethods));
    return result;
}
