/*
 * Copyright (C) 2016 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 "android_os_HwParcel"
#include <android-base/logging.h>

#include "android_os_HwParcel.h"

#include "android_os_HwBinder.h"
#include "android_os_HwBlob.h"
#include "android_os_NativeHandle.h"
#include "android_os_HwRemoteBinder.h"

#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/Status.h>
#include <nativehelper/ScopedLocalRef.h>

#include "core_jni_helpers.h"

using android::AndroidRuntime;

using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;

#define PACKAGE_PATH    "android/os"
#define CLASS_NAME      "HwParcel"
#define CLASS_PATH      PACKAGE_PATH "/" CLASS_NAME

namespace android {

static struct fields_t {
    jfieldID contextID;
    jmethodID constructID;

} gFields;

void signalExceptionForError(JNIEnv *env, status_t err, bool canThrowRemoteException) {
    switch (err) {
        case OK:
            break;

        case NO_MEMORY:
        {
            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
            break;
        }

        case INVALID_OPERATION:
        {
            jniThrowException(
                    env, "java/lang/UnsupportedOperationException", NULL);
            break;
        }

        case BAD_VALUE:
        {
            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
            break;
        }

        case -ERANGE:
        case BAD_INDEX:
        {
            jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
            break;
        }

        case BAD_TYPE:
        {
            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
            break;
        }

        case NAME_NOT_FOUND:
        {
            jniThrowException(env, "java/util/NoSuchElementException", NULL);
            break;
        }

        case PERMISSION_DENIED:
        {
            jniThrowException(env, "java/lang/SecurityException", NULL);
            break;
        }

        case NO_INIT:
        {
            jniThrowException(
                    env, "java/lang/RuntimeException", "Not initialized");
            break;
        }

        case ALREADY_EXISTS:
        {
            jniThrowException(
                    env, "java/lang/RuntimeException", "Item already exists");
            break;
        }

        default:
        {
            std::stringstream ss;
            ss << "HwBinder Error: (" << err << ")";

            jniThrowException(
                    env,
                    canThrowRemoteException ? "android/os/RemoteException" : "java/lang/RuntimeException",
                    ss.str().c_str());

            break;
        }
    }
}

// static
void JHwParcel::InitClass(JNIEnv *env) {
    ScopedLocalRef<jclass> clazz(
            env, FindClassOrDie(env, CLASS_PATH));

    gFields.contextID =
        GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");

    gFields.constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");
}

// static
sp<JHwParcel> JHwParcel::SetNativeContext(
        JNIEnv *env, jobject thiz, const sp<JHwParcel> &context) {
    sp<JHwParcel> old = (JHwParcel *)env->GetLongField(thiz, gFields.contextID);

    if (context != NULL) {
        context->incStrong(NULL /* id */);
    }

    if (old != NULL) {
        old->decStrong(NULL /* id */);
    }

    env->SetLongField(thiz, gFields.contextID, (long)context.get());

    return old;
}

// static
sp<JHwParcel> JHwParcel::GetNativeContext(JNIEnv *env, jobject thiz) {
    return (JHwParcel *)env->GetLongField(thiz, gFields.contextID);
}

JHwParcel::JHwParcel(JNIEnv *env, jobject thiz)
    : mParcel(NULL),
      mOwnsParcel(false),
      mTransactCallback(nullptr),
      mWasSent(false) {
}

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

    mStorage.release(env);

    setParcel(NULL, false /* assumeOwnership */);
}

hardware::Parcel *JHwParcel::getParcel() {
    return mParcel;
}

EphemeralStorage *JHwParcel::getStorage() {
    return &mStorage;
}

void JHwParcel::setParcel(hardware::Parcel *parcel, bool assumeOwnership) {
    if (mParcel && mOwnsParcel) {
        delete mParcel;
    }

    mParcel = parcel;
    mOwnsParcel = assumeOwnership;
}

// static
jobject JHwParcel::NewObject(JNIEnv *env) {
    ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));

    jmethodID constructID =
        GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");

    return env->NewObject(clazz.get(), constructID, false /* allocate */);
}

void JHwParcel::setTransactCallback(
        ::android::hardware::IBinder::TransactCallback cb) {
    mTransactCallback = cb;
}

