• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AudioManagerJni()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 
SetAndroidAudioDeviceObjects(void * jvm,void * env,void * context)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 
ClearAndroidAudioDeviceObjects()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 
SetLowLatencySupported(JNIEnv * env)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 
SetNativeOutputSampleRate(JNIEnv * env)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 
SetNativeFrameSize(JNIEnv * env)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 
HasDeviceObjects()98 bool AudioManagerJni::HasDeviceObjects() {
99   return g_jvm_ && g_jni_env_ && g_context_ && g_audio_manager_class_;
100 }
101 
LookUpMethodId(JNIEnv * env,const char * method_name,const char * method_signature)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 
CreateInstance(JNIEnv * env)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