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

#include "jni.h"
#include "JNIHelp.h"
#include "core_jni_helpers.h"
#include <system/radio.h>
#include <system/radio_metadata.h>
#include <radio/RadioCallback.h>
#include <radio/Radio.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
#include <binder/IMemory.h>
#include <binder/MemoryDealer.h>

using namespace android;

static jclass gArrayListClass;
static struct {
    jmethodID    add;
} gArrayListMethods;

static const char* const kRadioManagerClassPathName = "android/hardware/radio/RadioManager";
static jclass gRadioManagerClass;

static const char* const kRadioModuleClassPathName = "android/hardware/radio/RadioModule";
static jclass gRadioModuleClass;
static struct {
    jfieldID    mNativeContext;
    jfieldID    mId;
} gModuleFields;
static jmethodID gPostEventFromNative;

static const char* const kModulePropertiesClassPathName =
                                     "android/hardware/radio/RadioManager$ModuleProperties";
static jclass gModulePropertiesClass;
static jmethodID gModulePropertiesCstor;


static const char* const kRadioBandDescriptorClassPathName =
                             "android/hardware/radio/RadioManager$BandDescriptor";
static jclass gRadioBandDescriptorClass;
static struct {
    jfieldID mRegion;
    jfieldID mType;
    jfieldID mLowerLimit;
    jfieldID mUpperLimit;
    jfieldID mSpacing;
} gRadioBandDescriptorFields;

static const char* const kRadioFmBandDescriptorClassPathName =
                             "android/hardware/radio/RadioManager$FmBandDescriptor";
static jclass gRadioFmBandDescriptorClass;
static jmethodID gRadioFmBandDescriptorCstor;

static const char* const kRadioAmBandDescriptorClassPathName =
                             "android/hardware/radio/RadioManager$AmBandDescriptor";
static jclass gRadioAmBandDescriptorClass;
static jmethodID gRadioAmBandDescriptorCstor;

static const char* const kRadioBandConfigClassPathName =
                             "android/hardware/radio/RadioManager$BandConfig";
static jclass gRadioBandConfigClass;
static struct {
    jfieldID mDescriptor;
} gRadioBandConfigFields;


static const char* const kRadioFmBandConfigClassPathName =
                             "android/hardware/radio/RadioManager$FmBandConfig";
static jclass gRadioFmBandConfigClass;
static jmethodID gRadioFmBandConfigCstor;
static struct {
    jfieldID mStereo;
    jfieldID mRds;
    jfieldID mTa;
    jfieldID mAf;
    jfieldID mEa;
} gRadioFmBandConfigFields;

static const char* const kRadioAmBandConfigClassPathName =
                             "android/hardware/radio/RadioManager$AmBandConfig";
static jclass gRadioAmBandConfigClass;
static jmethodID gRadioAmBandConfigCstor;
static struct {
    jfieldID mStereo;
} gRadioAmBandConfigFields;


static const char* const kRadioProgramInfoClassPathName =
                             "android/hardware/radio/RadioManager$ProgramInfo";
static jclass gRadioProgramInfoClass;
static jmethodID gRadioProgramInfoCstor;

static const char* const kRadioMetadataClassPathName =
                             "android/hardware/radio/RadioMetadata";
static jclass gRadioMetadataClass;
static jmethodID gRadioMetadataCstor;
static struct {
    jmethodID putIntFromNative;
    jmethodID putStringFromNative;
    jmethodID putBitmapFromNative;
    jmethodID putClockFromNative;
} gRadioMetadataMethods;

static Mutex gLock;

enum {
    RADIO_STATUS_OK = 0,
    RADIO_STATUS_ERROR = INT_MIN,
    RADIO_PERMISSION_DENIED = -1,
    RADIO_STATUS_NO_INIT = -19,
    RADIO_STATUS_BAD_VALUE = -22,
    RADIO_STATUS_DEAD_OBJECT = -32,
    RADIO_STATUS_INVALID_OPERATION = -38,
    RADIO_STATUS_TIMED_OUT = -110,
};


// ----------------------------------------------------------------------------