void JHwParcel::send() {
    CHECK(mTransactCallback != nullptr);
    CHECK(mParcel != nullptr);

    mTransactCallback(*mParcel);
    mTransactCallback = nullptr;

    mWasSent = true;
}

bool JHwParcel::wasSent() const {
    return mWasSent;
}

}  // namespace android

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

using namespace android;

static void releaseNativeContext(void *nativeContext) {
    sp<JHwParcel> parcel = (JHwParcel *)nativeContext;

    if (parcel != NULL) {
        parcel->decStrong(NULL /* id */);
    }
}

static jlong JHwParcel_native_init(JNIEnv *env) {
    JHwParcel::InitClass(env);

    return reinterpret_cast<jlong>(&releaseNativeContext);
}

static void JHwParcel_native_setup(
        JNIEnv *env, jobject thiz, jboolean allocate) {
    sp<JHwParcel> context = new JHwParcel(env, thiz);

    if (allocate) {
        context->setParcel(new hardware::Parcel, true /* assumeOwnership */);
    }

    JHwParcel::SetNativeContext(env, thiz, context);
}

static void JHwParcel_native_writeInterfaceToken(
        JNIEnv *env, jobject thiz, jstring interfaceNameObj) {
    if (interfaceNameObj == NULL) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return;
    }

    const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
    if (interfaceName) {
        String8 nameCopy = String8(String16(
                reinterpret_cast<const char16_t *>(interfaceName),
                env->GetStringLength(interfaceNameObj)));

        env->ReleaseStringCritical(interfaceNameObj, interfaceName);
        interfaceName = NULL;

        hardware::Parcel *parcel =
            JHwParcel::GetNativeContext(env, thiz)->getParcel();

        status_t err = parcel->writeInterfaceToken(nameCopy.string());
        signalExceptionForError(env, err);
    }
}

static void JHwParcel_native_enforceInterface(
        JNIEnv *env, jobject thiz, jstring interfaceNameObj) {
    // XXX original binder Parcel enforceInterface implementation does some
    // mysterious things regarding strictModePolicy(), figure out if we need
    // that here as well.
    if (interfaceNameObj == NULL) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return;
    }

    const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
    if (interfaceName) {
        String8 interfaceNameCopy = String8(String16(
                reinterpret_cast<const char16_t *>(interfaceName),
                env->GetStringLength(interfaceNameObj)));

        env->ReleaseStringCritical(interfaceNameObj, interfaceName);
        interfaceName = NULL;

        hardware::Parcel *parcel =
            JHwParcel::GetNativeContext(env, thiz)->getParcel();

        bool valid = parcel->enforceInterface(interfaceNameCopy.string());

        if (!valid) {
            jniThrowException(
                    env,
                    "java/lang/SecurityException",
                    "HWBinder invocation to an incorrect interface");
        }
    }
}

#define DEFINE_PARCEL_WRITER(Suffix,Type)                               \
static void JHwParcel_native_write ## Suffix(                           \
        JNIEnv *env, jobject thiz, Type val) {                          \
    hardware::Parcel *parcel =                                          \
        JHwParcel::GetNativeContext(env, thiz)->getParcel();            \
                                                                        \
    status_t err = parcel->write ## Suffix(val);                        \
    signalExceptionForError(env, err);                                  \
}

#define DEFINE_PARCEL_READER(Suffix,Type)                               \
static Type JHwParcel_native_read ## Suffix(                            \
        JNIEnv *env, jobject thiz) {                                    \
    hardware::Parcel *parcel =                                          \
        JHwParcel::GetNativeContext(env, thiz)->getParcel();            \
                                                                        \
    Type val;                                                           \
    status_t err = parcel->read ## Suffix(&val);                        \
    signalExceptionForError(env, err);                                  \
                                                                        \
    return val;                                                         \
}

DEFINE_PARCEL_WRITER(Bool,jboolean)
DEFINE_PARCEL_WRITER(Int8,jbyte)
DEFINE_PARCEL_WRITER(Int16,jshort)
DEFINE_PARCEL_WRITER(Int32,jint)
DEFINE_PARCEL_WRITER(Int64,jlong)
DEFINE_PARCEL_WRITER(Float,jfloat)
DEFINE_PARCEL_WRITER(Double,jdouble)

