/* * Copyright (c) 2013 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 "webrtc/modules/audio_device/android/audio_manager_jni.h" #include #include "webrtc/modules/utility/interface/helpers_android.h" #include "webrtc/system_wrappers/interface/trace.h" namespace webrtc { static JavaVM* g_jvm_ = NULL; static JNIEnv* g_jni_env_ = NULL; static jobject g_context_ = NULL; static jclass g_audio_manager_class_ = NULL; static jobject g_audio_manager_ = NULL; AudioManagerJni::AudioManagerJni() : low_latency_supported_(false), native_output_sample_rate_(0), native_buffer_size_(0) { if (!HasDeviceObjects()) { assert(false); } AttachThreadScoped ats(g_jvm_); JNIEnv* env = ats.env(); assert(env && "Unsupported JNI version!"); CreateInstance(env); // Pre-store device specific values. SetLowLatencySupported(env); SetNativeOutputSampleRate(env); SetNativeFrameSize(env); } void AudioManagerJni::SetAndroidAudioDeviceObjects(void* jvm, void* env, void* context) { assert(jvm); assert(env); assert(context); // Store global Java VM variables to be accessed by API calls. g_jvm_ = reinterpret_cast(jvm); g_jni_env_ = reinterpret_cast(env); g_context_ = g_jni_env_->NewGlobalRef(reinterpret_cast(context)); // FindClass must be made in this function since this function's contract // requires it to be called by a Java thread. // See // http://developer.android.com/training/articles/perf-jni.html#faq_FindClass // as to why this is necessary. // Get the AudioManagerAndroid class object. jclass javaAmClassLocal = g_jni_env_->FindClass( "org/webrtc/voiceengine/AudioManagerAndroid"); assert(javaAmClassLocal); // Create a global reference such that the class object is not recycled by // the garbage collector. g_audio_manager_class_ = reinterpret_cast( g_jni_env_->NewGlobalRef(javaAmClassLocal)); assert(g_audio_manager_class_); } void AudioManagerJni::ClearAndroidAudioDeviceObjects() { g_jni_env_->DeleteGlobalRef(g_audio_manager_class_); g_audio_manager_class_ = NULL; g_jni_env_->DeleteGlobalRef(g_context_); g_context_ = NULL; g_jni_env_->DeleteGlobalRef(g_audio_manager_); g_audio_manager_ = NULL; g_jni_env_ = NULL; g_jvm_ = NULL; } void AudioManagerJni::SetLowLatencySupported(JNIEnv* env) { jmethodID id = LookUpMethodId(env, "isAudioLowLatencySupported", "()Z"); low_latency_supported_ = env->CallBooleanMethod(g_audio_manager_, id); } void AudioManagerJni::SetNativeOutputSampleRate(JNIEnv* env) { jmethodID id = LookUpMethodId(env, "getNativeOutputSampleRate", "()I"); native_output_sample_rate_ = env->CallIntMethod(g_audio_manager_, id); } void AudioManagerJni::SetNativeFrameSize(JNIEnv* env) { jmethodID id = LookUpMethodId(env, "getAudioLowLatencyOutputFrameSize", "()I"); native_buffer_size_ = env->CallIntMethod(g_audio_manager_, id); } bool AudioManagerJni::HasDeviceObjects() { return g_jvm_ && g_jni_env_ && g_context_ && g_audio_manager_class_; } jmethodID AudioManagerJni::LookUpMethodId(JNIEnv* env, const char* method_name, const char* method_signature) { jmethodID ret_val = env->GetMethodID(g_audio_manager_class_, method_name, method_signature); assert(ret_val); return ret_val; } void AudioManagerJni::CreateInstance(JNIEnv* env) { // Get the method ID for the constructor taking Context. jmethodID id = LookUpMethodId(env, "", "(Landroid/content/Context;)V"); g_audio_manager_ = env->NewObject(g_audio_manager_class_, id, g_context_); // Create a global reference so that the instance is accessible until no // longer needed. g_audio_manager_ = env->NewGlobalRef(g_audio_manager_); assert(g_audio_manager_); } } // namespace webrtc