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

#include "jni.h"
#include "JNIHelp.h"
#include "core_jni_helpers.h"
#include <system/sound_trigger.h>
#include <soundtrigger/SoundTriggerCallback.h>
#include <soundtrigger/SoundTrigger.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
#include <binder/IMemory.h>
#include <binder/MemoryDealer.h>
#include "android_media_AudioFormat.h"

using namespace android;

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

static jclass gUUIDClass;
static struct {
    jmethodID    toString;
} gUUIDMethods;

static const char* const kSoundTriggerClassPathName = "android/hardware/soundtrigger/SoundTrigger";
static jclass gSoundTriggerClass;

static const char* const kModuleClassPathName = "android/hardware/soundtrigger/SoundTriggerModule";
static jclass gModuleClass;
static struct {
    jfieldID    mNativeContext;
    jfieldID    mId;
} gModuleFields;
static jmethodID   gPostEventFromNative;

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

static const char* const kSoundModelClassPathName =
                                     "android/hardware/soundtrigger/SoundTrigger$SoundModel";
static jclass gSoundModelClass;
static struct {
    jfieldID    uuid;
    jfieldID    vendorUuid;
    jfieldID    data;
} gSoundModelFields;

static const char* const kKeyphraseClassPathName =
                                     "android/hardware/soundtrigger/SoundTrigger$Keyphrase";
static jclass gKeyphraseClass;
static struct {
    jfieldID id;
    jfieldID recognitionModes;
    jfieldID locale;
    jfieldID text;
    jfieldID users;
} gKeyphraseFields;

static const char* const kKeyphraseSoundModelClassPathName =
                                 "android/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel";
static jclass gKeyphraseSoundModelClass;
static struct {
    jfieldID    keyphrases;
} gKeyphraseSoundModelFields;

static const char* const kRecognitionConfigClassPathName =
                                     "android/hardware/soundtrigger/SoundTrigger$RecognitionConfig";
static jclass gRecognitionConfigClass;
static struct {
    jfieldID captureRequested;
    jfieldID keyphrases;
    jfieldID data;
} gRecognitionConfigFields;

static const char* const kRecognitionEventClassPathName =
                                     "android/hardware/soundtrigger/SoundTrigger$RecognitionEvent";
static jclass gRecognitionEventClass;
static jmethodID   gRecognitionEventCstor;

static const char* const kKeyphraseRecognitionEventClassPathName =
                             "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent";
static jclass gKeyphraseRecognitionEventClass;
static jmethodID   gKeyphraseRecognitionEventCstor;

static const char* const kKeyphraseRecognitionExtraClassPathName =
                             "android/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra";
static jclass gKeyphraseRecognitionExtraClass;
static jmethodID   gKeyphraseRecognitionExtraCstor;
static struct {
    jfieldID id;
    jfieldID recognitionModes;
    jfieldID coarseConfidenceLevel;
    jfieldID confidenceLevels;
} gKeyphraseRecognitionExtraFields;

static const char* const kConfidenceLevelClassPathName =
                             "android/hardware/soundtrigger/SoundTrigger$ConfidenceLevel";
static jclass gConfidenceLevelClass;
static jmethodID   gConfidenceLevelCstor;
static struct {
    jfieldID userId;
    jfieldID confidenceLevel;
} gConfidenceLevelFields;

static const char* const kAudioFormatClassPathName =
                             "android/media/AudioFormat";
static jclass gAudioFormatClass;
static jmethodID gAudioFormatCstor;

static const char* const kSoundModelEventClassPathName =
                                     "android/hardware/soundtrigger/SoundTrigger$SoundModelEvent";
static jclass gSoundModelEventClass;
static jmethodID   gSoundModelEventCstor;

static Mutex gLock;

enum {
    SOUNDTRIGGER_STATUS_OK = 0,
    SOUNDTRIGGER_STATUS_ERROR = INT_MIN,
    SOUNDTRIGGER_PERMISSION_DENIED = -1,
    SOUNDTRIGGER_STATUS_NO_INIT = -19,
    SOUNDTRIGGER_STATUS_BAD_VALUE = -22,
    SOUNDTRIGGER_STATUS_DEAD_OBJECT = -32,
    SOUNDTRIGGER_INVALID_OPERATION = -38,
};