DEFINE_PARCEL_READER(Int8,jbyte)
DEFINE_PARCEL_READER(Int16,jshort)
DEFINE_PARCEL_READER(Int32,jint)
DEFINE_PARCEL_READER(Int64,jlong)
DEFINE_PARCEL_READER(Float,jfloat)
DEFINE_PARCEL_READER(Double,jdouble)

static jboolean JHwParcel_native_readBool(JNIEnv *env, jobject thiz) {
    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    bool val;
    status_t err = parcel->readBool(&val);
    signalExceptionForError(env, err);

    return (jboolean)val;
}

static void JHwParcel_native_writeStatus(
        JNIEnv *env, jobject thiz, jint statusCode) {
    using hardware::Status;

    Status status;
    switch (statusCode) {
        case 0:  // kStatusSuccess
            status = Status::ok();
            break;
        case -1:  // kStatusError
            status = Status::fromStatusT(UNKNOWN_ERROR);
            break;
        default:
            CHECK(!"Should not be here");
    }

    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    status_t err = ::android::hardware::writeToParcel(status, parcel);
    signalExceptionForError(env, err);
}

static void JHwParcel_native_verifySuccess(JNIEnv *env, jobject thiz) {
    using hardware::Status;

    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    Status status;
    status_t err = ::android::hardware::readFromParcel(&status, *parcel);
    signalExceptionForError(env, err);

    if (!status.isOk()) {
        signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
    }
}

static void JHwParcel_native_release(
        JNIEnv *env, jobject thiz) {
    JHwParcel::GetNativeContext(env, thiz)->setParcel(NULL, false /* assumeOwnership */);
}

static void JHwParcel_native_releaseTemporaryStorage(
        JNIEnv *env, jobject thiz) {
    JHwParcel::GetNativeContext(env, thiz)->getStorage()->release(env);
}

static void JHwParcel_native_send(JNIEnv *env, jobject thiz) {
    JHwParcel::GetNativeContext(env, thiz)->send();
}

static void JHwParcel_native_writeString(
        JNIEnv *env, jobject thiz, jstring valObj) {
    if (valObj == NULL) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return;
    }

    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);

    const hidl_string *s =
        impl->getStorage()->allocTemporaryString(env, valObj);

    hardware::Parcel *parcel = impl->getParcel();

    size_t parentHandle;
    status_t err = parcel->writeBuffer(s, sizeof(*s), &parentHandle);

    if (err == OK) {
        err = ::android::hardware::writeEmbeddedToParcel(
                *s, parcel, parentHandle, 0 /* parentOffset */);
    }

    signalExceptionForError(env, err);
}

static void JHwParcel_native_writeNativeHandle(JNIEnv *env, jobject thiz, jobject valObj) {
    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);

    EphemeralStorage *storage = impl->getStorage();
    native_handle_t *handle = JNativeHandle::MakeCppNativeHandle(env, valObj, storage);

    hardware::Parcel *parcel = impl->getParcel();
    status_t err = parcel->writeNativeHandleNoDup(handle);

    signalExceptionForError(env, err);
}

#define DEFINE_PARCEL_VECTOR_WRITER(Suffix,Type)                               \
static void JHwParcel_native_write ## Suffix ## Vector(                        \
        JNIEnv *env, jobject thiz, Type ## Array valObj) {                     \
    if (valObj == NULL) {                                                      \
        jniThrowException(env, "java/lang/NullPointerException", NULL);        \
        return;                                                                \
    }                                                                          \
                                                                               \
    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);               \
                                                                               \
    const hidl_vec<Type> *vec =                                                \
        impl->getStorage()->allocTemporary ## Suffix ## Vector(env, valObj);   \
                                                                               \
    hardware::Parcel *parcel = impl->getParcel();                              \
                                                                               \
    size_t parentHandle;                                                       \
    status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle);      \
                                                                               \
    if (err == OK) {                                                           \
        size_t childHandle;                                                    \
                                                                               \
        err = ::android::hardware::writeEmbeddedToParcel(                      \
                *vec,                                                          \
                parcel,                                                        \
                parentHandle,                                                  \
                0 /* parentOffset */,                                          \
                &childHandle);                                                 \
    }                                                                          \
                                                                               \
    signalExceptionForError(env, err);                                         \
}