static sp<Radio> getRadio(JNIEnv* env, jobject thiz)
{
    Mutex::Autolock l(gLock);
    Radio* const radio = (Radio*)env->GetLongField(thiz, gModuleFields.mNativeContext);
    return sp<Radio>(radio);
}

static sp<Radio> setRadio(JNIEnv* env, jobject thiz, const sp<Radio>& module)
{
    Mutex::Autolock l(gLock);
    sp<Radio> old = (Radio*)env->GetLongField(thiz, gModuleFields.mNativeContext);
    if (module.get()) {
        module->incStrong((void*)setRadio);
    }
    if (old != 0) {
        old->decStrong((void*)setRadio);
    }
    env->SetLongField(thiz, gModuleFields.mNativeContext, (jlong)module.get());
    return old;
}

static jint convertBandDescriptorFromNative(JNIEnv *env,
                                           jobject *jBandDescriptor,
                                           const radio_band_config_t *nBandconfig)
{
    ALOGV("%s type %d region %d", __FUNCTION__, nBandconfig->band.type, nBandconfig->region);

    if (nBandconfig->band.type == RADIO_BAND_FM ||
            nBandconfig->band.type == RADIO_BAND_FM_HD) {
        *jBandDescriptor = env->NewObject(gRadioFmBandDescriptorClass, gRadioFmBandDescriptorCstor,
                                      nBandconfig->region, nBandconfig->band.type,
                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
                                      nBandconfig->band.spacings[0],
                                      nBandconfig->band.fm.stereo,
                                      nBandconfig->band.fm.rds != RADIO_RDS_NONE,
                                      nBandconfig->band.fm.ta,
                                      nBandconfig->band.fm.af,
                                      nBandconfig->band.fm.ea);
    } else if (nBandconfig->band.type == RADIO_BAND_AM) {
        *jBandDescriptor = env->NewObject(gRadioAmBandDescriptorClass, gRadioAmBandDescriptorCstor,
                                      nBandconfig->region, nBandconfig->band.type,
                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
                                      nBandconfig->band.spacings[0],
                                      nBandconfig->band.am.stereo);
    } else {
        ALOGE("%s unknown band type %d", __FUNCTION__, nBandconfig->band.type);
        return (jint)RADIO_STATUS_BAD_VALUE;
    }

    if (*jBandDescriptor == NULL) {
        return (jint)RADIO_STATUS_NO_INIT;
    }

    return (jint)RADIO_STATUS_OK;
}

static jint convertBandConfigFromNative(JNIEnv *env,
                                           jobject *jBandConfig,
                                           const radio_band_config_t *nBandconfig)
{
    ALOGV("%s type %d region %d", __FUNCTION__, nBandconfig->band.type, nBandconfig->region);

    if (nBandconfig->band.type == RADIO_BAND_FM ||
            nBandconfig->band.type == RADIO_BAND_FM_HD) {
        *jBandConfig = env->NewObject(gRadioFmBandConfigClass, gRadioFmBandConfigCstor,
                                      nBandconfig->region, nBandconfig->band.type,
                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
                                      nBandconfig->band.spacings[0],
                                      nBandconfig->band.fm.stereo,
                                      nBandconfig->band.fm.rds != RADIO_RDS_NONE,
                                      nBandconfig->band.fm.ta,
                                      nBandconfig->band.fm.af,
                                      nBandconfig->band.fm.ea);
    } else if (nBandconfig->band.type == RADIO_BAND_AM) {
        *jBandConfig = env->NewObject(gRadioAmBandConfigClass, gRadioAmBandConfigCstor,
                                      nBandconfig->region, nBandconfig->band.type,
                                      nBandconfig->band.lower_limit, nBandconfig->band.upper_limit,
                                      nBandconfig->band.spacings[0],
                                      nBandconfig->band.am.stereo);
    } else {
        ALOGE("%s unknown band type %d", __FUNCTION__, nBandconfig->band.type);
        return (jint)RADIO_STATUS_BAD_VALUE;
    }

    if (*jBandConfig == NULL) {
        return (jint)RADIO_STATUS_NO_INIT;
    }

    return (jint)RADIO_STATUS_OK;
}

