/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <android/log.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "webrtc/voice_engine/test/android/android_test/jni/org_webrtc_voiceengine_test_AndroidTest.h"

#include "webrtc/base/platform_thread.h"

#include "webrtc/voice_engine/include/voe_audio_processing.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"

#include "webrtc/voice_engine/test/auto_test/voe_test_interface.h"

//#define INIT_FROM_THREAD
//#define START_CALL_FROM_THREAD

#define WEBRTC_LOG_TAG "*WEBRTCN*" // As in WEBRTC Native...
#define VALIDATE_BASE_POINTER \
    if (!veData1.base) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Base pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_CODEC_POINTER \
    if (!veData1.codec) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Codec pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_FILE_POINTER \
    if (!veData1.file) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "File pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_NETWORK_POINTER \
    if (!veData1.netw) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Network pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_APM_POINTER \
    if (!veData1.codec) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Apm pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_VOLUME_POINTER \
    if (!veData1.volume) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Volume pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_HARDWARE_POINTER \
    if (!veData1.hardware) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Hardware pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_RTP_RTCP_POINTER \
    if (!veData1.rtp_rtcp) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "RTP / RTCP pointer doesn't exist"); \
        return -1; \
    }

// Register functions in JNI_OnLoad()
// How do we ensure that VoE is deleted? JNI_OnUnload?
// What happens if class is unloaded? When loaded again, NativeInit will be
// called again. Keep what we have?
// Should we do something in JNI_OnUnload?
// General design: create a class or keep global struct with "C" functions?
// Otherwise make sure symbols are as unique as possible.

// TestType enumerator
enum TestType
{
  Invalid = -1,
  Standard = 0,
  Extended = 1,
  Stress   = 2,
  Unit     = 3,
  CPU      = 4
};

using namespace webrtc;

class my_transportation;

// VoiceEngine data struct
typedef struct
{
    // VoiceEngine
    VoiceEngine* ve;
    // Sub-APIs
    VoEBase* base;
    VoECodec* codec;
    VoEFile* file;
    VoENetwork* netw;
    VoEAudioProcessing* apm;
    VoEVolumeControl* volume;
    VoEHardware* hardware;
    VoERTP_RTCP* rtp_rtcp;
    // Other
    my_transportation* extTrans;
    JavaVM* jvm;
} VoiceEngineData;

// my_transportation is used when useExtTrans is enabled
class my_transportation : public Transport
{
 public:
  my_transportation(VoENetwork * network) :
      netw(network) {
  }

  int SendPacket(int channel, const void* data, size_t len) override;
  int SendRTCPPacket(int channel, const void* data, size_t len) override;

 private:
  VoENetwork * netw;
};

int my_transportation::SendPacket(int channel, const void *data, size_t len)
{
  netw->ReceivedRTPPacket(channel, data, len);
  return len;
}

int my_transportation::SendRTCPPacket(int channel, const void *data, size_t len)
{
  netw->ReceivedRTCPPacket(channel, data, len);
  return len;
}

//Global variables visible in this file
static VoiceEngineData veData1;
static VoiceEngineData veData2;

// "Local" functions (i.e. not Java accessible)
static bool GetSubApis(VoiceEngineData &veData);
static bool ReleaseSubApis(VoiceEngineData &veData);

class ThreadTest
{
public:
    ThreadTest();
    ~ThreadTest();
    int RunTest();
    int CloseTest();
private:
    static bool Run(void* ptr);
    bool Process();
private:
    rtc::PlatformThread _thread;
};

ThreadTest::~ThreadTest()
{
    if (_thread)
        _thread->Stop();
}

ThreadTest::ThreadTest()
{
    _thread(Run, this, "ThreadTest thread");
}

bool ThreadTest::Run(void* ptr)
{
    return static_cast<ThreadTest*> (ptr)->Process();
}

