/*
 *  Copyright (c) 2012 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 "video_capture_android.h"

#include <stdio.h>

#include "critical_section_wrapper.h"
#include "ref_count.h"
#include "trace.h"

namespace webrtc
{
#if defined(WEBRTC_ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
// TODO(leozwang) These SetAndroidVM apis will be refactored, thus we only
// keep and reference java vm.
WebRtc_Word32 SetCaptureAndroidVM(void* javaVM, void* javaContext) {
  return videocapturemodule::VideoCaptureAndroid::SetAndroidObjects(
      javaVM,
      javaContext);
}
#endif

namespace videocapturemodule
{

VideoCaptureModule* VideoCaptureImpl::Create(
    const WebRtc_Word32 id,
    const char* deviceUniqueIdUTF8) {

  RefCountImpl<videocapturemodule::VideoCaptureAndroid>* implementation =
      new RefCountImpl<videocapturemodule::VideoCaptureAndroid>(id);

  if (!implementation || implementation->Init(id, deviceUniqueIdUTF8) != 0) {
    delete implementation;
    implementation = NULL;
  }
  return implementation;
}

// Android logging, uncomment to print trace to
// logcat instead of trace file/callback
// #include <android/log.h>
// #undef WEBRTC_TRACE
// #define WEBRTC_TRACE(a,b,c,...)
// __android_log_print(ANDROID_LOG_DEBUG, "*WEBRTCN*", __VA_ARGS__)

JavaVM* VideoCaptureAndroid::g_jvm = NULL;
//VideoCaptureAndroid.java
jclass VideoCaptureAndroid::g_javaCmClass = NULL;
//VideoCaptureDeviceInfoAndroid.java
jclass VideoCaptureAndroid::g_javaCmDevInfoClass = NULL;
//static instance of VideoCaptureDeviceInfoAndroid.java
jobject VideoCaptureAndroid::g_javaCmDevInfoObject = NULL;
jobject VideoCaptureAndroid::g_javaContext = NULL;

/*
 * Register references to Java Capture class.
 */
