| // Copyright 2019 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 "src/media/audio/audio_core/volume_control.h" |
| |
| #include <lib/fidl/cpp/interface_ptr.h> |
| #include <lib/gtest/test_loop_fixture.h> |
| |
| #include <gtest/gtest.h> |
| |
| namespace media::audio { |
| namespace { |
| |
| class MockVolumeSetting : public VolumeSetting { |
| public: |
| void SetVolume(float volume) override { volume_ = volume; } |
| |
| float volume() const { return volume_; } |
| |
| private: |
| float volume_; |
| }; |
| |
| class VolumeControlTest : public ::gtest::TestLoopFixture { |
| protected: |
| VolumeControlTest() : volume_control_(&setting_, dispatcher()) {} |
| |
| fuchsia::media::audio::VolumeControlPtr BindVolumeControl() { |
| fuchsia::media::audio::VolumeControlPtr volume_control_ptr; |
| volume_control_.AddBinding(volume_control_ptr.NewRequest(dispatcher())); |
| return volume_control_ptr; |
| } |
| |
| MockVolumeSetting setting_; |
| VolumeControl volume_control_; |
| }; |
| |
| TEST_F(VolumeControlTest, SetsVolume) { |
| auto client = BindVolumeControl(); |
| |
| client->SetVolume(0.5); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.5); |
| } |
| |
| TEST_F(VolumeControlTest, SetsMute) { |
| auto client = BindVolumeControl(); |
| |
| client->SetVolume(0.5); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.5); |
| |
| client->SetMute(true); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.0); |
| |
| // On unmute, volume should restore. |
| client->SetMute(false); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.5); |
| } |
| |
| TEST_F(VolumeControlTest, MultipleClients) { |
| auto client1 = BindVolumeControl(); |
| auto client2 = BindVolumeControl(); |
| |
| client1->SetVolume(0.1); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.1); |
| |
| client2->SetVolume(0.4); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.4); |
| } |
| |
| TEST_F(VolumeControlTest, SetVolumeDoesNotUnmute) { |
| auto client = BindVolumeControl(); |
| |
| client->SetVolume(0.1); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.1); |
| |
| client->SetMute(true); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.0); |
| |
| client->SetVolume(0.8); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.0); |
| |
| client->SetMute(false); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(setting_.volume(), 0.8); |
| } |
| |
| TEST_F(VolumeControlTest, ClientEvents) { |
| float volume; |
| bool muted; |
| auto client = BindVolumeControl(); |
| client.events().OnVolumeMuteChanged = [&volume, &muted](float new_volume, bool new_muted) { |
| volume = new_volume; |
| muted = new_muted; |
| }; |
| |
| client->SetVolume(0.1); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume, 0.1); |
| EXPECT_FALSE(muted); |
| |
| client->SetMute(true); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume, 0.1); |
| EXPECT_TRUE(muted); |
| |
| client->SetVolume(0.8); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume, 0.8); |
| EXPECT_TRUE(muted); |
| |
| client->SetMute(false); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume, 0.8); |
| EXPECT_FALSE(muted); |
| } |
| |
| TEST_F(VolumeControlTest, DuplicateSetsGenerateNoEvents) { |
| float volume; |
| bool muted; |
| size_t event_count = 0; |
| auto client = BindVolumeControl(); |
| client.events().OnVolumeMuteChanged = [&event_count, &volume, &muted](float new_volume, |
| bool new_muted) { |
| volume = new_volume; |
| muted = new_muted; |
| ++event_count; |
| }; |
| RunLoopUntilIdle(); |
| EXPECT_EQ(event_count, 1u); |
| event_count = 0; |
| |
| client->SetVolume(0.1); |
| client->SetVolume(0.1); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume, 0.1); |
| EXPECT_FALSE(muted); |
| EXPECT_EQ(event_count, 1u); |
| |
| event_count = 0; |
| client->SetMute(true); |
| client->SetMute(true); |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(muted); |
| EXPECT_EQ(event_count, 1u); |
| } |
| |
| TEST_F(VolumeControlTest, AllClientsReceiveEvents) { |
| float volume1; |
| bool muted1; |
| auto client1 = BindVolumeControl(); |
| client1.events().OnVolumeMuteChanged = [&volume1, &muted1](float new_volume, bool new_muted) { |
| volume1 = new_volume; |
| muted1 = new_muted; |
| }; |
| |
| float volume2; |
| bool muted2; |
| auto client2 = BindVolumeControl(); |
| client2.events().OnVolumeMuteChanged = [&volume2, &muted2](float new_volume, bool new_muted) { |
| volume2 = new_volume; |
| muted2 = new_muted; |
| }; |
| |
| client1->SetVolume(0.1); |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume1, 0.1); |
| EXPECT_FALSE(muted1); |
| EXPECT_FLOAT_EQ(volume2, 0.1); |
| EXPECT_FALSE(muted2); |
| } |
| |
| TEST_F(VolumeControlTest, ClientsReceiveStateOnConnection) { |
| auto client1 = BindVolumeControl(); |
| client1.events().OnVolumeMuteChanged = [](float new_volume, bool new_muted) {}; |
| client1->SetVolume(0.1); |
| RunLoopUntilIdle(); |
| |
| float volume2; |
| bool muted2; |
| auto client2 = BindVolumeControl(); |
| client2.events().OnVolumeMuteChanged = [&volume2, &muted2](float new_volume, bool new_muted) { |
| volume2 = new_volume; |
| muted2 = new_muted; |
| }; |
| |
| RunLoopUntilIdle(); |
| EXPECT_FLOAT_EQ(volume2, 0.1); |
| EXPECT_FALSE(muted2); |
| } |
| |
| } // namespace |
| } // namespace media::audio |