DEFINE_PARCEL_VECTOR_WRITER(Int8,jbyte)
DEFINE_PARCEL_VECTOR_WRITER(Int16,jshort)
DEFINE_PARCEL_VECTOR_WRITER(Int32,jint)
DEFINE_PARCEL_VECTOR_WRITER(Int64,jlong)
DEFINE_PARCEL_VECTOR_WRITER(Float,jfloat)
DEFINE_PARCEL_VECTOR_WRITER(Double,jdouble)

static void JHwParcel_native_writeBoolVector(
        JNIEnv *env, jobject thiz, jbooleanArray valObj) {
    if (valObj == NULL) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return;
    }

    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);

    void *vecPtr =
        impl->getStorage()->allocTemporaryStorage(sizeof(hidl_vec<bool>));

    hidl_vec<bool> *vec = new (vecPtr) hidl_vec<bool>;

    jsize len = env->GetArrayLength(valObj);

    jboolean *src = env->GetBooleanArrayElements(valObj, nullptr);

    bool *dst =
        (bool *)impl->getStorage()->allocTemporaryStorage(len * sizeof(bool));

    for (jsize i = 0; i < len; ++i) {
        dst[i] = src[i];
    }

    env->ReleaseBooleanArrayElements(valObj, src, 0 /* mode */);
    src = nullptr;

    vec->setToExternal(dst, len);

    hardware::Parcel *parcel = impl->getParcel();

    size_t parentHandle;
    status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle);

    if (err == OK) {
        size_t childHandle;

        err = ::android::hardware::writeEmbeddedToParcel(
                *vec,
                parcel,
                parentHandle,
                0 /* parentOffset */,
                &childHandle);
    }

    signalExceptionForError(env, err);
}

template<typename T>
static void WriteHidlVector(JNIEnv *env, jobject thiz, const hidl_vec<T> &vec) {
    hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel();

    size_t parentHandle;
    status_t err = parcel->writeBuffer(&vec, sizeof(vec), &parentHandle);

    if (err == OK) {
        size_t childHandle;
        err = ::android::hardware::writeEmbeddedToParcel(
                vec,
                parcel,
                parentHandle,
                0 /* parentOffset */,
                &childHandle);

        for (size_t i = 0; (err == OK) && (i < vec.size()); ++i) {
            err = ::android::hardware::writeEmbeddedToParcel(
                    vec[i],
                    parcel,
                    childHandle,
                    i * sizeof(T));
        }
    }

    signalExceptionForError(env, err);
}

static void JHwParcel_native_writeStringVector(
        JNIEnv *env, jobject thiz, jobjectArray arrayObj) {
    if (arrayObj == nullptr) {
        jniThrowException(env, "java/lang/NullPointerException", nullptr);
        return;
    }

    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
    EphemeralStorage *storage = impl->getStorage();

    void *vecPtr = storage->allocTemporaryStorage(sizeof(hidl_vec<hidl_string>));
    hidl_vec<hidl_string> *vec = new (vecPtr) hidl_vec<hidl_string>();

    jsize len = env->GetArrayLength(arrayObj);
    hidl_string *strings = storage->allocStringArray(len);
    vec->setToExternal(strings, len, false /* shouldOwn */);

    for (jsize i = 0; i < len; ++i) {
        ScopedLocalRef<jstring> stringObj(env, (jstring) env->GetObjectArrayElement(arrayObj, i));

        const hidl_string *s = storage->allocTemporaryString(env, stringObj.get());
        strings[i].setToExternal(s->c_str(), s->size());
    }

    WriteHidlVector(env, thiz, *vec);
}