enum  {
    SOUNDTRIGGER_EVENT_RECOGNITION = 1,
    SOUNDTRIGGER_EVENT_SERVICE_DIED = 2,
    SOUNDTRIGGER_EVENT_SOUNDMODEL = 3,
    SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE = 4,
};

// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class JNISoundTriggerCallback: public SoundTriggerCallback
{
public:
    JNISoundTriggerCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
    ~JNISoundTriggerCallback();

    virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event);
    virtual void onSoundModelEvent(struct sound_trigger_model_event *event);
    virtual void onServiceStateChange(sound_trigger_service_state_t state);
    virtual void onServiceDied();

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

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

    // Hold onto the SoundTriggerModule 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", kModuleClassPathName);
        return;
    }
    mClass = (jclass)env->NewGlobalRef(clazz);

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

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

void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognition_event *event)
{
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jobject jEvent = NULL;
    jbyteArray jData = NULL;

    if (event->data_size) {
        jData = env->NewByteArray(event->data_size);
        jbyte *nData = env->GetByteArrayElements(jData, NULL);
        memcpy(nData, (char *)event + event->data_offset, event->data_size);
        env->ReleaseByteArrayElements(jData, nData, 0);
    }

    jobject jAudioFormat = NULL;
    if (event->trigger_in_data || event->capture_available) {
        jAudioFormat = env->NewObject(gAudioFormatClass,
                                    gAudioFormatCstor,
                                    audioFormatFromNative(event->audio_config.format),
                                    event->audio_config.sample_rate,
                                    inChannelMaskFromNative(event->audio_config.channel_mask));

    }
    if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        struct sound_trigger_phrase_recognition_event *phraseEvent =
                (struct sound_trigger_phrase_recognition_event *)event;

        jobjectArray jExtras = env->NewObjectArray(phraseEvent->num_phrases,
                                                  gKeyphraseRecognitionExtraClass, NULL);
        if (jExtras == NULL) {
            return;
        }

        for (size_t i = 0; i < phraseEvent->num_phrases; i++) {
            jobjectArray jConfidenceLevels = env->NewObjectArray(
                                                        phraseEvent->phrase_extras[i].num_levels,
                                                        gConfidenceLevelClass, NULL);

            if (jConfidenceLevels == NULL) {
                return;
            }
            for (size_t j = 0; j < phraseEvent->phrase_extras[i].num_levels; j++) {
                jobject jConfidenceLevel = env->NewObject(gConfidenceLevelClass,
                                                  gConfidenceLevelCstor,
                                                  phraseEvent->phrase_extras[i].levels[j].user_id,
                                                  phraseEvent->phrase_extras[i].levels[j].level);
                env->SetObjectArrayElement(jConfidenceLevels, j, jConfidenceLevel);
                env->DeleteLocalRef(jConfidenceLevel);
            }

            jobject jNewExtra = env->NewObject(gKeyphraseRecognitionExtraClass,
                                               gKeyphraseRecognitionExtraCstor,
                                               phraseEvent->phrase_extras[i].id,
                                               phraseEvent->phrase_extras[i].recognition_modes,
                                               phraseEvent->phrase_extras[i].confidence_level,
                                               jConfidenceLevels);

            if (jNewExtra == NULL) {
                return;
            }
            env->SetObjectArrayElement(jExtras, i, jNewExtra);
            env->DeleteLocalRef(jNewExtra);
            env->DeleteLocalRef(jConfidenceLevels);
        }
        jEvent = env->NewObject(gKeyphraseRecognitionEventClass, gKeyphraseRecognitionEventCstor,
                                event->status, event->model, event->capture_available,
                                event->capture_session, event->capture_delay_ms,
                                event->capture_preamble_ms, event->trigger_in_data,
                                jAudioFormat, jData, jExtras);
        env->DeleteLocalRef(jExtras);
    } else {
        jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor,
                                event->status, event->model, event->capture_available,
                                event->capture_session, event->capture_delay_ms,
                                event->capture_preamble_ms, event->trigger_in_data,
                                jAudioFormat, jData);
    }

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

    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
                              SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent);

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