static jint convertMetadataFromNative(JNIEnv *env,
                                           jobject *jMetadata,
                                           const radio_metadata_t *nMetadata)
{
    ALOGV("%s", __FUNCTION__);
    int count = radio_metadata_get_count(nMetadata);
    if (count <= 0) {
        return (jint)count;
    }
    *jMetadata = env->NewObject(gRadioMetadataClass, gRadioMetadataCstor);

    jint jCount = 0;
    jint jStatus = 0;
    for (unsigned int i = 0; i < (unsigned int)count; i++) {
        radio_metadata_key_t key;
        radio_metadata_type_t type;
        void *value;
        unsigned int size;
        if (radio_metadata_get_at_index(nMetadata, i , &key, &type, &value, &size) != 0) {
            continue;
        }
        switch (type) {
            case RADIO_METADATA_TYPE_INT: {
                ALOGV("%s RADIO_METADATA_TYPE_INT %d", __FUNCTION__, key);
                jStatus = env->CallIntMethod(*jMetadata,
                                   gRadioMetadataMethods.putIntFromNative,
                                   key, *(jint *)value);
                if (jStatus == 0) {
                    jCount++;
                }
            } break;
            case RADIO_METADATA_TYPE_TEXT: {
                ALOGV("%s RADIO_METADATA_TYPE_TEXT %d", __FUNCTION__, key);
                jstring jText = env->NewStringUTF((char *)value);
                jStatus = env->CallIntMethod(*jMetadata,
                                   gRadioMetadataMethods.putStringFromNative,
                                   key, jText);
                if (jStatus == 0) {
                    jCount++;
                }
                env->DeleteLocalRef(jText);
            } break;
            case RADIO_METADATA_TYPE_RAW: {
                ALOGV("%s RADIO_METADATA_TYPE_RAW %d size %u", __FUNCTION__, key, size);
                if (size == 0) {
                    break;
                }
                jbyteArray jData = env->NewByteArray(size);
                if (jData == NULL) {
                    break;
                }
                env->SetByteArrayRegion(jData, 0, size, (jbyte *)value);
                jStatus = env->CallIntMethod(*jMetadata,
                                   gRadioMetadataMethods.putBitmapFromNative,
                                   key, jData);
                if (jStatus == 0) {
                    jCount++;
                }
                env->DeleteLocalRef(jData);
            } break;
            case RADIO_METADATA_TYPE_CLOCK: {
                  ALOGV("%s RADIO_METADATA_TYPE_CLOCK %d", __FUNCTION__, key);
                  radio_metadata_clock_t *clock = (radio_metadata_clock_t *) value;
                  jStatus =
                      env->CallIntMethod(*jMetadata,
                                         gRadioMetadataMethods.putClockFromNative,
                                         key, (jint) clock->utc_seconds_since_epoch,
                                         (jint) clock->timezone_offset_in_minutes);
                  if (jStatus == 0) {
                      jCount++;
                  }
            } break;
        }
    }
    return jCount;
}

static jint convertProgramInfoFromNative(JNIEnv *env,
                                           jobject *jProgramInfo,
                                           const radio_program_info_t *nProgramInfo)
{
    ALOGV("%s", __FUNCTION__);
    int jStatus;
    jobject jMetadata = NULL;
    if (nProgramInfo->metadata != NULL) {
        ALOGV("%s metadata %p", __FUNCTION__, nProgramInfo->metadata);
        jStatus = convertMetadataFromNative(env, &jMetadata, nProgramInfo->metadata);
        if (jStatus < 0) {
            return jStatus;
        }
    }

    ALOGV("%s channel %d tuned %d", __FUNCTION__, nProgramInfo->channel, nProgramInfo->tuned);

    *jProgramInfo = env->NewObject(gRadioProgramInfoClass, gRadioProgramInfoCstor,
                                  nProgramInfo->channel, nProgramInfo->sub_channel,
                                  nProgramInfo->tuned, nProgramInfo->stereo,
                                  nProgramInfo->digital, nProgramInfo->signal_strength,
                                  jMetadata);

    env->DeleteLocalRef(jMetadata);
    return (jint)RADIO_STATUS_OK;
}


