From a90a5cba08fdf6c0ceb95101c275108a152a3aed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:35:37 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- dom/media/gtest/TestAudioInputSource.cpp | 114 +++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 7 deletions(-) (limited to 'dom/media/gtest/TestAudioInputSource.cpp') diff --git a/dom/media/gtest/TestAudioInputSource.cpp b/dom/media/gtest/TestAudioInputSource.cpp index f3f18b26a9..5defd1d053 100644 --- a/dom/media/gtest/TestAudioInputSource.cpp +++ b/dom/media/gtest/TestAudioInputSource.cpp @@ -10,16 +10,22 @@ #include "gtest/gtest.h" #include "MockCubeb.h" +#include "mozilla/Result.h" #include "mozilla/gtest/WaitFor.h" #include "nsContentUtils.h" using namespace mozilla; using testing::ContainerEq; -namespace { +// Short-hand for DispatchToCurrentThread with a function. #define DispatchFunction(f) \ NS_DispatchToCurrentThread(NS_NewRunnableFunction(__func__, f)) -} // namespace + +// Short-hand for draining the current threads event queue, i.e. processing +// those runnables dispatched per above. +#define ProcessEventQueue() \ + while (NS_ProcessNextEvent(nullptr, false)) { \ + } class MockEventListener : public AudioInputSource::EventListener { public: @@ -63,7 +69,10 @@ TEST(TestAudioInputSource, StartAndStop) // Make sure start and stop works. { - DispatchFunction([&] { ais->Start(); }); + DispatchFunction([&] { + ais->Init(); + ais->Start(); + }); RefPtr stream = WaitFor(cubeb->StreamInitEvent()); EXPECT_TRUE(stream->mHasInput); EXPECT_FALSE(stream->mHasOutput); @@ -79,7 +88,10 @@ TEST(TestAudioInputSource, StartAndStop) // Make sure restart is ok. { - DispatchFunction([&] { ais->Start(); }); + DispatchFunction([&] { + ais->Init(); + ais->Start(); + }); RefPtr stream = WaitFor(cubeb->StreamInitEvent()); EXPECT_TRUE(stream->mHasInput); EXPECT_FALSE(stream->mHasOutput); @@ -133,7 +145,10 @@ TEST(TestAudioInputSource, DataOutputBeforeStartAndAfterStop) EXPECT_TRUE(data.IsNull()); } - DispatchFunction([&] { ais->Start(); }); + DispatchFunction([&] { + ais->Init(); + ais->Start(); + }); RefPtr stream = WaitFor(cubeb->StreamInitEvent()); EXPECT_TRUE(stream->mHasInput); EXPECT_FALSE(stream->mHasOutput); @@ -206,7 +221,10 @@ TEST(TestAudioInputSource, ErrorCallback) sourceRate, targetRate); ASSERT_TRUE(ais); - DispatchFunction([&] { ais->Start(); }); + DispatchFunction([&] { + ais->Init(); + ais->Start(); + }); RefPtr stream = WaitFor(cubeb->StreamInitEvent()); EXPECT_TRUE(stream->mHasInput); EXPECT_FALSE(stream->mHasOutput); @@ -251,7 +269,10 @@ TEST(TestAudioInputSource, DeviceChangedCallback) sourceRate, targetRate); ASSERT_TRUE(ais); - DispatchFunction([&] { ais->Start(); }); + DispatchFunction([&] { + ais->Init(); + ais->Start(); + }); RefPtr stream = WaitFor(cubeb->StreamInitEvent()); EXPECT_TRUE(stream->mHasInput); EXPECT_FALSE(stream->mHasOutput); @@ -267,3 +288,82 @@ TEST(TestAudioInputSource, DeviceChangedCallback) ais = nullptr; // Drop the SharedThreadPool here. } + +TEST(TestAudioInputSource, InputProcessing) +{ + MockCubeb* cubeb = new MockCubeb(); + CubebUtils::ForceSetCubebContext(cubeb->AsCubebContext()); + + const AudioInputSource::Id sourceId = 1; + const CubebUtils::AudioDeviceID deviceId = (CubebUtils::AudioDeviceID)1; + const uint32_t channels = 2; + const PrincipalHandle testPrincipal = + MakePrincipalHandle(nsContentUtils::GetSystemPrincipal()); + const TrackRate sourceRate = 44100; + const TrackRate targetRate = 48000; + using ProcessingPromise = + AudioInputSource::SetRequestedProcessingParamsPromise; + + auto listener = MakeRefPtr(); + EXPECT_CALL(*listener, + AudioStateCallback( + sourceId, AudioInputSource::EventListener::State::Started)) + .Times(0); + EXPECT_CALL(*listener, + AudioStateCallback( + sourceId, AudioInputSource::EventListener::State::Stopped)) + .Times(10); + + RefPtr ais = MakeRefPtr( + std::move(listener), sourceId, deviceId, channels, true, testPrincipal, + sourceRate, targetRate); + + const auto test = + [&](cubeb_input_processing_params aRequested, + const Result& aExpected) { + RefPtr p; + DispatchFunction([&] { + ais->Init(); + p = ais->SetRequestedProcessingParams(aRequested); + }); + ProcessEventQueue(); + EXPECT_EQ(WaitFor(p), aExpected); + + DispatchFunction([&] { ais->Stop(); }); + Unused << WaitFor(cubeb->StreamDestroyEvent()); + }; + + // Not supported by backend. + cubeb->SetSupportedInputProcessingParams(CUBEB_INPUT_PROCESSING_PARAM_NONE, + CUBEB_ERROR_NOT_SUPPORTED); + test(CUBEB_INPUT_PROCESSING_PARAM_NONE, Err(CUBEB_ERROR_NOT_SUPPORTED)); + + // Not supported by params. + cubeb->SetSupportedInputProcessingParams(CUBEB_INPUT_PROCESSING_PARAM_NONE, + CUBEB_OK); + test(CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION, + CUBEB_INPUT_PROCESSING_PARAM_NONE); + + constexpr cubeb_input_processing_params allParams = + CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION | + CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION | + CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL | + CUBEB_INPUT_PROCESSING_PARAM_VOICE_ISOLATION; + + // Successful all. + cubeb->SetSupportedInputProcessingParams(allParams, CUBEB_OK); + test(allParams, allParams); + + // Successful partial. + test(CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION, + CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION); + + // Not supported by stream. + // Note this also tests that AudioInputSource resets its configured params + // state from the previous successful test. + constexpr int propagatedError = 99; + cubeb->SetInputProcessingApplyRv(propagatedError); + test(CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION, Err(propagatedError)); + + ais = nullptr; // Drop the SharedThreadPool here. +} -- cgit v1.2.3