WebRtc_Word32 VideoCaptureAndroid::SetAndroidObjects(void* javaVM,
                                                     void* javaContext) {

  g_jvm = static_cast<JavaVM*> (javaVM);
  g_javaContext = static_cast<jobject> (javaContext);

  if (javaVM) {
    JNIEnv* env = NULL;
    if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: could not get Java environment", __FUNCTION__);
      return -1;
    }
    // get java capture class type (note path to class packet)
    jclass javaCmClassLocal = env->FindClass(AndroidJavaCaptureClass);
    if (!javaCmClassLocal) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: could not find java class", __FUNCTION__);
      return -1;
    }
    // create a global reference to the class
    // (to tell JNI that we are referencing it
    // after this function has returned)
    g_javaCmClass = static_cast<jclass>
        (env->NewGlobalRef(javaCmClassLocal));
    if (!g_javaCmClass) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: InitVideoEngineJava(): could not create"
                   " Java Camera class reference",
                   __FUNCTION__);
      return -1;
    }
    // Delete local class ref, we only use the global ref
    env->DeleteLocalRef(javaCmClassLocal);
    JNINativeMethod nativeFunctions =
        { "ProvideCameraFrame", "([BIJ)V",
          (void*) &VideoCaptureAndroid::ProvideCameraFrame };
    if (env->RegisterNatives(g_javaCmClass, &nativeFunctions, 1) == 0) {
      WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                   "%s: Registered native functions", __FUNCTION__);
    }
    else {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: Failed to register native functions",
                   __FUNCTION__);
      return -1;
    }

    // get java capture class type (note path to class packet)
    jclass javaCmDevInfoClassLocal = env->FindClass(
        AndroidJavaCaptureDeviceInfoClass);
    if (!javaCmDevInfoClassLocal) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: could not find java class", __FUNCTION__);
      return -1;
    }

    // create a global reference to the class
    // (to tell JNI that we are referencing it
    // after this function has returned)
    g_javaCmDevInfoClass = static_cast<jclass>
        (env->NewGlobalRef(javaCmDevInfoClassLocal));
    if (!g_javaCmDevInfoClass) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: InitVideoEngineJava(): could not create Java "
                   "Camera Device info class reference",
                   __FUNCTION__);
      return -1;
    }
    // Delete local class ref, we only use the global ref
    env->DeleteLocalRef(javaCmDevInfoClassLocal);

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                 "VideoCaptureDeviceInfoAndroid get method id");

    // get the method ID for the Android Java CaptureClass static
    //CreateVideoCaptureAndroid factory method.
    jmethodID cid = env->GetStaticMethodID(
        g_javaCmDevInfoClass,
        "CreateVideoCaptureDeviceInfoAndroid",
        "(ILandroid/content/Context;)"
        "Lorg/webrtc/videoengine/VideoCaptureDeviceInfoAndroid;");
    if (cid == NULL) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: could not get java"
                   "VideoCaptureDeviceInfoAndroid constructor ID",
                   __FUNCTION__);
      return -1;
    }

    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                 "%s: construct static java device object", __FUNCTION__);

    // construct the object by calling the static constructor object
    jobject javaCameraDeviceInfoObjLocal =
        env->CallStaticObjectMethod(g_javaCmDevInfoClass,
                                    cid, (int) -1,
                                    g_javaContext);
    if (!javaCameraDeviceInfoObjLocal) {
      WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, -1,
                   "%s: could not create Java Capture Device info object",
                   __FUNCTION__);
      return -1;
    }
    // create a reference to the object (to tell JNI that
    // we are referencing it after this function has returned)
    g_javaCmDevInfoObject = env->NewGlobalRef(javaCameraDeviceInfoObjLocal);
    if (!g_javaCmDevInfoObject) {
      WEBRTC_TRACE(webrtc::kTraceError,
                   webrtc::kTraceAudioDevice,
                   -1,
                   "%s: could not create Java"
                   "cameradevinceinfo object reference",
                   __FUNCTION__);
      return -1;
    }
    // Delete local object ref, we only use the global ref
    env->DeleteLocalRef(javaCameraDeviceInfoObjLocal);
    return 0;
  }
  else {
    WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
                 "%s: JVM is NULL, assuming deinit", __FUNCTION__);
    if (!g_jvm) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: SetAndroidObjects not called with a valid JVM.",
                   __FUNCTION__);
      return -1;
    }
    JNIEnv* env = NULL;
    bool attached = false;
    if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
      // try to attach the thread and get the env
      // Attach this thread to JVM
      jint res = g_jvm->AttachCurrentThread(&env, NULL);
      if ((res < 0) || !env) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,
                     -1, "%s: Could not attach thread to JVM (%d, %p)",
                     __FUNCTION__, res, env);
        return -1;
      }
      attached = true;
    }
    env->DeleteGlobalRef(g_javaCmDevInfoObject);
    env->DeleteGlobalRef(g_javaCmDevInfoClass);
    env->DeleteGlobalRef(g_javaCmClass);
    if (attached && g_jvm->DetachCurrentThread() < 0) {
      WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, -1,
                   "%s: Could not detach thread from JVM", __FUNCTION__);
      return -1;
    }
    return 0;
    env = (JNIEnv *) NULL;
  }
  return 0;
}

WebRtc_Word32 VideoCaptureAndroid::AttachAndUseAndroidDeviceInfoObjects(
    JNIEnv*& env,
    jclass& javaCmDevInfoClass,
    jobject& javaCmDevInfoObject,
    bool& attached) {
  // get the JNI env for this thread
  if (!g_jvm) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                 "%s: SetAndroidObjects not called with a valid JVM.",
                 __FUNCTION__);
    return -1;
  }
  attached = false;
  if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    // try to attach the thread and get the env
    // Attach this thread to JVM
    jint res = g_jvm->AttachCurrentThread(&env, NULL);
    if ((res < 0) || !env) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: Could not attach thread to JVM (%d, %p)",
                   __FUNCTION__, res, env);
      return -1;
    }
    attached = true;
  }
  javaCmDevInfoClass = g_javaCmDevInfoClass;
  javaCmDevInfoObject = g_javaCmDevInfoObject;
  return 0;

}

