|  | /* | 
|  | *  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 <assert.h> | 
|  |  | 
|  | #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<JavaVM*>(jvm); | 
|  | g_jni_env_ = reinterpret_cast<JNIEnv*>(env); | 
|  | g_context_ = g_jni_env_->NewGlobalRef(reinterpret_cast<jobject>(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<jclass>( | 
|  | 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, "<init>", "(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 |