void JNISoundTriggerCallback::onSoundModelEvent(struct sound_trigger_model_event *event)
{
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jobject jEvent = NULL;
    jbyteArray jData = NULL;

    if (event->data_size) {
        jData = env->NewByteArray(event->data_size);
        jbyte *nData = env->GetByteArrayElements(jData, NULL);
        memcpy(nData, (char *)event + event->data_offset, event->data_size);
        env->ReleaseByteArrayElements(jData, nData, 0);
    }

    jEvent = env->NewObject(gSoundModelEventClass, gSoundModelEventCstor,
                            event->status, event->model, jData);

    env->DeleteLocalRef(jData);
    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
                              SOUNDTRIGGER_EVENT_SOUNDMODEL, 0, 0, jEvent);
    env->DeleteLocalRef(jEvent);
    if (env->ExceptionCheck()) {
        ALOGW("An exception occurred while notifying an event.");
        env->ExceptionClear();
    }
}

void JNISoundTriggerCallback::onServiceStateChange(sound_trigger_service_state_t state)
{
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
                                        SOUNDTRIGGER_EVENT_SERVICE_STATE_CHANGE, state, 0, NULL);
    if (env->ExceptionCheck()) {
        ALOGW("An exception occurred while notifying an event.");
        env->ExceptionClear();
    }
}

void JNISoundTriggerCallback::onServiceDied()
{
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
                              SOUNDTRIGGER_EVENT_SERVICE_DIED, 0, 0, NULL);
    if (env->ExceptionCheck()) {
        ALOGW("An exception occurred while notifying an event.");
        env->ExceptionClear();
    }
}

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

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

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


static jint
android_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
                                          jobject jModules)
{
    ALOGV("listModules");

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

    unsigned int numModules = 0;
    struct sound_trigger_module_descriptor *nModules = NULL;

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

    nModules = (struct sound_trigger_module_descriptor *)
                            calloc(numModules, sizeof(struct sound_trigger_module_descriptor));

    status = SoundTrigger::listModules(nModules, &numModules);
    ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);

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

    for (size_t i = 0; i < numModules; i++) {
        char str[SOUND_TRIGGER_MAX_STRING_LEN];

        jstring implementor = env->NewStringUTF(nModules[i].properties.implementor);
        jstring description = env->NewStringUTF(nModules[i].properties.description);
        SoundTrigger::guidToString(&nModules[i].properties.uuid,
                                   str,
                                   SOUND_TRIGGER_MAX_STRING_LEN);
        jstring uuid = env->NewStringUTF(str);

        ALOGV("listModules module %zu id %d description %s maxSoundModels %d",
              i, nModules[i].handle, nModules[i].properties.description,
              nModules[i].properties.max_sound_models);

        jobject newModuleDesc = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
                                               nModules[i].handle,
                                               implementor, description, uuid,
                                               nModules[i].properties.version,
                                               nModules[i].properties.max_sound_models,
                                               nModules[i].properties.max_key_phrases,
                                               nModules[i].properties.max_users,
                                               nModules[i].properties.recognition_modes,
                                               nModules[i].properties.capture_transition,
                                               nModules[i].properties.max_buffer_ms,
                                               nModules[i].properties.concurrent_capture,
                                               nModules[i].properties.power_consumption_mw,
                                               nModules[i].properties.trigger_in_event);

        env->DeleteLocalRef(implementor);
        env->DeleteLocalRef(description);
        env->DeleteLocalRef(uuid);
        if (newModuleDesc == NULL) {
            status = SOUNDTRIGGER_STATUS_ERROR;
            goto exit;
        }
        env->CallBooleanMethod(jModules, gArrayListMethods.add, newModuleDesc);
    }

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