static jint convertBandConfigToNative(JNIEnv *env,
                                      radio_band_config_t *nBandconfig,
                                      jobject jBandConfig)
{
    ALOGV("%s", __FUNCTION__);

    jobject jDescriptor = env->GetObjectField(jBandConfig, gRadioBandConfigFields.mDescriptor);

    if (jDescriptor == NULL) {
        return (jint)RADIO_STATUS_NO_INIT;
    }

    nBandconfig->region =
            (radio_region_t)env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mRegion);
    nBandconfig->band.type =
            (radio_band_t)env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mType);
    nBandconfig->band.lower_limit =
            env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mLowerLimit);
    nBandconfig->band.upper_limit =
            env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mUpperLimit);
    nBandconfig->band.num_spacings = 1;
    nBandconfig->band.spacings[0] =
            env->GetIntField(jDescriptor, gRadioBandDescriptorFields.mSpacing);

    if (env->IsInstanceOf(jBandConfig, gRadioFmBandConfigClass)) {
        nBandconfig->band.fm.deemphasis = radio_demephasis_for_region(nBandconfig->region);
        nBandconfig->band.fm.stereo =
                env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mStereo);
        nBandconfig->band.fm.rds =
                radio_rds_for_region(env->GetBooleanField(jBandConfig,
                                                          gRadioFmBandConfigFields.mRds),
                                     nBandconfig->region);
        nBandconfig->band.fm.ta = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mTa);
        nBandconfig->band.fm.af = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mAf);
        nBandconfig->band.fm.ea = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mEa);
    } else if (env->IsInstanceOf(jBandConfig, gRadioAmBandConfigClass)) {
        nBandconfig->band.am.stereo =
                env->GetBooleanField(jBandConfig, gRadioAmBandConfigFields.mStereo);
    } else {
        return (jint)RADIO_STATUS_BAD_VALUE;
    }

    return (jint)RADIO_STATUS_OK;
}

static jint
android_hardware_Radio_listModules(JNIEnv *env, jobject clazz,
                                          jobject jModules)
{
    ALOGV("%s", __FUNCTION__);

    if (jModules == NULL) {
        ALOGE("listModules NULL ArrayList");
        return RADIO_STATUS_BAD_VALUE;
    }
    if (!env->IsInstanceOf(jModules, gArrayListClass)) {
        ALOGE("listModules not an arraylist");
        return RADIO_STATUS_BAD_VALUE;
    }

    unsigned int numModules = 0;
    radio_properties_t *nModules = NULL;

    status_t status = Radio::listModules(nModules, &numModules);
    if (status != NO_ERROR || numModules == 0) {
        return (jint)status;
    }

    nModules = (radio_properties_t *)calloc(numModules, sizeof(radio_properties_t));

    status = Radio::listModules(nModules, &numModules);
    ALOGV("%s Radio::listModules status %d numModules %d", __FUNCTION__, status, numModules);

    if (status != NO_ERROR) {
        numModules = 0;
    }

    for (size_t i = 0; i < numModules; i++) {
        if (nModules[i].num_bands == 0) {
            continue;
        }
        ALOGV("%s module %zu id %d implementor %s product %s",
              __FUNCTION__, i, nModules[i].handle, nModules[i].implementor,
              nModules[i].product);


        jobjectArray jBands = env->NewObjectArray(nModules[i].num_bands,
                                                  gRadioBandDescriptorClass, NULL);

        for (size_t j = 0; j < nModules[i].num_bands; j++) {
            jobject jBandDescriptor;
            int jStatus =
                    convertBandDescriptorFromNative(env, &jBandDescriptor, &nModules[i].bands[j]);
            if (jStatus != RADIO_STATUS_OK) {
                continue;
            }
            env->SetObjectArrayElement(jBands, j, jBandDescriptor);
            env->DeleteLocalRef(jBandDescriptor);
        }

        if (env->GetArrayLength(jBands) == 0) {
            continue;
        }
        jstring jImplementor = env->NewStringUTF(nModules[i].implementor);
        jstring jProduct = env->NewStringUTF(nModules[i].product);
        jstring jVersion = env->NewStringUTF(nModules[i].version);
        jstring jSerial = env->NewStringUTF(nModules[i].serial);
        jobject jModule = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
                                               nModules[i].handle, nModules[i].class_id,
                                               jImplementor, jProduct, jVersion, jSerial,
                                               nModules[i].num_tuners,
                                               nModules[i].num_audio_sources,
                                               nModules[i].supports_capture,
                                               jBands);

        env->DeleteLocalRef(jImplementor);
        env->DeleteLocalRef(jProduct);
        env->DeleteLocalRef(jVersion);
        env->DeleteLocalRef(jSerial);
        env->DeleteLocalRef(jBands);
        if (jModule == NULL) {
            continue;
        }
        env->CallBooleanMethod(jModules, gArrayListMethods.add, jModule);
    }

    free(nModules);
    return (jint) status;
}

