change android test app folder name
Review URL: http://webrtc-codereview.appspot.com/37003

git-svn-id: http://webrtc.googlecode.com/svn/trunk@65 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/Android.mk b/Android.mk
index 3b61bfd..be7c658 100644
--- a/Android.mk
+++ b/Android.mk
@@ -57,5 +57,5 @@
 #include $(MY_WEBRTC_ROOT_PATH)/modules/audio_processing/main/test/process_test/Android.mk
 #include $(MY_WEBRTC_ROOT_PATH)/voice_engine/main/test/ui_linux_test/Android.mk
 #include $(MY_WEBRTC_ROOT_PATH)/voice_engine/main/test/auto_test/Android.mk
-#include $(MY_WEBRTC_ROOT_PATH)/video_engine/main/test/AutoTest/Android/Android.mk
-#include $(MY_WEBRTC_ROOT_PATH)/video_engine/main/test/AndroidTest/Android.mk
+#include $(MY_WEBRTC_ROOT_PATH)/video_engine/main/test/AutoTest/android/Android.mk
+#include $(MY_WEBRTC_ROOT_PATH)/video_engine/main/test/android_test/Android.mk
diff --git a/video_engine/main/test/AndroidTest/jni/vie_android_java_api.cc b/video_engine/main/test/AndroidTest/jni/vie_android_java_api.cc
deleted file mode 100644
index f6c7102..0000000
--- a/video_engine/main/test/AndroidTest/jni/vie_android_java_api.cc
+++ /dev/null
@@ -1,1754 +0,0 @@
-/*
- *  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 <stdio.h>
-#include <string.h>
-#include <android/log.h>
-
-#include "org_webrtc_videoengineapp_vie_android_java_api.h"
-
-#include "voe_base.h"
-#include "voe_codec.h"
-#include "voe_file.h"
-#include "voe_network.h"
-#include "voe_audio_processing.h"
-#include "voe_volume_control.h"
-#include "voe_hardware.h"
-
-#include "vie_base.h"
-#include "vie_codec.h"
-#include "vie_capture.h"
-#include "vie_network.h"
-#include "vie_render.h"
-#include "vie_rtp_rtcp.h"
-
-#include "common_types.h"
-
-#define WEBRTC_LOG_TAG "*WEBRTCN*"
-#define VALIDATE_BASE_POINTER \
-    if (!veData.base) \
-    { \
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Base pointer doesn't exist"); \
-        return -1; \
-    }
-#define VALIDATE_CODEC_POINTER \
-    if (!veData.codec) \
-    { \
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Codec pointer doesn't exist"); \
-        return -1; \
-    }
-#define VALIDATE_FILE_POINTER \
-    if (!veData.file) \
-    { \
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "File pointer doesn't exist"); \
-        return -1; \
-    }
-#define VALIDATE_APM_POINTER \
-    if (!veData.codec) \
-    { \
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Apm pointer doesn't exist"); \
-        return -1; \
-    }
-#define VALIDATE_HARDWARE_POINTER \
-    if (!veData.hardware) \
-    { \
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Hardware pointer doesn't exist"); \
-        return -1; \
-    }
-#define VALIDATE_VOLUME_POINTER \
-    if (!veData.volume) \
-    { \
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Volume pointer doesn't exist"); \
-        return -1; \
-    }
-
-using namespace webrtc;
-
-//Forward declaration.
-class VideoCallbackAndroid;
-
-// VoiceEngine data struct
-typedef struct
-{
-    // VoiceEngine
-    VoiceEngine* ve;
-    // Sub-APIs
-    VoEBase* base;
-    VoECodec* codec;
-    VoEFile* file;
-    VoENetwork* netw;
-    VoEAudioProcessing* apm;
-    VoEVolumeControl* volume;
-    VoEHardware* hardware;
-    JavaVM* jvm;
-} VoiceEngineData;
-
-class AndroidVideoRenderCallback;
-// VideoEngine data struct
-typedef struct
-{
-    VideoEngine* vie;
-    ViEBase* base;
-    ViECodec* codec;
-    ViENetwork* netw;
-    ViERTP_RTCP* rtp;
-    ViERender* render;
-    ViECapture* capture;
-    VideoCallbackAndroid* callback;
-
-} VideoEngineData;
-
-// Global variables
-JavaVM* webrtcGlobalVM;
-
-// Global variables visible in this file
-static VoiceEngineData veData;
-static VideoEngineData vieData;
-
-// "Local" functions (i.e. not Java accessible)
-#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 1024
-static bool VE_GetSubApis();
-static bool VE_ReleaseSubApis();
-
-#define CHECK_API_RETURN(ret) \
-    if (ret!=0) \
-    { \
-        __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Return error %d",ret); \
-        break; \
-    }
-
-class VideoCallbackAndroid: public ViEDecoderObserver,
-    public ViEEncoderObserver
-{
-
-    // Implements ViEDecoderObserver
-    virtual void IncomingRate(const int videoChannel,
-                              const unsigned int framerate,
-                              const unsigned int bitrate)
-    {
-        //Let's print out the network statistics from this call back as well
-        unsigned short fraction_lost;
-        unsigned int dummy;
-        int intdummy;
-        _vieData.rtp->GetReceivedRTCPStatistics(videoChannel, fraction_lost,
-                                                dummy, dummy, dummy, intdummy);
-        unsigned short packetLossRate = 0;
-        if (fraction_lost > 0)
-        {
-            // Change from frac to %
-            packetLossRate = (fraction_lost * 100) >> 8;
-        }
-
-        JNIEnv* threadEnv = NULL;
-        int ret = webrtcGlobalVM->AttachCurrentThread(&threadEnv, NULL);
-        // Get the JNI env for this thread
-        if ((ret < 0) || !threadEnv)
-        {
-            __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                                "Could not attach thread to JVM (%d, %p)", ret,
-                                threadEnv);
-            return;
-        }
-        threadEnv->CallIntMethod(_callbackObj, _callbackId, framerate, bitrate,
-                                 packetLossRate, _frameRateO, _bitRateO);
-        webrtcGlobalVM->DetachCurrentThread();
-    }
-    ;
-
-    virtual void IncomingCodecChanged(const int videoChannel,
-                                      const webrtc::VideoCodec& videoCodec)
-    {
-    }
-    ;
-
-    virtual void RequestNewKeyFrame(const int videoChannel)
-    {
-    }
-    ;
-
-    virtual void OutgoingRate(const int videoChannel,
-                              const unsigned int framerate,
-                              const unsigned int bitrate)
-    {
-        _frameRateO = framerate;
-        _bitRateO = bitrate;
-        //__android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SendRate frameRate %d bitrate %d\n",frameRate,bitrate);
-    }
-    ;
-
-public:
-    VideoEngineData& _vieData;
-    JNIEnv * _env;
-    jobject _callbackObj;
-    jclass _callbackCls;
-    jmethodID _callbackId;
-    int _frameRateO, _bitRateO;
-    VideoCallbackAndroid(VideoEngineData& vieData, JNIEnv * env,
-                         jobject callback) :
-        _vieData(vieData), _env(env), _callbackObj(callback), _frameRateO(0),
-            _bitRateO(0)
-    {
-        _callbackCls = _env->GetObjectClass(_callbackObj);
-        _callbackId
-            = _env->GetMethodID(_callbackCls, "UpdateStats", "(IIIII)I");
-        if (_callbackId == NULL)
-        {
-            __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to get jid");
-        }
-        _callbackObj = _env->NewGlobalRef(_callbackObj);
-    }
-};
-
-//////////////////////////////////////////////////////////////////
-// General functions
-//////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////
-// JNI_OnLoad
-jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
-{
-    webrtcGlobalVM = vm;
-    if (!webrtcGlobalVM)
-    {
-        __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;
-    }
-
-    // Init VoiceEngine data
-    memset(&veData, 0, sizeof(veData));
-    // Store the JVM
-    veData.jvm = vm;
-
-    // Init VideoEngineData data
-    memset(&vieData, 0, sizeof(vieData));
-
-    return JNI_VERSION_1_4;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    NativeInit
- * Signature: (Landroid/content/Context;)Z
- */
-JNIEXPORT jboolean JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_NativeInit(
-                                                               JNIEnv * env,
-                                                               jobject,
-                                                               jobject context)
-{
-
-    return true;
-}
-
-//////////////////////////////////////////////////////////////////
-// VideoEngine API wrapper functions
-//////////////////////////////////////////////////////////////////
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    GetVideoEngine
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_GetVideoEngine(
-                                                               JNIEnv *,
-                                                               jobject context)
-{
-
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "GetVideoEngine");
-
-    VideoEngine::SetAndroidObjects(webrtcGlobalVM, context);
-
-    // Check if already got 
-    if (vieData.vie)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "ViE already got");
-        return -1;
-    }
-
-    // Create
-    vieData.vie = VideoEngine::Create();
-    if (!vieData.vie)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Get ViE failed");
-        return -1;
-    }
-    vieData.base = ViEBase::GetInterface(vieData.vie);
-    if (!vieData.base)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get base sub-API failed");
-        return -1;
-    }
-
-    vieData.codec = ViECodec::GetInterface(vieData.vie);
-    if (!vieData.codec)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get codec sub-API failed");
-        return -1;
-    }
-
-    vieData.netw = ViENetwork::GetInterface(vieData.vie);
-    if (!vieData.netw)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get network sub-API failed");
-        return -1;
-    }
-
-    vieData.rtp = ViERTP_RTCP::GetInterface(vieData.vie);
-    if (!vieData.rtp)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get RTP sub-API failed");
-        return -1;
-    }
-
-    vieData.render = ViERender::GetInterface(vieData.vie);
-    if (!vieData.render)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get Render sub-API failed");
-        return -1;
-    }
-    vieData.capture = ViECapture::GetInterface(vieData.vie);
-    if (!vieData.capture)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get Capture sub-API failed");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    Init
- * Signature: (IIIZ)I
- */
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_Init(
-                                                                  JNIEnv *,
-                                                                  jobject,
-                                                                  jboolean enableTrace)
-{
-    if (vieData.vie)
-    {
-        __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "Init");
-
-        int ret = vieData.base->Init();
-        __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "Init return %d", ret);
-        if (enableTrace)
-        {
-            __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                                "SetTraceFile");
-            if (0 != vieData.vie->SetTraceFile(("/sdcard/trace.txt"), false))
-            {
-                __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                    "Video Engine could not enable trace");
-            }
-
-            __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                                "SetTraceFilter");
-            if (0 != vieData.vie->SetTraceFilter(webrtc::kTraceDefault))
-            {
-                __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG,
-                                    "Could not set trace filter");
-            }
-        }
-        else
-        {
-            if (0 != vieData.vie->SetTraceFilter(webrtc::kTraceNone))
-            {
-                __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG,
-                                    "Could not set trace filter");
-            }
-        }
-        if (veData.ve) // VoiceEngine is enabled
-        {
-            __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                                "SetVoiceEngine");
-            if (0 != vieData.base->SetVoiceEngine(veData.ve))
-            {
-                __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                                    "SetVoiceEngine failed");
-            }
-        }
-        return ret;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    Terminate
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_Terminate(
-                                                                       JNIEnv *,
-                                                                       jobject)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "Terminate");
-
-    if (vieData.vie)
-    {
-        if (!vieData.rtp || vieData.rtp->Release() != 0)
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to release RTP sub-API");
-
-        }
-        if (!vieData.netw || vieData.netw->Release() != 0)
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to release Network sub-API");
-
-        }
-        if (!vieData.codec || vieData.codec->Release() != 0)
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to release Codec sub-API");
-
-        }
-        if (!vieData.render || vieData.render->Release())
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to release Render sub-API");
-        }
-        if (!vieData.capture || vieData.capture->Release())
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to release Capture sub-API");
-        }
-
-        if (!vieData.base || vieData.base->Release() != 0)
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to release Base sub-API");
-        }
-        // Delete Vie
-        if (!VideoEngine::Delete(vieData.vie))
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Failed to delete ViE ");
-            return -1;
-        }
-        memset(&vieData, 0, sizeof(vieData));
-        VideoEngine::SetAndroidObjects(NULL, NULL);
-        return 0;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StartSend
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartSend(
-                                                                           JNIEnv *,
-                                                                           jobject,
-                                                                           jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartSend");
-
-    if (vieData.base)
-    {
-        int ret = vieData.base->StartSend(channel);
-        return ret;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StopRender
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopRender(
-                                                                            JNIEnv *,
-                                                                            jobject,
-                                                                            jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StopRender");
-
-    if (vieData.render)
-    {
-        return vieData.render->StopRender(channel);
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    Stop
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopSend(
-                                                                          JNIEnv *,
-                                                                          jobject,
-                                                                          jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StopSend");
-
-    if (vieData.base)
-    {
-        return vieData.base->StopSend(channel);
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StartReceive
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartReceive(
-                                                                              JNIEnv *,
-                                                                              jobject,
-                                                                              jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartReceive");
-
-    if (vieData.base)
-    {
-        return vieData.base->StartReceive(channel);
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StopReceive
- * Signature: ()I
- */
-
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopReceive(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StopReceive");
-    if (vieData.base)
-    {
-        return vieData.base->StopReceive(channel);
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    CreateChannel
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_CreateChannel(
-                                                               JNIEnv *,
-                                                               jobject,
-                                                               jint voiceChannel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "CreateChannel");
-
-    if (vieData.vie)
-    {
-        int channel = 0;
-        if (vieData.base->CreateChannel(channel) != 0)
-        {
-            return -1;
-        }
-        if (voiceChannel >= 0)
-        {
-            vieData.base->ConnectAudioChannel(channel, voiceChannel);
-        }
-
-        return channel;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    SetLocalReceiver
- * Signature: (II)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetLocalReceiver(
-                                                                      JNIEnv *,
-                                                                      jobject,
-                                                                      jint channel,
-                                                                      jint port)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetLocalReceiver");
-
-    if (vieData.vie)
-    {
-        int ret = vieData.netw->SetLocalReceiver(channel, port);
-        return ret;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    SetSendDestination
- * Signature: (II[B)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetSendDestination(
-                                                                JNIEnv * env,
-                                                                jobject,
-                                                                jint channel,
-                                                                jint port,
-                                                                jbyteArray ipadr)
-{
-
-    if (NULL == vieData.vie)
-        return -1;
-
-    char ip[64];
-    jsize len = env->GetArrayLength(ipadr);
-    if ((len >= 64) || (len == 0))
-        return -1;
-    env->GetByteArrayRegion(ipadr, 0, len, (jbyte*) ip);
-    ip[len] = '\0';
-
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                        "SetSendDestination: channel=%d, port=%d, ip=%s\n",
-                        channel, port, ip);
-
-    int ret = vieData.netw->SetSendDestination(channel, "127.0.0.1"/*ip*/, port);
-    return ret;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    SetReceiveCodec
- * Signature: (IIIIII)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetReceiveCodec(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jint channel,
-                                                                 jint codecNum,
-                                                                 jint intbitRate,
-                                                                 jint width,
-                                                                 jint height,
-                                                                 jint frameRate)
-{
-    if (NULL == vieData.codec)
-        return -1;
-
-    //Create codec
-    webrtc::VideoCodec codec;
-    vieData.codec->GetCodec(codecNum, codec);
-
-    __android_log_print(
-                        ANDROID_LOG_DEBUG,
-                        WEBRTC_LOG_TAG,
-                        "SetReceiveCodec %s, pltype=%d, bitRate=%d, maxBitRate=%d,"
-                        " width=%d, height=%d, frameRate=%d, codecSpecific=%d \n",
-                        codec.plName, codec.plType, codec.startBitrate,
-                        codec.maxBitrate, codec.width, codec.height,
-                        codec.maxFramerate, codec.codecSpecific);
-    int ret = vieData.codec->SetReceiveCodec(channel, codec);
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                        "SetReceiveCodec return %d", ret);
-    return ret;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    SetSendCodec
- * Signature: (IIIIII)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetSendCodec(
-                                                                  JNIEnv *,
-                                                                  jobject,
-                                                                  jint channel,
-                                                                  jint codecNum,
-                                                                  jint intbitRate,
-                                                                  jint width,
-                                                                  jint height,
-                                                                  jint frameRate)
-{
-    if (NULL == vieData.codec)
-        return -1;
-
-    //Create codec
-    webrtc::VideoCodec codec;
-    vieData.codec->GetCodec(codecNum, codec);
-    codec.startBitrate = intbitRate;
-    codec.maxBitrate = 600;
-    codec.width = width;
-    codec.height = height;
-    codec.maxFramerate = frameRate;
-
-    for (int i = 0; i < vieData.codec->NumberOfCodecs(); ++i)
-    {
-        webrtc::VideoCodec codecToList;
-        vieData.codec->GetCodec(i, codecToList);
-        __android_log_print(
-                            ANDROID_LOG_DEBUG,
-                            WEBRTC_LOG_TAG,
-                            "Codec list %s, pltype=%d, bitRate=%d, maxBitRate=%d,"
-                            " width=%d, height=%d, frameRate=%d\n",
-                            codecToList.plName, codecToList.plType,
-                            codecToList.startBitrate, codecToList.maxBitrate,
-                            codecToList.width, codecToList.height,
-                            codecToList.maxFramerate);
-    }
-    __android_log_print(
-                        ANDROID_LOG_DEBUG,
-                        WEBRTC_LOG_TAG,
-                        "SetSendCodec %s, pltype=%d, bitRate=%d, maxBitRate=%d, "
-                        "width=%d, height=%d, frameRate=%d\n",
-                        codec.plName, codec.plType, codec.startBitrate,
-                        codec.maxBitrate, codec.width, codec.height,
-                        codec.maxFramerate);
-
-    return vieData.codec->SetSendCodec(channel, codec);
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    AddRemoteRenderer
- * Signature: (ILandroid/view/SurfaceView;)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_AddRemoteRenderer(
-                                                               JNIEnv *,
-                                                               jobject,
-                                                               jint channel,
-                                                               jobject glSurface)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "AddRemoteRenderer");
-    if (vieData.vie)
-    {
-        return vieData.render->AddRenderer(channel, glSurface, 0, 0, 0, 1, 1);
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    RemoveRemoteRenderer
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_RemoveRemoteRenderer(
-    JNIEnv *,
-    jobject,
-    jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "RemoveRemoteRenderer");
-
-    if (vieData.vie)
-    {
-        return vieData.render->RemoveRenderer(channel);
-    }
-    else
-    {
-        return -1;
-    }
-    return 0;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StartRender
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartRender(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartRender");
-
-    if (vieData.render)
-    {
-        return vieData.render->StartRender(channel);
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StarteCamera
- * Signature: (II)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartCamera(
-                                                                 JNIEnv * env,
-                                                                 jobject,
-                                                                 jint channel,
-                                                                 jint cameraNum)
-{
-    if (NULL == vieData.vie)
-        return -1;
-
-    int i = 0;
-    char deviceName[64];
-    char deviceUniqueName[64];
-    int re;
-    do
-    {
-        re = vieData.capture->GetCaptureDevice(i, deviceName,
-                                               sizeof(deviceName),
-                                               deviceUniqueName,
-                                               sizeof(deviceUniqueName));
-        __android_log_print(
-                            ANDROID_LOG_DEBUG,
-                            WEBRTC_LOG_TAG,
-                            "GetCaptureDevice ret %d devicenum %d deviceUniqueName %s",
-                            re, i, deviceUniqueName);
-        i++;
-    } while (re == 0);
-
-    int ret;
-    int cameraId;
-    vieData.capture->GetCaptureDevice(cameraNum, deviceName,
-                                      sizeof(deviceName), deviceUniqueName,
-                                      sizeof(deviceUniqueName));
-    vieData.capture->AllocateCaptureDevice(deviceUniqueName,
-                                           sizeof(deviceUniqueName), cameraId);
-
-    if (cameraId >= 0)
-    { //Connect the
-        ret = vieData.capture->ConnectCaptureDevice(cameraId, channel);
-        __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "ConnectCaptureDevice ret %d ", ret);
-
-        ret = vieData.capture->StartCapture(cameraId);
-        __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "StartCapture ret %d ", ret);
-
-    }
-
-    return cameraId;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    StopCamera
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopCamera(
-                                                                JNIEnv *,
-                                                                jobject,
-                                                                jint cameraId)
-{
-    if (NULL == vieData.capture)
-        return -1;
-
-    int ret = vieData.capture->StopCapture(cameraId);
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                        "StopCapture  ret %d ", ret);
-    ret = vieData.capture->ReleaseCaptureDevice(cameraId);
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                        "ReleaseCaptureDevice  ret %d ", ret);
-
-    return ret;
-}
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    GetCameraOrientation
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_GetCameraOrientation(
-                                                                  JNIEnv *,
-                                                                  jobject,
-                                                                  jint cameraNum)
-{
-    char deviceName[64];
-    char deviceUniqueName[64];
-    int ret;
-
-    ret = vieData.capture->GetCaptureDevice(cameraNum, deviceName,
-                                            sizeof(deviceName),
-                                            deviceUniqueName,
-                                            sizeof(deviceUniqueName));
-    if (ret != 0)
-    {
-        return -1;
-    }
-
-    RotateCapturedFrame orientation;
-    ret = vieData.capture->GetOrientation(deviceUniqueName, orientation);
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                        "GetOrientation  ret %d orientation %d", ret,
-                        orientation);
-
-    return (jint) orientation;
-
-}
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    SetRotation
- * Signature: (II)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetRotation(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jint captureId,
-                                                                 jint degrees)
-{
-
-    if (NULL == vieData.capture)
-        return -1;
-    RotateCapturedFrame rotation = RotateCapturedFrame_0;
-    if (degrees == 90)
-        rotation = RotateCapturedFrame_90;
-    else if (degrees == 180)
-        rotation = RotateCapturedFrame_180;
-    else if (degrees == 270)
-        rotation = RotateCapturedFrame_270;
-
-    int ret = vieData.capture->SetRotateCapturedFrames(captureId, rotation);
-    return ret;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    EnableNACK
- * Signature: (IZ)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_EnableNACK(
-                                                                JNIEnv *,
-                                                                jobject,
-                                                                jint channel,
-                                                                jboolean enable)
-{
-    if (NULL == vieData.rtp)
-        return -1;
-
-    if (enable)
-        __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "EnableNACK enable");
-    else
-        __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "EnableNACK disable");
-
-    int ret = vieData.rtp->SetNACKStatus(channel, enable);
-    return ret;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    EnablePLI
- * Signature: (IZ)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_EnablePLI(
-                                                               JNIEnv *,
-                                                               jobject,
-                                                               jint channel,
-                                                               jboolean enable)
-{
-    if (NULL == vieData.rtp)
-        return -1;
-
-    if (enable)
-        __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "EnablePLI enable");
-    else
-        __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "EnablePLI disable");
-
-    int ret = vieData.rtp->SetKeyFrameRequestMethod(channel,
-                                                    kViEKeyFrameRequestPliRtcp);
-    return ret;
-}
-
-/*
- * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
- * Method:    SetCallback
- * Signature: (ILorg/webrtc/videoengineapp/IViEAndroidCallback;)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetCallback(
-                                                                 JNIEnv * env,
-                                                                 jobject,
-                                                                 jint channel,
-                                                                 jobject callback)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetCallback");
-
-    if (NULL == vieData.codec)
-        return -1;
-    if (vieData.callback == NULL)
-    {
-        vieData.callback = new VideoCallbackAndroid(vieData, env, callback);
-    }
-    else if (vieData.codec)
-    {
-        vieData.codec->DeregisterDecoderObserver(channel); // Wrong channel?
-        vieData.codec->DeregisterEncoderObserver(channel);
-    }
-
-    vieData.codec->RegisterDecoderObserver(channel, *vieData.callback);
-    vieData.codec->RegisterEncoderObserver(channel, *vieData.callback);
-
-    return 0;
-}
-//////////////////////////////////////////////////////////////////
-// VoiceEngine API wrapper functions
-//////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////
-// Create VoiceEngine instance
-//
-JNIEXPORT jboolean JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Create(
-                                                               JNIEnv *env,
-                                                               jobject,
-                                                               jobject context)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "Create");
-
-    // Check if already created
-    if (veData.ve)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "VoE already created");
-        return false;
-    }
-
-    // Init Android Object
-    VoiceEngine::SetAndroidObjects(veData.jvm, env, context);
-    // Create
-    veData.ve = VoiceEngine::Create();
-    if (!veData.ve)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Create VoE failed");
-        return false;
-    }
-
-    // Get sub-APIs
-    if (!VE_GetSubApis())
-    {
-        // If not OK, release all sub-APIs and delete VoE
-        VE_ReleaseSubApis();
-        if (!VoiceEngine::Delete(veData.ve))
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Delete VoE failed");
-        }
-        return false;
-    }
-
-    return true;
-}
-
-/////////////////////////////////////////////
-// Delete VoiceEngine instance
-//
-JNIEXPORT jboolean JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Delete(
-                                                               JNIEnv *,
-                                                               jobject)
-{
-    // Check if exists
-    if (!veData.ve)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "VoE does not exist");
-        return false;
-    }
-
-    // Release sub-APIs
-    VE_ReleaseSubApis();
-
-    // Delete
-    if (!VoiceEngine::Delete(veData.ve))
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Delete VoE failed");
-        return false;
-    }
-
-    veData.ve = NULL;
-
-    // Clear instance independent Java objects
-    VoiceEngine::SetAndroidObjects(NULL, NULL, NULL);
-
-    return true;
-}
-
-/////////////////////////////////////////////
-// [Base] Initialize VoiceEngine
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Init(
-                                                         JNIEnv *,
-                                                         jobject,
-                                                         jboolean enableTrace,
-                                                         jboolean useExtTrans)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "VE_Init");
-
-    VALIDATE_BASE_POINTER;
-
-    if (useExtTrans)
-    {
-        // Not implemented
-        return -1;
-    }
-
-    return veData.base->Init();
-}
-
-/////////////////////////////////////////////
-// [Base] Terminate VoiceEngine
-//
-JNIEXPORT jint
-JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Terminate(
-                                                                          JNIEnv *,
-                                                                          jobject)
-{
-    VALIDATE_BASE_POINTER;
-
-    jint retVal = veData.base->Terminate();
-    return retVal;
-}
-
-/////////////////////////////////////////////
-// [Base] Create channel
-//
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_CreateChannel(
-                                                                                          JNIEnv *,
-                                                                                          jobject)
-{
-    VALIDATE_BASE_POINTER;
-
-    webrtc::CodecInst voiceCodec;
-    int numOfVeCodecs = veData.codec->NumOfCodecs();
-
-    //enum all the supported codec
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                        "Supported Voice Codec:\n");
-    for (int i = 0; i < numOfVeCodecs; ++i)
-    {
-        if (veData.codec->GetCodec(i, voiceCodec) != -1)
-        {
-            __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                                "num: %d name: %s\n", i, voiceCodec.plname);
-        }
-    }
-
-    jint channel = veData.base->CreateChannel();
-
-    return channel;
-}
-
-/////////////////////////////////////////////
-// [Base] Delete channel
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_DeleteChannel(
-                                                                      JNIEnv *,
-                                                                      jobject,
-                                                                      jint channel)
-    {
-    VALIDATE_BASE_POINTER;
-    return veData.base->DeleteChannel(channel);
-}
-
-/////////////////////////////////////////////
-// [Base] SetLocalReceiver
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetLocalReceiver(
-                                                                         JNIEnv *,
-                                                                         jobject,
-                                                                         jint channel,
-                                                                         jint port)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetLocalReceiver");
-    VALIDATE_BASE_POINTER;
-    return veData.base->SetLocalReceiver(channel, port);
-}
-
-/////////////////////////////////////////////
-// [Base] SetSendDestination
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetSendDestination(
-                                                                   JNIEnv *env,
-                                                                   jobject,
-                                                                   jint channel,
-                                                                   jint port,
-                                                                   jstring ipaddr)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetSendDestination");
-    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 = veData.base->SetSendDestination(channel, port, ipaddrNative);
-    env->ReleaseStringUTFChars(ipaddr, ipaddrNative);
-    return retVal;
-}
-
-/////////////////////////////////////////////
-// [Base] StartListen
-//
-JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StartListen(
-                                                                    JNIEnv *,
-                                                                    jobject,
-                                                                    jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartListen");
-    VALIDATE_BASE_POINTER;
-    return veData.base->StartReceive(channel);
-}
-
-/////////////////////////////////////////////
-// [Base] Start playout
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StartPlayout(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartPlayout");
-    VALIDATE_BASE_POINTER;
-    return veData.base->StartPlayout(channel);
-}
-
-/////////////////////////////////////////////
-// [Base] Start send
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StartSend(
-                                                                  JNIEnv *,
-                                                                  jobject,
-                                                                  jint channel)
-{
-    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartSend");
-    VALIDATE_BASE_POINTER;
-    return veData.base->StartSend(channel);
-}
-
-/////////////////////////////////////////////
-// [Base] Stop listen
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopListen(
-                                                                   JNIEnv *,
-                                                                   jobject,
-                                                                   jint channel)
-{
-    VALIDATE_BASE_POINTER;
-    return veData.base->StartReceive(channel);
-}
-
-/////////////////////////////////////////////
-// [Base] Stop playout
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopPlayout(
-                                                                    JNIEnv *,
-                                                                    jobject,
-                                                                    jint channel)
-{
-    VALIDATE_BASE_POINTER;
-    return veData.base->StopPlayout(channel);
-}
-
-/////////////////////////////////////////////
-// [Base] Stop send
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopSend(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jint channel)
-{
-    VALIDATE_BASE_POINTER;
-    return veData.base->StopSend(channel);
-}
-
-/////////////////////////////////////////////
-// [codec] Number of codecs
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_NumOfCodecs(
-                                                                    JNIEnv *,
-                                                                    jobject)
-{
-    VALIDATE_CODEC_POINTER;
-    return veData.codec->NumOfCodecs();
-}
-
-/////////////////////////////////////////////
-// [codec] Set send codec
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetSendCodec(
-                                                                     JNIEnv *,
-                                                                     jobject,
-                                                                     jint channel,
-                                                                     jint index)
-{
-    VALIDATE_CODEC_POINTER;
-
-    webrtc::CodecInst codec;
-
-    for (int i = 0; i < veData.codec->NumOfCodecs(); ++i)
-    {
-        webrtc::CodecInst codecToList;
-        veData.codec->GetCodec(i, codecToList);
-        __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
-                            "VE Codec list %s, pltype=%d\n",
-                            codecToList.plname, codecToList.pltype);
-    }
-
-    if (veData.codec->GetCodec(index, codec) != 0)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Failed to get codec");
-        return -1;
-    }
-    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetSendCodec %s\n",
-                        codec.plname);
-
-    return veData.codec->SetSendCodec(channel, codec);
-}
-
-/////////////////////////////////////////////
-// [audioprocessing] SetNSStatus
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetNSStatus(
-                                                                    JNIEnv *,
-                                                                    jobject,
-                                                                    jboolean enable,
-                                                                    jint mode)
-{
-    //TODO implement
-    return -1;
-}
-
-/////////////////////////////////////////////
-// [audioprocessing] SetAGCStatus
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetAGCStatus(
-                                                                     JNIEnv *,
-                                                                     jobject,
-                                                                     jboolean enable,
-                                                                     jint mode)
-{
-    //TODO implement
-    return -1;
-}
-
-/////////////////////////////////////////////
-// [audioprocessing] SetECStatus
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetECStatus(
-                                                            JNIEnv *,
-                                                            jobject,
-                                                            jboolean enable,
-                                                            jint mode,
-                                                            jint AESmode,
-                                                            jint AESattenuation)
-{
-    //TODO implement
-    return -1;
-}
-
-/////////////////////////////////////////////
-// [File] Start play file locally
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_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 = veData.file->StartPlayingFileLocally(channel, fileNameNative,
-                                                       loop);
-
-    env->ReleaseStringUTFChars(fileName, fileNameNative);
-
-    return retVal;
-}
-
-/////////////////////////////////////////////
-// [File] Stop play file locally
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopPlayingFileLocally(
-                                                                    JNIEnv *,
-                                                                    jobject,
-                                                                    jint channel)
-{
-    VALIDATE_FILE_POINTER;
-    return veData.file->StopPlayingFileLocally(channel);
-}
-
-/////////////////////////////////////////////
-// [File] Start playing file as microphone
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_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 = veData.file->StartPlayingFileAsMicrophone(channel,
-                                                            fileNameNative,
-                                                            loop);
-
-    env->ReleaseStringUTFChars(fileName, fileNameNative);
-
-    return retVal;
-}
-
-/////////////////////////////////////////////
-// [File] Stop playing file as microphone
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopPlayingFileAsMicrophone(
-                                                                    JNIEnv *,
-                                                                    jobject,
-                                                                    jint channel)
-{
-    VALIDATE_FILE_POINTER;
-    return veData.file->StopPlayingFileAsMicrophone(channel);
-}
-
-/////////////////////////////////////////////
-// [Volume] Set speaker volume
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetSpeakerVolume(
-                                                                     JNIEnv *,
-                                                                     jobject,
-                                                                     jint level)
-{
-    VALIDATE_VOLUME_POINTER;
-
-    if (veData.volume->SetSpeakerVolume(level) != 0)
-    {
-        return -1;
-    }
-
-    unsigned int storedVolume = 0;
-    if (veData.volume->GetSpeakerVolume(storedVolume) != 0)
-    {
-        return -1;
-    }
-
-    if (storedVolume != level)
-    {
-        return -1;
-    }
-
-    return 0;
-}
-
-/////////////////////////////////////////////
-// [Hardware] Set speaker volume
-//
-JNIEXPORT jint JNICALL
-Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetLoudspeakerStatus(
-                                                                 JNIEnv *,
-                                                                 jobject,
-                                                                 jboolean enable)
-{
-    VALIDATE_HARDWARE_POINTER;
-
-    if (veData.hardware->SetLoudspeakerStatus(enable) != 0)
-    {
-        return -1;
-    }
-
-    return 0;
-}
-
-//////////////////////////////////////////////////////////////////
-//local function
-//////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////
-// Get all sub-APIs
-//
-bool VE_GetSubApis()
-{
-    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
-    veData.apm = VoEAudioProcessing::GetInterface(veData.ve);
-    if (!veData.apm)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Get VoEAudioProcessing 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;
-    }
-
-    return getOK;
-}
-
-/////////////////////////////////////////////
-// Release all sub-APIs
-//
-bool VE_ReleaseSubApis()
-{
-    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;
-        }
-    }
-
-    return releaseOK;
-}
diff --git a/video_engine/main/test/AndroidTest/res/layout/aconfig.xml b/video_engine/main/test/AndroidTest/res/layout/aconfig.xml
deleted file mode 100644
index 807ef69..0000000
--- a/video_engine/main/test/AndroidTest/res/layout/aconfig.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:orientation="vertical" 
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView android:layout_width="wrap_content" 
-	android:layout_height="wrap_content"
-	android:textStyle="bold" 
-	android:textSize="24dip" 
-	android:text="Audio Settings"></TextView>
-	<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-	<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_width="wrap_content" android:text="@string/codecType"></TextView>
-	<Spinner android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/spVoiceCodecType"></Spinner>
-		
-	<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent">	
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/aTxPort"></TextView>
-	<EditText android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/etATxPort" ></EditText>
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/aRxPort"></TextView>
-	<EditText android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/etARxPort" ></EditText>		
-	</LinearLayout>		
-	
-	<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent">
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbSpeaker" android:text="@string/speaker"></CheckBox>
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbAutoGainControl" android:text="@string/AutoGainControl"></CheckBox>	
-	</LinearLayout>
-	
-	<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent">
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbAECM" android:text="@string/AECM"></CheckBox>
-	</LinearLayout>
-	
-	<LinearLayout android:id="@+id/LinearLayout03" android:layout_height="wrap_content" android:layout_width="fill_parent">
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbNoiseSuppression" android:text="@string/NoiseSuppression"></CheckBox>
-	</LinearLayout>	
-	
-</LinearLayout>
\ No newline at end of file
diff --git a/video_engine/main/test/AndroidTest/res/layout/main.xml b/video_engine/main/test/AndroidTest/res/layout/main.xml
deleted file mode 100644
index 83d9def..0000000
--- a/video_engine/main/test/AndroidTest/res/layout/main.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:layout_gravity="right"
-	android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
-
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvTitle" android:textStyle="bold" android:textSize="24dip" android:text="@string/gSettings"></TextView>
-	<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-	<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent">
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbVideoReceive" android:text="@string/enableVideoReceive"></CheckBox>
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbVideoSend" android:text="@string/enableVideoSend"></CheckBox>
-	</LinearLayout>
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbVoice" android:text="@string/enableVoice"></CheckBox>	
-		
-	<TextView android:id="@+id/TextView02" android:layout_width="wrap_content"
-		android:layout_height="wrap_content" android:text="@string/remoteIp"></TextView>
-	<EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/etRemoteIp" ></EditText>
-	
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbLoopback" android:text="@string/loopback"></CheckBox>
-</LinearLayout>
\ No newline at end of file
diff --git a/video_engine/main/test/AndroidTest/res/layout/send.xml b/video_engine/main/test/AndroidTest/res/layout/send.xml
deleted file mode 100644
index dfe6d54..0000000
--- a/video_engine/main/test/AndroidTest/res/layout/send.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    >
-
-
-<SurfaceView android:id="@+id/svLocal" android:layout_width="wrap_content" android:layout_height="wrap_content"></SurfaceView><ImageView android:id="@+id/ivPreview" android:layout_height="fill_parent" android:layout_width="fill_parent"></ImageView>
-
-</LinearLayout>
diff --git a/video_engine/main/test/AndroidTest/res/layout/stats.xml b/video_engine/main/test/AndroidTest/res/layout/stats.xml
deleted file mode 100644
index 2a31b14..0000000
--- a/video_engine/main/test/AndroidTest/res/layout/stats.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:orientation="vertical" 
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView android:layout_width="wrap_content" 
-	android:layout_height="wrap_content"
-	android:textStyle="bold" 
-	android:textSize="24dip" 
-	android:text="Stats"></TextView>
-	
-	<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-	
-	<TextView android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/tvLocalIp"
-		android:textStyle="bold"></TextView>
-	
-	<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-	
-	<TextView android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/tvFrameRateI"
-		android:textStyle="bold"></TextView>
-	<TextView android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/tvBitRateI"
-		android:textStyle="bold"></TextView>
-	<TextView android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/tvPacketLoss"
-		android:textStyle="bold"></TextView>
-	
-	<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-	
-	<TextView android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/tvFrameRateO"
-		android:textStyle="bold"></TextView>
-	<TextView android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/tvBitRateO"
-		android:textStyle="bold"></TextView>
-</LinearLayout>
\ No newline at end of file
diff --git a/video_engine/main/test/AndroidTest/res/layout/tabhost.xml b/video_engine/main/test/AndroidTest/res/layout/tabhost.xml
deleted file mode 100644
index 7441438..0000000
--- a/video_engine/main/test/AndroidTest/res/layout/tabhost.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/tabhost"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-    <LinearLayout
-        android:orientation="vertical"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent">
-        <TabWidget
-            android:id="@android:id/tabs"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content" />
-        <FrameLayout
-            android:id="@android:id/tabcontent"
-            android:layout_width="fill_parent"
-            android:layout_height="fill_parent">            
-        <include android:id="@+id/tab_video" layout="@layout/both" />
-        <include android:id="@+id/tab_config" layout="@layout/main" />
-        <include android:id="@+id/tab_vconfig" layout="@layout/vconfig" />
-        <include android:id="@+id/tab_aconfig" layout="@layout/aconfig" />
-        <include android:id="@+id/tab_stats" layout="@layout/stats" />		  
-        </FrameLayout>
-    </LinearLayout>
-</TabHost>
\ No newline at end of file
diff --git a/video_engine/main/test/AndroidTest/res/layout/vconfig.xml b/video_engine/main/test/AndroidTest/res/layout/vconfig.xml
deleted file mode 100644
index be8d175..0000000
--- a/video_engine/main/test/AndroidTest/res/layout/vconfig.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:orientation="vertical" 
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView android:layout_width="wrap_content" 
-	android:layout_height="wrap_content"
-	android:textStyle="bold" 
-	android:textSize="24dip" 
-	android:text="@string/vSettings"></TextView>
-	<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>	
-	
-	<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/codecType"></TextView>
-	<Spinner android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/spCodecType"></Spinner>
-	
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvCodecSize" android:text="@string/codecSize"></TextView>
-	<Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spCodecSize"></Spinner>
-	
-	<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent">
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/vTxPort"></TextView>
-	<EditText android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/etVTxPort" ></EditText>
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/vRxPort"></TextView>
-	<EditText android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/etVRxPort" ></EditText>
-	</LinearLayout>
-	
-	<LinearLayout android:id="@+id/LinearLayout03" android:layout_height="wrap_content" android:layout_width="fill_parent">
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cbNack" android:text="@string/nack"></CheckBox>	
-	</LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/video_engine/main/test/AutoTest/Android/AndroidManifest.xml b/video_engine/main/test/AutoTest/Android/AndroidManifest.xml
deleted file mode 100644
index e5bcfcc..0000000
--- a/video_engine/main/test/AutoTest/Android/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      android:versionCode="1"
-      android:versionName="1.0" package="org.webrtc.vieautotest">
-    <application android:label="@string/app_name" android:debuggable="true" android:icon="@drawable/logo">
-        <activity android:label="@string/app_name" android:name="ViEAutotest">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-    </application>
-    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
-    <uses-permission android:name="android.permission.CAMERA"></uses-permission>
-    <uses-feature android:name="android.hardware.camera" />
-    <uses-feature android:name="android.hardware.camera.autofocus" />
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-</manifest> 
diff --git a/video_engine/main/test/AutoTest/Android/jni/vie_autotest_jni.cc b/video_engine/main/test/AutoTest/Android/jni/vie_autotest_jni.cc
deleted file mode 100644
index 97ceb81..0000000
--- a/video_engine/main/test/AutoTest/Android/jni/vie_autotest_jni.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- *  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 <stdio.h>
-#include <string.h>
-#include <android/log.h>
-#include <pthread.h>
-#include <unistd.h>
-
-#include "org_webrtc_vieautotest_vie_autotest.h"
-
-#include "vie_autotest_android.h"
-
-#define WEBRTC_LOG_TAG "*WEBRTCN*"
-
-// VideoEngine data struct
-typedef struct
-{
-    JavaVM* jvm;
-} VideoEngineData;
-
-// Global variables
-JavaVM* webrtcGlobalVM;
-
-// Global variables visible in this file
-static VideoEngineData vieData;
-
-// "Local" functions (i.e. not Java accessible)
-#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 1024
-
-static bool GetSubAPIs(VideoEngineData& vieData);
-static bool ReleaseSubAPIs(VideoEngineData& vieData);
-
-//////////////////////////////////////////////////////////////////
-// 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;
-    }
-
-    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;
-    }
-
-    // Init ViE data
-    vieData.jvm = vm;
-
-    return JNI_VERSION_1_4;
-}
-
-/*
- * Class:     org_webrtc_vieautotest_ViEAutotest
- * Method:    RunTest
- * Signature: (IILandroid/opengl/GLSurfaceView;Landroid/opengl/GLSurfaceView;)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_vieautotest_ViEAutotest_RunTest__IILandroid_opengl_GLSurfaceView_2Landroid_opengl_GLSurfaceView_2(
-                                                             JNIEnv* env,
-                                                             jobject context,
-                                                             jint testType,
-                                                             jint subtestType,
-                                                             jobject glView1,
-                                                             jobject glView2)
-
-{
-    int numErrors = -1;
-    numErrors = ViEAutoTestAndroid::RunAutotest(testType, subtestType, glView1,
-                                                glView2, vieData.jvm, env,
-                                                context);
-    return numErrors;
-}
-
-/*
- * Class:     org_webrtc_vieautotest_ViEAutotest
- * Method:    RunTest
- * Signature: (IILandroid/view/SurfaceView;Landroid/view/SurfaceView;)I
- */
-JNIEXPORT jint JNICALL
-Java_org_webrtc_vieautotest_ViEAutotest_RunTest__IILandroid_view_SurfaceView_2Landroid_view_SurfaceView_2(
-                                                                                         JNIEnv* env,
-                                                                                         jobject context,
-                                                                                         jint testType,
-                                                                                         jint subtestType,
-                                                                                         jobject surfaceHolder1,
-                                                                                         jobject surfaceHolder2)
-{
-    int numErrors = -1;
-    numErrors = ViEAutoTestAndroid::RunAutotest(testType, subtestType,
-                                                surfaceHolder1, surfaceHolder2,
-                                                vieData.jvm, env, context);
-    return numErrors;
-}
-
-//////////////////////////////////////////////////////////////////
-//local function
-//////////////////////////////////////////////////////////////////
-
-bool GetSubAPIs(VideoEngineData& vieData)
-{
-    bool retVal = true;
-    //vieData.base = ViEBase::GetInterface(vieData.vie);
-    //if (vieData.base == NULL)
-    {
-        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                            "Could not get Base API");
-        retVal = false;
-    }
-    return retVal;
-}
-
-bool ReleaseSubAPIs(VideoEngineData& vieData)
-{
-    bool releaseOk = true;
-    //if (vieData.base)
-    {
-        //if (vieData.base->Release() != 0)
-        if (false)
-        {
-            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
-                                "Release base sub-API failed");
-            releaseOk = false;
-        }
-        else
-        {
-            //vieData.base = NULL;
-        }
-    }
-
-    return releaseOk;
-}
-
diff --git a/video_engine/main/test/AutoTest/Android/res/layout/main.xml b/video_engine/main/test/AutoTest/Android/res/layout/main.xml
deleted file mode 100644
index 34d9549..0000000
--- a/video_engine/main/test/AutoTest/Android/res/layout/main.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent">
-	<RelativeLayout
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent">
-		<LinearLayout 
-            android:id="@+id/RemoteView"
-           	android:layout_width="fill_parent"
-           	android:layout_height="fill_parent"
-            android:layout_weight="1">
-            <!-- log instead of video
-            <ImageView
-        		android:layout_width="fill_parent"
-        		android:layout_height="fill_parent" 
-        		android:scaleType="fitXY"
-        		android:src="@drawable/logo" /> -->
-        	
-        </LinearLayout>
-		<LinearLayout 
-           	android:id="@+id/LocalView"
-           	android:layout_width="120dip"
-           	android:layout_height="120dip"
-           	android:layout_weight="1">
-           	<!-- <ImageView
-       		android:layout_width="fill_parent"
-       		android:layout_height="fill_parent" 
-       		android:scaleType="fitXY"
-       		android:src="@drawable/logo" /> -->
-		</LinearLayout>
-		<LinearLayout
-			android:orientation="horizontal"
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:layout_alignParentBottom="true">
-			<LinearLayout
-			android:orientation="vertical"
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:layout_alignParentBottom="true">
-				<Spinner
-					android:id="@+id/testSpinner"
-					android:layout_width="wrap_content"
-					android:layout_height="wrap_content"
-					android:prompt="@string/SpinnerTitle"
-				/>
-				<Spinner
-					android:id="@+id/subtestSpinner"
-					android:layout_width="wrap_content"
-					android:layout_height="wrap_content"
-					android:prompt="@string/SpinnerSubtest"
-				/>
-				<Button
-					android:text="@string/run_button"
-					android:id="@+id/Button01"
-					android:layout_width="wrap_content"
-					android:layout_height="wrap_content">
-				</Button>
-			</LinearLayout>
-
-		</LinearLayout>
-	</RelativeLayout>
-</FrameLayout>
diff --git a/video_engine/main/test/AutoTest/Android/.classpath b/video_engine/main/test/AutoTest/android/.classpath
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/.classpath
rename to video_engine/main/test/AutoTest/android/.classpath
diff --git a/video_engine/main/test/AutoTest/Android/.project b/video_engine/main/test/AutoTest/android/.project
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/.project
rename to video_engine/main/test/AutoTest/android/.project
diff --git a/video_engine/main/test/AutoTest/Android/Android.mk b/video_engine/main/test/AutoTest/android/Android.mk
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/Android.mk
rename to video_engine/main/test/AutoTest/android/Android.mk
diff --git a/video_engine/main/test/AutoTest/android/AndroidManifest.xml b/video_engine/main/test/AutoTest/android/AndroidManifest.xml
new file mode 100644
index 0000000..11b3e27
--- /dev/null
+++ b/video_engine/main/test/AutoTest/android/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+	  android:versionCode="1"
+	  android:versionName="1.0" package="org.webrtc.vieautotest">
+  <application android:label="@string/app_name"
+	       android:debuggable="true"
+	       android:icon="@drawable/logo">
+    <activity android:label="@string/app_name"
+	      android:name="ViEAutotest">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+
+  </application>
+  <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
+  <uses-permission android:name="android.permission.CAMERA"></uses-permission>
+  <uses-feature android:name="android.hardware.camera" />
+  <uses-feature android:name="android.hardware.camera.autofocus" />
+  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+  <uses-permission android:name="android.permission.RECORD_AUDIO" />
+  <uses-permission android:name="android.permission.INTERNET" />
+  <uses-permission android:name="android.permission.WAKE_LOCK" />
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+</manifest> 
diff --git a/video_engine/main/test/AutoTest/Android/default.properties b/video_engine/main/test/AutoTest/android/default.properties
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/default.properties
rename to video_engine/main/test/AutoTest/android/default.properties
diff --git a/video_engine/main/test/AutoTest/Android/gen/org/webrtc/vieautotest/R.java b/video_engine/main/test/AutoTest/android/gen/org/webrtc/vieautotest/R.java
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/gen/org/webrtc/vieautotest/R.java
rename to video_engine/main/test/AutoTest/android/gen/org/webrtc/vieautotest/R.java
diff --git a/video_engine/main/test/AutoTest/Android/jni/Android.mk b/video_engine/main/test/AutoTest/android/jni/Android.mk
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/jni/Android.mk
rename to video_engine/main/test/AutoTest/android/jni/Android.mk
diff --git a/video_engine/main/test/AutoTest/Android/jni/org_webrtc_vieautotest_vie_autotest.h b/video_engine/main/test/AutoTest/android/jni/org_webrtc_vieautotest_vie_autotest.h
similarity index 82%
rename from video_engine/main/test/AutoTest/Android/jni/org_webrtc_vieautotest_vie_autotest.h
rename to video_engine/main/test/AutoTest/android/jni/org_webrtc_vieautotest_vie_autotest.h
index a3f5616..68ec601 100644
--- a/video_engine/main/test/AutoTest/Android/jni/org_webrtc_vieautotest_vie_autotest.h
+++ b/video_engine/main/test/AutoTest/android/jni/org_webrtc_vieautotest_vie_autotest.h
@@ -24,8 +24,9 @@
  * Method:    RunTest
  * Signature: (IILandroid/view/SurfaceView;Landroid/view/SurfaceView;)I
  */
-JNIEXPORT jint JNICALL Java_org_webrtc_vieautotest_ViEAutotest_RunTest__IILandroid_view_SurfaceView_2Landroid_view_SurfaceView_2
-  (JNIEnv *, jobject, jint, jint, jobject, jobject);
+JNIEXPORT jint JNICALL
+Java_org_webrtc_vieautotest_ViEAutotest_RunTest__IILandroid_view_SurfaceView_2Landroid_view_SurfaceView_2
+(JNIEnv *, jobject, jint, jint, jobject, jobject);
 
 #ifdef __cplusplus
 }
diff --git a/video_engine/main/test/AutoTest/android/jni/vie_autotest_jni.cc b/video_engine/main/test/AutoTest/android/jni/vie_autotest_jni.cc
new file mode 100644
index 0000000..2e55283
--- /dev/null
+++ b/video_engine/main/test/AutoTest/android/jni/vie_autotest_jni.cc
@@ -0,0 +1,137 @@
+/*
+ *  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 <stdio.h>
+#include <string.h>
+#include <android/log.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "org_webrtc_vieautotest_vie_autotest.h"
+
+#include "vie_autotest_android.h"
+
+#define WEBRTC_LOG_TAG "*WEBRTCN*"
+
+// VideoEngine data struct
+typedef struct
+{
+    JavaVM* jvm;
+} VideoEngineData;
+
+// Global variables
+JavaVM* webrtcGlobalVM;
+
+// Global variables visible in this file
+static VideoEngineData vieData;
+
+// "Local" functions (i.e. not Java accessible)
+#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 1024
+
+static bool GetSubAPIs(VideoEngineData& vieData);
+static bool ReleaseSubAPIs(VideoEngineData& vieData);
+
+//
+// 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;
+  }
+
+  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;
+  }
+
+  // Init ViE data
+  vieData.jvm = vm;
+
+  return JNI_VERSION_1_4;
+}
+
+// Class:     org_webrtc_vieautotest_ViEAutotest
+// Method:    RunTest
+// Signature: (IILandroid/opengl/GLSurfaceView;Landroid/opengl/GLSurfaceView;)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_vieautotest_ViEAutotest_RunTest__IILandroid_opengl_GLSurfaceView_2Landroid_opengl_GLSurfaceView_2(
+    JNIEnv* env,
+    jobject context,
+    jint testType,
+    jint subtestType,
+    jobject glView1,
+    jobject glView2)
+{
+  int numErrors = -1;
+  numErrors = ViEAutoTestAndroid::RunAutotest(testType, subtestType, glView1,
+                                              glView2, vieData.jvm, env,
+                                              context);
+  return numErrors;
+}
+
+// Class:     org_webrtc_vieautotest_ViEAutotest
+// Method:    RunTest
+// Signature: (IILandroid/view/SurfaceView;Landroid/view/SurfaceView;)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_vieautotest_ViEAutotest_RunTest__IILandroid_view_SurfaceView_2Landroid_view_SurfaceView_2(
+    JNIEnv* env,
+    jobject context,
+    jint testType,
+    jint subtestType,
+    jobject surfaceHolder1,
+    jobject surfaceHolder2)
+{
+  int numErrors = -1;
+  numErrors = ViEAutoTestAndroid::RunAutotest(testType, subtestType,
+                                              surfaceHolder1, surfaceHolder2,
+                                              vieData.jvm, env, context);
+  return numErrors;
+}
+
+//
+//local function
+//
+
+bool GetSubAPIs(VideoEngineData& vieData) {
+  bool retVal = true;
+  //vieData.base = ViEBase::GetInterface(vieData.vie);
+  //if (vieData.base == NULL)
+  {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Could not get Base API");
+    retVal = false;
+  }
+  return retVal;
+}
+
+bool ReleaseSubAPIs(VideoEngineData& vieData) {
+  bool releaseOk = true;
+  //if (vieData.base)
+  {
+    //if (vieData.base->Release() != 0)
+    if (false) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Release base sub-API failed");
+      releaseOk = false;
+    }
+    else {
+      //vieData.base = NULL;
+    }
+  }
+
+  return releaseOk;
+}
diff --git a/video_engine/main/test/AutoTest/Android/res/drawable/logo.png b/video_engine/main/test/AutoTest/android/res/drawable/logo.png
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/res/drawable/logo.png
rename to video_engine/main/test/AutoTest/android/res/drawable/logo.png
Binary files differ
diff --git a/video_engine/main/test/AutoTest/android/res/layout/main.xml b/video_engine/main/test/AutoTest/android/res/layout/main.xml
new file mode 100644
index 0000000..1f2aaf9
--- /dev/null
+++ b/video_engine/main/test/AutoTest/android/res/layout/main.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	     android:layout_width="fill_parent"
+	     android:layout_height="fill_parent">
+  <RelativeLayout
+     android:layout_width="fill_parent"
+     android:layout_height="fill_parent">
+    <LinearLayout 
+       android:id="@+id/RemoteView"
+       android:layout_width="fill_parent"
+       android:layout_height="fill_parent"
+       android:layout_weight="1">
+      <!-- log instead of video
+           <ImageView
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent" 
+              android:scaleType="fitXY"
+              android:src="@drawable/logo" /> -->
+
+    </LinearLayout>
+    <LinearLayout 
+       android:id="@+id/LocalView"
+       android:layout_width="120dip"
+       android:layout_height="120dip"
+       android:layout_weight="1">
+      <!-- <ImageView
+       	      android:layout_width="fill_parent"
+       	      android:layout_height="fill_parent" 
+       	      android:scaleType="fitXY"
+       	      android:src="@drawable/logo" /> -->
+    </LinearLayout>
+    <LinearLayout
+       android:orientation="horizontal"
+       android:layout_width="fill_parent"
+       android:layout_height="wrap_content"
+       android:layout_alignParentBottom="true">
+      <LinearLayout
+	 android:orientation="vertical"
+	 android:layout_width="fill_parent"
+	 android:layout_height="wrap_content"
+	 android:layout_alignParentBottom="true">
+	<Spinner
+	   android:id="@+id/testSpinner"
+	   android:layout_width="wrap_content"
+	   android:layout_height="wrap_content"
+	   android:prompt="@string/SpinnerTitle"
+	   />
+	<Spinner
+	   android:id="@+id/subtestSpinner"
+	   android:layout_width="wrap_content"
+	   android:layout_height="wrap_content"
+	   android:prompt="@string/SpinnerSubtest"
+	   />
+	<Button
+	   android:text="@string/run_button"
+	   android:id="@+id/Button01"
+	   android:layout_width="wrap_content"
+	   android:layout_height="wrap_content">
+	</Button>
+      </LinearLayout>
+
+    </LinearLayout>
+  </RelativeLayout>
+</FrameLayout>
diff --git a/video_engine/main/test/AutoTest/Android/res/values/strings.xml b/video_engine/main/test/AutoTest/android/res/values/strings.xml
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/res/values/strings.xml
rename to video_engine/main/test/AutoTest/android/res/values/strings.xml
diff --git a/video_engine/main/test/AutoTest/Android/src/org/webrtc/vieautotest/ViEAutotest.java b/video_engine/main/test/AutoTest/android/src/org/webrtc/vieautotest/ViEAutotest.java
similarity index 100%
rename from video_engine/main/test/AutoTest/Android/src/org/webrtc/vieautotest/ViEAutotest.java
rename to video_engine/main/test/AutoTest/android/src/org/webrtc/vieautotest/ViEAutotest.java
diff --git a/video_engine/main/test/AndroidTest/.classpath b/video_engine/main/test/android_test/.classpath
similarity index 100%
rename from video_engine/main/test/AndroidTest/.classpath
rename to video_engine/main/test/android_test/.classpath
diff --git a/video_engine/main/test/AndroidTest/.project b/video_engine/main/test/android_test/.project
similarity index 100%
rename from video_engine/main/test/AndroidTest/.project
rename to video_engine/main/test/android_test/.project
diff --git a/video_engine/main/test/AndroidTest/Android.mk b/video_engine/main/test/android_test/Android.mk
similarity index 100%
rename from video_engine/main/test/AndroidTest/Android.mk
rename to video_engine/main/test/android_test/Android.mk
diff --git a/video_engine/main/test/AndroidTest/AndroidManifest.xml b/video_engine/main/test/android_test/AndroidManifest.xml
similarity index 92%
rename from video_engine/main/test/AndroidTest/AndroidManifest.xml
rename to video_engine/main/test/android_test/AndroidManifest.xml
index a39f895..0714aed 100644
--- a/video_engine/main/test/AndroidTest/AndroidManifest.xml
+++ b/video_engine/main/test/android_test/AndroidManifest.xml
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       android:versionCode="1" package="org.webrtc.videoengineapp" android:versionName="1.07">
-    <application android:icon="@drawable/logo" android:label="@string/app_name" android:debuggable="true">
+    <application android:icon="@drawable/logo"
+		 android:label="@string/app_name"
+		 android:debuggable="true">
         <activity android:name=".ViEAndroidDemo"
                   android:label="@string/app_name" 
                   android:configChanges="keyboardHidden|orientation"                  
diff --git a/video_engine/main/test/AndroidTest/default.properties b/video_engine/main/test/android_test/default.properties
similarity index 100%
rename from video_engine/main/test/AndroidTest/default.properties
rename to video_engine/main/test/android_test/default.properties
diff --git a/video_engine/main/test/AndroidTest/gen/org/webrtc/androidapp/R.java b/video_engine/main/test/android_test/gen/org/webrtc/androidapp/R.java
similarity index 100%
rename from video_engine/main/test/AndroidTest/gen/org/webrtc/androidapp/R.java
rename to video_engine/main/test/android_test/gen/org/webrtc/androidapp/R.java
diff --git a/video_engine/main/test/AndroidTest/jni/Android.mk b/video_engine/main/test/android_test/jni/Android.mk
similarity index 100%
rename from video_engine/main/test/AndroidTest/jni/Android.mk
rename to video_engine/main/test/android_test/jni/Android.mk
diff --git a/video_engine/main/test/AndroidTest/jni/org_webrtc_videoengineapp_vie_android_java_api.h b/video_engine/main/test/android_test/jni/org_webrtc_videoengineapp_vie_android_java_api.h
similarity index 100%
rename from video_engine/main/test/AndroidTest/jni/org_webrtc_videoengineapp_vie_android_java_api.h
rename to video_engine/main/test/android_test/jni/org_webrtc_videoengineapp_vie_android_java_api.h
diff --git a/video_engine/main/test/android_test/jni/vie_android_java_api.cc b/video_engine/main/test/android_test/jni/vie_android_java_api.cc
new file mode 100644
index 0000000..b45ac20
--- /dev/null
+++ b/video_engine/main/test/android_test/jni/vie_android_java_api.cc
@@ -0,0 +1,1564 @@
+/*
+ *  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 <stdio.h>
+#include <string.h>
+#include <android/log.h>
+
+#include "org_webrtc_videoengineapp_vie_android_java_api.h"
+
+#include "voe_base.h"
+#include "voe_codec.h"
+#include "voe_file.h"
+#include "voe_network.h"
+#include "voe_audio_processing.h"
+#include "voe_volume_control.h"
+#include "voe_hardware.h"
+
+#include "vie_base.h"
+#include "vie_codec.h"
+#include "vie_capture.h"
+#include "vie_network.h"
+#include "vie_render.h"
+#include "vie_rtp_rtcp.h"
+
+#include "common_types.h"
+
+#define WEBRTC_LOG_TAG "*WEBRTCN*"
+#define VALIDATE_BASE_POINTER                                           \
+  if (!veData.base)                                                     \
+  {                                                                     \
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,              \
+                        "Base pointer doesn't exist");                  \
+    return -1;                                                          \
+  }
+#define VALIDATE_CODEC_POINTER                                          \
+  if (!veData.codec)                                                    \
+  {                                                                     \
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,              \
+                        "Codec pointer doesn't exist");                 \
+    return -1;                                                          \
+  }
+#define VALIDATE_FILE_POINTER                                           \
+  if (!veData.file)                                                     \
+  {                                                                     \
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,              \
+                        "File pointer doesn't exist");                  \
+    return -1;                                                          \
+  }
+#define VALIDATE_APM_POINTER                                            \
+  if (!veData.codec)                                                    \
+  {                                                                     \
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,              \
+                        "Apm pointer doesn't exist");                   \
+    return -1;                                                          \
+  }
+#define VALIDATE_HARDWARE_POINTER                                       \
+  if (!veData.hardware)                                                 \
+  {                                                                     \
+    __android_log_write(                                                \
+        ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,                              \
+        "Hardware pointer doesn't exist");                              \
+    return -1;                                                          \
+  }
+#define VALIDATE_VOLUME_POINTER                                         \
+  if (!veData.volume)                                                   \
+  {                                                                     \
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,              \
+                        "Volume pointer doesn't exist");                \
+    return -1;                                                          \
+  }
+
+using namespace webrtc;
+
+//Forward declaration.
+class VideoCallbackAndroid;
+
+// VoiceEngine data struct
+typedef struct
+{
+  // VoiceEngine
+  VoiceEngine* ve;
+  // Sub-APIs
+  VoEBase* base;
+  VoECodec* codec;
+  VoEFile* file;
+  VoENetwork* netw;
+  VoEAudioProcessing* apm;
+  VoEVolumeControl* volume;
+  VoEHardware* hardware;
+  JavaVM* jvm;
+} VoiceEngineData;
+
+class AndroidVideoRenderCallback;
+// VideoEngine data struct
+typedef struct
+{
+  VideoEngine* vie;
+  ViEBase* base;
+  ViECodec* codec;
+  ViENetwork* netw;
+  ViERTP_RTCP* rtp;
+  ViERender* render;
+  ViECapture* capture;
+  VideoCallbackAndroid* callback;
+
+} VideoEngineData;
+
+// Global variables
+JavaVM* webrtcGlobalVM;
+
+// Global variables visible in this file
+static VoiceEngineData veData;
+static VideoEngineData vieData;
+
+// "Local" functions (i.e. not Java accessible)
+#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 1024
+static bool VE_GetSubApis();
+static bool VE_ReleaseSubApis();
+
+#define CHECK_API_RETURN(ret)                                           \
+  if (ret!=0)                                                           \
+  {                                                                     \
+    __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,              \
+                        "Return error %d",ret);                         \
+    break;                                                              \
+  }
+
+class VideoCallbackAndroid: public ViEDecoderObserver,
+                            public ViEEncoderObserver
+{
+
+    // Implements ViEDecoderObserver
+    virtual void IncomingRate(const int videoChannel,
+                              const unsigned int framerate,
+                              const unsigned int bitrate)
+    {
+        // Let's print out the network statistics from this call back as well
+        unsigned short fraction_lost;
+        unsigned int dummy;
+        int intdummy;
+        _vieData.rtp->GetReceivedRTCPStatistics(videoChannel, fraction_lost,
+                                                dummy, dummy, dummy, intdummy);
+        unsigned short packetLossRate = 0;
+        if (fraction_lost > 0)
+        {
+            // Change from frac to %
+            packetLossRate = (fraction_lost * 100) >> 8;
+        }
+
+        JNIEnv* threadEnv = NULL;
+        int ret = webrtcGlobalVM->AttachCurrentThread(&threadEnv, NULL);
+        // Get the JNI env for this thread
+        if ((ret < 0) || !threadEnv)
+        {
+            __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                                "Could not attach thread to JVM (%d, %p)", ret,
+                                threadEnv);
+            return;
+        }
+        threadEnv->CallIntMethod(_callbackObj, _callbackId, framerate, bitrate,
+                                 packetLossRate, _frameRateO, _bitRateO);
+        webrtcGlobalVM->DetachCurrentThread();
+    }
+    ;
+
+    virtual void IncomingCodecChanged(const int videoChannel,
+                                      const webrtc::VideoCodec& videoCodec)
+    {
+    }
+    ;
+
+    virtual void RequestNewKeyFrame(const int videoChannel)
+    {
+    }
+    ;
+
+    virtual void OutgoingRate(const int videoChannel,
+                              const unsigned int framerate,
+                              const unsigned int bitrate)
+    {
+        _frameRateO = framerate;
+        _bitRateO = bitrate;
+        //__android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+        // "SendRate frameRate %d bitrate %d\n",frameRate,bitrate);
+    }
+    ;
+
+public:
+  VideoEngineData& _vieData;
+  JNIEnv * _env;
+  jobject _callbackObj;
+  jclass _callbackCls;
+  jmethodID _callbackId;
+  int _frameRateO, _bitRateO;
+  VideoCallbackAndroid(VideoEngineData& vieData, JNIEnv * env,
+                       jobject callback) :
+      _vieData(vieData), _env(env), _callbackObj(callback),
+      _frameRateO(0), _bitRateO(0) {
+    _callbackCls = _env->GetObjectClass(_callbackObj);
+    _callbackId
+        = _env->GetMethodID(_callbackCls, "UpdateStats", "(IIIII)I");
+    if (_callbackId == NULL) {
+      __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to get jid");
+    }
+    _callbackObj = _env->NewGlobalRef(_callbackObj);
+  }
+};
+
+// JNI_OnLoad
+jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) {
+  webrtcGlobalVM = vm;
+  if (!webrtcGlobalVM)
+  {
+    __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;
+  }
+
+  // Init VoiceEngine data
+  memset(&veData, 0, sizeof(veData));
+  // Store the JVM
+  veData.jvm = vm;
+
+  // Init VideoEngineData data
+  memset(&vieData, 0, sizeof(vieData));
+
+  return JNI_VERSION_1_4;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    NativeInit
+// Signature: (Landroid/content/Context;)Z
+JNIEXPORT jboolean JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_NativeInit(
+    JNIEnv * env,
+    jobject,
+    jobject context)
+{
+  return true;
+}
+
+// VideoEngine API wrapper functions
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    GetVideoEngine
+// Signature: ()I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_GetVideoEngine(
+    JNIEnv *,
+    jobject context) {
+
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "GetVideoEngine");
+
+  VideoEngine::SetAndroidObjects(webrtcGlobalVM, context);
+
+  // Check if already got
+  if (vieData.vie) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "ViE already got");
+    return -1;
+  }
+
+  // Create
+  vieData.vie = VideoEngine::Create();
+  if (!vieData.vie) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, "Get ViE failed");
+    return -1;
+  }
+  vieData.base = ViEBase::GetInterface(vieData.vie);
+  if (!vieData.base) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get base sub-API failed");
+    return -1;
+  }
+
+  vieData.codec = ViECodec::GetInterface(vieData.vie);
+  if (!vieData.codec) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get codec sub-API failed");
+    return -1;
+  }
+
+  vieData.netw = ViENetwork::GetInterface(vieData.vie);
+  if (!vieData.netw) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get network sub-API failed");
+    return -1;
+  }
+
+  vieData.rtp = ViERTP_RTCP::GetInterface(vieData.vie);
+  if (!vieData.rtp) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get RTP sub-API failed");
+    return -1;
+  }
+
+  vieData.render = ViERender::GetInterface(vieData.vie);
+  if (!vieData.render) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get Render sub-API failed");
+    return -1;
+  }
+
+  vieData.capture = ViECapture::GetInterface(vieData.vie);
+  if (!vieData.capture) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get Capture sub-API failed");
+    return -1;
+  }
+
+  return 0;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    Init
+// Signature: (IIIZ)I
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_Init(
+    JNIEnv *,
+    jobject,
+    jboolean enableTrace)
+{
+    if (vieData.vie) {
+      __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "Init");
+
+      int ret = vieData.base->Init();
+      __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                            "Init return %d", ret);
+        if (enableTrace)
+        {
+            __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                                "SetTraceFile");
+            if (0 != vieData.vie->SetTraceFile(("/sdcard/trace.txt"), false))
+            {
+                __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                                    "Video Engine could not enable trace");
+            }
+
+            __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                                "SetTraceFilter");
+            if (0 != vieData.vie->SetTraceFilter(webrtc::kTraceDefault))
+            {
+                __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG,
+                                    "Could not set trace filter");
+            }
+        }
+        else
+        {
+            if (0 != vieData.vie->SetTraceFilter(webrtc::kTraceNone))
+            {
+                __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG,
+                                    "Could not set trace filter");
+            }
+        }
+        if (veData.ve) // VoiceEngine is enabled
+        {
+            __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                                "SetVoiceEngine");
+            if (0 != vieData.base->SetVoiceEngine(veData.ve))
+            {
+                __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                                    "SetVoiceEngine failed");
+            }
+        }
+        return ret;
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+/*
+ * Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method:    Terminate
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_Terminate(
+    JNIEnv *,
+    jobject)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "Terminate");
+
+  if (vieData.vie) {
+    if (!vieData.rtp || vieData.rtp->Release() != 0) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to release RTP sub-API");
+    }
+
+    if (!vieData.netw || vieData.netw->Release() != 0) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to release Network sub-API");
+    }
+
+    if (!vieData.codec || vieData.codec->Release() != 0) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                                "Failed to release Codec sub-API");
+    }
+
+    if (!vieData.render || vieData.render->Release()) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to release Render sub-API");
+    }
+
+    if (!vieData.capture || vieData.capture->Release()) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to release Capture sub-API");
+    }
+
+    if (!vieData.base || vieData.base->Release() != 0) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to release Base sub-API");
+    }
+
+    // Delete Vie
+    if (!VideoEngine::Delete(vieData.vie)) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Failed to delete ViE ");
+      return -1;
+    }
+    memset(&vieData, 0, sizeof(vieData));
+    VideoEngine::SetAndroidObjects(NULL, NULL);
+    return 0;
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StartSend
+// Signature: (I)I
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartSend(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartSend");
+
+  if (vieData.base) {
+    int ret = vieData.base->StartSend(channel);
+    return ret;
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StopRender
+// Signature: (I)I
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopRender(
+                                                                            JNIEnv *,
+                                                                            jobject,
+                                                                            jint channel)
+{
+    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StopRender");
+
+    if (vieData.render) {
+        return vieData.render->StopRender(channel);
+    }
+    else {
+        return -1;
+    }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    Stop
+// Signature: ()I
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopSend(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StopSend");
+
+  if (vieData.base) {
+    return vieData.base->StopSend(channel);
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StartReceive
+// Signature: ()I
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartReceive(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartReceive");
+
+  if (vieData.base) {
+    return vieData.base->StartReceive(channel);
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StopReceive
+// Signature: ()I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopReceive(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StopReceive");
+  if (vieData.base) {
+    return vieData.base->StopReceive(channel);
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    CreateChannel
+// Signature: ()I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_CreateChannel(
+    JNIEnv *,
+    jobject,
+    jint voiceChannel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "CreateChannel");
+
+  if (vieData.vie) {
+    int channel = 0;
+    if (vieData.base->CreateChannel(channel) != 0) {
+      return -1;
+    }
+    if (voiceChannel >= 0) {
+      vieData.base->ConnectAudioChannel(channel, voiceChannel);
+    }
+
+    return channel;
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    SetLocalReceiver
+// Signature: (II)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetLocalReceiver(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jint port)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetLocalReceiver");
+
+  if (vieData.vie) {
+    int ret = vieData.netw->SetLocalReceiver(channel, port);
+    return ret;
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    SetSendDestination
+// Signature: (II[B)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetSendDestination(
+    JNIEnv * env,
+    jobject,
+    jint channel,
+    jint port,
+    jbyteArray ipadr)
+{
+
+  if (NULL == vieData.vie)
+    return -1;
+
+  char ip[64];
+  jsize len = env->GetArrayLength(ipadr);
+  if ((len >= 64) || (len == 0))
+    return -1;
+  env->GetByteArrayRegion(ipadr, 0, len, (jbyte*) ip);
+  ip[len] = '\0';
+
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                      "SetSendDestination: channel=%d, port=%d, ip=%s\n",
+                      channel, port, ip);
+
+  int ret = vieData.netw->SetSendDestination(channel, "127.0.0.1"/*ip*/, port);
+  return ret;
+}
+
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    SetReceiveCodec
+// Signature: (IIIIII)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetReceiveCodec(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jint codecNum,
+    jint intbitRate,
+    jint width,
+    jint height,
+    jint frameRate)
+{
+  if (NULL == vieData.codec)
+    return -1;
+
+  //Create codec
+  webrtc::VideoCodec codec;
+  vieData.codec->GetCodec(codecNum, codec);
+
+  __android_log_print(
+      ANDROID_LOG_DEBUG,
+      WEBRTC_LOG_TAG,
+      "SetReceiveCodec %s, pltype=%d, bitRate=%d, maxBitRate=%d,"
+      " width=%d, height=%d, frameRate=%d, codecSpecific=%d \n",
+      codec.plName, codec.plType, codec.startBitrate,
+      codec.maxBitrate, codec.width, codec.height,
+      codec.maxFramerate, codec.codecSpecific);
+  int ret = vieData.codec->SetReceiveCodec(channel, codec);
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                      "SetReceiveCodec return %d", ret);
+  return ret;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    SetSendCodec
+// Signature: (IIIIII)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetSendCodec(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jint codecNum,
+    jint intbitRate,
+    jint width,
+    jint height,
+    jint frameRate)
+{
+  if (NULL == vieData.codec)
+    return -1;
+
+  //Create codec
+  webrtc::VideoCodec codec;
+  vieData.codec->GetCodec(codecNum, codec);
+  codec.startBitrate = intbitRate;
+  codec.maxBitrate = 600;
+  codec.width = width;
+  codec.height = height;
+  codec.maxFramerate = frameRate;
+
+  for (int i = 0; i < vieData.codec->NumberOfCodecs(); ++i) {
+    webrtc::VideoCodec codecToList;
+    vieData.codec->GetCodec(i, codecToList);
+    __android_log_print(
+        ANDROID_LOG_DEBUG,
+        WEBRTC_LOG_TAG,
+        "Codec list %s, pltype=%d, bitRate=%d, maxBitRate=%d,"
+        " width=%d, height=%d, frameRate=%d\n",
+        codecToList.plName, codecToList.plType,
+        codecToList.startBitrate, codecToList.maxBitrate,
+        codecToList.width, codecToList.height,
+        codecToList.maxFramerate);
+  }
+  __android_log_print(
+      ANDROID_LOG_DEBUG,
+      WEBRTC_LOG_TAG,
+      "SetSendCodec %s, pltype=%d, bitRate=%d, maxBitRate=%d, "
+      "width=%d, height=%d, frameRate=%d\n",
+      codec.plName, codec.plType, codec.startBitrate,
+      codec.maxBitrate, codec.width, codec.height,
+      codec.maxFramerate);
+
+  return vieData.codec->SetSendCodec(channel, codec);
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    AddRemoteRenderer
+// Signature: (ILandroid/view/SurfaceView;)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_AddRemoteRenderer(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jobject glSurface)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "AddRemoteRenderer");
+  if (vieData.vie) {
+    return vieData.render->AddRenderer(channel, glSurface, 0, 0, 0, 1, 1);
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    RemoveRemoteRenderer
+// Signature: (I)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_RemoveRemoteRenderer(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "RemoveRemoteRenderer");
+
+  if (vieData.vie) {
+    return vieData.render->RemoveRenderer(channel);
+  }
+  else {
+    return -1;
+  }
+  return 0;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StartRender
+// Signature: (I)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartRender(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartRender");
+
+  if (vieData.render) {
+    return vieData.render->StartRender(channel);
+  }
+  else {
+    return -1;
+  }
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StarteCamera
+// Signature: (II)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartCamera(
+    JNIEnv * env,
+    jobject,
+    jint channel,
+    jint cameraNum)
+{
+  if (NULL == vieData.vie)
+    return -1;
+
+  int i = 0;
+  char deviceName[64];
+  char deviceUniqueName[64];
+  int re;
+  do {
+      re = vieData.capture->GetCaptureDevice(i, deviceName,
+                                             sizeof(deviceName),
+                                             deviceUniqueName,
+                                             sizeof(deviceUniqueName));
+      __android_log_print(
+          ANDROID_LOG_DEBUG,
+          WEBRTC_LOG_TAG,
+          "GetCaptureDevice ret %d devicenum %d deviceUniqueName %s",
+          re, i, deviceUniqueName);
+      i++;
+  } while (re == 0);
+
+  int ret;
+  int cameraId;
+  vieData.capture->GetCaptureDevice(cameraNum, deviceName,
+                                    sizeof(deviceName), deviceUniqueName,
+                                    sizeof(deviceUniqueName));
+  vieData.capture->AllocateCaptureDevice(deviceUniqueName,
+                                         sizeof(deviceUniqueName), cameraId);
+
+  if (cameraId >= 0) { //Connect the
+    ret = vieData.capture->ConnectCaptureDevice(cameraId, channel);
+    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                        "ConnectCaptureDevice ret %d ", ret);
+
+    ret = vieData.capture->StartCapture(cameraId);
+    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                            "StartCapture ret %d ", ret);
+  }
+
+  return cameraId;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    StopCamera
+// Signature: ()I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopCamera(
+    JNIEnv *,
+    jobject,
+    jint cameraId)
+{
+  if (NULL == vieData.capture)
+    return -1;
+
+  int ret = vieData.capture->StopCapture(cameraId);
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                      "StopCapture  ret %d ", ret);
+  ret = vieData.capture->ReleaseCaptureDevice(cameraId);
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                      "ReleaseCaptureDevice  ret %d ", ret);
+
+  return ret;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    GetCameraOrientation
+// Signature: (I)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_GetCameraOrientation(
+    JNIEnv *,
+    jobject,
+    jint cameraNum)
+{
+  char deviceName[64];
+  char deviceUniqueName[64];
+  int ret;
+
+  ret = vieData.capture->GetCaptureDevice(cameraNum, deviceName,
+                                          sizeof(deviceName),
+                                          deviceUniqueName,
+                                          sizeof(deviceUniqueName));
+  if (ret != 0) {
+    return -1;
+  }
+
+  RotateCapturedFrame orientation;
+  ret = vieData.capture->GetOrientation(deviceUniqueName, orientation);
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                      "GetOrientation  ret %d orientation %d", ret,
+                      orientation);
+
+  return (jint) orientation;
+
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    SetRotation
+// Signature: (II)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetRotation(
+    JNIEnv *,
+    jobject,
+    jint captureId,
+    jint degrees)
+{
+
+  if (NULL == vieData.capture)
+    return -1;
+  RotateCapturedFrame rotation = RotateCapturedFrame_0;
+  if (degrees == 90)
+    rotation = RotateCapturedFrame_90;
+  else if (degrees == 180)
+    rotation = RotateCapturedFrame_180;
+  else if (degrees == 270)
+    rotation = RotateCapturedFrame_270;
+
+  int ret = vieData.capture->SetRotateCapturedFrames(captureId, rotation);
+  return ret;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    EnableNACK
+// Signature: (IZ)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_EnableNACK(
+                                                                JNIEnv *,
+                                                                jobject,
+                                                                jint channel,
+                                                                jboolean enable)
+{
+  if (NULL == vieData.rtp)
+    return -1;
+
+  if (enable)
+    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                            "EnableNACK enable");
+  else
+    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                            "EnableNACK disable");
+
+  int ret = vieData.rtp->SetNACKStatus(channel, enable);
+  return ret;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    EnablePLI
+// Signature: (IZ)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_EnablePLI(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jboolean enable)
+{
+  if (NULL == vieData.rtp)
+    return -1;
+
+  if (enable)
+    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                        "EnablePLI enable");
+  else
+    __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                        "EnablePLI disable");
+
+  int ret = vieData.rtp->SetKeyFrameRequestMethod(channel,
+                                                  kViEKeyFrameRequestPliRtcp);
+  return ret;
+}
+
+// Class:     org_webrtc_videoengineapp_ViEAndroidJavaAPI
+// Method:    SetCallback
+// Signature: (ILorg/webrtc/videoengineapp/IViEAndroidCallback;)I
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetCallback(
+    JNIEnv * env,
+    jobject,
+    jint channel,
+    jobject callback)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetCallback");
+
+  if (NULL == vieData.codec)
+    return -1;
+  if (vieData.callback == NULL) {
+    vieData.callback = new VideoCallbackAndroid(vieData, env, callback);
+  }
+  else if (vieData.codec) {
+    vieData.codec->DeregisterDecoderObserver(channel); // Wrong channel?
+    vieData.codec->DeregisterEncoderObserver(channel);
+  }
+
+  vieData.codec->RegisterDecoderObserver(channel, *vieData.callback);
+  vieData.codec->RegisterEncoderObserver(channel, *vieData.callback);
+
+  return 0;
+}
+
+//
+// VoiceEngine API wrapper functions
+//
+
+// Create VoiceEngine instance
+JNIEXPORT jboolean JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Create(
+    JNIEnv *env,
+    jobject,
+    jobject context)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "Create");
+
+  // Check if already created
+  if (veData.ve) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "VoE already created");
+    return false;
+  }
+
+  // Init Android Object
+  VoiceEngine::SetAndroidObjects(veData.jvm, env, context);
+  // Create
+  veData.ve = VoiceEngine::Create();
+  if (!veData.ve) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Create VoE failed");
+    return false;
+  }
+
+  // Get sub-APIs
+  if (!VE_GetSubApis()) {
+    // If not OK, release all sub-APIs and delete VoE
+    VE_ReleaseSubApis();
+    if (!VoiceEngine::Delete(veData.ve)) {
+      __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                          "Delete VoE failed");
+    }
+    return false;
+  }
+
+  return true;
+}
+
+// Delete VoiceEngine instance
+JNIEXPORT jboolean JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Delete(
+    JNIEnv *,
+    jobject)
+{
+  // Check if exists
+  if (!veData.ve) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "VoE does not exist");
+    return false;
+  }
+
+  // Release sub-APIs
+  VE_ReleaseSubApis();
+
+  // Delete
+  if (!VoiceEngine::Delete(veData.ve)) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Delete VoE failed");
+    return false;
+  }
+
+  veData.ve = NULL;
+
+  // Clear instance independent Java objects
+  VoiceEngine::SetAndroidObjects(NULL, NULL, NULL);
+
+  return true;
+}
+
+// [Base] Initialize VoiceEngine
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Init(
+    JNIEnv *,
+    jobject,
+    jboolean enableTrace,
+    jboolean useExtTrans)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "VE_Init");
+
+  VALIDATE_BASE_POINTER;
+
+  if (useExtTrans) {
+    // Not implemented
+    return -1;
+  }
+
+  return veData.base->Init();
+}
+
+// [Base] Terminate VoiceEngine
+JNIEXPORT jint
+JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_Terminate(
+    JNIEnv *,
+    jobject)
+{
+  VALIDATE_BASE_POINTER;
+
+  jint retVal = veData.base->Terminate();
+  return retVal;
+}
+
+// [Base] Create channel
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_CreateChannel(
+    JNIEnv *,
+    jobject)
+{
+  VALIDATE_BASE_POINTER;
+
+  webrtc::CodecInst voiceCodec;
+  int numOfVeCodecs = veData.codec->NumOfCodecs();
+
+  //enum all the supported codec
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                      "Supported Voice Codec:\n");
+  for (int i = 0; i < numOfVeCodecs; ++i) {
+    if (veData.codec->GetCodec(i, voiceCodec) != -1) {
+      __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                          "num: %d name: %s\n", i, voiceCodec.plname);
+    }
+  }
+
+  jint channel = veData.base->CreateChannel();
+
+  return channel;
+}
+
+// [Base] Delete channel
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_DeleteChannel(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  VALIDATE_BASE_POINTER;
+  return veData.base->DeleteChannel(channel);
+}
+
+// [Base] SetLocalReceiver
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetLocalReceiver(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jint port)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetLocalReceiver");
+  VALIDATE_BASE_POINTER;
+  return veData.base->SetLocalReceiver(channel, port);
+}
+
+// [Base] SetSendDestination
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetSendDestination(
+    JNIEnv *env,
+    jobject,
+    jint channel,
+    jint port,
+    jstring ipaddr)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetSendDestination");
+  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 = veData.base->SetSendDestination(channel, port, ipaddrNative);
+  env->ReleaseStringUTFChars(ipaddr, ipaddrNative);
+  return retVal;
+}
+
+// [Base] StartListen
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StartListen(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartListen");
+  VALIDATE_BASE_POINTER;
+  return veData.base->StartReceive(channel);
+}
+
+// [Base] Start playout
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StartPlayout(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartPlayout");
+  VALIDATE_BASE_POINTER;
+  return veData.base->StartPlayout(channel);
+}
+
+// [Base] Start send
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StartSend(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "StartSend");
+  VALIDATE_BASE_POINTER;
+  return veData.base->StartSend(channel);
+}
+
+// [Base] Stop listen
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopListen(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  VALIDATE_BASE_POINTER;
+  return veData.base->StartReceive(channel);
+}
+
+// [Base] Stop playout
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopPlayout(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  VALIDATE_BASE_POINTER;
+  return veData.base->StopPlayout(channel);
+}
+
+// [Base] Stop send
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopSend(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  VALIDATE_BASE_POINTER;
+  return veData.base->StopSend(channel);
+}
+
+// [codec] Number of codecs
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_NumOfCodecs(
+    JNIEnv *,
+    jobject)
+{
+  VALIDATE_CODEC_POINTER;
+  return veData.codec->NumOfCodecs();
+}
+
+// [codec] Set send codec
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetSendCodec(
+    JNIEnv *,
+    jobject,
+    jint channel,
+    jint index)
+{
+  VALIDATE_CODEC_POINTER;
+
+  webrtc::CodecInst codec;
+
+  for (int i = 0; i < veData.codec->NumOfCodecs(); ++i) {
+    webrtc::CodecInst codecToList;
+    veData.codec->GetCodec(i, codecToList);
+    __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
+                        "VE Codec list %s, pltype=%d\n",
+                        codecToList.plname, codecToList.pltype);
+  }
+
+  if (veData.codec->GetCodec(index, codec) != 0) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Failed to get codec");
+    return -1;
+  }
+  __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetSendCodec %s\n",
+                      codec.plname);
+
+  return veData.codec->SetSendCodec(channel, codec);
+}
+
+// [audioprocessing] SetNSStatus
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetNSStatus(
+    JNIEnv *,
+    jobject,
+    jboolean enable,
+    jint mode)
+{
+  //TODO implement
+  return -1;
+}
+
+// [audioprocessing] SetAGCStatus
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetAGCStatus(
+    JNIEnv *,
+    jobject,
+    jboolean enable,
+    jint mode)
+{
+  //TODO implement
+  return -1;
+}
+
+// [audioprocessing] SetECStatus
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetECStatus(
+    JNIEnv *,
+    jobject,
+    jboolean enable,
+    jint mode,
+    jint AESmode,
+    jint AESattenuation)
+{
+  //TODO implement
+  return -1;
+}
+
+// [File] Start play file locally
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_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 = veData.file->StartPlayingFileLocally(channel,
+                                                     fileNameNative,
+                                                     loop);
+
+  env->ReleaseStringUTFChars(fileName, fileNameNative);
+
+  return retVal;
+}
+
+// [File] Stop play file locally
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopPlayingFileLocally(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  VALIDATE_FILE_POINTER;
+  return veData.file->StopPlayingFileLocally(channel);
+}
+
+// [File] Start playing file as microphone
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_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 = veData.file->StartPlayingFileAsMicrophone(channel,
+                                                          fileNameNative,
+                                                          loop);
+
+  env->ReleaseStringUTFChars(fileName, fileNameNative);
+
+  return retVal;
+}
+
+// [File] Stop playing file as microphone
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_StopPlayingFileAsMicrophone(
+    JNIEnv *,
+    jobject,
+    jint channel)
+{
+  VALIDATE_FILE_POINTER;
+  return veData.file->StopPlayingFileAsMicrophone(channel);
+}
+
+// [Volume] Set speaker volume
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetSpeakerVolume(
+    JNIEnv *,
+    jobject,
+    jint level)
+{
+  VALIDATE_VOLUME_POINTER;
+
+  if (veData.volume->SetSpeakerVolume(level) != 0) {
+    return -1;
+  }
+
+  unsigned int storedVolume = 0;
+  if (veData.volume->GetSpeakerVolume(storedVolume) != 0) {
+    return -1;
+  }
+
+  if (storedVolume != level) {
+    return -1;
+  }
+
+  return 0;
+}
+
+// [Hardware] Set speaker volume
+JNIEXPORT jint JNICALL
+Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VE_SetLoudspeakerStatus(
+    JNIEnv *,
+    jobject,
+    jboolean enable)
+{
+  VALIDATE_HARDWARE_POINTER;
+
+  if (veData.hardware->SetLoudspeakerStatus(enable) != 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+//
+// local function
+//
+
+// Get all sub-APIs
+bool VE_GetSubApis() {
+  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
+  veData.apm = VoEAudioProcessing::GetInterface(veData.ve);
+  if (!veData.apm) {
+    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+                        "Get VoEAudioProcessing 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;
+  }
+
+  return getOK;
+}
+
+// Release all sub-APIs
+bool VE_ReleaseSubApis() {
+  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;
+    }
+  }
+
+  return releaseOK;
+}
diff --git a/video_engine/main/test/AndroidTest/res/drawable/logo.png b/video_engine/main/test/android_test/res/drawable/logo.png
similarity index 100%
rename from video_engine/main/test/AndroidTest/res/drawable/logo.png
rename to video_engine/main/test/android_test/res/drawable/logo.png
Binary files differ
diff --git a/video_engine/main/test/android_test/res/layout/aconfig.xml b/video_engine/main/test/android_test/res/layout/aconfig.xml
new file mode 100644
index 0000000..e88b7c6
--- /dev/null
+++ b/video_engine/main/test/android_test/res/layout/aconfig.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout android:layout_width="fill_parent"
+	android:layout_height="fill_parent" android:orientation="vertical" 
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<TextView android:layout_width="wrap_content" 
+	android:layout_height="wrap_content"
+	android:textStyle="bold" 
+	android:textSize="24dip" 
+	android:text="Audio Settings"></TextView>
+	<TextView android:id="@+id/TextView03"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content">
+	</TextView>
+	<TextView android:id="@+id/TextView01"
+		  android:layout_height="wrap_content"
+		  android:layout_gravity="bottom"
+		  android:layout_width="wrap_content"
+		  android:text="@string/codecType">
+	</TextView>
+	<Spinner android:layout_height="wrap_content"
+		 android:layout_width="fill_parent"
+		 android:id="@+id/spVoiceCodecType">
+	</Spinner>
+		
+	<LinearLayout android:id="@+id/LinearLayout02"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">	
+	<TextView android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:text="@string/aTxPort">
+	</TextView>
+	<EditText android:layout_height="wrap_content"
+		  android:layout_width="wrap_content"
+		  android:id="@+id/etATxPort">
+	</EditText>
+	<TextView android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:text="@string/aRxPort">
+	</TextView>
+	<EditText android:layout_height="wrap_content"
+		  android:layout_width="wrap_content"
+		  android:id="@+id/etARxPort" >
+	</EditText>		
+	</LinearLayout>		
+	
+	<LinearLayout android:id="@+id/LinearLayout02"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbSpeaker"
+		  android:text="@string/speaker">
+	</CheckBox>
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbAutoGainControl"
+		  android:text="@string/AutoGainControl">
+	</CheckBox>	
+	</LinearLayout>
+	
+	<LinearLayout android:id="@+id/LinearLayout02"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbAECM"
+		  android:text="@string/AECM">
+	</CheckBox>
+	</LinearLayout>
+	
+	<LinearLayout android:id="@+id/LinearLayout03"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbNoiseSuppression"
+		  android:text="@string/NoiseSuppression">
+	</CheckBox>
+	</LinearLayout>	
+	
+</LinearLayout>
diff --git a/video_engine/main/test/AndroidTest/res/layout/both.xml b/video_engine/main/test/android_test/res/layout/both.xml
similarity index 100%
rename from video_engine/main/test/AndroidTest/res/layout/both.xml
rename to video_engine/main/test/android_test/res/layout/both.xml
diff --git a/video_engine/main/test/android_test/res/layout/main.xml b/video_engine/main/test/android_test/res/layout/main.xml
new file mode 100644
index 0000000..3b16cb7
--- /dev/null
+++ b/video_engine/main/test/android_test/res/layout/main.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout android:layout_width="fill_parent"
+	android:layout_height="fill_parent" android:layout_gravity="right"
+	android:orientation="vertical"
+	      xmlns:android="http://schemas.android.com/apk/res/android">
+
+	<TextView android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/tvTitle"
+		  android:textStyle="bold"
+		  android:textSize="24dip"
+		  android:text="@string/gSettings">
+	</TextView>
+	<TextView android:id="@+id/TextView03"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content">
+	</TextView>
+	<LinearLayout android:id="@+id/LinearLayout02"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbVideoReceive"
+		  android:text="@string/enableVideoReceive">
+	</CheckBox>
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbVideoSend"
+		  android:text="@string/enableVideoSend">
+	</CheckBox>
+	</LinearLayout>
+	
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbVoice"
+		  android:text="@string/enableVoice">
+	</CheckBox>
+		
+	<TextView android:id="@+id/TextView02"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:text="@string/remoteIp">
+	</TextView>
+	<EditText android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/etRemoteIp" >
+	</EditText>
+	
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbLoopback"
+		  android:text="@string/loopback">
+	</CheckBox>
+</LinearLayout>
diff --git a/video_engine/main/test/android_test/res/layout/send.xml b/video_engine/main/test/android_test/res/layout/send.xml
new file mode 100644
index 0000000..ee230f5
--- /dev/null
+++ b/video_engine/main/test/android_test/res/layout/send.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	      android:orientation="vertical"
+	      android:layout_width="fill_parent"
+	      android:layout_height="fill_parent">
+
+
+  <SurfaceView android:id="@+id/svLocal"
+	       android:layout_width="wrap_content"
+	       android:layout_height="wrap_content">
+  </SurfaceView>
+  <ImageView android:id="@+id/ivPreview"
+	     android:layout_height="fill_parent"
+	     android:layout_width="fill_parent">
+  </ImageView>
+
+</LinearLayout>
diff --git a/video_engine/main/test/android_test/res/layout/stats.xml b/video_engine/main/test/android_test/res/layout/stats.xml
new file mode 100644
index 0000000..1612ec3
--- /dev/null
+++ b/video_engine/main/test/android_test/res/layout/stats.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout android:layout_width="fill_parent"
+	android:layout_height="fill_parent" android:orientation="vertical" 
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<TextView android:layout_width="wrap_content" 
+	android:layout_height="wrap_content"
+	android:textStyle="bold" 
+	android:textSize="24dip" 
+	android:text="Stats">
+	</TextView>
+	
+	<TextView android:id="@+id/TextView03"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content">
+	</TextView>
+	
+	<TextView android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/tvLocalIp"
+		  android:textStyle="bold">
+	</TextView>
+	
+	<TextView android:id="@+id/TextView03"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content">
+	</TextView>
+	
+	<TextView android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/tvFrameRateI"
+		  android:textStyle="bold">
+	</TextView>
+	<TextView android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/tvBitRateI"
+		  android:textStyle="bold">
+	</TextView>
+	<TextView android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/tvPacketLoss"
+		  android:textStyle="bold">
+	</TextView>
+	
+	<TextView android:id="@+id/TextView03"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content">
+	</TextView>
+	
+	<TextView android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/tvFrameRateO"
+		  android:textStyle="bold">
+	</TextView>
+	<TextView android:layout_height="wrap_content"
+		  android:layout_width="fill_parent"
+		  android:id="@+id/tvBitRateO"
+		  android:textStyle="bold">
+	</TextView>
+</LinearLayout>
diff --git a/video_engine/main/test/android_test/res/layout/tabhost.xml b/video_engine/main/test/android_test/res/layout/tabhost.xml
new file mode 100644
index 0000000..9997113
--- /dev/null
+++ b/video_engine/main/test/android_test/res/layout/tabhost.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+	 android:id="@android:id/tabhost"
+	 android:layout_width="fill_parent"
+	 android:layout_height="fill_parent">
+  <LinearLayout
+     android:orientation="vertical"
+     android:layout_width="fill_parent"
+     android:layout_height="fill_parent">
+    <TabWidget
+       android:id="@android:id/tabs"
+       android:layout_width="fill_parent"
+       android:layout_height="wrap_content" />
+    <FrameLayout
+       android:id="@android:id/tabcontent"
+       android:layout_width="fill_parent"
+       android:layout_height="fill_parent">            
+      <include android:id="@+id/tab_video" layout="@layout/both" />
+      <include android:id="@+id/tab_config" layout="@layout/main" />
+      <include android:id="@+id/tab_vconfig" layout="@layout/vconfig" />
+      <include android:id="@+id/tab_aconfig" layout="@layout/aconfig" />
+      <include android:id="@+id/tab_stats" layout="@layout/stats" />		  
+    </FrameLayout>
+  </LinearLayout>
+</TabHost>
diff --git a/video_engine/main/test/android_test/res/layout/vconfig.xml b/video_engine/main/test/android_test/res/layout/vconfig.xml
new file mode 100644
index 0000000..5270c10
--- /dev/null
+++ b/video_engine/main/test/android_test/res/layout/vconfig.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout android:layout_width="fill_parent"
+	android:layout_height="fill_parent" android:orientation="vertical" 
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<TextView android:layout_width="wrap_content" 
+	android:layout_height="wrap_content"
+	android:textStyle="bold" 
+	android:textSize="24dip" 
+	android:text="@string/vSettings">
+	</TextView>
+	
+	<TextView android:id="@+id/TextView03"
+		  android:layout_width="wrap_content"
+		  android:layout_height="wrap_content">
+	</TextView>	
+	
+	<TextView android:id="@+id/TextView01"
+		  android:layout_height="wrap_content"
+		  android:layout_width="wrap_content"
+		  android:text="@string/codecType">
+	</TextView>
+	<Spinner android:layout_height="wrap_content"
+		 android:layout_width="fill_parent"
+		 android:id="@+id/spCodecType">
+	</Spinner>
+	
+	<TextView android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/tvCodecSize"
+		  android:text="@string/codecSize">
+	</TextView>
+	<Spinner android:layout_height="wrap_content"
+		 android:layout_width="fill_parent"
+		 android:id="@+id/spCodecSize">
+	</Spinner>
+	
+	<LinearLayout android:id="@+id/LinearLayout02"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">
+	<TextView android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:text="@string/vTxPort">
+	</TextView>
+	<EditText android:layout_height="wrap_content"
+		  android:layout_width="wrap_content"
+		  android:id="@+id/etVTxPort" >
+	</EditText>
+	<TextView android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:text="@string/vRxPort">
+	</TextView>
+	<EditText android:layout_height="wrap_content"
+		  android:layout_width="wrap_content"
+		  android:id="@+id/etVRxPort" >
+	</EditText>
+	</LinearLayout>
+	
+	<LinearLayout android:id="@+id/LinearLayout03"
+		      android:layout_height="wrap_content"
+		      android:layout_width="fill_parent">
+	<CheckBox android:layout_width="wrap_content"
+		  android:layout_height="wrap_content"
+		  android:id="@+id/cbNack"
+		  android:text="@string/nack">
+	</CheckBox>	
+	</LinearLayout>
+</LinearLayout>
diff --git a/video_engine/main/test/AndroidTest/res/values/arrays.xml b/video_engine/main/test/android_test/res/values/arrays.xml
similarity index 100%
rename from video_engine/main/test/AndroidTest/res/values/arrays.xml
rename to video_engine/main/test/android_test/res/values/arrays.xml
diff --git a/video_engine/main/test/AndroidTest/res/values/strings.xml b/video_engine/main/test/android_test/res/values/strings.xml
similarity index 100%
rename from video_engine/main/test/AndroidTest/res/values/strings.xml
rename to video_engine/main/test/android_test/res/values/strings.xml
diff --git a/video_engine/main/test/AndroidTest/src/org/webrtc/videoengineapp/IViEAndroidCallback.java b/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/IViEAndroidCallback.java
similarity index 100%
rename from video_engine/main/test/AndroidTest/src/org/webrtc/videoengineapp/IViEAndroidCallback.java
rename to video_engine/main/test/android_test/src/org/webrtc/videoengineapp/IViEAndroidCallback.java
diff --git a/video_engine/main/test/AndroidTest/src/org/webrtc/videoengineapp/ViEAndroidDemo.java b/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidDemo.java
similarity index 100%
rename from video_engine/main/test/AndroidTest/src/org/webrtc/videoengineapp/ViEAndroidDemo.java
rename to video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidDemo.java
diff --git a/video_engine/main/test/AndroidTest/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java b/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java
similarity index 100%
rename from video_engine/main/test/AndroidTest/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java
rename to video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java