Restores stored audio mode when all streaming stops. TBR=glaznev BUG=NONE TEST=AppRTCDemo Review URL: https://webrtc-codereview.appspot.com/46869005 Cr-Commit-Position: refs/heads/master@{#8970}
186 lines
6.3 KiB
C++
186 lines
6.3 KiB
C++
/*
|
|
* Copyright (c) 2015 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.h"
|
|
|
|
#include <android/log.h>
|
|
|
|
#include "webrtc/base/arraysize.h"
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/modules/audio_device/android/audio_common.h"
|
|
#include "webrtc/modules/utility/interface/helpers_android.h"
|
|
|
|
#define TAG "AudioManager"
|
|
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
|
|
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
|
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
|
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
|
|
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
|
|
|
|
namespace webrtc {
|
|
|
|
static JavaVM* g_jvm = NULL;
|
|
static jobject g_context = NULL;
|
|
static jclass g_audio_manager_class = NULL;
|
|
|
|
void AudioManager::SetAndroidAudioDeviceObjects(void* jvm, void* context) {
|
|
ALOGD("SetAndroidAudioDeviceObjects%s", GetThreadInfo().c_str());
|
|
|
|
CHECK(jvm);
|
|
CHECK(context);
|
|
|
|
g_jvm = reinterpret_cast<JavaVM*>(jvm);
|
|
JNIEnv* jni = GetEnv(g_jvm);
|
|
CHECK(jni) << "AttachCurrentThread must be called on this tread";
|
|
|
|
g_context = NewGlobalRef(jni, reinterpret_cast<jobject>(context));
|
|
jclass local_class = FindClass(
|
|
jni, "org/webrtc/voiceengine/WebRtcAudioManager");
|
|
g_audio_manager_class = reinterpret_cast<jclass>(
|
|
NewGlobalRef(jni, local_class));
|
|
CHECK_EXCEPTION(jni);
|
|
|
|
// Register native methods with the WebRtcAudioManager class. These methods
|
|
// are declared private native in WebRtcAudioManager.java.
|
|
JNINativeMethod native_methods[] = {
|
|
{"nativeCacheAudioParameters", "(IIJ)V",
|
|
reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
|
|
jni->RegisterNatives(g_audio_manager_class,
|
|
native_methods, arraysize(native_methods));
|
|
CHECK_EXCEPTION(jni) << "Error during RegisterNatives";
|
|
}
|
|
|
|
void AudioManager::ClearAndroidAudioDeviceObjects() {
|
|
ALOGD("ClearAndroidAudioDeviceObjects%s", GetThreadInfo().c_str());
|
|
JNIEnv* jni = GetEnv(g_jvm);
|
|
CHECK(jni) << "AttachCurrentThread must be called on this tread";
|
|
jni->UnregisterNatives(g_audio_manager_class);
|
|
CHECK_EXCEPTION(jni) << "Error during UnregisterNatives";
|
|
DeleteGlobalRef(jni, g_audio_manager_class);
|
|
g_audio_manager_class = NULL;
|
|
DeleteGlobalRef(jni, g_context);
|
|
g_context = NULL;
|
|
g_jvm = NULL;
|
|
}
|
|
|
|
AudioManager::AudioManager()
|
|
: j_audio_manager_(NULL),
|
|
initialized_(false) {
|
|
ALOGD("ctor%s", GetThreadInfo().c_str());
|
|
CHECK(HasDeviceObjects());
|
|
CreateJavaInstance();
|
|
}
|
|
|
|
AudioManager::~AudioManager() {
|
|
ALOGD("~dtor%s", GetThreadInfo().c_str());
|
|
DCHECK(thread_checker_.CalledOnValidThread());
|
|
Close();
|
|
AttachThreadScoped ats(g_jvm);
|
|
JNIEnv* jni = ats.env();
|
|
jni->DeleteGlobalRef(j_audio_manager_);
|
|
j_audio_manager_ = NULL;
|
|
DCHECK(!initialized_);
|
|
}
|
|
|
|
bool AudioManager::Init() {
|
|
ALOGD("Init%s", GetThreadInfo().c_str());
|
|
DCHECK(thread_checker_.CalledOnValidThread());
|
|
DCHECK(!initialized_);
|
|
AttachThreadScoped ats(g_jvm);
|
|
JNIEnv* jni = ats.env();
|
|
jmethodID initID = GetMethodID(jni, g_audio_manager_class, "init", "()Z");
|
|
jboolean res = jni->CallBooleanMethod(j_audio_manager_, initID);
|
|
CHECK_EXCEPTION(jni);
|
|
if (!res) {
|
|
ALOGE("init failed!");
|
|
return false;
|
|
}
|
|
initialized_ = true;
|
|
return true;
|
|
}
|
|
|
|
bool AudioManager::Close() {
|
|
ALOGD("Close%s", GetThreadInfo().c_str());
|
|
DCHECK(thread_checker_.CalledOnValidThread());
|
|
if (!initialized_)
|
|
return true;
|
|
AttachThreadScoped ats(g_jvm);
|
|
JNIEnv* jni = ats.env();
|
|
jmethodID disposeID = GetMethodID(
|
|
jni, g_audio_manager_class, "dispose", "()V");
|
|
jni->CallVoidMethod(j_audio_manager_, disposeID);
|
|
CHECK_EXCEPTION(jni);
|
|
initialized_ = false;
|
|
return true;
|
|
}
|
|
|
|
void AudioManager::SetCommunicationMode(bool enable) {
|
|
ALOGD("SetCommunicationMode(%d)%s", enable, GetThreadInfo().c_str());
|
|
DCHECK(thread_checker_.CalledOnValidThread());
|
|
DCHECK(initialized_);
|
|
AttachThreadScoped ats(g_jvm);
|
|
JNIEnv* jni = ats.env();
|
|
jmethodID setcommID = GetMethodID(
|
|
jni, g_audio_manager_class, "setCommunicationMode", "(Z)V");
|
|
jni->CallVoidMethod(j_audio_manager_, setcommID, enable);
|
|
CHECK_EXCEPTION(jni);
|
|
}
|
|
|
|
void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env, jobject obj,
|
|
jint sample_rate, jint channels, jlong nativeAudioManager) {
|
|
webrtc::AudioManager* this_object =
|
|
reinterpret_cast<webrtc::AudioManager*> (nativeAudioManager);
|
|
this_object->OnCacheAudioParameters(env, sample_rate, channels);
|
|
}
|
|
|
|
void AudioManager::OnCacheAudioParameters(
|
|
JNIEnv* env, jint sample_rate, jint channels) {
|
|
ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str());
|
|
ALOGD("sample_rate: %d", sample_rate);
|
|
ALOGD("channels: %d", channels);
|
|
DCHECK(thread_checker_.CalledOnValidThread());
|
|
// TODO(henrika): add support stereo output.
|
|
playout_parameters_.reset(sample_rate, channels);
|
|
record_parameters_.reset(sample_rate, channels);
|
|
}
|
|
|
|
AudioParameters AudioManager::GetPlayoutAudioParameters() const {
|
|
CHECK(playout_parameters_.is_valid());
|
|
return playout_parameters_;
|
|
}
|
|
|
|
AudioParameters AudioManager::GetRecordAudioParameters() const {
|
|
CHECK(record_parameters_.is_valid());
|
|
return record_parameters_;
|
|
}
|
|
|
|
bool AudioManager::HasDeviceObjects() {
|
|
return (g_jvm && g_context && g_audio_manager_class);
|
|
}
|
|
|
|
void AudioManager::CreateJavaInstance() {
|
|
ALOGD("CreateJavaInstance");
|
|
AttachThreadScoped ats(g_jvm);
|
|
JNIEnv* jni = ats.env();
|
|
jmethodID constructorID = GetMethodID(
|
|
jni, g_audio_manager_class, "<init>", "(Landroid/content/Context;J)V");
|
|
j_audio_manager_ = jni->NewObject(g_audio_manager_class,
|
|
constructorID,
|
|
g_context,
|
|
reinterpret_cast<intptr_t>(this));
|
|
CHECK_EXCEPTION(jni) << "Error during NewObject";
|
|
CHECK(j_audio_manager_);
|
|
j_audio_manager_ = jni->NewGlobalRef(j_audio_manager_);
|
|
CHECK_EXCEPTION(jni) << "Error during NewGlobalRef";
|
|
CHECK(j_audio_manager_);
|
|
}
|
|
|
|
} // namespace webrtc
|