// ----------------------------------------------------------------------------

class JNIRadioCallback: public RadioCallback
{
public:
    JNIRadioCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
    ~JNIRadioCallback();

    virtual void onEvent(struct radio_event *event);

private:
    jclass      mClass;     // Reference to Radio class
    jobject     mObject;    // Weak ref to Radio Java object to call on
};

JNIRadioCallback::JNIRadioCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
{

    // Hold onto the RadioModule class for use in calling the static method
    // that posts events to the application thread.
    jclass clazz = env->GetObjectClass(thiz);
    if (clazz == NULL) {
        ALOGE("Can't find class %s", kRadioModuleClassPathName);
        return;
    }
    mClass = (jclass)env->NewGlobalRef(clazz);

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

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

void JNIRadioCallback::onEvent(struct radio_event *event)
{
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    if (env == NULL) {
        return;
    }

    ALOGV("%s", __FUNCTION__);

    jobject jObj = NULL;
    jint jArg2 = 0;
    jint jStatus = RADIO_STATUS_OK;
    switch (event->type) {
        case RADIO_EVENT_CONFIG:
            jStatus = convertBandConfigFromNative(env, &jObj, &event->config);
            break;
        case RADIO_EVENT_TUNED:
        case RADIO_EVENT_AF_SWITCH:
            ALOGV("%s RADIO_EVENT_TUNED channel %d", __FUNCTION__, event->info.channel);
            jStatus = convertProgramInfoFromNative(env, &jObj, &event->info);
            break;
        case RADIO_EVENT_METADATA:
            jStatus = convertMetadataFromNative(env, &jObj, event->metadata);
            if (jStatus >= 0) {
                jStatus = RADIO_STATUS_OK;
            }
            break;
        case RADIO_EVENT_ANTENNA:
        case RADIO_EVENT_TA:
        case RADIO_EVENT_EA:
        case RADIO_EVENT_CONTROL:
            jArg2 = event->on ? 1 : 0;
            break;
    }

    if (jStatus != RADIO_STATUS_OK) {
        return;
    }
    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
                              event->type, event->status, jArg2, jObj);

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

// ----------------------------------------------------------------------------

static void
android_hardware_Radio_setup(JNIEnv *env, jobject thiz,
                             jobject weak_this, jobject jConfig, jboolean withAudio)
{
    ALOGV("%s", __FUNCTION__);

    setRadio(env, thiz, 0);

    sp<JNIRadioCallback> callback = new JNIRadioCallback(env, thiz, weak_this);

    radio_handle_t handle = (radio_handle_t)env->GetIntField(thiz, gModuleFields.mId);

    struct radio_band_config nConfig;
    struct radio_band_config *configPtr = NULL;
    if (jConfig != NULL) {
        jint jStatus = convertBandConfigToNative(env, &nConfig, jConfig);
        if (jStatus != RADIO_STATUS_OK) {
            return;
        }
        configPtr = &nConfig;
    }
    sp<Radio> module = Radio::attach(handle, configPtr, (bool)withAudio, callback);
    if (module == 0) {
        return;
    }

    setRadio(env, thiz, module);
}

static void
android_hardware_Radio_close(JNIEnv *env, jobject thiz)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = setRadio(env, thiz, 0);
    ALOGV("detach module %p", module.get());
    if (module != 0) {
        ALOGV("detach module->detach()");
        module->detach();
    }
}