static void JHwParcel_native_writeNativeHandleVector(
        JNIEnv *env, jobject thiz, jobjectArray jHandleArray) {
    if (jHandleArray == nullptr) {
        jniThrowException(env, "java/lang/NullPointerException", nullptr);
        return;
    }

    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
    EphemeralStorage *storage = impl->getStorage();

    void *vecPtr = storage->allocTemporaryStorage(sizeof(hidl_vec<hidl_handle>));
    hidl_vec<hidl_handle> *vec = new (vecPtr) hidl_vec<hidl_handle>();

    jsize len = env->GetArrayLength(jHandleArray);
    hidl_handle *handles = static_cast<hidl_handle *>(
            storage->allocTemporaryStorage(len * sizeof(hidl_handle)));

    vec->setToExternal(handles, len, false /* shouldOwn */);
    for (jsize i = 0; i < len; i++) {
        ScopedLocalRef<jobject> jHandle(env, env->GetObjectArrayElement(jHandleArray, i));

        native_handle_t* handle = JNativeHandle::MakeCppNativeHandle(env, jHandle.get(), storage);

        new (&(handles[i])) hidl_handle();
        handles[i].setTo(handle, false /* shouldOwn */);
    }

    WriteHidlVector(env, thiz, *vec);
}

static void JHwParcel_native_writeStrongBinder(
        JNIEnv *env, jobject thiz, jobject binderObj) {
    sp<hardware::IBinder> binder;
    if (binderObj != NULL) {
        ScopedLocalRef<jclass> hwBinderKlass(env, FindClassOrDie(env, PACKAGE_PATH "/HwBinder"));

        ScopedLocalRef<jclass> hwRemoteBinderKlass(
                env, FindClassOrDie(env, PACKAGE_PATH "/HwRemoteBinder"));

        if (env->IsInstanceOf(binderObj, hwBinderKlass.get())) {
            binder = JHwBinder::GetNativeBinder(env, binderObj);
        } else if (env->IsInstanceOf(binderObj, hwRemoteBinderKlass.get())) {
            binder = JHwRemoteBinder::GetNativeContext(
                    env, binderObj)->getBinder();
        } else {
            signalExceptionForError(env, INVALID_OPERATION);
            return;
        }
    }

    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    status_t err = parcel->writeStrongBinder(binder);
    signalExceptionForError(env, err);
}

static jstring MakeStringObjFromHidlString(JNIEnv *env, const hidl_string &s) {
    String16 utf16String(s.c_str(), s.size());

    return env->NewString(
            reinterpret_cast<const jchar *>(utf16String.string()),
            utf16String.size());
}

static jstring JHwParcel_native_readString(JNIEnv *env, jobject thiz) {
    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    size_t parentHandle;

    const hidl_string *s;
    status_t err = parcel->readBuffer(sizeof(*s), &parentHandle,
            reinterpret_cast<const void**>(&s));

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

    err = ::android::hardware::readEmbeddedFromParcel(
            const_cast<hidl_string &>(*s),
            *parcel, parentHandle, 0 /* parentOffset */);

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

    return MakeStringObjFromHidlString(env, *s);
}

static jobject ReadNativeHandle(JNIEnv *env, jobject thiz, jboolean embedded,
        jlong parentHandle, jlong offset) {
    hardware::Parcel *parcel =
            JHwParcel::GetNativeContext(env, thiz)->getParcel();

    const native_handle_t *handle = nullptr;
    status_t err = OK;

    if (embedded) {
        err = parcel->readNullableEmbeddedNativeHandle(parentHandle, offset, &handle);
    } else {
        err = parcel->readNullableNativeHandleNoDup(&handle);
    }

    if (err != OK) {
        signalExceptionForError(env, err);
        return nullptr;
    }

    return JNativeHandle::MakeJavaNativeHandleObj(env, handle);
}

static jobject JHwParcel_native_readNativeHandle(JNIEnv *env, jobject thiz) {
    return ReadNativeHandle(env, thiz, false /*embedded*/, 0L /*parentHandle*/, 0L /*offset*/);
}

static jobject JHwParcel_native_readEmbeddedNativeHandle(
        JNIEnv *env, jobject thiz, jlong parentHandle, jlong offset) {
    return ReadNativeHandle(env, thiz, true /*embedded*/, parentHandle, offset);
}

