blob: d7108dca481134be8523fc067d12055e1f8aeab3 [file] [log] [blame]
henrika8324b522015-03-27 10:56:23 +01001/*
2 * Copyright (c) 2015 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.h"
12
kwiberg0eb15ed2015-12-17 03:04:15 -080013#include <utility>
14
henrika8324b522015-03-27 10:56:23 +010015#include <android/log.h>
16
17#include "webrtc/base/arraysize.h"
18#include "webrtc/base/checks.h"
19#include "webrtc/modules/audio_device/android/audio_common.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010020#include "webrtc/modules/utility/include/helpers_android.h"
henrika8324b522015-03-27 10:56:23 +010021
22#define TAG "AudioManager"
23#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
24#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
25#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
26#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
27#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
28
29namespace webrtc {
30
henrikab2619892015-05-18 16:49:16 +020031// AudioManager::JavaAudioManager implementation
32AudioManager::JavaAudioManager::JavaAudioManager(
kwiberg0eb15ed2015-12-17 03:04:15 -080033 NativeRegistration* native_reg,
kwibergf01633e2016-02-24 05:00:36 -080034 std::unique_ptr<GlobalRef> audio_manager)
kwiberg0eb15ed2015-12-17 03:04:15 -080035 : audio_manager_(std::move(audio_manager)),
henrikab2619892015-05-18 16:49:16 +020036 init_(native_reg->GetMethodId("init", "()Z")),
37 dispose_(native_reg->GetMethodId("dispose", "()V")),
henrikafe55c382015-06-05 11:45:56 +020038 is_communication_mode_enabled_(
henrika8a897182015-06-09 10:45:09 +020039 native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")),
40 is_device_blacklisted_for_open_sles_usage_(
kwiberg0eb15ed2015-12-17 03:04:15 -080041 native_reg->GetMethodId("isDeviceBlacklistedForOpenSLESUsage",
42 "()Z")) {
henrikab2619892015-05-18 16:49:16 +020043 ALOGD("JavaAudioManager::ctor%s", GetThreadInfo().c_str());
henrika8324b522015-03-27 10:56:23 +010044}
45
henrikab2619892015-05-18 16:49:16 +020046AudioManager::JavaAudioManager::~JavaAudioManager() {
47 ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str());
henrika8324b522015-03-27 10:56:23 +010048}
49
henrikab2619892015-05-18 16:49:16 +020050bool AudioManager::JavaAudioManager::Init() {
51 return audio_manager_->CallBooleanMethod(init_);
52}
53
54void AudioManager::JavaAudioManager::Close() {
55 audio_manager_->CallVoidMethod(dispose_);
56}
57
henrikafe55c382015-06-05 11:45:56 +020058bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
59 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
henrikab2619892015-05-18 16:49:16 +020060}
61
henrika8a897182015-06-09 10:45:09 +020062bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() {
63 return audio_manager_->CallBooleanMethod(
64 is_device_blacklisted_for_open_sles_usage_);
65}
66
henrikab2619892015-05-18 16:49:16 +020067// AudioManager implementation
henrika8324b522015-03-27 10:56:23 +010068AudioManager::AudioManager()
kwiberg1c7fdd82016-04-26 08:18:04 -070069 : j_environment_(JVM::GetInstance()->environment()),
henrikab2619892015-05-18 16:49:16 +020070 audio_layer_(AudioDeviceModule::kPlatformDefaultAudio),
71 initialized_(false),
72 hardware_aec_(false),
henrikac14f5ff2015-09-23 14:08:33 +020073 hardware_agc_(false),
74 hardware_ns_(false),
henrikab2619892015-05-18 16:49:16 +020075 low_latency_playout_(false),
henrika1ba936a2015-11-03 04:27:58 -080076 delay_estimate_in_milliseconds_(0) {
henrika8324b522015-03-27 10:56:23 +010077 ALOGD("ctor%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -070078 RTC_CHECK(j_environment_);
henrikab2619892015-05-18 16:49:16 +020079 JNINativeMethod native_methods[] = {
80 {"nativeCacheAudioParameters",
henrika1f0ad102016-05-25 05:15:10 -070081 "(IIZZZZZIIJ)V",
henrikab2619892015-05-18 16:49:16 +020082 reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
kwiberg1c7fdd82016-04-26 08:18:04 -070083 j_native_registration_ = j_environment_->RegisterNatives(
84 "org/webrtc/voiceengine/WebRtcAudioManager", native_methods,
85 arraysize(native_methods));
henrikab2619892015-05-18 16:49:16 +020086 j_audio_manager_.reset(new JavaAudioManager(
87 j_native_registration_.get(),
kwiberg1c7fdd82016-04-26 08:18:04 -070088 j_native_registration_->NewObject(
henrikab2619892015-05-18 16:49:16 +020089 "<init>", "(Landroid/content/Context;J)V",
kwiberg1c7fdd82016-04-26 08:18:04 -070090 JVM::GetInstance()->context(), PointerTojlong(this))));
henrika8324b522015-03-27 10:56:23 +010091}
92
93AudioManager::~AudioManager() {
94 ALOGD("~dtor%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -070095 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +010096 Close();
henrikab2619892015-05-18 16:49:16 +020097}
98
99void AudioManager::SetActiveAudioLayer(
100 AudioDeviceModule::AudioLayer audio_layer) {
101 ALOGD("SetActiveAudioLayer(%d)%s", audio_layer, GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -0700102 RTC_DCHECK(thread_checker_.CalledOnValidThread());
103 RTC_DCHECK(!initialized_);
henrikab2619892015-05-18 16:49:16 +0200104 // Store the currenttly utilized audio layer.
105 audio_layer_ = audio_layer;
106 // The delay estimate can take one of two fixed values depending on if the
107 // device supports low-latency output or not. However, it is also possible
108 // that the user explicitly selects the high-latency audio path, hence we use
109 // the selected |audio_layer| here to set the delay estimate.
110 delay_estimate_in_milliseconds_ =
111 (audio_layer == AudioDeviceModule::kAndroidJavaAudio) ?
112 kHighLatencyModeDelayEstimateInMilliseconds :
113 kLowLatencyModeDelayEstimateInMilliseconds;
114 ALOGD("delay_estimate_in_milliseconds: %d", delay_estimate_in_milliseconds_);
henrika8324b522015-03-27 10:56:23 +0100115}
116
117bool AudioManager::Init() {
118 ALOGD("Init%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -0700119 RTC_DCHECK(thread_checker_.CalledOnValidThread());
120 RTC_DCHECK(!initialized_);
121 RTC_DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio);
henrikab2619892015-05-18 16:49:16 +0200122 if (!j_audio_manager_->Init()) {
henrika8324b522015-03-27 10:56:23 +0100123 ALOGE("init failed!");
124 return false;
125 }
126 initialized_ = true;
127 return true;
128}
129
130bool AudioManager::Close() {
131 ALOGD("Close%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -0700132 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100133 if (!initialized_)
134 return true;
henrikab2619892015-05-18 16:49:16 +0200135 j_audio_manager_->Close();
henrika8324b522015-03-27 10:56:23 +0100136 initialized_ = false;
137 return true;
138}
139
henrikafe55c382015-06-05 11:45:56 +0200140bool AudioManager::IsCommunicationModeEnabled() const {
141 ALOGD("IsCommunicationModeEnabled()");
henrikg91d6ede2015-09-17 00:24:34 -0700142 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikafe55c382015-06-05 11:45:56 +0200143 return j_audio_manager_->IsCommunicationModeEnabled();
henrika09bf1a12015-04-10 11:46:55 +0200144}
145
henrikab2619892015-05-18 16:49:16 +0200146bool AudioManager::IsAcousticEchoCancelerSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700147 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200148 return hardware_aec_;
149}
150
henrikac14f5ff2015-09-23 14:08:33 +0200151bool AudioManager::IsAutomaticGainControlSupported() const {
152 RTC_DCHECK(thread_checker_.CalledOnValidThread());
153 return hardware_agc_;
154}
155
156bool AudioManager::IsNoiseSuppressorSupported() const {
157 RTC_DCHECK(thread_checker_.CalledOnValidThread());
158 return hardware_ns_;
159}
160
henrikab2619892015-05-18 16:49:16 +0200161bool AudioManager::IsLowLatencyPlayoutSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700162 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200163 ALOGD("IsLowLatencyPlayoutSupported()");
henrika8a897182015-06-09 10:45:09 +0200164 // Some devices are blacklisted for usage of OpenSL ES even if they report
165 // that low-latency playout is supported. See b/21485703 for details.
166 return j_audio_manager_->IsDeviceBlacklistedForOpenSLESUsage() ?
167 false : low_latency_playout_;
henrikab2619892015-05-18 16:49:16 +0200168}
169
henrika1f0ad102016-05-25 05:15:10 -0700170bool AudioManager::IsProAudioSupported() const {
171 RTC_DCHECK(thread_checker_.CalledOnValidThread());
172 ALOGD("IsProAudioSupported()");
173 // TODO(henrika): return the state independently of if OpenSL ES is
174 // blacklisted or not for now. We could use the same approach as in
175 // IsLowLatencyPlayoutSupported() but I can't see the need for it yet.
176 return pro_audio_;
177}
178
henrikab2619892015-05-18 16:49:16 +0200179int AudioManager::GetDelayEstimateInMilliseconds() const {
180 return delay_estimate_in_milliseconds_;
181}
182
183void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env,
184 jobject obj,
185 jint sample_rate,
186 jint channels,
187 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200188 jboolean hardware_agc,
189 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200190 jboolean low_latency_output,
henrika1f0ad102016-05-25 05:15:10 -0700191 jboolean pro_audio,
henrikab2619892015-05-18 16:49:16 +0200192 jint output_buffer_size,
193 jint input_buffer_size,
194 jlong native_audio_manager) {
henrika8324b522015-03-27 10:56:23 +0100195 webrtc::AudioManager* this_object =
henrikab2619892015-05-18 16:49:16 +0200196 reinterpret_cast<webrtc::AudioManager*>(native_audio_manager);
197 this_object->OnCacheAudioParameters(
henrikac14f5ff2015-09-23 14:08:33 +0200198 env, sample_rate, channels, hardware_aec, hardware_agc, hardware_ns,
henrika1f0ad102016-05-25 05:15:10 -0700199 low_latency_output, pro_audio, output_buffer_size, input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100200}
201
henrikab2619892015-05-18 16:49:16 +0200202void AudioManager::OnCacheAudioParameters(JNIEnv* env,
203 jint sample_rate,
204 jint channels,
205 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200206 jboolean hardware_agc,
207 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200208 jboolean low_latency_output,
henrika1f0ad102016-05-25 05:15:10 -0700209 jboolean pro_audio,
henrikab2619892015-05-18 16:49:16 +0200210 jint output_buffer_size,
henrika1ba936a2015-11-03 04:27:58 -0800211 jint input_buffer_size) {
henrika8324b522015-03-27 10:56:23 +0100212 ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str());
henrikab2619892015-05-18 16:49:16 +0200213 ALOGD("hardware_aec: %d", hardware_aec);
henrikac14f5ff2015-09-23 14:08:33 +0200214 ALOGD("hardware_agc: %d", hardware_agc);
215 ALOGD("hardware_ns: %d", hardware_ns);
henrikab2619892015-05-18 16:49:16 +0200216 ALOGD("low_latency_output: %d", low_latency_output);
henrika1f0ad102016-05-25 05:15:10 -0700217 ALOGD("pro_audio: %d", pro_audio);
henrika8324b522015-03-27 10:56:23 +0100218 ALOGD("sample_rate: %d", sample_rate);
219 ALOGD("channels: %d", channels);
henrikab2619892015-05-18 16:49:16 +0200220 ALOGD("output_buffer_size: %d", output_buffer_size);
221 ALOGD("input_buffer_size: %d", input_buffer_size);
henrikg91d6ede2015-09-17 00:24:34 -0700222 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200223 hardware_aec_ = hardware_aec;
henrikac14f5ff2015-09-23 14:08:33 +0200224 hardware_agc_ = hardware_agc;
225 hardware_ns_ = hardware_ns;
henrikab2619892015-05-18 16:49:16 +0200226 low_latency_playout_ = low_latency_output;
henrika1f0ad102016-05-25 05:15:10 -0700227 pro_audio_ = pro_audio;
henrikab2619892015-05-18 16:49:16 +0200228 // TODO(henrika): add support for stereo output.
Peter Kasting69558702016-01-12 16:26:35 -0800229 playout_parameters_.reset(sample_rate, static_cast<size_t>(channels),
Peter Kasting1380e262015-08-28 17:31:03 -0700230 static_cast<size_t>(output_buffer_size));
Peter Kasting69558702016-01-12 16:26:35 -0800231 record_parameters_.reset(sample_rate, static_cast<size_t>(channels),
Peter Kasting1380e262015-08-28 17:31:03 -0700232 static_cast<size_t>(input_buffer_size));
henrika8324b522015-03-27 10:56:23 +0100233}
234
henrikab2619892015-05-18 16:49:16 +0200235const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700236 RTC_CHECK(playout_parameters_.is_valid());
237 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100238 return playout_parameters_;
239}
240
henrikab2619892015-05-18 16:49:16 +0200241const AudioParameters& AudioManager::GetRecordAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700242 RTC_CHECK(record_parameters_.is_valid());
243 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100244 return record_parameters_;
245}
246
henrika8324b522015-03-27 10:56:23 +0100247} // namespace webrtc