static void
android_hardware_Radio_finalize(JNIEnv *env, jobject thiz)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module != 0) {
        ALOGW("Radio finalized without being detached");
    }
    android_hardware_Radio_close(env, thiz);
}

static jint
android_hardware_Radio_setConfiguration(JNIEnv *env, jobject thiz, jobject jConfig)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }

    if (!env->IsInstanceOf(jConfig, gRadioFmBandConfigClass) &&
            !env->IsInstanceOf(jConfig, gRadioAmBandConfigClass)) {
        return RADIO_STATUS_BAD_VALUE;
    }

    struct radio_band_config nConfig;
    jint jStatus = convertBandConfigToNative(env, &nConfig, jConfig);
    if (jStatus != RADIO_STATUS_OK) {
        return jStatus;
    }

    status_t status = module->setConfiguration(&nConfig);
    return (jint)status;
}

static jint
android_hardware_Radio_getConfiguration(JNIEnv *env, jobject thiz, jobjectArray jConfigs)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    if (env->GetArrayLength(jConfigs) != 1) {
        return (jint)RADIO_STATUS_BAD_VALUE;
    }

    struct radio_band_config nConfig;

    status_t status = module->getConfiguration(&nConfig);
    if (status != NO_ERROR) {
        return (jint)status;
    }
    jobject jConfig;
    int jStatus = convertBandConfigFromNative(env, &jConfig, &nConfig);
    if (jStatus != RADIO_STATUS_OK) {
        return jStatus;
    }
    env->SetObjectArrayElement(jConfigs, 0, jConfig);
    env->DeleteLocalRef(jConfig);
    return RADIO_STATUS_OK;
}

static jint
android_hardware_Radio_setMute(JNIEnv *env, jobject thiz, jboolean mute)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    status_t status = module->setMute((bool)mute);
    return (jint)status;
}

static jboolean
android_hardware_Radio_getMute(JNIEnv *env, jobject thiz)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return true;
    }
    bool mute = true;
    status_t status = module->getMute(&mute);
    if (status != NO_ERROR) {
        return true;
    }
    return (jboolean)mute;
}

static jint
android_hardware_Radio_step(JNIEnv *env, jobject thiz, jint direction, jboolean skipSubChannel)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    status_t status = module->step((radio_direction_t)direction, (bool)skipSubChannel);
    return (jint)status;
}

static jint
android_hardware_Radio_scan(JNIEnv *env, jobject thiz, jint direction, jboolean skipSubChannel)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    status_t status = module->scan((radio_direction_t)direction, (bool)skipSubChannel);
    return (jint)status;
}

static jint
android_hardware_Radio_tune(JNIEnv *env, jobject thiz, jint channel, jint subChannel)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    status_t status = module->tune((unsigned int)channel, (unsigned int)subChannel);
    return (jint)status;
}

static jint
android_hardware_Radio_cancel(JNIEnv *env, jobject thiz)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    status_t status = module->cancel();
    return (jint)status;
}

static jint
android_hardware_Radio_getProgramInformation(JNIEnv *env, jobject thiz, jobjectArray jInfos)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return RADIO_STATUS_NO_INIT;
    }
    if (env->GetArrayLength(jInfos) != 1) {
        return (jint)RADIO_STATUS_BAD_VALUE;
    }

    struct radio_program_info nInfo;
    radio_metadata_allocate(&nInfo.metadata, 0, 0);
    jobject jInfo = NULL;
    int jStatus;

    jStatus = (int)module->getProgramInformation(&nInfo);
    if (jStatus != RADIO_STATUS_OK) {
        goto exit;
    }
    jStatus = convertProgramInfoFromNative(env, &jInfo, &nInfo);
    if (jStatus != RADIO_STATUS_OK) {
        goto exit;
    }
    env->SetObjectArrayElement(jInfos, 0, jInfo);

