| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "garnet/bin/media/audio_core/test/gain_control_test.h" |
| |
| #include <fuchsia/media/cpp/fidl.h> |
| #include <lib/gtest/real_loop_fixture.h> |
| #include <cmath> |
| |
| #include "garnet/bin/media/audio_core/test/audio_fidl_tests_shared.h" |
| #include "lib/component/cpp/environment_services_helper.h" |
| #include "lib/fxl/logging.h" |
| |
| namespace media::audio::test { |
| |
| // GainControlTestBase |
| // |
| void GainControlTestBase::SetUp() { |
| ::gtest::RealLoopFixture::SetUp(); |
| |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_ = true; |
| QuitLoop(); |
| }; |
| |
| environment_services_ = component::GetEnvironmentServices(); |
| environment_services_->ConnectToService(audio_.NewRequest()); |
| audio_.set_error_handler(err_handler); |
| } |
| |
| void GainControlTestBase::TearDown() { |
| // Base Audio interface should still survive even when the others are reset. |
| ASSERT_TRUE(AudioIsBound()); |
| |
| // These expect_ vars indicate negative cases where we expect failure. |
| EXPECT_EQ(ApiIsNull(), expect_null_api_); |
| |
| EXPECT_EQ(error_occurred_, expect_error_); |
| EXPECT_EQ(!gain_control_.is_bound(), expect_null_gain_control_); |
| |
| EXPECT_EQ(error_occurred_2_, expect_error_2_); |
| EXPECT_EQ(!gain_control_2_.is_bound(), expect_null_gain_control_2_); |
| } |
| |
| void GainControlTestBase::SetUpRenderer() { |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_ = true; |
| QuitLoop(); |
| }; |
| |
| audio_->CreateAudioRenderer(audio_renderer_.NewRequest()); |
| audio_renderer_.set_error_handler(err_handler); |
| } |
| |
| void GainControlTestBase::SetUpCapturer() { |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_ = true; |
| QuitLoop(); |
| }; |
| |
| audio_->CreateAudioCapturer(audio_capturer_.NewRequest(), false); |
| audio_capturer_.set_error_handler(err_handler); |
| } |
| |
| void GainControlTestBase::SetUpRenderer2() { |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_2_ = true; |
| QuitLoop(); |
| }; |
| |
| audio_->CreateAudioRenderer(audio_renderer_2_.NewRequest()); |
| audio_renderer_2_.set_error_handler(err_handler); |
| } |
| |
| void GainControlTestBase::SetUpCapturer2() { |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_2_ = true; |
| QuitLoop(); |
| }; |
| |
| audio_->CreateAudioCapturer(audio_capturer_2_.NewRequest(), false); |
| audio_capturer_2_.set_error_handler(err_handler); |
| } |
| |
| void GainControlTestBase::SetUpGainControl() { |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_ = true; |
| QuitLoop(); |
| }; |
| gain_control_.set_error_handler(err_handler); |
| |
| gain_control_.events().OnGainMuteChanged = [this](float gain_db, bool muted) { |
| received_gain_callback_ = true; |
| received_gain_db_ = gain_db; |
| received_mute_ = muted; |
| QuitLoop(); |
| }; |
| |
| expect_null_gain_control_ = false; |
| } |
| |
| void GainControlTestBase::SetUpGainControlOnRenderer() { |
| audio_renderer_->BindGainControl(gain_control_.NewRequest()); |
| SetUpGainControl(); |
| } |
| |
| void GainControlTestBase::SetUpGainControlOnCapturer() { |
| audio_capturer_->BindGainControl(gain_control_.NewRequest()); |
| SetUpGainControl(); |
| } |
| |
| void GainControlTestBase::SetUpGainControl2() { |
| auto err_handler = [this](zx_status_t error) { |
| error_occurred_2_ = true; |
| QuitLoop(); |
| }; |
| gain_control_2_.set_error_handler(err_handler); |
| |
| gain_control_2_.events().OnGainMuteChanged = [this](float gain_db, |
| bool muted) { |
| received_gain_callback_2_ = true; |
| |
| received_gain_db_2_ = gain_db; |
| received_mute_2_ = muted; |
| QuitLoop(); |
| }; |
| |
| expect_null_gain_control_2_ = false; |
| } |
| |
| void GainControlTestBase::SetUpGainControl2OnRenderer() { |
| audio_renderer_->BindGainControl(gain_control_2_.NewRequest()); |
| SetUpGainControl2(); |
| } |
| |
| void GainControlTestBase::SetUpGainControl2OnCapturer() { |
| audio_capturer_->BindGainControl(gain_control_2_.NewRequest()); |
| SetUpGainControl2(); |
| } |
| |
| void GainControlTestBase::SetUpGainControl2OnRenderer2() { |
| audio_renderer_2_->BindGainControl(gain_control_2_.NewRequest()); |
| SetUpGainControl2(); |
| } |
| |
| void GainControlTestBase::SetUpGainControl2OnCapturer2() { |
| audio_capturer_2_->BindGainControl(gain_control_2_.NewRequest()); |
| SetUpGainControl2(); |
| } |
| |
| // For tests that cause a GainControl to disconnect, set these expectations. |
| void GainControlTestBase::SetNegativeExpectations() { |
| expect_null_api_ = true; |
| expect_error_ = true; |
| expect_null_gain_control_ = true; |
| } |
| |
| // Set Gain, asserting that state is already reset so error can be detected. |
| void GainControlTestBase::SetGain(float gain_db) { |
| // On initialization and every Receive...Callback(), this is set to false. |
| ASSERT_FALSE(received_gain_callback_) |
| << "Failed to reset received_gain_callback_ previously"; |
| ASSERT_FALSE(received_gain_callback_2_) |
| << "Failed to reset received_gain_callback_2_ previously"; |
| |
| gain_control_->SetGain(gain_db); |
| } |
| |
| // Set Mute, asserting that state is already reset so error can be detected. |
| void GainControlTestBase::SetMute(bool mute) { |
| // On initialization and every Receive...Callback(), this is set to false. |
| ASSERT_FALSE(received_gain_callback_) |
| << "Failed to reset received_gain_callback_ previously"; |
| ASSERT_FALSE(received_gain_callback_2_) |
| << "Failed to reset received_gain_callback_2_ previously"; |
| |
| gain_control_->SetMute(mute); |
| } |
| |
| // Tests expect a gain callback. Absorb this; perform related error checking. |
| bool GainControlTestBase::ReceiveGainCallback(float gain_db, bool mute) { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this, gain_db, mute]() { |
| return (error_occurred_ || |
| ((received_gain_db_ == gain_db) && (received_mute_ == mute))); |
| }, |
| kDurationResponseExpected, kDurationGranularity); |
| |
| EXPECT_FALSE(error_occurred_) << kConnectionErr; |
| EXPECT_TRUE(gain_control_.is_bound()); |
| |
| EXPECT_FALSE(timed_out) << kTimeoutErr; |
| |
| EXPECT_TRUE(received_gain_callback_); |
| EXPECT_EQ(received_gain_db_, gain_db); |
| EXPECT_EQ(received_mute_, mute); |
| |
| bool return_val = !error_occurred_ && !timed_out; |
| |
| received_gain_callback_ = false; |
| return return_val; |
| } |
| |
| // Tests expect to receive neither gain callback nor error; assert this. |
| bool GainControlTestBase::ReceiveNoGainCallback() { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { return (error_occurred_ || received_gain_callback_); }, |
| kDurationTimeoutExpected); |
| |
| EXPECT_FALSE(error_occurred_) << kConnectionErr; |
| EXPECT_TRUE(gain_control_.is_bound()); |
| |
| EXPECT_TRUE(timed_out) << kNoTimeoutErr; |
| |
| EXPECT_FALSE(received_gain_callback_); |
| |
| bool return_val = !error_occurred_ && !received_gain_callback_; |
| |
| received_gain_callback_ = false; |
| return return_val; |
| } |
| |
| // Tests expect to receive a disconnect callback for API binding, then for |
| // GainControl binding. Treat any regular gain callback received as error. |
| bool GainControlTestBase::ReceiveDisconnectCallback() { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { |
| return (ApiIsNull() && !gain_control_.is_bound()) || |
| received_gain_callback_; |
| }, |
| kDurationResponseExpected, kDurationGranularity); |
| |
| // If GainControl causes disconnect, renderer/capturer disconnects first. |
| EXPECT_TRUE(error_occurred_); |
| EXPECT_TRUE(ApiIsNull()); |
| EXPECT_FALSE(gain_control_.is_bound()); |
| |
| EXPECT_FALSE(timed_out); |
| |
| EXPECT_FALSE(received_gain_callback_); |
| |
| bool return_val = !timed_out && !received_gain_callback_; |
| |
| received_gain_callback_ = false; |
| return return_val; |
| } |
| |
| // Test implementations, called by various objects across the class hierarchy |
| void GainControlTestBase::TestSetGain() { |
| constexpr float expect_gain_db = 20.0f; |
| SetGain(expect_gain_db); |
| EXPECT_TRUE(ReceiveGainCallback(expect_gain_db, false)); |
| |
| SetGain(kUnityGainDb); |
| EXPECT_TRUE(ReceiveGainCallback(kUnityGainDb, false)); |
| } |
| |
| void GainControlTestBase::TestSetMute() { |
| float expect_mute = true; |
| SetMute(expect_mute); |
| EXPECT_TRUE(ReceiveGainCallback(kUnityGainDb, expect_mute)); |
| |
| expect_mute = false; |
| SetMute(expect_mute); |
| EXPECT_TRUE(ReceiveGainCallback(kUnityGainDb, expect_mute)); |
| } |
| |
| void GainControlTestBase::TestSetGainMute() { |
| constexpr float expect_gain_db = -5.5f; |
| constexpr bool expect_mute = true; |
| |
| SetGain(expect_gain_db); |
| SetMute(expect_mute); |
| |
| EXPECT_TRUE(ReceiveGainCallback(expect_gain_db, false)); |
| EXPECT_TRUE(ReceiveGainCallback(expect_gain_db, expect_mute)); |
| } |
| |
| void GainControlTestBase::TestDuplicateSetGain() { |
| constexpr float expect_gain_db = 20.0f; |
| SetGain(expect_gain_db); |
| EXPECT_TRUE(ReceiveGainCallback(expect_gain_db, false)); |
| |
| SetGain(expect_gain_db); |
| EXPECT_TRUE(ReceiveNoGainCallback()); |
| } |
| |
| void GainControlTestBase::TestDuplicateSetMute() { |
| float expect_mute = true; |
| SetMute(expect_mute); |
| EXPECT_TRUE(ReceiveGainCallback(kUnityGainDb, expect_mute)); |
| |
| SetMute(expect_mute); |
| EXPECT_TRUE(ReceiveNoGainCallback()); |
| } |
| |
| // For negative expectations. |
| // |
| // Setting gain too high should cause a disconnect. |
| void GainControlTestBase::TestSetGainTooHigh() { |
| SetNegativeExpectations(); |
| |
| constexpr float expect_gain_db = kTooHighGainDb; |
| SetGain(expect_gain_db); |
| |
| EXPECT_TRUE(ReceiveDisconnectCallback()) << "Bindings did not disconnect!"; |
| EXPECT_FALSE(gain_control_.is_bound()); |
| } |
| |
| // Setting gain too low should cause a disconnect. |
| void GainControlTestBase::TestSetGainTooLow() { |
| SetNegativeExpectations(); |
| |
| constexpr float expect_gain_db = kTooLowGainDb; |
| SetGain(expect_gain_db); |
| |
| EXPECT_TRUE(ReceiveDisconnectCallback()) << "Bindings did not disconnect!"; |
| EXPECT_FALSE(gain_control_.is_bound()); |
| } |
| |
| // Setting stream-specific gain to NAN should cause both FIDL channels |
| // (renderer/capturer and gain_control) to disconnect. |
| void GainControlTestBase::TestSetGainNaN() { |
| SetNegativeExpectations(); |
| |
| constexpr float expect_gain_db = NAN; |
| SetGain(expect_gain_db); |
| |
| EXPECT_TRUE(ReceiveDisconnectCallback()) << "Bindings did not disconnect!"; |
| EXPECT_FALSE(gain_control_.is_bound()); |
| } |
| |
| // |
| // Basic GainControl validation with single instance. |
| // |
| |
| // RenderGainControlTest |
| // |
| void RenderGainControlTest::SetUp() { |
| GainControlTestBase::SetUp(); |
| |
| SetUpRenderer(); |
| SetUpGainControlOnRenderer(); |
| } |
| |
| // Single renderer with one gain control: Gain, Mute and GainMute combo. |
| // |
| TEST_F(RenderGainControlTest, SetGain) { TestSetGain(); } |
| |
| TEST_F(RenderGainControlTest, SetMute) { TestSetMute(); } |
| |
| TEST_F(RenderGainControlTest, SetGainMute) { TestSetGainMute(); } |
| |
| // TODO(mpuryear): Ramp-related tests (render). Relevant FIDL signature is: |
| // SetGainWithRamp(float32 gain_db, int64 duration_ns, AudioRamp rampType); |
| |
| // TODO(mpuryear): Validate GainChange notifications of gainramps. |
| |
| // N.B. DuplicateSetGain behavior is tested in RendererTwoGainControlsTest. |
| TEST_F(RenderGainControlTest, DuplicateSetMute) { TestDuplicateSetMute(); } |
| |
| TEST_F(RenderGainControlTest, SetGainTooHigh) { TestSetGainTooHigh(); } |
| |
| TEST_F(RenderGainControlTest, SetGainTooLow) { TestSetGainTooLow(); } |
| |
| TEST_F(RenderGainControlTest, SetGainNaN) { TestSetGainNaN(); } |
| |
| // TODO(mpuryear): Ramp-related negative tests, across all scenarios |
| |
| // CaptureGainControlTest |
| // |
| void CaptureGainControlTest::SetUp() { |
| GainControlTestBase::SetUp(); |
| |
| SetUpCapturer(); |
| SetUpGainControlOnCapturer(); |
| } |
| |
| // Single capturer with one gain control |
| // |
| TEST_F(CaptureGainControlTest, SetGain) { TestSetGain(); } |
| |
| TEST_F(CaptureGainControlTest, SetMute) { TestSetMute(); } |
| |
| TEST_F(CaptureGainControlTest, SetGainMute) { TestSetGainMute(); } |
| |
| // TODO(mpuryear): Ramp-related tests (capture) |
| |
| TEST_F(CaptureGainControlTest, DuplicateSetGain) { TestDuplicateSetGain(); } |
| // N.B. DuplicateSetMute behavior is tested in CapturerTwoGainControlsTest. |
| |
| TEST_F(CaptureGainControlTest, SetGainTooHigh) { TestSetGainTooHigh(); } |
| |
| TEST_F(CaptureGainControlTest, SetGainTooLow) { TestSetGainTooLow(); } |
| |
| TEST_F(CaptureGainControlTest, SetGainNaN) { TestSetGainNaN(); } |
| |
| // SiblingGainControlsTest |
| // On a renderer/capturer, sibling GainControls receive identical notifications. |
| // |
| // For tests that cause a GainControl to disconnect, set these expectations. |
| void SiblingGainControlsTest::SetNegativeExpectations() { |
| GainControlTestBase::SetNegativeExpectations(); |
| |
| expect_null_gain_control_2_ = true; |
| expect_error_2_ = true; |
| } |
| |
| // Tests expect a gain callback on both gain_controls, with the provided gain_db |
| // and mute values -- and no errors. |
| bool SiblingGainControlsTest::ReceiveGainCallback(float gain_db, bool mute) { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this, gain_db, mute]() { |
| return (error_occurred_ || error_occurred_2_ || |
| ((received_gain_db_ == gain_db) && (received_mute_ == mute) && |
| (received_gain_db_2_ == gain_db) && |
| (received_mute_2_ == mute))); |
| }, |
| kDurationResponseExpected, kDurationGranularity); |
| |
| EXPECT_FALSE(error_occurred_); |
| EXPECT_FALSE(error_occurred_2_); |
| EXPECT_FALSE(ApiIsNull()); |
| EXPECT_TRUE(gain_control_.is_bound()); |
| EXPECT_TRUE(gain_control_2_.is_bound()); |
| |
| EXPECT_FALSE(timed_out); |
| |
| EXPECT_TRUE(received_gain_callback_); |
| EXPECT_TRUE(received_gain_callback_2_); |
| EXPECT_EQ(received_gain_db_, gain_db); |
| EXPECT_EQ(received_gain_db_2_, gain_db); |
| EXPECT_EQ(received_mute_, mute); |
| EXPECT_EQ(received_mute_2_, mute); |
| |
| bool return_val = (!timed_out && !error_occurred_ && !error_occurred_2_); |
| |
| received_gain_callback_ = received_gain_callback_2_ = false; |
| return return_val; |
| } |
| |
| // Tests expect neither gain interface to receive gain callback nor error. |
| bool SiblingGainControlsTest::ReceiveNoGainCallback() { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { |
| return (error_occurred_ || error_occurred_2_ || |
| received_gain_callback_ || received_gain_callback_2_); |
| }, |
| kDurationTimeoutExpected); |
| |
| EXPECT_FALSE(error_occurred_); |
| EXPECT_FALSE(error_occurred_2_); |
| EXPECT_FALSE(ApiIsNull()); |
| EXPECT_TRUE(gain_control_.is_bound()); |
| EXPECT_TRUE(gain_control_2_.is_bound()); |
| |
| EXPECT_TRUE(timed_out) << kNoTimeoutErr; |
| |
| EXPECT_FALSE(received_gain_callback_); |
| EXPECT_FALSE(received_gain_callback_2_); |
| |
| bool return_val = (!error_occurred_ && !error_occurred_2_ && |
| !received_gain_callback_ && !received_gain_callback_2_); |
| |
| received_gain_callback_ = received_gain_callback_2_ = false; |
| return return_val; |
| } |
| |
| // Tests expect to receive a disconnect callback for the API binding, then |
| // one for each of the two GainControl bindings. In our loop, we wait until all |
| // three of these have occurred. Also, if any normal gain callback is received |
| // during this time, it is unexpected and treated as an error. |
| bool SiblingGainControlsTest::ReceiveDisconnectCallback() { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { |
| return (ApiIsNull()) && (!gain_control_.is_bound()) && |
| (!gain_control_2_.is_bound()); |
| }, |
| kDurationResponseExpected, kDurationGranularity); |
| |
| EXPECT_TRUE(error_occurred_); |
| EXPECT_TRUE(error_occurred_2_); |
| EXPECT_TRUE(ApiIsNull()); |
| EXPECT_FALSE(gain_control_.is_bound()); |
| EXPECT_FALSE(gain_control_2_.is_bound()); |
| |
| EXPECT_FALSE(timed_out); |
| |
| EXPECT_FALSE(received_gain_callback_); |
| EXPECT_FALSE(received_gain_callback_2_); |
| |
| bool return_val = |
| (!timed_out && !received_gain_callback_ && !received_gain_callback_2_); |
| |
| received_gain_callback_ = received_gain_callback_2_ = false; |
| return return_val; |
| } |
| |
| // RendererTwoGainControlsTest |
| // Renderer with two gain controls: both should receive identical notifications. |
| // |
| void RendererTwoGainControlsTest::SetUp() { |
| SiblingGainControlsTest::SetUp(); |
| |
| SetUpRenderer(); |
| SetUpGainControl2OnRenderer(); |
| SetUpGainControlOnRenderer(); |
| } |
| |
| TEST_F(RendererTwoGainControlsTest, BothControlsReceiveGainNotifications) { |
| TestSetGain(); |
| } |
| |
| TEST_F(RendererTwoGainControlsTest, BothControlsReceiveMuteNotifications) { |
| TestSetMute(); |
| } |
| |
| TEST_F(RendererTwoGainControlsTest, DuplicateSetGain) { |
| TestDuplicateSetGain(); |
| } |
| |
| // N.B. DuplicateSetMute behavior is tested in RendererGainControlTest. |
| |
| TEST_F(RendererTwoGainControlsTest, SetGainTooHigh) { TestSetGainTooHigh(); } |
| |
| TEST_F(RendererTwoGainControlsTest, SetGainTooLow) { TestSetGainTooLow(); } |
| |
| TEST_F(RendererTwoGainControlsTest, SetGainNaN) { TestSetGainNaN(); } |
| |
| // CapturerTwoGainControlsTest |
| // Capturer with two gain controls: both should receive identical notifications. |
| // |
| void CapturerTwoGainControlsTest::SetUp() { |
| SiblingGainControlsTest::SetUp(); |
| |
| SetUpCapturer(); |
| SetUpGainControl2OnCapturer(); |
| SetUpGainControlOnCapturer(); |
| } |
| |
| TEST_F(CapturerTwoGainControlsTest, BothControlsReceiveGainNotifications) { |
| TestSetGain(); |
| } |
| |
| TEST_F(CapturerTwoGainControlsTest, BothControlsReceiveMuteNotifications) { |
| TestSetMute(); |
| } |
| |
| // N.B. DuplicateSetGain behavior is tested in CapturerGainControlTest. |
| TEST_F(CapturerTwoGainControlsTest, DuplicateSetMute) { |
| TestDuplicateSetMute(); |
| } |
| |
| TEST_F(CapturerTwoGainControlsTest, SetGainTooHigh) { TestSetGainTooHigh(); } |
| |
| TEST_F(CapturerTwoGainControlsTest, SetGainTooLow) { TestSetGainTooLow(); } |
| |
| TEST_F(CapturerTwoGainControlsTest, SetGainNaN) { TestSetGainNaN(); } |
| |
| // IndependentGainControlsTest |
| // Verify that GainControls on different API instances are fully independent. |
| // |
| |
| // Tests expect a gain callback and no error, and neither on the independent |
| // API binding and gain_control (thus we wait for timeout below). |
| bool IndependentGainControlsTest::ReceiveGainCallback(float gain_db, |
| bool mute) { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { |
| return (error_occurred_ || error_occurred_2_ || |
| received_gain_callback_2_); |
| }, |
| kDurationTimeoutExpected); |
| |
| EXPECT_FALSE(error_occurred_); |
| EXPECT_FALSE(error_occurred_2_); |
| EXPECT_FALSE(ApiIsNull()); |
| EXPECT_TRUE(gain_control_.is_bound()); |
| EXPECT_TRUE(gain_control_2_.is_bound()); |
| |
| EXPECT_TRUE(timed_out); |
| |
| EXPECT_TRUE(received_gain_callback_); |
| EXPECT_FALSE(received_gain_callback_2_); |
| EXPECT_EQ(received_gain_db_, gain_db); |
| EXPECT_EQ(received_mute_, mute); |
| |
| bool return_val = |
| (!error_occurred_ && !error_occurred_2_ && !received_gain_callback_2_); |
| // Not only must we not have disconnected or received unexpected gain2 |
| // callback, also gain1 must have received the expected callback. |
| return_val &= (received_gain_db_ == gain_db && received_mute_ == mute); |
| |
| received_gain_callback_ = received_gain_callback_2_ = false; |
| return return_val; |
| } |
| |
| // Tests expect to receive neither gain callback nor error, on both gains. |
| bool IndependentGainControlsTest::ReceiveNoGainCallback() { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { |
| return (error_occurred_ || error_occurred_2_ || |
| received_gain_callback_ || received_gain_callback_2_); |
| }, |
| kDurationTimeoutExpected); |
| |
| EXPECT_FALSE(error_occurred_); |
| EXPECT_FALSE(error_occurred_2_); |
| EXPECT_FALSE(ApiIsNull()); |
| EXPECT_TRUE(gain_control_.is_bound()); |
| EXPECT_TRUE(gain_control_2_.is_bound()); |
| |
| EXPECT_TRUE(timed_out); |
| |
| EXPECT_FALSE(received_gain_callback_); |
| EXPECT_FALSE(received_gain_callback_2_); |
| |
| bool return_val = (!error_occurred_ && !error_occurred_2_ && |
| !received_gain_callback_ && !received_gain_callback_2_); |
| |
| received_gain_callback_ = received_gain_callback_2_ = false; |
| return return_val; |
| } |
| |
| // Tests expect to receive a disconnect callback for the API binding, then |
| // another for the GainControl binding. If before unbinding, that GainControl |
| // generates a gain callback, this is unexpected and treated as an error. We |
| // still expect nothing from the independent API binding and its gain_control |
| // (thus we wait for timeout). |
| bool IndependentGainControlsTest::ReceiveDisconnectCallback() { |
| bool timed_out = !RunLoopWithTimeoutOrUntil( |
| [this]() { |
| return error_occurred_2_ || received_gain_callback_ || |
| received_gain_callback_2_; |
| }, |
| kDurationTimeoutExpected); |
| |
| EXPECT_TRUE(error_occurred_); |
| EXPECT_FALSE(error_occurred_2_); |
| EXPECT_TRUE(ApiIsNull()); |
| EXPECT_FALSE(gain_control_.is_bound()); |
| EXPECT_TRUE(gain_control_2_.is_bound()); |
| |
| EXPECT_TRUE(timed_out); |
| |
| EXPECT_FALSE(received_gain_callback_); |
| EXPECT_FALSE(received_gain_callback_2_); |
| |
| bool return_val = (!error_occurred_2_ && !received_gain_callback_ && |
| !received_gain_callback_2_); |
| // While waiting for timeout, we must also have received gain1 disconnect. |
| return_val &= error_occurred_; |
| |
| received_gain_callback_ = received_gain_callback_2_ = false; |
| return return_val; |
| } |
| |
| // TwoRenderersGainControlsTest |
| // Two renderers, each with a gain control: we expect no cross-impact. |
| // |
| void TwoRenderersGainControlsTest::SetUp() { |
| IndependentGainControlsTest::SetUp(); |
| |
| SetUpRenderer2(); |
| SetUpGainControl2OnRenderer2(); |
| |
| SetUpRenderer(); |
| SetUpGainControlOnRenderer(); |
| } |
| |
| TEST_F(TwoRenderersGainControlsTest, OtherInstanceReceivesNoMuteNotification) { |
| TestSetMute(); |
| } |
| |
| // We expect primary GainControl/Renderer to disconnect. |
| TEST_F(TwoRenderersGainControlsTest, SetGainTooLow) { TestSetGainTooLow(); } |
| |
| // RendererCapturerGainControlsTest |
| // Renderer gain control should not affect capturer gain control. |
| // |
| void RendererCapturerGainControlsTest::SetUp() { |
| IndependentGainControlsTest::SetUp(); |
| |
| SetUpCapturer(); |
| SetUpGainControl2OnCapturer(); |
| |
| SetUpRenderer(); |
| SetUpGainControlOnRenderer(); |
| } |
| |
| TEST_F(RendererCapturerGainControlsTest, |
| OtherInstanceReceivesNoGainNotification) { |
| TestSetGain(); |
| } |
| |
| // We expect primary GainControl/Renderer to disconnect. |
| TEST_F(RendererCapturerGainControlsTest, SetGainTooHigh) { |
| TestSetGainTooHigh(); |
| } |
| |
| // CapturerRendererGainControlsTest |
| // Capturer gain control should not affect renderer gain control. |
| // |
| void CapturerRendererGainControlsTest::SetUp() { |
| IndependentGainControlsTest::SetUp(); |
| |
| SetUpRenderer(); |
| SetUpGainControl2OnRenderer(); |
| |
| SetUpCapturer(); |
| SetUpGainControlOnCapturer(); |
| } |
| |
| TEST_F(CapturerRendererGainControlsTest, |
| OtherInstanceReceivesNoGainNotification) { |
| TestSetGain(); |
| } |
| |
| // We expect primary GainControl/Capturer to disconnect. |
| TEST_F(CapturerRendererGainControlsTest, SetGainTooHigh) { |
| TestSetGainTooHigh(); |
| } |
| |
| // TwoCapturersGainControlsTest |
| // Two capturers, each with a gain control: we expect no cross-impact. |
| // |
| void TwoCapturersGainControlsTest::SetUp() { |
| IndependentGainControlsTest::SetUp(); |
| |
| SetUpCapturer2(); |
| SetUpGainControl2OnCapturer2(); |
| |
| SetUpCapturer(); |
| SetUpGainControlOnCapturer(); |
| } |
| |
| TEST_F(TwoCapturersGainControlsTest, OtherInstanceReceivesNoMuteNotification) { |
| TestSetMute(); |
| } |
| |
| // We expect primary GainControl/Capturer to disconnect. |
| TEST_F(TwoCapturersGainControlsTest, SetGainTooLow) { TestSetGainTooLow(); } |
| |
| } // namespace media::audio::test |