summaryrefslogtreecommitdiffstats
path: root/dom/media/gtest/TestAudioInputSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/gtest/TestAudioInputSource.cpp')
-rw-r--r--dom/media/gtest/TestAudioInputSource.cpp114
1 files changed, 107 insertions, 7 deletions
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<SmartMockCubebStream> 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<SmartMockCubebStream> 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<SmartMockCubebStream> 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<SmartMockCubebStream> 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<SmartMockCubebStream> 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<MockEventListener>();
+ EXPECT_CALL(*listener,
+ AudioStateCallback(
+ sourceId, AudioInputSource::EventListener::State::Started))
+ .Times(0);
+ EXPECT_CALL(*listener,
+ AudioStateCallback(
+ sourceId, AudioInputSource::EventListener::State::Stopped))
+ .Times(10);
+
+ RefPtr<AudioInputSource> ais = MakeRefPtr<AudioInputSource>(
+ std::move(listener), sourceId, deviceId, channels, true, testPrincipal,
+ sourceRate, targetRate);
+
+ const auto test =
+ [&](cubeb_input_processing_params aRequested,
+ const Result<cubeb_input_processing_params, int>& aExpected) {
+ RefPtr<ProcessingPromise> 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.
+}