exit:
    if (jInfo != NULL) {
        env->DeleteLocalRef(jInfo);
    }
    radio_metadata_deallocate(nInfo.metadata);
    return jStatus;
}

static jboolean
android_hardware_Radio_isAntennaConnected(JNIEnv *env, jobject thiz)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return false;
    }

    struct radio_band_config nConfig;

    status_t status = module->getConfiguration(&nConfig);
    if (status != NO_ERROR) {
        return false;
    }

    return (jboolean)nConfig.band.antenna_connected;
}


static jboolean
android_hardware_Radio_hasControl(JNIEnv *env, jobject thiz)
{
    ALOGV("%s", __FUNCTION__);
    sp<Radio> module = getRadio(env, thiz);
    if (module == NULL) {
        return false;
    }

    bool hasControl;
    status_t status = module->hasControl(&hasControl);
    if (status != NO_ERROR) {
        return false;
    }

    return (jboolean)hasControl;
}


static JNINativeMethod gMethods[] = {
    {"listModules",
        "(Ljava/util/List;)I",
        (void *)android_hardware_Radio_listModules},
};

static JNINativeMethod gModuleMethods[] = {
    {"native_setup",
        "(Ljava/lang/Object;Landroid/hardware/radio/RadioManager$BandConfig;Z)V",
        (void *)android_hardware_Radio_setup},
    {"native_finalize",
        "()V",
        (void *)android_hardware_Radio_finalize},
    {"close",
        "()V",
        (void *)android_hardware_Radio_close},
    {"setConfiguration",
        "(Landroid/hardware/radio/RadioManager$BandConfig;)I",
        (void *)android_hardware_Radio_setConfiguration},
    {"getConfiguration",
        "([Landroid/hardware/radio/RadioManager$BandConfig;)I",
        (void *)android_hardware_Radio_getConfiguration},
    {"setMute",
        "(Z)I",
        (void *)android_hardware_Radio_setMute},
    {"getMute",
        "()Z",
        (void *)android_hardware_Radio_getMute},
    {"step",
        "(IZ)I",
        (void *)android_hardware_Radio_step},
    {"scan",
        "(IZ)I",
        (void *)android_hardware_Radio_scan},
    {"tune",
        "(II)I",
        (void *)android_hardware_Radio_tune},
    {"cancel",
        "()I",
        (void *)android_hardware_Radio_cancel},
    {"getProgramInformation",
        "([Landroid/hardware/radio/RadioManager$ProgramInfo;)I",
        (void *)android_hardware_Radio_getProgramInformation},
    {"isAntennaConnected",
        "()Z",
        (void *)android_hardware_Radio_isAntennaConnected},
    {"hasControl",
        "()Z",
        (void *)android_hardware_Radio_hasControl},
};