WebRtc_Word32 VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(
    bool attached) {
  if (attached && g_jvm->DetachCurrentThread() < 0) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, -1,
                 "%s: Could not detach thread from JVM", __FUNCTION__);
    return -1;
  }
  return 0;
}

/*
 * JNI callback from Java class. Called
 * when the camera has a new frame to deliver
 * Class:     org_webrtc_capturemodule_VideoCaptureAndroid
 * Method:    ProvideCameraFrame
 * Signature: ([BIJ)V
 */
void JNICALL VideoCaptureAndroid::ProvideCameraFrame(JNIEnv * env,
                                                     jobject,
                                                     jbyteArray javaCameraFrame,
                                                     jint length,
                                                     jlong context) {
  VideoCaptureAndroid* captureModule =
      reinterpret_cast<VideoCaptureAndroid*>(context);
  WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture,
               -1, "%s: IncomingFrame %d", __FUNCTION__,length);
  jbyte* cameraFrame= env->GetByteArrayElements(javaCameraFrame,NULL);
  captureModule->IncomingFrame((WebRtc_UWord8*) cameraFrame,
                               length,captureModule->_frameInfo,0);
  env->ReleaseByteArrayElements(javaCameraFrame,cameraFrame,JNI_ABORT);
}



VideoCaptureAndroid::VideoCaptureAndroid(const WebRtc_Word32 id)
    : VideoCaptureImpl(id), _capInfo(id), _javaCaptureObj(NULL),
      _captureStarted(false) {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
               "%s: context %x", __FUNCTION__, (int) this);
}

// ----------------------------------------------------------------------------
//  Init
//
//  Initializes needed Java resources like the JNI interface to
//  VideoCaptureAndroid.java
// ----------------------------------------------------------------------------
WebRtc_Word32 VideoCaptureAndroid::Init(const WebRtc_Word32 id,
                                        const char* deviceUniqueIdUTF8) {
  const int nameLength = strlen(deviceUniqueIdUTF8);
  if (nameLength >= kVideoCaptureUniqueNameLength) {
    return -1;
  }

  // Store the device name
  _deviceUniqueId = new char[nameLength + 1];
  memcpy(_deviceUniqueId, deviceUniqueIdUTF8, nameLength + 1);

  if (_capInfo.Init() != 0) {
    WEBRTC_TRACE(webrtc::kTraceError,
                 webrtc::kTraceVideoCapture,
                 _id,
                 "%s: Failed to initialize CaptureDeviceInfo",
                 __FUNCTION__);
    return -1;
  }

  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1, "%s:",
               __FUNCTION__);
  // use the jvm that has been set
  if (!g_jvm) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                 "%s: Not a valid Java VM pointer", __FUNCTION__);
    return -1;
  }
  // get the JNI env for this thread
  JNIEnv *env;
  bool isAttached = false;

  // get the JNI env for this thread
  if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    // try to attach the thread and get the env
    // Attach this thread to JVM
    jint res = g_jvm->AttachCurrentThread(&env, NULL);
    if ((res < 0) || !env) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                   "%s: Could not attach thread to JVM (%d, %p)",
                   __FUNCTION__, res, env);
      return -1;
    }
    isAttached = true;
  }

  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
               "get method id");

  // get the method ID for the Android Java
  // CaptureDeviceInfoClass AllocateCamera factory method.
  char signature[256];
  sprintf(signature, "(IJLjava/lang/String;)L%s;", AndroidJavaCaptureClass);

  jmethodID cid = env->GetMethodID(g_javaCmDevInfoClass, "AllocateCamera",
                                   signature);
  if (cid == NULL) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                 "%s: could not get constructor ID", __FUNCTION__);
    return -1; /* exception thrown */
  }

  jstring capureIdString = env->NewStringUTF((char*) deviceUniqueIdUTF8);
  // construct the object by calling the static constructor object
  jobject javaCameraObjLocal = env->CallObjectMethod(g_javaCmDevInfoObject,
                                                     cid, (jint) id,
                                                     (jlong) this,
                                                     capureIdString);
  if (!javaCameraObjLocal) {
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                 "%s: could not create Java Capture object", __FUNCTION__);
    return -1;
  }

  // create a reference to the object (to tell JNI that we are referencing it
  // after this function has returned)
  _javaCaptureObj = env->NewGlobalRef(javaCameraObjLocal);
  if (!_javaCaptureObj) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioDevice, _id,
                 "%s: could not create Java camera object reference",
                 __FUNCTION__);
    return -1;
  }

  // Delete local object ref, we only use the global ref
  env->DeleteLocalRef(javaCameraObjLocal);

  // Detach this thread if it was attached
  if (isAttached) {
    if (g_jvm->DetachCurrentThread() < 0) {
      WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioDevice, _id,
                   "%s: Could not detach thread from JVM", __FUNCTION__);
    }
  }

  return 0;
}