bool ThreadTest::Process()
{
    // Attach this thread to JVM
    /*JNIEnv* env = NULL;
     jint res = veData1.jvm->AttachCurrentThread(&env, NULL);
     char msg[32];
     sprintf(msg, "res=%d, env=%d", res, env);
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, msg);*/

#ifdef INIT_FROM_THREAD
    VALIDATE_BASE_POINTER;
    veData1.base->Init();
#endif

#ifdef START_CALL_FROM_THREAD
    // receiving instance
    veData2.ve = VoiceEngine::Create();
    GetSubApis(veData2);
    veData2.base->Init();
    veData2.base->CreateChannel();
    if(veData2.base->SetLocalReceiver(0, 1234) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "set local receiver 2 failed");
    }
    veData2.volume->SetSpeakerVolume(204);
    veData2.base->StartReceive(0);
    if(veData2.base->StartPlayout(0) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "start playout failed");
    }

    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
            "receiving instance started from thread");

    // sending instance
    veData1.ve = VoiceEngine::Create();
    GetSubApis(veData1);
    veData1.base->Init();
    if(veData1.base->CreateChannel() < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "create channel failed");
    }
    if(veData1.base->SetLocalReceiver(0, 1256) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "set local receiver failed");
    }
    if(veData1.base->SetSendDestination(0, 1234, "127.0.0.1") < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "set send destination failed");
    }
    if(veData1.base->StartSend(0) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "start send failed");
    }

    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
            "sending instance started from thread");
#endif

    _thread->Stop();

    //res = veData1.jvm->DetachCurrentThread();

    return true;
}

int ThreadTest::RunTest()
{
    if (_thread)
    {
        _thread->Start();
    }
    return 0;
}

int ThreadTest::CloseTest()
{
    VALIDATE_BASE_POINTER

    veData1.base->DeleteChannel(0);
    veData2.base->DeleteChannel(0);
    veData1.base->Terminate();
    veData2.base->Terminate();

    // Release sub-APIs
    ReleaseSubApis(veData1);
    ReleaseSubApis(veData2);

    // Delete
    VoiceEngine::Delete(veData1.ve);
    VoiceEngine::Delete(veData2.ve);
    veData2.ve = NULL;
    veData2.ve = NULL;

    return 0;
}

ThreadTest threadTest;

//////////////////////////////////////////////////////////////////
// General functions
//////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// JNI_OnLoad
//
jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
{
    if (!vm)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "JNI_OnLoad did not receive a valid VM pointer");
        return -1;
    }

    // Get JNI
    JNIEnv* env;
    if (JNI_OK != vm->GetEnv(reinterpret_cast<void**> (&env),
                             JNI_VERSION_1_4))
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "JNI_OnLoad could not get JNI env");
        return -1;
    }

    // Get class to register the native functions with
    // jclass regClass = env->FindClass("webrtc/android/AndroidTest");
    // if (!regClass) {
    // return -1; // Exception thrown
    // }

    // Register native functions
    // JNINativeMethod methods[1];
    // methods[0].name = NULL;
    // methods[0].signature = NULL;
    // methods[0].fnPtr = NULL;
    // if (JNI_OK != env->RegisterNatives(regClass, methods, 1))
    // {
    // return -1;
    // }

    // Init VoiceEngine data
    memset(&veData1, 0, sizeof(veData1));
    memset(&veData2, 0, sizeof(veData2));

    // Store the JVM
    veData1.jvm = vm;
    veData2.jvm = vm;

    return JNI_VERSION_1_4;
}

/////////////////////////////////////////////
// Native initialization
//
JNIEXPORT jboolean JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_NativeInit(
        JNIEnv * env,
        jclass)
{
    // Look up and cache any interesting class, field and method IDs for
    // any used java class here

    return true;
}

/////////////////////////////////////////////
// Run auto standard test
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_RunAutoTest(
        JNIEnv *env,
        jobject context,
        jint testType,
        jint extendedSel)
{
    TestType tType(Invalid);

    switch (testType)
    {
        case 0:
            return 0;
        case 1:
            tType = Standard;
            break;
        case 2:
            tType = Extended;
            break;
        case 3:
            tType = Stress;
            break;
        case 4:
            tType = Unit;
            break;
        default:
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "RunAutoTest - Invalid TestType");
            return -1;
    }

    // Set instance independent Java objects
    VoiceEngine::SetAndroidObjects(veData1.jvm, env, context);

    // Call voe test interface function
    // TODO(leozwang) add autotest setAndroidObjects(veData1.jvm, context);
    // jint retVal = runAutoTest(tType);

    // Clear instance independent Java objects
    VoiceEngine::SetAndroidObjects(NULL, NULL, NULL);

    return 0;
}

