Home | History | Annotate | Download | only in android
      1 /*
      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 
     13 #include <utility>
     14 
     15 #include <android/log.h>
     16 
     17 #include "webrtc/base/arraysize.h"
     18 #include "webrtc/base/checks.h"
     19 #include "webrtc/base/scoped_ptr.h"
     20 #include "webrtc/modules/audio_device/android/audio_common.h"
     21 #include "webrtc/modules/utility/include/helpers_android.h"
     22 
     23 #define TAG "AudioManager"
     24 #define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
     25 #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
     26 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
     27 #define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
     28 #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
     29 
     30 namespace webrtc {
     31 
     32 // AudioManager::JavaAudioManager implementation
     33 AudioManager::JavaAudioManager::JavaAudioManager(
     34     NativeRegistration* native_reg,
     35     rtc::scoped_ptr<GlobalRef> audio_manager)
     36     : audio_manager_(std::move(audio_manager)),
     37       init_(native_reg->GetMethodId("init", "()Z")),
     38       dispose_(native_reg->GetMethodId("dispose", "()V")),
     39       is_communication_mode_enabled_(
     40           native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")),
     41       is_device_blacklisted_for_open_sles_usage_(
     42           native_reg->GetMethodId("isDeviceBlacklistedForOpenSLESUsage",
     43                                   "()Z")) {
     44   ALOGD("JavaAudioManager::ctor%s", GetThreadInfo().c_str());
     45 }
     46 
     47 AudioManager::JavaAudioManager::~JavaAudioManager() {
     48   ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str());
     49 }
     50 
     51 bool AudioManager::JavaAudioManager::Init() {
     52   return audio_manager_->CallBooleanMethod(init_);
     53 }
     54 
     55 void AudioManager::JavaAudioManager::Close() {
     56   audio_manager_->CallVoidMethod(dispose_);
     57 }
     58 
     59 bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
     60   return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
     61 }
     62 
     63 bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() {
     64   return audio_manager_->CallBooleanMethod(
     65       is_device_blacklisted_for_open_sles_usage_);
     66 }
     67 
     68 // AudioManager implementation
     69 AudioManager::AudioManager()
     70     : j_environment_(JVM::GetInstance()->environment()),
     71       audio_layer_(AudioDeviceModule::kPlatformDefaultAudio),
     72       initialized_(false),
     73       hardware_aec_(false),
     74       hardware_agc_(false),
     75       hardware_ns_(false),
     76       low_latency_playout_(false),
     77       delay_estimate_in_milliseconds_(0) {
     78   ALOGD("ctor%s", GetThreadInfo().c_str());
     79   RTC_CHECK(j_environment_);
     80   JNINativeMethod native_methods[] = {
     81       {"nativeCacheAudioParameters",
     82        "(IIZZZZIIJ)V",
     83        reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
     84   j_native_registration_ = j_environment_->RegisterNatives(
     85       "org/webrtc/voiceengine/WebRtcAudioManager",
     86       native_methods, arraysize(native_methods));
     87   j_audio_manager_.reset(new JavaAudioManager(
     88       j_native_registration_.get(),
     89       j_native_registration_->NewObject(
     90           "<init>", "(Landroid/content/Context;J)V",
     91           JVM::GetInstance()->context(), PointerTojlong(this))));
     92 }
     93 
     94 AudioManager::~AudioManager() {
     95   ALOGD("~dtor%s", GetThreadInfo().c_str());
     96   RTC_DCHECK(thread_checker_.CalledOnValidThread());
     97   Close();
     98 }
     99 
    100 void AudioManager::SetActiveAudioLayer(
    101     AudioDeviceModule::AudioLayer audio_layer) {
    102   ALOGD("SetActiveAudioLayer(%d)%s", audio_layer, GetThreadInfo().c_str());
    103   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    104   RTC_DCHECK(!initialized_);
    105   // Store the currenttly utilized audio layer.
    106   audio_layer_ = audio_layer;
    107   // The delay estimate can take one of two fixed values depending on if the
    108   // device supports low-latency output or not. However, it is also possible
    109   // that the user explicitly selects the high-latency audio path, hence we use
    110   // the selected |audio_layer| here to set the delay estimate.
    111   delay_estimate_in_milliseconds_ =
    112       (audio_layer == AudioDeviceModule::kAndroidJavaAudio) ?
    113       kHighLatencyModeDelayEstimateInMilliseconds :
    114       kLowLatencyModeDelayEstimateInMilliseconds;
    115   ALOGD("delay_estimate_in_milliseconds: %d", delay_estimate_in_milliseconds_);
    116 }
    117 
    118 bool AudioManager::Init() {
    119   ALOGD("Init%s", GetThreadInfo().c_str());
    120   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    121   RTC_DCHECK(!initialized_);
    122   RTC_DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio);
    123   if (!j_audio_manager_->Init()) {
    124     ALOGE("init failed!");
    125     return false;
    126   }
    127   initialized_ = true;
    128   return true;
    129 }
    130 
    131 bool AudioManager::Close() {
    132   ALOGD("Close%s", GetThreadInfo().c_str());
    133   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    134   if (!initialized_)
    135     return true;
    136   j_audio_manager_->Close();
    137   initialized_ = false;
    138   return true;
    139 }
    140 
    141 bool AudioManager::IsCommunicationModeEnabled() const {
    142   ALOGD("IsCommunicationModeEnabled()");
    143   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    144   return j_audio_manager_->IsCommunicationModeEnabled();
    145 }
    146 
    147 bool AudioManager::IsAcousticEchoCancelerSupported() const {
    148   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    149   return hardware_aec_;
    150 }
    151 
    152 bool AudioManager::IsAutomaticGainControlSupported() const {
    153   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    154   return hardware_agc_;
    155 }
    156 
    157 bool AudioManager::IsNoiseSuppressorSupported() const {
    158   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    159   return hardware_ns_;
    160 }
    161 
    162 bool AudioManager::IsLowLatencyPlayoutSupported() const {
    163   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    164   ALOGD("IsLowLatencyPlayoutSupported()");
    165   // Some devices are blacklisted for usage of OpenSL ES even if they report
    166   // that low-latency playout is supported. See b/21485703 for details.
    167   return j_audio_manager_->IsDeviceBlacklistedForOpenSLESUsage() ?
    168       false : low_latency_playout_;
    169 }
    170 
    171 int AudioManager::GetDelayEstimateInMilliseconds() const {
    172   return delay_estimate_in_milliseconds_;
    173 }
    174 
    175 void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env,
    176                                                 jobject obj,
    177                                                 jint sample_rate,
    178                                                 jint channels,
    179                                                 jboolean hardware_aec,
    180                                                 jboolean hardware_agc,
    181                                                 jboolean hardware_ns,
    182                                                 jboolean low_latency_output,
    183                                                 jint output_buffer_size,
    184                                                 jint input_buffer_size,
    185                                                 jlong native_audio_manager) {
    186   webrtc::AudioManager* this_object =
    187       reinterpret_cast<webrtc::AudioManager*>(native_audio_manager);
    188   this_object->OnCacheAudioParameters(
    189       env, sample_rate, channels, hardware_aec, hardware_agc, hardware_ns,
    190       low_latency_output, output_buffer_size, input_buffer_size);
    191 }
    192 
    193 void AudioManager::OnCacheAudioParameters(JNIEnv* env,
    194                                           jint sample_rate,
    195                                           jint channels,
    196                                           jboolean hardware_aec,
    197                                           jboolean hardware_agc,
    198                                           jboolean hardware_ns,
    199                                           jboolean low_latency_output,
    200                                           jint output_buffer_size,
    201                                           jint input_buffer_size) {
    202   ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str());
    203   ALOGD("hardware_aec: %d", hardware_aec);
    204   ALOGD("hardware_agc: %d", hardware_agc);
    205   ALOGD("hardware_ns: %d", hardware_ns);
    206   ALOGD("low_latency_output: %d", low_latency_output);
    207   ALOGD("sample_rate: %d", sample_rate);
    208   ALOGD("channels: %d", channels);
    209   ALOGD("output_buffer_size: %d", output_buffer_size);
    210   ALOGD("input_buffer_size: %d", input_buffer_size);
    211   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    212   hardware_aec_ = hardware_aec;
    213   hardware_agc_ = hardware_agc;
    214   hardware_ns_ = hardware_ns;
    215   low_latency_playout_ = low_latency_output;
    216   // TODO(henrika): add support for stereo output.
    217   playout_parameters_.reset(sample_rate, static_cast<size_t>(channels),
    218                             static_cast<size_t>(output_buffer_size));
    219   record_parameters_.reset(sample_rate, static_cast<size_t>(channels),
    220                            static_cast<size_t>(input_buffer_size));
    221 }
    222 
    223 const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
    224   RTC_CHECK(playout_parameters_.is_valid());
    225   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    226   return playout_parameters_;
    227 }
    228 
    229 const AudioParameters& AudioManager::GetRecordAudioParameters() {
    230   RTC_CHECK(record_parameters_.is_valid());
    231   RTC_DCHECK(thread_checker_.CalledOnValidThread());
    232   return record_parameters_;
    233 }
    234 
    235 }  // namespace webrtc
    236