#define DEFINE_PARCEL_VECTOR_READER(Suffix,Type,NewType)                       \
static Type ## Array JHwParcel_native_read ## Suffix ## Vector(                \
        JNIEnv *env, jobject thiz) {                                           \
    hardware::Parcel *parcel =                                                 \
        JHwParcel::GetNativeContext(env, thiz)->getParcel();                   \
    size_t parentHandle;                                                       \
                                                                               \
    const hidl_vec<Type> *vec;                                                 \
    status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,             \
            reinterpret_cast<const void**>(&vec));                             \
                                                                               \
    if (err != OK) {                                                           \
        signalExceptionForError(env, err);                                     \
        return NULL;                                                           \
    }                                                                          \
                                                                               \
    size_t childHandle;                                                        \
                                                                               \
    err = ::android::hardware::readEmbeddedFromParcel(                         \
                const_cast<hidl_vec<Type> &>(*vec),                            \
                *parcel,                                                       \
                parentHandle,                                                  \
                0 /* parentOffset */,                                          \
                &childHandle);                                                 \
                                                                               \
    if (err != OK) {                                                           \
        signalExceptionForError(env, err);                                     \
        return NULL;                                                           \
    }                                                                          \
                                                                               \
    Type ## Array valObj = env->New ## NewType ## Array(vec->size());          \
    env->Set ## NewType ## ArrayRegion(valObj, 0, vec->size(), &(*vec)[0]);    \
                                                                               \
    return valObj;                                                             \
}

DEFINE_PARCEL_VECTOR_READER(Int8,jbyte,Byte)
DEFINE_PARCEL_VECTOR_READER(Int16,jshort,Short)
DEFINE_PARCEL_VECTOR_READER(Int32,jint,Int)
DEFINE_PARCEL_VECTOR_READER(Int64,jlong,Long)
DEFINE_PARCEL_VECTOR_READER(Float,jfloat,Float)
DEFINE_PARCEL_VECTOR_READER(Double,jdouble,Double)

static jbooleanArray JHwParcel_native_readBoolVector(JNIEnv *env, jobject thiz) {
    hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel();

    size_t parentHandle;

    const hidl_vec<bool> *vec;
    status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,
            reinterpret_cast<const void**>(&vec));

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

    size_t childHandle;

    err = ::android::hardware::readEmbeddedFromParcel(
                const_cast<hidl_vec<bool> &>(*vec),
                *parcel,
                parentHandle,
                0 /* parentOffset */,
                &childHandle);

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

    jbooleanArray valObj = env->NewBooleanArray(vec->size());

    for (size_t i = 0; i < vec->size(); ++i) {
        jboolean x = (*vec)[i];
        env->SetBooleanArrayRegion(valObj, i, 1, &x);
    }

    return valObj;
}

static jobjectArray MakeStringArray(
        JNIEnv *env, const hidl_string *array, size_t size) {
    ScopedLocalRef<jclass> stringKlass(
            env,
            env->FindClass("java/lang/String"));

    // XXX Why can't I use ScopedLocalRef<> for the arrayObj and the stringObjs?

    jobjectArray arrayObj = env->NewObjectArray(size, stringKlass.get(), NULL);

    for (size_t i = 0; i < size; ++i) {
        jstring stringObj = MakeStringObjFromHidlString(env, array[i]);

        env->SetObjectArrayElement(
                arrayObj,
                i,
                stringObj);
    }

    return arrayObj;
}

template<typename T>
static const hidl_vec<T> *ReadHidlVector(JNIEnv *env, jobject thiz) {
    const hidl_vec<T> *vec;

    hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel();

    size_t parentHandle;
    status_t err = parcel->readBuffer(sizeof(hidl_vec<T>),
            &parentHandle, reinterpret_cast<const void **>(&vec));

    if (err == OK) {
        size_t childHandle;
        err = ::android::hardware::readEmbeddedFromParcel(
                const_cast<hidl_vec<T> &>(*vec),
                *parcel, parentHandle,
                0 /* parentOffset */,
                &childHandle);

        for (size_t i = 0; (err == OK) && (i < vec->size()); i++) {
            err = android::hardware::readEmbeddedFromParcel(
                    const_cast<T &>((*vec)[i]),
                    *parcel,
                    childHandle,
                    i * sizeof(T) /* parentOffset */);
        }
    }

    if (err != OK) {
        signalExceptionForError(env, err);
        return nullptr;
    }

    return vec;
}

static jobjectArray JHwParcel_native_readStringVector(
        JNIEnv *env, jobject thiz) {
    const hidl_vec<hidl_string> *vec = ReadHidlVector<hidl_string>(env, thiz);
    return MakeStringArray(env, &(*vec)[0], vec->size());
}