//////////////////////////////////////////////////////////////////
// VoiceEngine API wrapper functions
//////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// Create VoiceEngine instance
//
JNIEXPORT jboolean JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Create(
        JNIEnv *env,
        jobject context)
{
    // Check if already created
    if (veData1.ve)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "VoE already created");
        return false;
    }

    // Set instance independent Java objects
    VoiceEngine::SetAndroidObjects(veData1.jvm, env, context);

#ifdef START_CALL_FROM_THREAD
    threadTest.RunTest();
#else
    // Create
    veData1.ve = VoiceEngine::Create();
    if (!veData1.ve)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Create VoE failed");
        return false;
    }

    // Get sub-APIs
    if (!GetSubApis(veData1))
    {
        // If not OK, release all sub-APIs and delete VoE
        ReleaseSubApis(veData1);
        if (!VoiceEngine::Delete(veData1.ve))
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Delete VoE failed");
        }
        return false;
    }
#endif

    return true;
}

/////////////////////////////////////////////
// Delete VoiceEngine instance
//
JNIEXPORT jboolean JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Delete(
        JNIEnv *,
        jobject)
{
#ifdef START_CALL_FROM_THREAD
    threadTest.CloseTest();
#else
    // Check if exists
    if (!veData1.ve)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "VoE does not exist");
        return false;
    }

    // Release sub-APIs
    ReleaseSubApis(veData1);

    // Delete
    if (!VoiceEngine::Delete(veData1.ve))
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Delete VoE failed");
        return false;
    }

    veData1.ve = NULL;
#endif

    // Clear instance independent Java objects
    VoiceEngine::SetAndroidObjects(NULL, NULL, NULL);

    return true;
}

/////////////////////////////////////////////
// [Base] Initialize VoiceEngine
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Init(
        JNIEnv *,
        jobject,
        jboolean enableTrace,
        jboolean useExtTrans)
{
    VALIDATE_BASE_POINTER;

    if (enableTrace)
    {
        if (0 != VoiceEngine::SetTraceFile("/sdcard/trace.txt"))
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Could not enable trace");
        }
        if (0 != VoiceEngine::SetTraceFilter(kTraceAll))
        {
            __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG,
                                "Could not set trace filter");
        }
    }

    if (useExtTrans)
    {
        VALIDATE_NETWORK_POINTER;
        veData1.extTrans = new my_transportation(veData1.netw);
    }

    int retVal = 0;
#ifdef INIT_FROM_THREAD
    threadTest.RunTest();
    usleep(200000);
#else
    retVal = veData1.base->Init();
#endif
    return retVal;
}

/////////////////////////////////////////////
// [Base] Terminate VoiceEngine
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Terminate(
        JNIEnv *,
        jobject)
{
    VALIDATE_BASE_POINTER;

    jint retVal = veData1.base->Terminate();

    delete veData1.extTrans;
    veData1.extTrans = NULL;

    return retVal;
}

/////////////////////////////////////////////
// [Base] Create channel
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_CreateChannel(
        JNIEnv *,
        jobject)
{
    VALIDATE_BASE_POINTER;
    jint channel = veData1.base->CreateChannel();

    if (veData1.extTrans)
    {
        VALIDATE_NETWORK_POINTER;
        __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
                            "Enabling external transport on channel %d",
                            channel);
        if (veData1.netw->RegisterExternalTransport(channel, *veData1.extTrans)
                < 0)
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Could not set external transport");
            return -1;
        }
    }

    return channel;
}

/////////////////////////////////////////////
// [Base] Delete channel
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_DeleteChannel(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->DeleteChannel(channel);
}