static void
android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
    ALOGV("setup");

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

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

    sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
    if (module == 0) {
        return;
    }

    setSoundTrigger(env, thiz, module);
}

static void
android_hardware_SoundTrigger_detach(JNIEnv *env, jobject thiz)
{
    ALOGV("detach");
    sp<SoundTrigger> module = setSoundTrigger(env, thiz, 0);
    ALOGV("detach module %p", module.get());
    if (module != 0) {
        ALOGV("detach module->detach()");
        module->detach();
    }
}

static void
android_hardware_SoundTrigger_finalize(JNIEnv *env, jobject thiz)
{
    ALOGV("finalize");
    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
    if (module != 0) {
        ALOGW("SoundTrigger finalized without being detached");
    }
    android_hardware_SoundTrigger_detach(env, thiz);
}

static jint
android_hardware_SoundTrigger_loadSoundModel(JNIEnv *env, jobject thiz,
                                             jobject jSoundModel, jintArray jHandle)
{
    jint status = SOUNDTRIGGER_STATUS_OK;
    jbyte *nData = NULL;
    struct sound_trigger_sound_model *nSoundModel;
    jbyteArray jData;
    sp<MemoryDealer> memoryDealer;
    sp<IMemory> memory;
    size_t size;
    sound_model_handle_t handle;
    jobject jUuid;
    jstring jUuidString;
    const char *nUuidString;

    ALOGV("loadSoundModel");
    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
    if (module == NULL) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }
    if (jHandle == NULL) {
        return SOUNDTRIGGER_STATUS_BAD_VALUE;
    }
    jsize jHandleLen = env->GetArrayLength(jHandle);
    if (jHandleLen == 0) {
        return SOUNDTRIGGER_STATUS_BAD_VALUE;
    }
    jint *nHandle = env->GetIntArrayElements(jHandle, NULL);
    if (nHandle == NULL) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }
    if (!env->IsInstanceOf(jSoundModel, gSoundModelClass)) {
        status = SOUNDTRIGGER_STATUS_BAD_VALUE;
        goto exit;
    }
    size_t offset;
    sound_trigger_sound_model_type_t type;
    if (env->IsInstanceOf(jSoundModel, gKeyphraseSoundModelClass)) {
        offset = sizeof(struct sound_trigger_phrase_sound_model);
        type = SOUND_MODEL_TYPE_KEYPHRASE;
    } else {
        offset = sizeof(struct sound_trigger_sound_model);
        type = SOUND_MODEL_TYPE_UNKNOWN;
    }

    jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.uuid);
    jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
    nUuidString = env->GetStringUTFChars(jUuidString, NULL);
    sound_trigger_uuid_t nUuid;
    SoundTrigger::stringToGuid(nUuidString, &nUuid);
    env->ReleaseStringUTFChars(jUuidString, nUuidString);
    env->DeleteLocalRef(jUuidString);

    sound_trigger_uuid_t nVendorUuid;
    jUuid = env->GetObjectField(jSoundModel, gSoundModelFields.vendorUuid);
    if (jUuid != NULL) {
        jUuidString = (jstring)env->CallObjectMethod(jUuid, gUUIDMethods.toString);
        nUuidString = env->GetStringUTFChars(jUuidString, NULL);
        SoundTrigger::stringToGuid(nUuidString, &nVendorUuid);
        env->ReleaseStringUTFChars(jUuidString, nUuidString);
        env->DeleteLocalRef(jUuidString);
    } else {
        SoundTrigger::stringToGuid("00000000-0000-0000-0000-000000000000", &nVendorUuid);
    }

    jData = (jbyteArray)env->GetObjectField(jSoundModel, gSoundModelFields.data);
    if (jData == NULL) {
        status = SOUNDTRIGGER_STATUS_BAD_VALUE;
        goto exit;
    }
    size = env->GetArrayLength(jData);

    nData = env->GetByteArrayElements(jData, NULL);
    if (jData == NULL) {
        status = SOUNDTRIGGER_STATUS_ERROR;
        goto exit;
    }

    memoryDealer = new MemoryDealer(offset + size, "SoundTrigge-JNI::LoadModel");
    if (memoryDealer == 0) {
        status = SOUNDTRIGGER_STATUS_ERROR;
        goto exit;
    }
    memory = memoryDealer->allocate(offset + size);
    if (memory == 0 || memory->pointer() == NULL) {
        status = SOUNDTRIGGER_STATUS_ERROR;
        goto exit;
    }

    nSoundModel = (struct sound_trigger_sound_model *)memory->pointer();

    nSoundModel->type = type;
    nSoundModel->uuid = nUuid;
    nSoundModel->vendor_uuid = nVendorUuid;
    nSoundModel->data_size = size;
    nSoundModel->data_offset = offset;
    memcpy((char *)nSoundModel + offset, nData, size);
    if (type == SOUND_MODEL_TYPE_KEYPHRASE) {
        struct sound_trigger_phrase_sound_model *phraseModel =
                (struct sound_trigger_phrase_sound_model *)nSoundModel;

        jobjectArray jPhrases =
            (jobjectArray)env->GetObjectField(jSoundModel, gKeyphraseSoundModelFields.keyphrases);
        if (jPhrases == NULL) {
            status = SOUNDTRIGGER_STATUS_BAD_VALUE;
            goto exit;
        }

        size_t numPhrases = env->GetArrayLength(jPhrases);
        phraseModel->num_phrases = numPhrases;
        ALOGV("loadSoundModel numPhrases %zu", numPhrases);
        for (size_t i = 0; i < numPhrases; i++) {
            jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
            phraseModel->phrases[i].id =
                                    env->GetIntField(jPhrase,gKeyphraseFields.id);
            phraseModel->phrases[i].recognition_mode =
                                    env->GetIntField(jPhrase,gKeyphraseFields.recognitionModes);

            jintArray jUsers = (jintArray)env->GetObjectField(jPhrase, gKeyphraseFields.users);
            phraseModel->phrases[i].num_users = env->GetArrayLength(jUsers);
            jint *nUsers = env->GetIntArrayElements(jUsers, NULL);
            memcpy(phraseModel->phrases[i].users,
                   nUsers,
                   phraseModel->phrases[i].num_users * sizeof(int));
            env->ReleaseIntArrayElements(jUsers, nUsers, 0);
            env->DeleteLocalRef(jUsers);

            jstring jLocale = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.locale);
            const char *nLocale = env->GetStringUTFChars(jLocale, NULL);
            strncpy(phraseModel->phrases[i].locale,
                    nLocale,
                    SOUND_TRIGGER_MAX_LOCALE_LEN);
            jstring jText = (jstring)env->GetObjectField(jPhrase, gKeyphraseFields.text);
            const char *nText = env->GetStringUTFChars(jText, NULL);
            strncpy(phraseModel->phrases[i].text,
                    nText,
                    SOUND_TRIGGER_MAX_STRING_LEN);

            env->ReleaseStringUTFChars(jLocale, nLocale);
            env->DeleteLocalRef(jLocale);
            env->ReleaseStringUTFChars(jText, nText);
            env->DeleteLocalRef(jText);
            ALOGV("loadSoundModel phrases %zu text %s locale %s",
                  i, phraseModel->phrases[i].text, phraseModel->phrases[i].locale);
            env->DeleteLocalRef(jPhrase);
        }
        env->DeleteLocalRef(jPhrases);
    }
    status = module->loadSoundModel(memory, &handle);
    ALOGV("loadSoundModel status %d handle %d", status, handle);