static jobjectArray JHwParcel_native_readNativeHandleVector(
        JNIEnv *env, jobject thiz) {
    const hidl_vec<hidl_handle> *vec = ReadHidlVector<hidl_handle>(env, thiz);

    jsize length = vec->size();
    jobjectArray objArray = JNativeHandle::AllocJavaNativeHandleObjArray(
            env, length);

    for (jsize i = 0; i < length; i++) {
        jobject jHandle = JNativeHandle::MakeJavaNativeHandleObj(env, (*vec)[i].getNativeHandle());

        env->SetObjectArrayElement(objArray, i, jHandle);
    }

    return objArray;
}

static jobject JHwParcel_native_readStrongBinder(JNIEnv *env, jobject thiz) {
    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    sp<hardware::IBinder> binder = parcel->readStrongBinder();

    if (binder == nullptr) {
        return nullptr;
    }

    if (!validateCanUseHwBinder(binder)) {
        return nullptr;
    }

    return JHwRemoteBinder::NewObject(env, binder);
}

static jobject JHwParcel_native_readBuffer(JNIEnv *env, jobject thiz,
                                           jlong expectedSize) {
    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    size_t handle;
    const void *ptr;

    if (expectedSize < 0) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return nullptr;
    }

    status_t status = parcel->readBuffer(expectedSize, &handle, &ptr);

    if (status != OK) {
        jniThrowException(env, "java/util/NoSuchElementException", NULL);
        return nullptr;
    }

    return JHwBlob::NewObject(env, ptr, handle);
}

static jobject JHwParcel_native_readEmbeddedBuffer(
        JNIEnv *env, jobject thiz, jlong expectedSize,
        jlong parentHandle, jlong offset, jboolean nullable) {
    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    size_t childHandle;

    const void *ptr;
    status_t status =
        parcel->readNullableEmbeddedBuffer(expectedSize,
                &childHandle, parentHandle, offset, &ptr);

    if (expectedSize < 0) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return nullptr;
    }

    if (status != OK) {
        jniThrowException(env, "java/util/NoSuchElementException", NULL);
        return 0;
    } else if (status == OK && !nullable && ptr == nullptr) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return 0;
    }

    return JHwBlob::NewObject(env, ptr, childHandle);
}

static void JHwParcel_native_writeBuffer(
        JNIEnv *env, jobject thiz, jobject blobObj) {
    if (blobObj == nullptr) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return;
    }

    hardware::Parcel *parcel =
        JHwParcel::GetNativeContext(env, thiz)->getParcel();

    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, blobObj);
    status_t err = blob->writeToParcel(parcel);

    if (err != OK) {
        signalExceptionForError(env, err);
    }
}

