1 /* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/audio_device/android/audio_manager_jni.h" 12 13 #include <assert.h> 14 15 #include "webrtc/modules/utility/interface/helpers_android.h" 16 #include "webrtc/system_wrappers/interface/trace.h" 17 18 namespace webrtc { 19 20 static JavaVM* g_jvm_ = NULL; 21 static JNIEnv* g_jni_env_ = NULL; 22 static jobject g_context_ = NULL; 23 static jclass g_audio_manager_class_ = NULL; 24 static jobject g_audio_manager_ = NULL; 25 26 AudioManagerJni::AudioManagerJni() 27 : low_latency_supported_(false), 28 native_output_sample_rate_(0), 29 native_buffer_size_(0) { 30 if (!HasDeviceObjects()) { 31 assert(false); 32 } 33 AttachThreadScoped ats(g_jvm_); 34 JNIEnv* env = ats.env(); 35 assert(env && "Unsupported JNI version!"); 36 CreateInstance(env); 37 // Pre-store device specific values. 38 SetLowLatencySupported(env); 39 SetNativeOutputSampleRate(env); 40 SetNativeFrameSize(env); 41 } 42 43 void AudioManagerJni::SetAndroidAudioDeviceObjects(void* jvm, void* env, 44 void* context) { 45 assert(jvm); 46 assert(env); 47 assert(context); 48 49 // Store global Java VM variables to be accessed by API calls. 50 g_jvm_ = reinterpret_cast<JavaVM*>(jvm); 51 g_jni_env_ = reinterpret_cast<JNIEnv*>(env); 52 g_context_ = g_jni_env_->NewGlobalRef(reinterpret_cast<jobject>(context)); 53 54 // FindClass must be made in this function since this function's contract 55 // requires it to be called by a Java thread. 56 // See 57 // http://developer.android.com/training/articles/perf-jni.html#faq_FindClass 58 // as to why this is necessary. 59 // Get the AudioManagerAndroid class object. 60 jclass javaAmClassLocal = g_jni_env_->FindClass( 61 "org/webrtc/voiceengine/AudioManagerAndroid"); 62 assert(javaAmClassLocal); 63 64 // Create a global reference such that the class object is not recycled by 65 // the garbage collector. 66 g_audio_manager_class_ = reinterpret_cast<jclass>( 67 g_jni_env_->NewGlobalRef(javaAmClassLocal)); 68 assert(g_audio_manager_class_); 69 } 70 71 void AudioManagerJni::ClearAndroidAudioDeviceObjects() { 72 g_jni_env_->DeleteGlobalRef(g_audio_manager_class_); 73 g_audio_manager_class_ = NULL; 74 g_jni_env_->DeleteGlobalRef(g_context_); 75 g_context_ = NULL; 76 g_jni_env_->DeleteGlobalRef(g_audio_manager_); 77 g_audio_manager_ = NULL; 78 g_jni_env_ = NULL; 79 g_jvm_ = NULL; 80 } 81 82 void AudioManagerJni::SetLowLatencySupported(JNIEnv* env) { 83 jmethodID id = LookUpMethodId(env, "isAudioLowLatencySupported", "()Z"); 84 low_latency_supported_ = env->CallBooleanMethod(g_audio_manager_, id); 85 } 86 87 void AudioManagerJni::SetNativeOutputSampleRate(JNIEnv* env) { 88 jmethodID id = LookUpMethodId(env, "getNativeOutputSampleRate", "()I"); 89 native_output_sample_rate_ = env->CallIntMethod(g_audio_manager_, id); 90 } 91 92 void AudioManagerJni::SetNativeFrameSize(JNIEnv* env) { 93 jmethodID id = LookUpMethodId(env, 94 "getAudioLowLatencyOutputFrameSize", "()I"); 95 native_buffer_size_ = env->CallIntMethod(g_audio_manager_, id); 96 } 97 98 bool AudioManagerJni::HasDeviceObjects() { 99 return g_jvm_ && g_jni_env_ && g_context_ && g_audio_manager_class_; 100 } 101 102 jmethodID AudioManagerJni::LookUpMethodId(JNIEnv* env, 103 const char* method_name, 104 const char* method_signature) { 105 jmethodID ret_val = env->GetMethodID(g_audio_manager_class_, method_name, 106 method_signature); 107 assert(ret_val); 108 return ret_val; 109 } 110 111 void AudioManagerJni::CreateInstance(JNIEnv* env) { 112 // Get the method ID for the constructor taking Context. 113 jmethodID id = LookUpMethodId(env, "<init>", "(Landroid/content/Context;)V"); 114 g_audio_manager_ = env->NewObject(g_audio_manager_class_, id, g_context_); 115 // Create a global reference so that the instance is accessible until no 116 // longer needed. 117 g_audio_manager_ = env->NewGlobalRef(g_audio_manager_); 118 assert(g_audio_manager_); 119 } 120 121 } // namespace webrtc 122