exit:
    if (nHandle != NULL) {
        nHandle[0] = (jint)handle;
        env->ReleaseIntArrayElements(jHandle, nHandle, NULL);
    }
    if (nData != NULL) {
        env->ReleaseByteArrayElements(jData, nData, NULL);
    }
    return status;
}

static jint
android_hardware_SoundTrigger_unloadSoundModel(JNIEnv *env, jobject thiz,
                                               jint jHandle)
{
    jint status = SOUNDTRIGGER_STATUS_OK;
    ALOGV("unloadSoundModel");
    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
    if (module == NULL) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }
    status = module->unloadSoundModel((sound_model_handle_t)jHandle);

    return status;
}

static jint
android_hardware_SoundTrigger_startRecognition(JNIEnv *env, jobject thiz,
                                               jint jHandle, jobject jConfig)
{
    jint status = SOUNDTRIGGER_STATUS_OK;
    ALOGV("startRecognition");
    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
    if (module == NULL) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }

    if (!env->IsInstanceOf(jConfig, gRecognitionConfigClass)) {
        return SOUNDTRIGGER_STATUS_BAD_VALUE;
    }

    jbyteArray jData = (jbyteArray)env->GetObjectField(jConfig, gRecognitionConfigFields.data);
    jsize dataSize = 0;
    jbyte *nData = NULL;
    if (jData != NULL) {
        dataSize = env->GetArrayLength(jData);
        if (dataSize == 0) {
            return SOUNDTRIGGER_STATUS_BAD_VALUE;
        }
        nData = env->GetByteArrayElements(jData, NULL);
        if (nData == NULL) {
            return SOUNDTRIGGER_STATUS_ERROR;
        }
    }

    size_t totalSize = sizeof(struct sound_trigger_recognition_config) + dataSize;
    sp<MemoryDealer> memoryDealer =
            new MemoryDealer(totalSize, "SoundTrigge-JNI::StartRecognition");
    if (memoryDealer == 0) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }
    sp<IMemory> memory = memoryDealer->allocate(totalSize);
    if (memory == 0 || memory->pointer() == NULL) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }
    if (dataSize != 0) {
        memcpy((char *)memory->pointer() + sizeof(struct sound_trigger_recognition_config),
                nData,
                dataSize);
        env->ReleaseByteArrayElements(jData, nData, 0);
    }
    env->DeleteLocalRef(jData);
    struct sound_trigger_recognition_config *config =
                                    (struct sound_trigger_recognition_config *)memory->pointer();
    config->data_size = dataSize;
    config->data_offset = sizeof(struct sound_trigger_recognition_config);
    config->capture_requested = env->GetBooleanField(jConfig,
                                                 gRecognitionConfigFields.captureRequested);

    config->num_phrases = 0;
    jobjectArray jPhrases =
        (jobjectArray)env->GetObjectField(jConfig, gRecognitionConfigFields.keyphrases);
    if (jPhrases != NULL) {
        config->num_phrases = env->GetArrayLength(jPhrases);
    }
    ALOGV("startRecognition num phrases %d", config->num_phrases);
    for (size_t i = 0; i < config->num_phrases; i++) {
        jobject jPhrase = env->GetObjectArrayElement(jPhrases, i);
        config->phrases[i].id = env->GetIntField(jPhrase,
                                                gKeyphraseRecognitionExtraFields.id);
        config->phrases[i].recognition_modes = env->GetIntField(jPhrase,
                                                gKeyphraseRecognitionExtraFields.recognitionModes);
        config->phrases[i].confidence_level = env->GetIntField(jPhrase,
                                            gKeyphraseRecognitionExtraFields.coarseConfidenceLevel);
        config->phrases[i].num_levels = 0;
        jobjectArray jConfidenceLevels = (jobjectArray)env->GetObjectField(jPhrase,
                                                gKeyphraseRecognitionExtraFields.confidenceLevels);
        if (jConfidenceLevels != NULL) {
            config->phrases[i].num_levels = env->GetArrayLength(jConfidenceLevels);
        }
        ALOGV("startRecognition phrase %zu num_levels %d", i, config->phrases[i].num_levels);
        for (size_t j = 0; j < config->phrases[i].num_levels; j++) {
            jobject jConfidenceLevel = env->GetObjectArrayElement(jConfidenceLevels, j);
            config->phrases[i].levels[j].user_id = env->GetIntField(jConfidenceLevel,
                                                                    gConfidenceLevelFields.userId);
            config->phrases[i].levels[j].level = env->GetIntField(jConfidenceLevel,
                                                          gConfidenceLevelFields.confidenceLevel);
            env->DeleteLocalRef(jConfidenceLevel);
        }
        ALOGV("startRecognition phrases %zu", i);
        env->DeleteLocalRef(jConfidenceLevels);
        env->DeleteLocalRef(jPhrase);
    }
    env->DeleteLocalRef(jPhrases);

    status = module->startRecognition(jHandle, memory);
    return status;
}

