blob: 17320ef8fcef1299a2df8409c6d57643b54c5959 [file] [log] [blame]
/*
* 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