VideoCaptureAndroid::~VideoCaptureAndroid() {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1, "%s:",
               __FUNCTION__);
  if (_javaCaptureObj == NULL || g_jvm == NULL) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                 "%s: Nothing to clean", __FUNCTION__);
  }
  else {
    bool isAttached = false;
    // get the JNI env for this thread
    JNIEnv *env;
    if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
      // try to attach the thread and get the env
      // Attach this thread to JVM
      jint res = g_jvm->AttachCurrentThread(&env, NULL);
      if ((res < 0) || !env) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,
                     _id,
                     "%s: Could not attach thread to JVM (%d, %p)",
                     __FUNCTION__, res, env);
      }
      else {
        isAttached = true;
      }
    }

    // get the method ID for the Android Java CaptureClass static
    // DeleteVideoCaptureAndroid  method. Call this to release the camera so
    // another application can use it.
    jmethodID cid = env->GetStaticMethodID(
        g_javaCmClass,
        "DeleteVideoCaptureAndroid",
        "(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
    if (cid != NULL) {
      WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                   "%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
      // Close the camera by calling the static destruct function.
      env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);

      // Delete global object ref to the camera.
      env->DeleteGlobalRef(_javaCaptureObj);
      _javaCaptureObj = NULL;
    }
    else {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: Failed to find DeleteVideoCaptureAndroid id",
                   __FUNCTION__);
    }

    // Detach this thread if it was attached
    if (isAttached) {
      if (g_jvm->DetachCurrentThread() < 0) {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioDevice,
                     _id, "%s: Could not detach thread from JVM",
                     __FUNCTION__);
      }
    }
  }
}

WebRtc_Word32 VideoCaptureAndroid::StartCapture(
    const VideoCaptureCapability& capability) {
  CriticalSectionScoped cs(&_apiCs);
  WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
               "%s: ", __FUNCTION__);

  bool isAttached = false;
  WebRtc_Word32 result = 0;
  // get the JNI env for this thread
  JNIEnv *env;
  if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    // try to attach the thread and get the env
    // Attach this thread to JVM
    jint res = g_jvm->AttachCurrentThread(&env, NULL);
    if ((res < 0) || !env) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                   "%s: Could not attach thread to JVM (%d, %p)",
                   __FUNCTION__, res, env);
    }
    else {
      isAttached = true;
    }
  }

  if (_capInfo.GetBestMatchedCapability(_deviceUniqueId, capability,
                                        _frameInfo) < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                 "%s: GetBestMatchedCapability failed. Req cap w%d h%d",
                 __FUNCTION__, capability.width, capability.height);
    return -1;
  }

  // Store the new expected capture delay
  _captureDelay = _frameInfo.expectedCaptureDelay;

  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
               "%s: _frameInfo w%d h%d", __FUNCTION__, _frameInfo.width,
               _frameInfo.height);

  // get the method ID for the Android Java
  // CaptureClass static StartCapture  method.
  jmethodID cid = env->GetMethodID(g_javaCmClass, "StartCapture", "(III)I");
  if (cid != NULL) {
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                 "%s: Call StartCapture", __FUNCTION__);
    // Close the camera by calling the static destruct function.
    result = env->CallIntMethod(_javaCaptureObj, cid, _frameInfo.width,
                                _frameInfo.height, _frameInfo.maxFPS);
  }
  else {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                 "%s: Failed to find StartCapture id", __FUNCTION__);
  }

  // Detach this thread if it was attached
  if (isAttached) {
    if (g_jvm->DetachCurrentThread() < 0) {
      WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioDevice, _id,
                   "%s: Could not detach thread from JVM", __FUNCTION__);
    }
  }
  if (result == 0) {
    _requestedCapability = capability;
    _captureStarted = true;
  }
  WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
               "%s: result %d", __FUNCTION__, result);
  return result;
}