/////////////////////////////////////////////
// [Base] SetLocalReceiver
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetLocalReceiver(
        JNIEnv *,
        jobject,
        jint channel,
        jint port)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->SetLocalReceiver(channel, port);
}

/////////////////////////////////////////////
// [Base] SetSendDestination
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetSendDestination(
        JNIEnv *env,
        jobject,
        jint channel,
        jint port,
        jstring ipaddr)
{
    VALIDATE_BASE_POINTER;

    const char* ipaddrNative = env->GetStringUTFChars(ipaddr, NULL);
    if (!ipaddrNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.base->SetSendDestination(channel, port, ipaddrNative);

    env->ReleaseStringUTFChars(ipaddr, ipaddrNative);

    return retVal;
}

/////////////////////////////////////////////
// [Base] StartListen
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartListen(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    int retVal = veData1.base->StartReceive(channel);

    return retVal;
}

/////////////////////////////////////////////
// [Base] Start playout
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayout(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    int retVal = veData1.base->StartPlayout(channel);

    return retVal;
}

/////////////////////////////////////////////
// [Base] Start send
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartSend(
        JNIEnv *,
        jobject,
        jint channel)
{
    /*    int dscp(0), serviceType(-1), overrideDscp(0), res(0);
     bool gqosEnabled(false), useSetSockOpt(false);

     if (veData1.netw->SetSendTOS(channel, 13, useSetSockOpt) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to set TOS");
     return -1;
     }

     res = veData1.netw->GetSendTOS(channel, dscp, useSetSockOpt);
     if (res != 0 || dscp != 13 || useSetSockOpt != true)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to get TOS");
     return -1;
     } */

    /* if (veData1.rtp_rtcp->SetREDStatus(channel, 1) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to enable RED");
     return -1;
     } */

    VALIDATE_BASE_POINTER;
    int retVal = veData1.base->StartSend(channel);

    return retVal;
}

/////////////////////////////////////////////
// [Base] Stop listen
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopListen(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->StopReceive(channel);
}

/////////////////////////////////////////////
// [Base] Stop playout
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayout(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->StopPlayout(channel);
}

/////////////////////////////////////////////
// [Base] Stop send
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopSend(
        JNIEnv *,
        jobject,
        jint channel)
{
    /* if (veData1.rtp_rtcp->SetREDStatus(channel, 0) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to disable RED");
     return -1;
     } */

    VALIDATE_BASE_POINTER;
    return veData1.base->StopSend(channel);
}

/////////////////////////////////////////////
// [codec] Number of codecs
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_NumOfCodecs(
        JNIEnv *,
        jobject)
{
    VALIDATE_CODEC_POINTER;
    return veData1.codec->NumOfCodecs();
}

/////////////////////////////////////////////
// [codec] Set send codec
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetSendCodec(
        JNIEnv *,
        jobject,
        jint channel,
        jint index)
{
    VALIDATE_CODEC_POINTER;

    CodecInst codec;

    if (veData1.codec->GetCodec(index, codec) != 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Failed to get codec");
        return -1;
    }

    return veData1.codec->SetSendCodec(channel, codec);
}

/////////////////////////////////////////////
// [codec] Set VAD status
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetVADStatus(
        JNIEnv *,
        jobject,
        jint channel,
        jboolean enable,
        jint mode)
{
    VALIDATE_CODEC_POINTER;

    VadModes VADmode = kVadConventional;

    switch (mode)
    {
        case 0:
            break; // already set
        case 1:
            VADmode = kVadAggressiveLow;
            break;
        case 2:
            VADmode = kVadAggressiveMid;
            break;
        case 3:
            VADmode = kVadAggressiveHigh;
            break;
        default:
            VADmode = (VadModes) 17; // force error
            break;
    }

    return veData1.codec->SetVADStatus(channel, enable, VADmode);
}

/////////////////////////////////////////////
// [apm] SetNSStatus
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_SetNSStatus(
        JNIEnv *,
        jobject,
        jboolean enable,
        jint mode)
{
    VALIDATE_APM_POINTER;

    NsModes NSmode = kNsDefault;

    switch (mode)
    {
        case 0:
            NSmode = kNsUnchanged;
            break;
        case 1:
            break; // already set
        case 2:
            NSmode = kNsConference;
            break;
        case 3:
            NSmode = kNsLowSuppression;
            break;
        case 4:
            NSmode = kNsModerateSuppression;
            break;
        case 5:
            NSmode = kNsHighSuppression;
            break;
        case 6:
            NSmode = kNsVeryHighSuppression;
            break;
        default:
            NSmode = (NsModes) 17; // force error
            break;
    }

    return veData1.apm->SetNsStatus(enable, NSmode);
}

/////////////////////////////////////////////
// [apm] SetAGCStatus
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetAGCStatus(
        JNIEnv *,
        jobject,
        jboolean enable,
        jint mode)
{
    VALIDATE_APM_POINTER;

    AgcModes AGCmode = kAgcDefault;

    switch (mode)
    {
        case 0:
            AGCmode = kAgcUnchanged;
            break;
        case 1:
            break; // already set
        case 2:
            AGCmode = kAgcAdaptiveAnalog;
            break;
        case 3:
            AGCmode = kAgcAdaptiveDigital;
            break;
        case 4:
            AGCmode = kAgcFixedDigital;
            break;
        default:
            AGCmode = (AgcModes) 17; // force error
            break;
    }

    /* AgcConfig agcConfig;
     agcConfig.targetLeveldBOv = 3;
     agcConfig.digitalCompressionGaindB = 50;
     agcConfig.limiterEnable = 0;

     if (veData1.apm->SetAGCConfig(agcConfig) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to set AGC config");
     return -1;
     } */

    return veData1.apm->SetAgcStatus(enable, AGCmode);
}

/////////////////////////////////////////////
// [apm] SetECStatus
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_SetECStatus(
        JNIEnv *,
        jobject,
        jboolean enable,
        jint mode)
{
    VALIDATE_APM_POINTER;

    EcModes ECmode = kEcDefault;

    switch (mode)
    {
        case 0:
            ECmode = kEcDefault;
            break;
        case 1:
            break; // already set
        case 2:
            ECmode = kEcConference;
            break;
        case 3:
            ECmode = kEcAec;
            break;
        case 4:
            ECmode = kEcAecm;
            break;
        default:
            ECmode = (EcModes) 17; // force error
            break;
    }

    return veData1.apm->SetEcStatus(enable, ECmode);
}

/////////////////////////////////////////////
// [File] Start play file locally
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayingFileLocally(
        JNIEnv * env,
        jobject,
        jint channel,
        jstring fileName,
        jboolean loop)
{
    VALIDATE_FILE_POINTER;

    const char* fileNameNative = env->GetStringUTFChars(fileName, NULL);
    if (!fileNameNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.file->StartPlayingFileLocally(channel,
                                                        fileNameNative, loop);

    env->ReleaseStringUTFChars(fileName, fileNameNative);

    return retVal;
}

/////////////////////////////////////////////
// [File] Stop play file locally
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayingFileLocally(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_FILE_POINTER;
    return veData1.file->StopPlayingFileLocally(channel);
}

/*
 * Class:     org_webrtc_voiceengine_test_AndroidTest
 * Method:    StartRecordingPlayout
 * Signature: (ILjava/lang/String;Z)I
 */
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartRecordingPlayout(
        JNIEnv * env,
        jobject,
        jint channel,
        jstring fileName,
        jboolean)
{
    VALIDATE_FILE_POINTER;

    const char* fileNameNative = env->GetStringUTFChars(fileName, NULL);
    if (!fileNameNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.file->StartRecordingPlayout(channel, fileNameNative,
                                                      0);

    env->ReleaseStringUTFChars(fileName, fileNameNative);

    return retVal;
}

/////////////////////////////////////////////
// [File] Stop Recording Playout
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StopRecordingPlayout(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_FILE_POINTER;
    return veData1.file->StopRecordingPlayout(channel);
}

/////////////////////////////////////////////
// [File] Start playing file as microphone
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayingFileAsMicrophone(
        JNIEnv *env,
        jobject,
        jint channel,
        jstring fileName,
        jboolean loop)
{
    VALIDATE_FILE_POINTER;

    const char* fileNameNative = env->GetStringUTFChars(fileName, NULL);
    if (!fileNameNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.file->StartPlayingFileAsMicrophone(channel,
                                                             fileNameNative,
                                                             loop);

    env->ReleaseStringUTFChars(fileName, fileNameNative);

    return retVal;
}

/////////////////////////////////////////////
// [File] Stop playing file as microphone
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayingFileAsMicrophone(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_FILE_POINTER;
    return veData1.file->StopPlayingFileAsMicrophone(channel);
}

/////////////////////////////////////////////
// [Volume] Set speaker volume
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetSpeakerVolume(
        JNIEnv *,
        jobject,
        jint level)
{
    VALIDATE_VOLUME_POINTER;
    if (veData1.volume->SetSpeakerVolume(level) != 0)
    {
        return -1;
    }

    unsigned int storedVolume = 0;
    if (veData1.volume->GetSpeakerVolume(storedVolume) != 0)
    {
        return -1;
    }

    if (storedVolume != level)
    {
        return -1;
    }

    return 0;
}

//////////////////////////////////////////////////////////////////
// "Local" functions (i.e. not Java accessible)
//////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// Get all sub-APIs
//
bool GetSubApis(VoiceEngineData &veData)
{
    bool getOK = true;

    // Base
    veData.base = VoEBase::GetInterface(veData.ve);
    if (!veData.base)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get base sub-API failed");
        getOK = false;
    }

    // Codec
    veData.codec = VoECodec::GetInterface(veData.ve);
    if (!veData.codec)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get codec sub-API failed");
        getOK = false;
    }

    // File
    veData.file = VoEFile::GetInterface(veData.ve);
    if (!veData.file)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get file sub-API failed");
        getOK = false;
    }

    // Network
    veData.netw = VoENetwork::GetInterface(veData.ve);
    if (!veData.netw)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get network sub-API failed");
        getOK = false;
    }

    // AudioProcessing module
    veData.apm = VoEAudioProcessing::GetInterface(veData.ve);
    if (!veData.apm)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get apm sub-API failed");
        getOK = false;
    }

    // Volume
    veData.volume = VoEVolumeControl::GetInterface(veData.ve);
    if (!veData.volume)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get volume sub-API failed");
        getOK = false;
    }

    // Hardware
    veData.hardware = VoEHardware::GetInterface(veData.ve);
    if (!veData.hardware)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get hardware sub-API failed");
        getOK = false;
    }

    // RTP / RTCP
    veData.rtp_rtcp = VoERTP_RTCP::GetInterface(veData.ve);
    if (!veData.rtp_rtcp)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get rtp_rtcp sub-API failed");
        getOK = false;
    }

    return getOK;
}

/////////////////////////////////////////////
// Release all sub-APIs
//
bool ReleaseSubApis(VoiceEngineData &veData)
{
    bool releaseOK = true;

    // Base
    if (veData.base)
    {
        if (0 != veData.base->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release base sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.base = NULL;
        }
    }

    // Codec
    if (veData.codec)
    {
        if (0 != veData.codec->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release codec sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.codec = NULL;
        }
    }

    // File
    if (veData.file)
    {
        if (0 != veData.file->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release file sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.file = NULL;
        }
    }

    // Network
    if (veData.netw)
    {
        if (0 != veData.netw->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release network sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.netw = NULL;
        }
    }

    // apm
    if (veData.apm)
    {
        if (0 != veData.apm->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release apm sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.apm = NULL;
        }
    }

    // Volume
    if (veData.volume)
    {
        if (0 != veData.volume->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release volume sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.volume = NULL;
        }
    }

    // Hardware
    if (veData.hardware)
    {
        if (0 != veData.hardware->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release hardware sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.hardware = NULL;
        }
    }

    // RTP RTCP
    if (veData.rtp_rtcp)
    {
        if (0 != veData.rtp_rtcp->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release rtp_rtcp sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.rtp_rtcp = NULL;
        }
    }

    return releaseOK;
}
