/**
 * Copyright (C) 2017 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_TAG "BroadcastRadioService.convert.jni"
#define LOG_NDEBUG 0

#include "convert.h"

#include "regions.h"

#include <broadcastradio-utils/Utils.h>
#include <core_jni_helpers.h>
#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>

namespace android {
namespace server {
namespace BroadcastRadio {
namespace convert {

namespace utils = V1_1::utils;

using hardware::Return;
using hardware::hidl_vec;
using regions::RegionalBandConfig;

using V1_0::Band;
using V1_0::Deemphasis;
using V1_0::Direction;
using V1_0::MetadataType;
using V1_0::Result;
using V1_0::Rds;
using V1_1::ProgramIdentifier;
using V1_1::ProgramListResult;
using V1_1::ProgramSelector;
using V1_1::VendorKeyValue;

static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const RegionalBandConfig &config);
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);

static struct {
    struct {
        jfieldID descriptor;
    } BandConfig;
    struct {
        jclass clazz;
        jmethodID cstor;
        jfieldID stereo;
        jfieldID rds;
        jfieldID ta;
        jfieldID af;
        jfieldID ea;
    } FmBandConfig;
    struct {
        jclass clazz;
        jmethodID cstor;
        jfieldID stereo;
    } AmBandConfig;

    struct {
        jclass clazz;
        jfieldID region;
        jfieldID type;
        jfieldID lowerLimit;
        jfieldID upperLimit;
        jfieldID spacing;
    } BandDescriptor;
    struct {
        jclass clazz;
        jmethodID cstor;
    } FmBandDescriptor;
    struct {
        jclass clazz;
        jmethodID cstor;
    } AmBandDescriptor;

    struct {
        jclass clazz;
        jmethodID stringMapToNative;
    } Convert;

    struct {
        jclass clazz;
        jmethodID cstor;
    } HashMap;

    struct {
        jmethodID put;
    } Map;

    struct {
        jclass clazz;
        jmethodID cstor;
    } ModuleProperties;

    struct {
        jclass clazz;
        jmethodID cstor;
    } ProgramInfo;

    struct {
        jclass clazz;
        jmethodID cstor;
        jfieldID programType;
        jfieldID primaryId;
        jfieldID secondaryIds;
        jfieldID vendorIds;

        struct {
            jclass clazz;
            jmethodID cstor;
            jfieldID type;
            jfieldID value;
        } Identifier;
    } ProgramSelector;

    struct {
        jclass clazz;
        jmethodID cstor;
        jmethodID putIntFromNative;
        jmethodID putStringFromNative;
        jmethodID putBitmapFromNative;
        jmethodID putClockFromNative;
    } RadioMetadata;

    struct {
        jclass clazz;
        jmethodID cstor;
    } RuntimeException;

    struct {
        jclass clazz;
        jmethodID cstor;
    } ParcelableException;
} gjni;

template <>
bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult) {
    return __ThrowIfFailedHidl(env, hidlResult);
}

bool __ThrowIfFailedHidl(JNIEnv *env, const hardware::details::return_status &hidlResult) {
    if (hidlResult.isOk()) return false;

    ThrowParcelableRuntimeException(env, "HIDL call failed: " + hidlResult.description());
    return true;
}

bool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
    switch (halResult) {
        case Result::OK:
            return false;
        case Result::NOT_INITIALIZED:
            ThrowParcelableRuntimeException(env, "Result::NOT_INITIALIZED");
            return true;
        case Result::INVALID_ARGUMENTS:
            jniThrowException(env, "java/lang/IllegalArgumentException",
                    "Result::INVALID_ARGUMENTS");
            return true;
        case Result::INVALID_STATE:
            jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
            return true;
        case Result::TIMEOUT:
            ThrowParcelableRuntimeException(env, "Result::TIMEOUT (unexpected here)");
            return true;
        default:
            ThrowParcelableRuntimeException(env, "Unknown failure, result: "
                    + std::to_string(static_cast<int32_t>(halResult)));
            return true;
    }
}

bool __ThrowIfFailed(JNIEnv *env, const ProgramListResult halResult) {
    switch (halResult) {
        case ProgramListResult::NOT_READY:
            jniThrowException(env, "java/lang/IllegalStateException", "Scan is in progress");
            return true;
        case ProgramListResult::NOT_STARTED:
            jniThrowException(env, "java/lang/IllegalStateException", "Scan has not been started");
            return true;
        case ProgramListResult::UNAVAILABLE:
            ThrowParcelableRuntimeException(env,
                    "ProgramListResult::UNAVAILABLE (unexpected here)");
            return true;
        default:
            return __ThrowIfFailed(env, static_cast<Result>(halResult));
    }
}

void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) {
    auto jMsg = make_javastr(env, msg);
    auto runtimeExc = make_javaref(env, env->NewObject(gjni.RuntimeException.clazz,
            gjni.RuntimeException.cstor, jMsg.get()));
    auto parcelableExc = make_javaref(env, env->NewObject(gjni.ParcelableException.clazz,
            gjni.ParcelableException.cstor, runtimeExc.get()));

    auto res = env->Throw(static_cast<jthrowable>(parcelableExc.get()));
    ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception");
}

static JavaRef<jintArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint32_t>& vec) {
    auto jArr = make_javaref(env, env->NewIntArray(vec.size()));
    auto jArrElements = env->GetIntArrayElements(jArr.get(), nullptr);
    for (size_t i = 0; i < vec.size(); i++) {
        jArrElements[i] = vec[i];
    }
    env->ReleaseIntArrayElements(jArr.get(), jArrElements, 0);
    return jArr;
}

static JavaRef<jlongArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint64_t>& vec) {
    auto jArr = make_javaref(env, env->NewLongArray(vec.size()));
    auto jArrElements = env->GetLongArrayElements(jArr.get(), nullptr);
    for (size_t i = 0; i < vec.size(); i++) {
        jArrElements[i] = vec[i];
    }
    env->ReleaseLongArrayElements(jArr.get(), jArrElements, 0);
    return jArr;
}

template <typename T>
static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec,
        jclass jElementClass, std::function<JavaRef<jobject>(JNIEnv*, const T&)> converter) {
    auto jArr = make_javaref(env, env->NewObjectArray(vec.size(), jElementClass, nullptr));
    for (size_t i = 0; i < vec.size(); i++) {
        auto jElement = converter(env, vec[i]);
        env->SetObjectArrayElement(jArr.get(), i, jElement.get());
    }
    return jArr;
}

template <typename T>
static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec,
        jclass jElementClass, JavaRef<jobject>(*converter)(JNIEnv*, const T&)) {
    return ArrayFromHal(env, vec, jElementClass,
            std::function<JavaRef<jobject>(JNIEnv*, const T&)>(converter));
}

static std::string StringFromJava(JNIEnv *env, JavaRef<jstring> &jStr) {
    auto cstr = (jStr == nullptr) ? nullptr : env->GetStringUTFChars(jStr.get(), nullptr);
    std::string str(cstr);
    env->ReleaseStringUTFChars(jStr.get(), cstr);
    return str;
}

JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hidl_vec<VendorKeyValue> &info) {
    ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str());

    auto jInfo = make_javaref(env, env->NewObject(gjni.HashMap.clazz, gjni.HashMap.cstor));

    for (auto&& entry : info) {
        auto jKey = make_javastr(env, entry.key);
        auto jValue = make_javastr(env, entry.value);
        env->CallObjectMethod(jInfo.get(), gjni.Map.put, jKey.get(), jValue.get());
    }

    return jInfo;
}

hidl_vec<VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo) {
    ALOGV("%s", __func__);

    auto jInfoArr = make_javaref(env, static_cast<jobjectArray>(env->CallStaticObjectMethod(
            gjni.Convert.clazz, gjni.Convert.stringMapToNative, jInfo)));
    LOG_FATAL_IF(jInfoArr == nullptr, "Converted array is null");

    auto len = env->GetArrayLength(jInfoArr.get());
    hidl_vec<VendorKeyValue> vec;
    vec.resize(len);

    for (jsize i = 0; i < len; i++) {
        auto entry = make_javaref(env, static_cast<jobjectArray>(
                env->GetObjectArrayElement(jInfoArr.get(), i)));
        auto jKey = make_javaref(env, static_cast<jstring>(
                env->GetObjectArrayElement(entry.get(), 0)));
        auto jValue = make_javaref(env, static_cast<jstring>(
                env->GetObjectArrayElement(entry.get(), 1)));
        auto key = StringFromJava(env, jKey);
        auto value = StringFromJava(env, jValue);
        vec[i] = { key, value };
    }

    return vec;
}

static Rds RdsForRegion(bool rds, Region region) {
    if (!rds) return Rds::NONE;

    switch(region) {
        case Region::ITU_1:
        case Region::OIRT:
        case Region::JAPAN:
        case Region::KOREA:
            return Rds::WORLD;
        case Region::ITU_2:
            return Rds::US;
        default:
            ALOGE("Unexpected region: %d", region);
            return Rds::NONE;
    }
}

static Deemphasis DeemphasisForRegion(Region region) {
    switch(region) {
        case Region::KOREA:
        case Region::ITU_2:
            return Deemphasis::D75;
        case Region::ITU_1:
        case Region::OIRT:
        case Region::JAPAN:
            return Deemphasis::D50;
        default:
            ALOGE("Unexpected region: %d", region);
            return Deemphasis::D50;
    }
}

static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &prop10,
        const V1_1::Properties *prop11, jint moduleId, const std::string& serviceName) {
    ALOGV("%s", __func__);
    using namespace std::placeholders;

    auto jServiceName = make_javastr(env, serviceName);
    auto jImplementor = make_javastr(env, prop10.implementor);
    auto jProduct = make_javastr(env, prop10.product);
    auto jVersion = make_javastr(env, prop10.version);
    auto jSerial = make_javastr(env, prop10.serial);
    bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false;
    auto jVendorInfo = prop11 ? VendorInfoFromHal(env, prop11->vendorInfo) : nullptr;

    auto regionalBands = regions::mapRegions(prop10.bands);
    auto jBands = ArrayFromHal<RegionalBandConfig>(env, regionalBands,
            gjni.BandDescriptor.clazz, BandDescriptorFromHal);
    auto jSupportedProgramTypes =
            prop11 ? ArrayFromHal(env, prop11->supportedProgramTypes) : nullptr;
    auto jSupportedIdentifierTypes =
            prop11 ? ArrayFromHal(env, prop11->supportedIdentifierTypes) : nullptr;

    return make_javaref(env, env->NewObject(gjni.ModuleProperties.clazz,
            gjni.ModuleProperties.cstor, moduleId, jServiceName.get(), prop10.classId,
            jImplementor.get(), jProduct.get(), jVersion.get(), jSerial.get(), prop10.numTuners,
            prop10.numAudioSources, prop10.supportsCapture, jBands.get(), isBgScanSupported,
            jSupportedProgramTypes.get(), jSupportedIdentifierTypes.get(), jVendorInfo.get()));
}

JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties,
        jint moduleId, const std::string& serviceName) {
    return ModulePropertiesFromHal(env, properties, nullptr, moduleId, serviceName);
}

JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_1::Properties &properties,
        jint moduleId, const std::string& serviceName) {
    return ModulePropertiesFromHal(env, properties.base, &properties, moduleId, serviceName);
}

static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const RegionalBandConfig &config) {
    return BandDescriptorFromHal(env, config.bandConfig, config.region);
}

static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
    ALOGV("%s", __func__);

    jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
    ALOGW_IF(config.spacings.size() > 1, "Multiple spacings - not a regional config");
    ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");

    if (utils::isFm(config.type)) {
        auto& fm = config.ext.fm;
        return make_javaref(env, env->NewObject(
                gjni.FmBandDescriptor.clazz, gjni.FmBandDescriptor.cstor,
                region, config.type, config.lowerLimit, config.upperLimit, spacing,
                fm.stereo, fm.rds != Rds::NONE, fm.ta, fm.af, fm.ea));
    } else if (utils::isAm(config.type)) {
        auto& am = config.ext.am;
        return make_javaref(env, env->NewObject(
                gjni.AmBandDescriptor.clazz, gjni.AmBandDescriptor.cstor,
                region, config.type, config.lowerLimit, config.upperLimit, spacing, am.stereo));
    } else {
        ALOGE("Unsupported band type: %d", config.type);
        return nullptr;
    }
}

JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
    ALOGV("%s", __func__);

    auto descriptor = BandDescriptorFromHal(env, config, region);
    if (descriptor == nullptr) return nullptr;

    if (utils::isFm(config.type)) {
        return make_javaref(env, env->NewObject(
                gjni.FmBandConfig.clazz, gjni.FmBandConfig.cstor, descriptor.get()));
    } else if (utils::isAm(config.type)) {
        return make_javaref(env, env->NewObject(
                gjni.AmBandConfig.clazz, gjni.AmBandConfig.cstor, descriptor.get()));
    } else {
        ALOGE("Unsupported band type: %d", config.type);
        return nullptr;
    }
}

V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region) {
    ALOGV("%s", __func__);
    auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
    if (jDescriptor == nullptr) {
        ALOGE("Descriptor is missing");
        return {};
    }

    region = static_cast<Region>(env->GetIntField(jDescriptor, gjni.BandDescriptor.region));

    V1_0::BandConfig config = {};
    config.type = static_cast<Band>(env->GetIntField(jDescriptor, gjni.BandDescriptor.type));
    config.antennaConnected = false;  // just don't set it
    config.lowerLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.lowerLimit);
    config.upperLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.upperLimit);
    config.spacings = hidl_vec<uint32_t>({
        static_cast<uint32_t>(env->GetIntField(jDescriptor, gjni.BandDescriptor.spacing))
    });

    if (env->IsInstanceOf(jConfig, gjni.FmBandConfig.clazz)) {
        auto& fm = config.ext.fm;
        fm.deemphasis = DeemphasisForRegion(region);
        fm.stereo = env->GetBooleanField(jConfig, gjni.FmBandConfig.stereo);
        fm.rds = RdsForRegion(env->GetBooleanField(jConfig, gjni.FmBandConfig.rds), region);
        fm.ta = env->GetBooleanField(jConfig, gjni.FmBandConfig.ta);
        fm.af = env->GetBooleanField(jConfig, gjni.FmBandConfig.af);
        fm.ea = env->GetBooleanField(jConfig, gjni.FmBandConfig.ea);
    } else if (env->IsInstanceOf(jConfig, gjni.AmBandConfig.clazz)) {
        auto& am = config.ext.am;
        am.stereo = env->GetBooleanField(jConfig, gjni.AmBandConfig.stereo);
    } else {
        ALOGE("Unexpected band config type");
        return {};
    }

    return config;
}

Direction DirectionToHal(bool directionDown) {
    return directionDown ? Direction::DOWN : Direction::UP;
}

JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> &metadata) {
    ALOGV("%s", __func__);
    if (metadata.size() == 0) return nullptr;

    auto jMetadata = make_javaref(env, env->NewObject(
            gjni.RadioMetadata.clazz, gjni.RadioMetadata.cstor));

    for (auto& item : metadata) {
        jint key = static_cast<jint>(item.key);
        jint status = 0;
        switch (item.type) {
            case MetadataType::INT:
                ALOGV("metadata INT %d", key);
                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putIntFromNative,
                        key, item.intValue);
                break;
            case MetadataType::TEXT: {
                ALOGV("metadata TEXT %d", key);
                auto value = make_javastr(env, item.stringValue);
                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putStringFromNative,
                        key, value.get());
                break;
            }
            case MetadataType::RAW: {
                ALOGV("metadata RAW %d", key);
                auto len = item.rawValue.size();
                if (len == 0) break;
                auto value = make_javaref(env, env->NewByteArray(len));
                if (value == nullptr) {
                    ALOGE("Failed to allocate byte array of len %zu", len);
                    break;
                }
                env->SetByteArrayRegion(value.get(), 0, len,
                        reinterpret_cast<const jbyte*>(item.rawValue.data()));
                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putBitmapFromNative,
                        key, value.get());
                break;
            }
            case MetadataType::CLOCK:
                ALOGV("metadata CLOCK %d", key);
                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putClockFromNative,
                        key, item.clockValue.utcSecondsSinceEpoch,
                        item.clockValue.timezoneOffsetInMinutes);
                break;
            default:
                ALOGW("invalid metadata type %d", item.type);
        }
        ALOGE_IF(status != 0, "Failed inserting metadata %d (of type %d)", key, item.type);
    }

    return jMetadata;
}

static JavaRef<jobject> ProgramIdentifierFromHal(JNIEnv *env, const ProgramIdentifier &id) {
    ALOGV("%s", __func__);
    return make_javaref(env, env->NewObject(gjni.ProgramSelector.Identifier.clazz,
            gjni.ProgramSelector.Identifier.cstor, id.type, id.value));
}

static JavaRef<jobject> ProgramSelectorFromHal(JNIEnv *env, const ProgramSelector &selector) {
    ALOGV("%s", __func__);
    auto jPrimary = ProgramIdentifierFromHal(env, selector.primaryId);
    auto jSecondary = ArrayFromHal(env, selector.secondaryIds,
            gjni.ProgramSelector.Identifier.clazz, ProgramIdentifierFromHal);
    auto jVendor = ArrayFromHal(env, selector.vendorIds);

    return make_javaref(env, env->NewObject(gjni.ProgramSelector.clazz, gjni.ProgramSelector.cstor,
            selector.programType, jPrimary.get(), jSecondary.get(), jVendor.get()));
}

static ProgramIdentifier ProgramIdentifierToHal(JNIEnv *env, jobject jId) {
    ALOGV("%s", __func__);

    ProgramIdentifier id = {};
    id.type = env->GetIntField(jId, gjni.ProgramSelector.Identifier.type);
    id.value = env->GetLongField(jId, gjni.ProgramSelector.Identifier.value);
    return id;
}

ProgramSelector ProgramSelectorToHal(JNIEnv *env, jobject jSelector) {
    ALOGV("%s", __func__);

    ProgramSelector selector = {};

    selector.programType = env->GetIntField(jSelector, gjni.ProgramSelector.programType);

    auto jPrimary = env->GetObjectField(jSelector, gjni.ProgramSelector.primaryId);
    auto jSecondary = reinterpret_cast<jobjectArray>(
            env->GetObjectField(jSelector, gjni.ProgramSelector.secondaryIds));
    auto jVendor = reinterpret_cast<jlongArray>(
            env->GetObjectField(jSelector, gjni.ProgramSelector.vendorIds));

    if (jPrimary == nullptr || jSecondary == nullptr || jVendor == nullptr) {
        ALOGE("ProgramSelector object is incomplete");
        return {};
    }

    selector.primaryId = ProgramIdentifierToHal(env, jPrimary);
    auto count = env->GetArrayLength(jSecondary);
    selector.secondaryIds.resize(count);
    for (jsize i = 0; i < count; i++) {
        auto jId = env->GetObjectArrayElement(jSecondary, i);
        selector.secondaryIds[i] = ProgramIdentifierToHal(env, jId);
    }

    count = env->GetArrayLength(jVendor);
    selector.vendorIds.resize(count);
    auto jVendorElements = env->GetLongArrayElements(jVendor, nullptr);
    for (jint i = 0; i < count; i++) {
        selector.vendorIds[i] = jVendorElements[i];
    }
    env->ReleaseLongArrayElements(jVendor, jVendorElements, 0);

    return selector;
}

static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
        const V1_1::ProgramInfo *info11, const ProgramSelector &selector) {
    ALOGV("%s", __func__);

    auto jMetadata = MetadataFromHal(env, info10.metadata);
    auto jVendorInfo = info11 ? VendorInfoFromHal(env, info11->vendorInfo) : nullptr;
    auto jSelector = ProgramSelectorFromHal(env, selector);

    return make_javaref(env, env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor,
            jSelector.get(), info10.tuned, info10.stereo, info10.digital, info10.signalStrength,
            jMetadata.get(), info11 ? info11->flags : 0, jVendorInfo.get()));
}

JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info, V1_0::Band band) {
    auto selector = utils::make_selector(band, info.channel, info.subChannel);
    return ProgramInfoFromHal(env, info, nullptr, selector);
}

JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info) {
    return ProgramInfoFromHal(env, info.base, &info, info.selector);
}

} // namespace convert
} // namespace BroadcastRadio
} // namespace server

void register_android_server_broadcastradio_convert(JNIEnv *env) {
    using namespace server::BroadcastRadio::convert;

    auto bandConfigClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$BandConfig");
    gjni.BandConfig.descriptor = GetFieldIDOrDie(env, bandConfigClass,
            "mDescriptor", "Landroid/hardware/radio/RadioManager$BandDescriptor;");

    auto fmBandConfigClass = FindClassOrDie(env,
            "android/hardware/radio/RadioManager$FmBandConfig");
    gjni.FmBandConfig.clazz = MakeGlobalRefOrDie(env, fmBandConfigClass);
    gjni.FmBandConfig.cstor = GetMethodIDOrDie(env, fmBandConfigClass,
            "<init>", "(Landroid/hardware/radio/RadioManager$FmBandDescriptor;)V");
    gjni.FmBandConfig.stereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
    gjni.FmBandConfig.rds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
    gjni.FmBandConfig.ta = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
    gjni.FmBandConfig.af = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
    gjni.FmBandConfig.ea = GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");

    auto amBandConfigClass = FindClassOrDie(env,
            "android/hardware/radio/RadioManager$AmBandConfig");
    gjni.AmBandConfig.clazz = MakeGlobalRefOrDie(env, amBandConfigClass);
    gjni.AmBandConfig.cstor = GetMethodIDOrDie(env, amBandConfigClass,
            "<init>", "(Landroid/hardware/radio/RadioManager$AmBandDescriptor;)V");
    gjni.AmBandConfig.stereo = GetFieldIDOrDie(env, amBandConfigClass, "mStereo", "Z");

    auto bandDescriptorClass = FindClassOrDie(env,
            "android/hardware/radio/RadioManager$BandDescriptor");
    gjni.BandDescriptor.clazz = MakeGlobalRefOrDie(env, bandDescriptorClass);
    gjni.BandDescriptor.region = GetFieldIDOrDie(env, bandDescriptorClass, "mRegion", "I");
    gjni.BandDescriptor.type = GetFieldIDOrDie(env, bandDescriptorClass, "mType", "I");
    gjni.BandDescriptor.lowerLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
    gjni.BandDescriptor.upperLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
    gjni.BandDescriptor.spacing = GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");

    auto fmBandDescriptorClass = FindClassOrDie(env,
            "android/hardware/radio/RadioManager$FmBandDescriptor");
    gjni.FmBandDescriptor.clazz = MakeGlobalRefOrDie(env, fmBandDescriptorClass);
    gjni.FmBandDescriptor.cstor = GetMethodIDOrDie(env, fmBandDescriptorClass,
            "<init>", "(IIIIIZZZZZ)V");

    auto amBandDescriptorClass = FindClassOrDie(env,
            "android/hardware/radio/RadioManager$AmBandDescriptor");
    gjni.AmBandDescriptor.clazz = MakeGlobalRefOrDie(env, amBandDescriptorClass);
    gjni.AmBandDescriptor.cstor = GetMethodIDOrDie(env, amBandDescriptorClass,
            "<init>", "(IIIIIZ)V");

    auto convertClass = FindClassOrDie(env, "com/android/server/broadcastradio/Convert");
    gjni.Convert.clazz = MakeGlobalRefOrDie(env, convertClass);
    gjni.Convert.stringMapToNative = GetStaticMethodIDOrDie(env, convertClass, "stringMapToNative",
            "(Ljava/util/Map;)[[Ljava/lang/String;");

    auto hashMapClass = FindClassOrDie(env, "java/util/HashMap");
    gjni.HashMap.clazz = MakeGlobalRefOrDie(env, hashMapClass);
    gjni.HashMap.cstor = GetMethodIDOrDie(env, hashMapClass, "<init>", "()V");

    auto mapClass = FindClassOrDie(env, "java/util/Map");
    gjni.Map.put = GetMethodIDOrDie(env, mapClass, "put",
            "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");

    auto modulePropertiesClass = FindClassOrDie(env,
            "android/hardware/radio/RadioManager$ModuleProperties");
    gjni.ModuleProperties.clazz = MakeGlobalRefOrDie(env, modulePropertiesClass);
    gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
            "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
            "Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z"
            "[I[ILjava/util/Map;)V");

    auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo");
    gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass);
    gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
            "(Landroid/hardware/radio/ProgramSelector;ZZZILandroid/hardware/radio/RadioMetadata;I"
            "Ljava/util/Map;)V");

    auto programSelectorClass = FindClassOrDie(env, "android/hardware/radio/ProgramSelector");
    gjni.ProgramSelector.clazz = MakeGlobalRefOrDie(env, programSelectorClass);
    gjni.ProgramSelector.cstor = GetMethodIDOrDie(env, programSelectorClass, "<init>",
            "(ILandroid/hardware/radio/ProgramSelector$Identifier;"
            "[Landroid/hardware/radio/ProgramSelector$Identifier;[J)V");
    gjni.ProgramSelector.programType = GetFieldIDOrDie(env, programSelectorClass,
            "mProgramType", "I");
    gjni.ProgramSelector.primaryId = GetFieldIDOrDie(env, programSelectorClass,
            "mPrimaryId", "Landroid/hardware/radio/ProgramSelector$Identifier;");
    gjni.ProgramSelector.secondaryIds = GetFieldIDOrDie(env, programSelectorClass,
            "mSecondaryIds", "[Landroid/hardware/radio/ProgramSelector$Identifier;");
    gjni.ProgramSelector.vendorIds = GetFieldIDOrDie(env, programSelectorClass,
            "mVendorIds", "[J");

    auto progSelIdClass = FindClassOrDie(env, "android/hardware/radio/ProgramSelector$Identifier");
    gjni.ProgramSelector.Identifier.clazz = MakeGlobalRefOrDie(env, progSelIdClass);
    gjni.ProgramSelector.Identifier.cstor = GetMethodIDOrDie(env, progSelIdClass,
            "<init>", "(IJ)V");
    gjni.ProgramSelector.Identifier.type = GetFieldIDOrDie(env, progSelIdClass,
            "mType", "I");
    gjni.ProgramSelector.Identifier.value = GetFieldIDOrDie(env, progSelIdClass,
            "mValue", "J");

    auto radioMetadataClass = FindClassOrDie(env, "android/hardware/radio/RadioMetadata");
    gjni.RadioMetadata.clazz = MakeGlobalRefOrDie(env, radioMetadataClass);
    gjni.RadioMetadata.cstor = GetMethodIDOrDie(env, radioMetadataClass, "<init>", "()V");
    gjni.RadioMetadata.putIntFromNative = GetMethodIDOrDie(env, radioMetadataClass,
            "putIntFromNative", "(II)I");
    gjni.RadioMetadata.putStringFromNative = GetMethodIDOrDie(env, radioMetadataClass,
            "putStringFromNative", "(ILjava/lang/String;)I");
    gjni.RadioMetadata.putBitmapFromNative = GetMethodIDOrDie(env, radioMetadataClass,
            "putBitmapFromNative", "(I[B)I");
    gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
            "putClockFromNative", "(IJI)I");

    auto runtimeExcClass = FindClassOrDie(env, "java/lang/RuntimeException");
    gjni.RuntimeException.clazz = MakeGlobalRefOrDie(env, runtimeExcClass);
    gjni.RuntimeException.cstor = GetMethodIDOrDie(env, runtimeExcClass, "<init>",
            "(Ljava/lang/String;)V");

    auto parcelableExcClass = FindClassOrDie(env, "android/os/ParcelableException");
    gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
    gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
            "(Ljava/lang/Throwable;)V");
}

} // namespace android