static jint
android_hardware_SoundTrigger_stopRecognition(JNIEnv *env, jobject thiz,
                                               jint jHandle)
{
    jint status = SOUNDTRIGGER_STATUS_OK;
    ALOGV("stopRecognition");
    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
    if (module == NULL) {
        return SOUNDTRIGGER_STATUS_ERROR;
    }
    status = module->stopRecognition(jHandle);
    return status;
}

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


static JNINativeMethod gModuleMethods[] = {
    {"native_setup",
        "(Ljava/lang/Object;)V",
        (void *)android_hardware_SoundTrigger_setup},
    {"native_finalize",
        "()V",
        (void *)android_hardware_SoundTrigger_finalize},
    {"detach",
        "()V",
        (void *)android_hardware_SoundTrigger_detach},
    {"loadSoundModel",
        "(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I",
        (void *)android_hardware_SoundTrigger_loadSoundModel},
    {"unloadSoundModel",
        "(I)I",
        (void *)android_hardware_SoundTrigger_unloadSoundModel},
    {"startRecognition",
        "(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I",
        (void *)android_hardware_SoundTrigger_startRecognition},
    {"stopRecognition",
        "(I)I",
        (void *)android_hardware_SoundTrigger_stopRecognition},
};

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

    jclass uuidClass = FindClassOrDie(env, "java/util/UUID");
    gUUIDClass = MakeGlobalRefOrDie(env, uuidClass);
    gUUIDMethods.toString = GetMethodIDOrDie(env, uuidClass, "toString", "()Ljava/lang/String;");

    jclass lClass = FindClassOrDie(env, kSoundTriggerClassPathName);
    gSoundTriggerClass = MakeGlobalRefOrDie(env, lClass);

    jclass moduleClass = FindClassOrDie(env, kModuleClassPathName);
    gModuleClass = 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>",
            "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V");

    jclass soundModelClass = FindClassOrDie(env, kSoundModelClassPathName);
    gSoundModelClass = MakeGlobalRefOrDie(env, soundModelClass);
    gSoundModelFields.uuid = GetFieldIDOrDie(env, soundModelClass, "uuid", "Ljava/util/UUID;");
    gSoundModelFields.vendorUuid = GetFieldIDOrDie(env, soundModelClass, "vendorUuid",
                                                   "Ljava/util/UUID;");
    gSoundModelFields.data = GetFieldIDOrDie(env, soundModelClass, "data", "[B");

    jclass keyphraseClass = FindClassOrDie(env, kKeyphraseClassPathName);
    gKeyphraseClass = MakeGlobalRefOrDie(env, keyphraseClass);
    gKeyphraseFields.id = GetFieldIDOrDie(env, keyphraseClass, "id", "I");
    gKeyphraseFields.recognitionModes = GetFieldIDOrDie(env, keyphraseClass, "recognitionModes",
                                                        "I");
    gKeyphraseFields.locale = GetFieldIDOrDie(env, keyphraseClass, "locale", "Ljava/lang/String;");
    gKeyphraseFields.text = GetFieldIDOrDie(env, keyphraseClass, "text", "Ljava/lang/String;");
    gKeyphraseFields.users = GetFieldIDOrDie(env, keyphraseClass, "users", "[I");

    jclass keyphraseSoundModelClass = FindClassOrDie(env, kKeyphraseSoundModelClassPathName);
    gKeyphraseSoundModelClass = MakeGlobalRefOrDie(env, keyphraseSoundModelClass);
    gKeyphraseSoundModelFields.keyphrases = GetFieldIDOrDie(env, keyphraseSoundModelClass,
                                         "keyphrases",
                                         "[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;");

    jclass recognitionEventClass = FindClassOrDie(env, kRecognitionEventClassPathName);
    gRecognitionEventClass = MakeGlobalRefOrDie(env, recognitionEventClass);
    gRecognitionEventCstor = GetMethodIDOrDie(env, recognitionEventClass, "<init>",
                                              "(IIZIIIZLandroid/media/AudioFormat;[B)V");

    jclass keyphraseRecognitionEventClass = FindClassOrDie(env,
                                                           kKeyphraseRecognitionEventClassPathName);
    gKeyphraseRecognitionEventClass = MakeGlobalRefOrDie(env, keyphraseRecognitionEventClass);
    gKeyphraseRecognitionEventCstor = GetMethodIDOrDie(env, keyphraseRecognitionEventClass, "<init>",
              "(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V");


    jclass keyRecognitionConfigClass = FindClassOrDie(env, kRecognitionConfigClassPathName);
    gRecognitionConfigClass = MakeGlobalRefOrDie(env, keyRecognitionConfigClass);
    gRecognitionConfigFields.captureRequested = GetFieldIDOrDie(env, keyRecognitionConfigClass,
                                                                "captureRequested", "Z");
    gRecognitionConfigFields.keyphrases = GetFieldIDOrDie(env, keyRecognitionConfigClass,
           "keyphrases", "[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;");
    gRecognitionConfigFields.data = GetFieldIDOrDie(env, keyRecognitionConfigClass, "data", "[B");

    jclass keyphraseRecognitionExtraClass = FindClassOrDie(env,
                                                           kKeyphraseRecognitionExtraClassPathName);
    gKeyphraseRecognitionExtraClass = MakeGlobalRefOrDie(env, keyphraseRecognitionExtraClass);
    gKeyphraseRecognitionExtraCstor = GetMethodIDOrDie(env, keyphraseRecognitionExtraClass,
            "<init>", "(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V");
    gKeyphraseRecognitionExtraFields.id = GetFieldIDOrDie(env, gKeyphraseRecognitionExtraClass,
                                                          "id", "I");
    gKeyphraseRecognitionExtraFields.recognitionModes = GetFieldIDOrDie(env,
            gKeyphraseRecognitionExtraClass, "recognitionModes", "I");
    gKeyphraseRecognitionExtraFields.coarseConfidenceLevel = GetFieldIDOrDie(env,
            gKeyphraseRecognitionExtraClass, "coarseConfidenceLevel", "I");
    gKeyphraseRecognitionExtraFields.confidenceLevels = GetFieldIDOrDie(env,
            gKeyphraseRecognitionExtraClass, "confidenceLevels",
            "[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;");

    jclass confidenceLevelClass = FindClassOrDie(env, kConfidenceLevelClassPathName);
    gConfidenceLevelClass = MakeGlobalRefOrDie(env, confidenceLevelClass);
    gConfidenceLevelCstor = GetMethodIDOrDie(env, confidenceLevelClass, "<init>", "(II)V");
    gConfidenceLevelFields.userId = GetFieldIDOrDie(env, confidenceLevelClass, "userId", "I");
    gConfidenceLevelFields.confidenceLevel = GetFieldIDOrDie(env, confidenceLevelClass,
                                                             "confidenceLevel", "I");

    jclass audioFormatClass = FindClassOrDie(env, kAudioFormatClassPathName);
    gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
    gAudioFormatCstor = GetMethodIDOrDie(env, audioFormatClass, "<init>", "(IIII)V");

    jclass soundModelEventClass = FindClassOrDie(env, kSoundModelEventClassPathName);
    gSoundModelEventClass = MakeGlobalRefOrDie(env, soundModelEventClass);
    gSoundModelEventCstor = GetMethodIDOrDie(env, soundModelEventClass, "<init>", "(II[B)V");


    RegisterMethodsOrDie(env, kSoundTriggerClassPathName, gMethods, NELEM(gMethods));
    return RegisterMethodsOrDie(env, kModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
}
