diff --git a/webrtc/modules/audio_device/android/audio_device_unittest.cc b/webrtc/modules/audio_device/android/audio_device_unittest.cc index eefab0f4e1..c1dba63897 100644 --- a/webrtc/modules/audio_device/android/audio_device_unittest.cc +++ b/webrtc/modules/audio_device/android/audio_device_unittest.cc @@ -524,12 +524,16 @@ class AudioDeviceTest : public ::testing::Test { audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio); EXPECT_NE(audio_device_.get(), nullptr); EXPECT_EQ(0, audio_device_->Init()); + // Set audio mode to MODE_IN_COMMUNICATION. + audio_manager()->SetCommunicationMode(true); playout_parameters_ = audio_manager()->GetPlayoutAudioParameters(); record_parameters_ = audio_manager()->GetRecordAudioParameters(); build_info_.reset(new BuildInfo()); } virtual ~AudioDeviceTest() { EXPECT_EQ(0, audio_device_->Terminate()); + // Restore audio mode back to MODE_NORMAL. + audio_manager()->SetCommunicationMode(false); } int playout_sample_rate() const { diff --git a/webrtc/modules/audio_device/android/audio_manager.cc b/webrtc/modules/audio_device/android/audio_manager.cc index d8b7640c9b..5c88d9e5d4 100644 --- a/webrtc/modules/audio_device/android/audio_manager.cc +++ b/webrtc/modules/audio_device/android/audio_manager.cc @@ -35,6 +35,8 @@ AudioManager::JavaAudioManager::JavaAudioManager( : audio_manager_(std::move(audio_manager)), init_(native_reg->GetMethodId("init", "()Z")), dispose_(native_reg->GetMethodId("dispose", "()V")), + set_communication_mode_( + native_reg->GetMethodId("setCommunicationMode", "(Z)V")), is_communication_mode_enabled_( native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")), is_device_blacklisted_for_open_sles_usage_( @@ -55,6 +57,11 @@ void AudioManager::JavaAudioManager::Close() { audio_manager_->CallVoidMethod(dispose_); } +void AudioManager::JavaAudioManager::SetCommunicationMode(bool enable) { + audio_manager_->CallVoidMethod(set_communication_mode_, + static_cast(enable)); +} + bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() { return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_); } @@ -176,6 +183,12 @@ bool AudioManager::Close() { return true; } +void AudioManager::SetCommunicationMode(bool enable) { + ALOGD("SetCommunicationMode(%d)", enable); + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + j_audio_manager_->SetCommunicationMode(enable); +} + bool AudioManager::IsCommunicationModeEnabled() const { ALOGD("IsCommunicationModeEnabled()"); RTC_DCHECK(thread_checker_.CalledOnValidThread()); diff --git a/webrtc/modules/audio_device/android/audio_manager.h b/webrtc/modules/audio_device/android/audio_manager.h index 341d426e41..8c32f0b082 100644 --- a/webrtc/modules/audio_device/android/audio_manager.h +++ b/webrtc/modules/audio_device/android/audio_manager.h @@ -47,6 +47,7 @@ class AudioManager { bool Init(); void Close(); + void SetCommunicationMode(bool enable); bool IsCommunicationModeEnabled(); bool IsDeviceBlacklistedForOpenSLESUsage(); @@ -54,6 +55,7 @@ class AudioManager { std::unique_ptr audio_manager_; jmethodID init_; jmethodID dispose_; + jmethodID set_communication_mode_; jmethodID is_communication_mode_enabled_; jmethodID is_device_blacklisted_for_open_sles_usage_; }; @@ -82,6 +84,9 @@ class AudioManager { // Revert any setting done by Init(). bool Close(); + // Set audio mode to AudioManager.MODE_IN_COMMUNICATION if |enable| is true + // and AudioManager.MODE_NORMAL otherwise. + void SetCommunicationMode(bool enable); // Returns true if current audio mode is AudioManager.MODE_IN_COMMUNICATION. bool IsCommunicationModeEnabled() const; diff --git a/webrtc/modules/audio_device/android/audio_manager_unittest.cc b/webrtc/modules/audio_device/android/audio_manager_unittest.cc index 2507976522..cb04beff76 100644 --- a/webrtc/modules/audio_device/android/audio_manager_unittest.cc +++ b/webrtc/modules/audio_device/android/audio_manager_unittest.cc @@ -35,6 +35,11 @@ class AudioManagerTest : public ::testing::Test { record_parameters_ = audio_manager()->GetRecordAudioParameters(); } + virtual ~AudioManagerTest() { + // Always ensure that we restore default/normal mode after the test. + audio_manager()->SetCommunicationMode(false); + } + AudioManager* audio_manager() const { return audio_manager_.get(); } // A valid audio layer must always be set before calling Init(), hence we @@ -107,6 +112,14 @@ TEST_F(AudioManagerTest, InitClose) { EXPECT_TRUE(audio_manager()->Close()); } +// Verify communication mode functionality. +TEST_F(AudioManagerTest, CommunicationMode) { + audio_manager()->SetCommunicationMode(true); + EXPECT_TRUE(audio_manager()->IsCommunicationModeEnabled()); + audio_manager()->SetCommunicationMode(false); + EXPECT_FALSE(audio_manager()->IsCommunicationModeEnabled()); +} + TEST_F(AudioManagerTest, IsAcousticEchoCancelerSupported) { PRINT("%sAcoustic Echo Canceler support: %s\n", kTag, audio_manager()->IsAcousticEchoCancelerSupported() ? "Yes" : "No"); diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java index fb0516fa06..2775118ca7 100644 --- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java +++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java @@ -172,6 +172,16 @@ public class WebRtcAudioManager { volumeLogger.stop(); } + private void setCommunicationMode(boolean enable) { + if (enable) { + audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + Logging.d(TAG, "audio mode is set to AudioManager.MODE_IN_COMMUNICATION"); + } else { + audioManager.setMode(AudioManager.MODE_NORMAL); + Logging.d(TAG, "audio mode is set to AudioManager.MODE_NORMAL"); + } + } + private boolean isCommunicationModeEnabled() { return (audioManager.getMode() == AudioManager.MODE_IN_COMMUNICATION); } diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java index c2874316a5..825f627d03 100644 --- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java +++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java @@ -188,6 +188,17 @@ public class WebRtcAudioTrack { Logging.e(TAG, "AudioTrack.getMinBufferSize returns an invalid value."); return false; } + // The default (preferred) stream type is STREAM_VOICE_CALL since the + // WebRTC stack is mainly intended for VoIP calls. + int streamType = AudioManager.STREAM_VOICE_CALL; + if (audioManager.getMode() != AudioManager.MODE_IN_COMMUNICATION) { + // But if the user wants to run in another mode than COMM mode, we + // accept it and change the stream type to STREAM_MUSIC instead. It can + // e.g. be suitable for applications that do not record audio or if a + // call shall be casted to a Chromecast device. + streamType = AudioManager.STREAM_MUSIC; + Logging.w(TAG, "Using AudioManager.STREAM_MUSIC as stream type."); + } // Ensure that prevision audio session was stopped correctly before trying // to create a new AudioTrack. @@ -199,9 +210,8 @@ public class WebRtcAudioTrack { // Create an AudioTrack object and initialize its associated audio buffer. // The size of this buffer determines how long an AudioTrack can play // before running out of data. - audioTrack = - new AudioTrack(AudioManager.STREAM_VOICE_CALL, sampleRate, AudioFormat.CHANNEL_OUT_MONO, - AudioFormat.ENCODING_PCM_16BIT, minBufferSizeInBytes, AudioTrack.MODE_STREAM); + audioTrack = new AudioTrack(streamType, sampleRate, AudioFormat.CHANNEL_OUT_MONO, + AudioFormat.ENCODING_PCM_16BIT, minBufferSizeInBytes, AudioTrack.MODE_STREAM); } catch (IllegalArgumentException e) { Logging.d(TAG, e.getMessage()); return false; diff --git a/webrtc/modules/audio_device/android/opensles_player.cc b/webrtc/modules/audio_device/android/opensles_player.cc index d675d637e3..b87c5fe5ca 100644 --- a/webrtc/modules/audio_device/android/opensles_player.cc +++ b/webrtc/modules/audio_device/android/opensles_player.cc @@ -308,6 +308,13 @@ bool OpenSLESPlayer::CreateAudioPlayer() { // Set audio player configuration to SL_ANDROID_STREAM_VOICE which // corresponds to android.media.AudioManager.STREAM_VOICE_CALL. SLint32 stream_type = SL_ANDROID_STREAM_VOICE; + if (!audio_manager_->IsCommunicationModeEnabled()) { + // But use STREAM_MUSIC if the user for some reason wants to run in a mode + // other than the preferred communication mode. + // SL_ANDROID_STREAM_MEDIA <=> android.media.AudioManager.STREAM_MUSIC. + stream_type = SL_ANDROID_STREAM_MEDIA; + ALOGW("Using non-default stream type SL_ANDROID_STREAM_MEDIA"); + } RETURN_ON_ERROR( (*player_config) ->SetConfiguration(player_config, SL_ANDROID_KEY_STREAM_TYPE,