int register_android_hardware_Radio(JNIEnv *env)
{
    jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
    gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
    gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");

    jclass lClass = FindClassOrDie(env, kRadioManagerClassPathName);
    gRadioManagerClass = MakeGlobalRefOrDie(env, lClass);

    jclass moduleClass = FindClassOrDie(env, kRadioModuleClassPathName);
    gRadioModuleClass = MakeGlobalRefOrDie(env, moduleClass);
    gPostEventFromNative = GetStaticMethodIDOrDie(env, moduleClass, "postEventFromNative",
                                                  "(Ljava/lang/Object;IIILjava/lang/Object;)V");
    gModuleFields.mNativeContext = GetFieldIDOrDie(env, moduleClass, "mNativeContext", "J");
    gModuleFields.mId = GetFieldIDOrDie(env, moduleClass, "mId", "I");

    jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName);
    gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass);
    gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
            "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;)V");

    jclass bandDescriptorClass = FindClassOrDie(env, kRadioBandDescriptorClassPathName);
    gRadioBandDescriptorClass = MakeGlobalRefOrDie(env, bandDescriptorClass);
    gRadioBandDescriptorFields.mRegion = GetFieldIDOrDie(env, bandDescriptorClass, "mRegion", "I");
    gRadioBandDescriptorFields.mType = GetFieldIDOrDie(env, bandDescriptorClass, "mType", "I");
    gRadioBandDescriptorFields.mLowerLimit =
            GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
    gRadioBandDescriptorFields.mUpperLimit =
            GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
    gRadioBandDescriptorFields.mSpacing =
            GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");

    jclass fmBandDescriptorClass = FindClassOrDie(env, kRadioFmBandDescriptorClassPathName);
    gRadioFmBandDescriptorClass = MakeGlobalRefOrDie(env, fmBandDescriptorClass);
    gRadioFmBandDescriptorCstor = GetMethodIDOrDie(env, fmBandDescriptorClass, "<init>",
            "(IIIIIZZZZZ)V");

    jclass amBandDescriptorClass = FindClassOrDie(env, kRadioAmBandDescriptorClassPathName);
    gRadioAmBandDescriptorClass = MakeGlobalRefOrDie(env, amBandDescriptorClass);
    gRadioAmBandDescriptorCstor = GetMethodIDOrDie(env, amBandDescriptorClass, "<init>",
            "(IIIIIZ)V");

    jclass bandConfigClass = FindClassOrDie(env, kRadioBandConfigClassPathName);
    gRadioBandConfigClass = MakeGlobalRefOrDie(env, bandConfigClass);
    gRadioBandConfigFields.mDescriptor =
            GetFieldIDOrDie(env, bandConfigClass, "mDescriptor",
                            "Landroid/hardware/radio/RadioManager$BandDescriptor;");

    jclass fmBandConfigClass = FindClassOrDie(env, kRadioFmBandConfigClassPathName);
    gRadioFmBandConfigClass = MakeGlobalRefOrDie(env, fmBandConfigClass);
    gRadioFmBandConfigCstor = GetMethodIDOrDie(env, fmBandConfigClass, "<init>",
            "(IIIIIZZZZZ)V");
    gRadioFmBandConfigFields.mStereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
    gRadioFmBandConfigFields.mRds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
    gRadioFmBandConfigFields.mTa = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
    gRadioFmBandConfigFields.mAf = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
    gRadioFmBandConfigFields.mEa =
        GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");


    jclass amBandConfigClass = FindClassOrDie(env, kRadioAmBandConfigClassPathName);
    gRadioAmBandConfigClass = MakeGlobalRefOrDie(env, amBandConfigClass);
    gRadioAmBandConfigCstor = GetMethodIDOrDie(env, amBandConfigClass, "<init>",
            "(IIIIIZ)V");
    gRadioAmBandConfigFields.mStereo = GetFieldIDOrDie(env, amBandConfigClass, "mStereo", "Z");

    jclass programInfoClass = FindClassOrDie(env, kRadioProgramInfoClassPathName);
    gRadioProgramInfoClass = MakeGlobalRefOrDie(env, programInfoClass);
    gRadioProgramInfoCstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
            "(IIZZZILandroid/hardware/radio/RadioMetadata;)V");

    jclass metadataClass = FindClassOrDie(env, kRadioMetadataClassPathName);
    gRadioMetadataClass = MakeGlobalRefOrDie(env, metadataClass);
    gRadioMetadataCstor = GetMethodIDOrDie(env, metadataClass, "<init>", "()V");
    gRadioMetadataMethods.putIntFromNative = GetMethodIDOrDie(env, metadataClass,
                                                              "putIntFromNative",
                                                              "(II)I");
    gRadioMetadataMethods.putStringFromNative = GetMethodIDOrDie(env, metadataClass,
                                                                 "putStringFromNative",
                                                                 "(ILjava/lang/String;)I");
    gRadioMetadataMethods.putBitmapFromNative = GetMethodIDOrDie(env, metadataClass,
                                                                 "putBitmapFromNative",
                                                                 "(I[B)I");
    gRadioMetadataMethods.putClockFromNative = GetMethodIDOrDie(env, metadataClass,
                                                                "putClockFromNative",
                                                                "(IJI)I");


    RegisterMethodsOrDie(env, kRadioManagerClassPathName, gMethods, NELEM(gMethods));

    int ret = RegisterMethodsOrDie(env, kRadioModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));

    ALOGI("%s DONE", __FUNCTION__);

    return ret;
}