WebRtc_Word32 VideoCaptureAndroid::StopCapture() {
  CriticalSectionScoped cs(&_apiCs);
  WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
               "%s: ", __FUNCTION__);

  bool isAttached = false;
  WebRtc_Word32 result = 0;
  // get the JNI env for this thread
  JNIEnv *env = NULL;
  if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    // try to attach the thread and get the env
    // Attach this thread to JVM
    jint res = g_jvm->AttachCurrentThread(&env, NULL);
    if ((res < 0) || !env) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                   "%s: Could not attach thread to JVM (%d, %p)",
                   __FUNCTION__, res, env);
    }
    else {
      isAttached = true;
    }
  }

  memset(&_requestedCapability, 0, sizeof(_requestedCapability));
  memset(&_frameInfo, 0, sizeof(_frameInfo));

  // get the method ID for the Android Java CaptureClass StopCapture  method.
  jmethodID cid = env->GetMethodID(g_javaCmClass, "StopCapture", "()I");
  if (cid != NULL) {
    WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                 "%s: Call StopCapture", __FUNCTION__);
    // Close the camera by calling the static destruct function.
    result = env->CallIntMethod(_javaCaptureObj, cid);
  }
  else {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                 "%s: Failed to find StopCapture id", __FUNCTION__);
  }

  // Detach this thread if it was attached
  if (isAttached) {
    if (g_jvm->DetachCurrentThread() < 0) {
      WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioDevice, _id,
                   "%s: Could not detach thread from JVM", __FUNCTION__);
    }
  }
  _captureStarted = false;

  WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
               "%s: result %d", __FUNCTION__, result);
  return result;
}

bool VideoCaptureAndroid::CaptureStarted() {
  CriticalSectionScoped cs(&_apiCs);
  WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
               "%s: ", __FUNCTION__);
  return _captureStarted;
}

WebRtc_Word32 VideoCaptureAndroid::CaptureSettings(
    VideoCaptureCapability& settings) {
  CriticalSectionScoped cs(&_apiCs);
  WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
               "%s: ", __FUNCTION__);
  settings = _requestedCapability;
  return 0;
}

WebRtc_Word32 VideoCaptureAndroid::SetCaptureRotation(
    VideoCaptureRotation rotation) {
  CriticalSectionScoped cs(&_apiCs);
  if (VideoCaptureImpl::SetCaptureRotation(rotation) == 0) {
    if (!g_jvm)
      return -1;

    // get the JNI env for this thread
    JNIEnv *env;
    bool isAttached = false;

    // get the JNI env for this thread
    if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
      // try to attach the thread and get the env
      // Attach this thread to JVM
      jint res = g_jvm->AttachCurrentThread(&env, NULL);
      if ((res < 0) || !env) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,
                     _id,
                     "%s: Could not attach thread to JVM (%d, %p)",
                     __FUNCTION__, res, env);
        return -1;
      }
      isAttached = true;
    }

    jmethodID cid = env->GetMethodID(g_javaCmClass, "SetPreviewRotation",
                                     "(I)V");
    if (cid == NULL) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                   "%s: could not get java SetPreviewRotation ID",
                   __FUNCTION__);
      return -1;
    }
    jint rotateFrame = 0;
    switch (rotation) {
      case kCameraRotate0:
        rotateFrame = 0;
        break;
      case kCameraRotate90:
        rotateFrame = 90;
        break;
      case kCameraRotate180:
        rotateFrame = 180;
        break;
      case kCameraRotate270:
        rotateFrame = 270;
        break;
    }
    env->CallVoidMethod(_javaCaptureObj, cid, rotateFrame);

    // Detach this thread if it was attached
    if (isAttached) {
      if (g_jvm->DetachCurrentThread() < 0) {
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioDevice,
                     _id, "%s: Could not detach thread from JVM",
                     __FUNCTION__);
      }
    }

  }
  return 0;
}

}  // namespace videocapturemodule
}  // namespace webrtc