static JNINativeMethod gMethods[] = {
    { "native_init", "()J", (void *)JHwParcel_native_init },
    { "native_setup", "(Z)V", (void *)JHwParcel_native_setup },

    { "writeInterfaceToken", "(Ljava/lang/String;)V",
        (void *)JHwParcel_native_writeInterfaceToken },

    { "writeBool", "(Z)V", (void *)JHwParcel_native_writeBool },
    { "writeInt8", "(B)V", (void *)JHwParcel_native_writeInt8 },
    { "writeInt16", "(S)V", (void *)JHwParcel_native_writeInt16 },
    { "writeInt32", "(I)V", (void *)JHwParcel_native_writeInt32 },
    { "writeInt64", "(J)V", (void *)JHwParcel_native_writeInt64 },
    { "writeFloat", "(F)V", (void *)JHwParcel_native_writeFloat },
    { "writeDouble", "(D)V", (void *)JHwParcel_native_writeDouble },

    { "writeString", "(Ljava/lang/String;)V",
        (void *)JHwParcel_native_writeString },

    { "writeNativeHandle", "(L" PACKAGE_PATH "/NativeHandle;)V",
        (void *)JHwParcel_native_writeNativeHandle },

    { "writeBoolVector", "([Z)V", (void *)JHwParcel_native_writeBoolVector },
    { "writeInt8Vector", "([B)V", (void *)JHwParcel_native_writeInt8Vector },
    { "writeInt16Vector", "([S)V", (void *)JHwParcel_native_writeInt16Vector },
    { "writeInt32Vector", "([I)V", (void *)JHwParcel_native_writeInt32Vector },
    { "writeInt64Vector", "([J)V", (void *)JHwParcel_native_writeInt64Vector },
    { "writeFloatVector", "([F)V", (void *)JHwParcel_native_writeFloatVector },

    { "writeDoubleVector", "([D)V",
        (void *)JHwParcel_native_writeDoubleVector },

    { "writeStringVector", "([Ljava/lang/String;)V",
        (void *)JHwParcel_native_writeStringVector },

    { "writeNativeHandleVector", "([L" PACKAGE_PATH "/NativeHandle;)V",
        (void *)JHwParcel_native_writeNativeHandleVector },

    { "writeStrongBinder", "(L" PACKAGE_PATH "/IHwBinder;)V",
        (void *)JHwParcel_native_writeStrongBinder },

    { "enforceInterface", "(Ljava/lang/String;)V",
        (void *)JHwParcel_native_enforceInterface },

    { "readBool", "()Z", (void *)JHwParcel_native_readBool },
    { "readInt8", "()B", (void *)JHwParcel_native_readInt8 },
    { "readInt16", "()S", (void *)JHwParcel_native_readInt16 },
    { "readInt32", "()I", (void *)JHwParcel_native_readInt32 },
    { "readInt64", "()J", (void *)JHwParcel_native_readInt64 },
    { "readFloat", "()F", (void *)JHwParcel_native_readFloat },
    { "readDouble", "()D", (void *)JHwParcel_native_readDouble },

    { "readString", "()Ljava/lang/String;",
        (void *)JHwParcel_native_readString },

    { "readNativeHandle", "()L" PACKAGE_PATH "/NativeHandle;",
        (void *)JHwParcel_native_readNativeHandle },

    { "readEmbeddedNativeHandle", "(JJ)L" PACKAGE_PATH "/NativeHandle;",
        (void *)JHwParcel_native_readEmbeddedNativeHandle },

    { "readBoolVectorAsArray", "()[Z",
        (void *)JHwParcel_native_readBoolVector },

    { "readInt8VectorAsArray", "()[B",
        (void *)JHwParcel_native_readInt8Vector },

    { "readInt16VectorAsArray", "()[S",
        (void *)JHwParcel_native_readInt16Vector },

    { "readInt32VectorAsArray", "()[I",
        (void *)JHwParcel_native_readInt32Vector },

    { "readInt64VectorAsArray", "()[J",
        (void *)JHwParcel_native_readInt64Vector },

    { "readFloatVectorAsArray", "()[F",
        (void *)JHwParcel_native_readFloatVector },

    { "readDoubleVectorAsArray", "()[D",
        (void *)JHwParcel_native_readDoubleVector },

    { "readStringVectorAsArray", "()[Ljava/lang/String;",
        (void *)JHwParcel_native_readStringVector },

    { "readNativeHandleAsArray", "()[L" PACKAGE_PATH "/NativeHandle;",
        (void *)JHwParcel_native_readNativeHandleVector },

    { "readStrongBinder", "()L" PACKAGE_PATH "/IHwBinder;",
        (void *)JHwParcel_native_readStrongBinder },

    { "writeStatus", "(I)V", (void *)JHwParcel_native_writeStatus },

    { "verifySuccess", "()V", (void *)JHwParcel_native_verifySuccess },

    { "releaseTemporaryStorage", "()V",
        (void *)JHwParcel_native_releaseTemporaryStorage },

    { "send", "()V", (void *)JHwParcel_native_send },

    { "readBuffer", "(J)L" PACKAGE_PATH "/HwBlob;",
        (void *)JHwParcel_native_readBuffer },

    { "readEmbeddedBuffer", "(JJJZ)L" PACKAGE_PATH "/HwBlob;",
        (void *)JHwParcel_native_readEmbeddedBuffer },

    { "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
        (void *)JHwParcel_native_writeBuffer },

    { "release", "()V",
        (void *)JHwParcel_native_release },

};

namespace android {

int register_android_os_HwParcel(JNIEnv *env) {
    return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
}

}  // namespace android
