Add an option to avoid early initialization of audio capture
This can cause issues on Android S if this initialization happens when
the app doesn't have permission to access the microphone.
Bug: b/197461765
Change-Id: Iebccff9d15f5bb12a7b2c78e1c373e379b37a127
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/246104
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Commit-Queue: Xavier Lepaul‎ <xalep@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35689}
diff --git a/api/audio_options.cc b/api/audio_options.cc
index 6832bbe..aca1fe8 100644
--- a/api/audio_options.cc
+++ b/api/audio_options.cc
@@ -65,6 +65,7 @@
SetFrom(&combined_audio_video_bwe, change.combined_audio_video_bwe);
SetFrom(&audio_network_adaptor, change.audio_network_adaptor);
SetFrom(&audio_network_adaptor_config, change.audio_network_adaptor_config);
+ SetFrom(&init_recording_on_send, change.init_recording_on_send);
}
bool AudioOptions::operator==(const AudioOptions& o) const {
@@ -92,7 +93,8 @@
tx_agc_limiter == o.tx_agc_limiter &&
combined_audio_video_bwe == o.combined_audio_video_bwe &&
audio_network_adaptor == o.audio_network_adaptor &&
- audio_network_adaptor_config == o.audio_network_adaptor_config;
+ audio_network_adaptor_config == o.audio_network_adaptor_config &&
+ init_recording_on_send == o.init_recording_on_send;
}
std::string AudioOptions::ToString() const {
@@ -126,6 +128,7 @@
ToStringIfSet(&result, "tx_agc_limiter", tx_agc_limiter);
ToStringIfSet(&result, "combined_audio_video_bwe", combined_audio_video_bwe);
ToStringIfSet(&result, "audio_network_adaptor", audio_network_adaptor);
+ ToStringIfSet(&result, "init_recording_on_send", init_recording_on_send);
result << "}";
return result.str();
}
diff --git a/api/audio_options.h b/api/audio_options.h
index 7d933ae..48dd628 100644
--- a/api/audio_options.h
+++ b/api/audio_options.h
@@ -83,6 +83,10 @@
absl::optional<bool> audio_network_adaptor;
// Config string for audio network adaptor.
absl::optional<std::string> audio_network_adaptor_config;
+ // Pre-initialize the ADM for recording when starting to send. Default to
+ // true.
+ // TODO(webrtc:13566): Remove this option. See issue for details.
+ absl::optional<bool> init_recording_on_send;
};
} // namespace cricket
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index 0a8d3da..536df8e 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -1862,13 +1862,15 @@
return;
}
- // Apply channel specific options, and initialize the ADM for recording (this
- // may take time on some platforms, e.g. Android).
+ // Apply channel specific options.
if (send) {
engine()->ApplyOptions(options_);
- // InitRecording() may return an error if the ADM is already recording.
- if (!engine()->adm()->RecordingIsInitialized() &&
+ // Initialize the ADM for recording (this may take time on some platforms,
+ // e.g. Android).
+ if (options_.init_recording_on_send.value_or(true) &&
+ // InitRecording() may return an error if the ADM is already recording.
+ !engine()->adm()->RecordingIsInitialized() &&
!engine()->adm()->Recording()) {
if (engine()->adm()->InitRecording() != 0) {
RTC_LOG(LS_WARNING) << "Failed to initialize recording";
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index 97e46b2..2770a0d 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -305,9 +305,15 @@
void SetSend(bool enable) {
ASSERT_TRUE(channel_);
if (enable) {
- EXPECT_CALL(*adm_, RecordingIsInitialized()).WillOnce(Return(false));
- EXPECT_CALL(*adm_, Recording()).WillOnce(Return(false));
- EXPECT_CALL(*adm_, InitRecording()).WillOnce(Return(0));
+ EXPECT_CALL(*adm_, RecordingIsInitialized())
+ .Times(::testing::AtMost(1))
+ .WillOnce(Return(false));
+ EXPECT_CALL(*adm_, Recording())
+ .Times(::testing::AtMost(1))
+ .WillOnce(Return(false));
+ EXPECT_CALL(*adm_, InitRecording())
+ .Times(::testing::AtMost(1))
+ .WillOnce(Return(0));
}
channel_->SetSend(enable);
}
@@ -3122,6 +3128,34 @@
}
}
+TEST_P(WebRtcVoiceEngineTestFake, InitRecordingOnSend) {
+ EXPECT_CALL(*adm_, RecordingIsInitialized()).WillOnce(Return(false));
+ EXPECT_CALL(*adm_, Recording()).WillOnce(Return(false));
+ EXPECT_CALL(*adm_, InitRecording()).Times(1);
+
+ std::unique_ptr<cricket::VoiceMediaChannel> channel(
+ engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
+ cricket::AudioOptions(),
+ webrtc::CryptoOptions()));
+
+ channel->SetSend(true);
+}
+
+TEST_P(WebRtcVoiceEngineTestFake, SkipInitRecordingOnSend) {
+ EXPECT_CALL(*adm_, RecordingIsInitialized()).Times(0);
+ EXPECT_CALL(*adm_, Recording()).Times(0);
+ EXPECT_CALL(*adm_, InitRecording()).Times(0);
+
+ cricket::AudioOptions options;
+ options.init_recording_on_send = false;
+
+ std::unique_ptr<cricket::VoiceMediaChannel> channel(
+ engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), options,
+ webrtc::CryptoOptions()));
+
+ channel->SetSend(true);
+}
+
TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
EXPECT_TRUE(SetupSendStream());
EXPECT_CALL(*adm_, BuiltInAECIsAvailable())
diff --git a/sdk/media_constraints.cc b/sdk/media_constraints.cc
index 08bd9dc..3cc08b2 100644
--- a/sdk/media_constraints.cc
+++ b/sdk/media_constraints.cc
@@ -106,6 +106,8 @@
const char MediaConstraints::kAudioMirroring[] = "googAudioMirroring";
const char MediaConstraints::kAudioNetworkAdaptorConfig[] =
"googAudioNetworkAdaptorConfig";
+const char MediaConstraints::kInitAudioRecordingOnSend[] =
+ "InitAudioRecordingOnSend";
// Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
const char MediaConstraints::kOfferToReceiveAudio[] = "OfferToReceiveAudio";
@@ -211,6 +213,9 @@
if (options->audio_network_adaptor_config) {
options->audio_network_adaptor = true;
}
+ ConstraintToOptional<bool>(constraints,
+ MediaConstraints::kInitAudioRecordingOnSend,
+ &options->init_recording_on_send);
}
bool CopyConstraintsIntoOfferAnswerOptions(
diff --git a/sdk/media_constraints.h b/sdk/media_constraints.h
index fd95a60..f41ad25 100644
--- a/sdk/media_constraints.h
+++ b/sdk/media_constraints.h
@@ -67,7 +67,8 @@
static const char kTypingNoiseDetection[]; // googTypingNoiseDetection
static const char kAudioMirroring[]; // googAudioMirroring
static const char
- kAudioNetworkAdaptorConfig[]; // goodAudioNetworkAdaptorConfig
+ kAudioNetworkAdaptorConfig[]; // googAudioNetworkAdaptorConfig
+ static const char kInitAudioRecordingOnSend[]; // InitAudioRecordingOnSend;
// Constraint keys for CreateOffer / CreateAnswer
// Specified by the W3C PeerConnection spec