| // 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/audio_device_settings_serialization_impl.h" |
| |
| #include <lib/gtest/test_loop_fixture.h> |
| #include <zircon/device/audio.h> |
| |
| #include <cstdio> |
| |
| #include "src/media/audio/audio_core/audio_device_settings.h" |
| #include "src/media/audio/audio_core/audio_driver.h" |
| |
| namespace media::audio { |
| namespace { |
| |
| static const std::string kAudioDeviceSettingsInvalidSchema = "asdf"; |
| static constexpr audio_stream_unique_id_t kTestUniqueId = { |
| {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}; |
| |
| // Both mute and agc are supported but disabled. Gain is initialized to 0.0f. |
| static constexpr HwGainState kDefaultInitialHwGainState = { |
| false, /* cur_mute */ |
| false, /* cur_agc */ |
| 0.0, /* cur_gain */ |
| true, /* can_mute */ |
| true, /* can_agc */ |
| -160.0f, /* min_gain */ |
| 24.0f, /* max_gain */ |
| 1.0f /* gain_step */ |
| }; |
| |
| class AudioDeviceSettingsSerializationImplTest : public gtest::TestLoopFixture { |
| protected: |
| void SetUp() override { |
| file_ = std::tmpfile(); |
| ASSERT_NE(file_, nullptr); |
| } |
| void TearDown() override { |
| ASSERT_NE(file_, nullptr); |
| std::fclose(file_); |
| } |
| void WriteToFile(std::string_view s) { |
| ASSERT_EQ(s.size(), std::fwrite(s.data(), 1, s.size(), file_)); |
| ASSERT_EQ(0, std::fflush(file_)); |
| } |
| |
| int fd() const { return fileno(file_); } |
| |
| private: |
| std::FILE* file_ = nullptr; |
| }; |
| |
| TEST_F(AudioDeviceSettingsSerializationImplTest, CreateWithSchema) { |
| std::unique_ptr<AudioDeviceSettingsSerialization> serialization; |
| zx_status_t status = AudioDeviceSettingsSerializationImpl::Create(&serialization); |
| ASSERT_EQ(ZX_OK, status); |
| ASSERT_TRUE(serialization); |
| } |
| |
| TEST_F(AudioDeviceSettingsSerializationImplTest, CreateWithInvalidSchemaFails) { |
| std::unique_ptr<AudioDeviceSettingsSerialization> serialization; |
| zx_status_t status = AudioDeviceSettingsSerializationImpl::CreateWithSchema( |
| kAudioDeviceSettingsInvalidSchema.c_str(), &serialization); |
| EXPECT_EQ(ZX_ERR_INVALID_ARGS, status); |
| ASSERT_FALSE(serialization); |
| } |
| |
| // Verify we can read a valid config JSON. |
| TEST_F(AudioDeviceSettingsSerializationImplTest, Deserialize) { |
| std::unique_ptr<AudioDeviceSettingsSerialization> serialization; |
| zx_status_t status = AudioDeviceSettingsSerializationImpl::Create(&serialization); |
| ASSERT_EQ(ZX_OK, status); |
| ASSERT_TRUE(serialization); |
| |
| WriteToFile( |
| R"JSON({ |
| "gain": { |
| "gain_db": 5.0, |
| "mute": true, |
| "agc": true |
| }, |
| "ignore_device": true, |
| "disallow_auto_routing": true |
| })JSON"); |
| |
| // Initialize AudioDeviceSettings from HwGainState. |
| AudioDeviceSettings settings(kTestUniqueId, kDefaultInitialHwGainState, false); |
| |
| // Verify initial conditions. |
| fuchsia::media::AudioGainInfo gain_info; |
| settings.GetGainInfo(&gain_info); |
| EXPECT_EQ(0.0f, gain_info.gain_db); |
| EXPECT_FALSE(gain_info.flags & fuchsia::media::AudioGainInfoFlag_Mute); |
| EXPECT_TRUE(gain_info.flags & fuchsia::media::AudioGainInfoFlag_AgcSupported); |
| EXPECT_FALSE(gain_info.flags & fuchsia::media::AudioGainInfoFlag_AgcEnabled); |
| EXPECT_FALSE(settings.AutoRoutingDisabled()); |
| EXPECT_FALSE(settings.Ignored()); |
| |
| // Deserialize and verify new settings. |
| EXPECT_EQ(ZX_OK, serialization->Deserialize(fd(), &settings)); |
| settings.GetGainInfo(&gain_info); |
| EXPECT_EQ(5.0f, gain_info.gain_db); |
| EXPECT_TRUE(gain_info.flags & fuchsia::media::AudioGainInfoFlag_Mute); |
| EXPECT_TRUE(gain_info.flags & fuchsia::media::AudioGainInfoFlag_AgcSupported); |
| EXPECT_TRUE(gain_info.flags & fuchsia::media::AudioGainInfoFlag_AgcEnabled); |
| EXPECT_TRUE(settings.AutoRoutingDisabled()); |
| EXPECT_TRUE(settings.Ignored()); |
| } |
| |
| TEST_F(AudioDeviceSettingsSerializationImplTest, DeserializeExtraToplevelKeysFailsToDeserialize) { |
| std::unique_ptr<AudioDeviceSettingsSerialization> serialization; |
| zx_status_t status = AudioDeviceSettingsSerializationImpl::Create(&serialization); |
| ASSERT_EQ(ZX_OK, status); |
| ASSERT_TRUE(serialization); |
| |
| WriteToFile( |
| R"JSON({ |
| "EXTRA_KEY": true, |
| "gain": { |
| "gain_db": 5.0, |
| "mute": true, |
| "agc": true |
| }, |
| "ignore_device": true, |
| "disallow_auto_routing": true |
| })JSON"); |
| |
| // Initialize AudioDeviceSettings from HwGainState. |
| AudioDeviceSettings settings(kTestUniqueId, kDefaultInitialHwGainState, false); |
| |
| // Deserialize should fail. |
| EXPECT_EQ(ZX_ERR_IO_DATA_INTEGRITY, serialization->Deserialize(fd(), &settings)); |
| } |
| |
| TEST_F(AudioDeviceSettingsSerializationImplTest, DeserializeExtraGainKeysFails) { |
| std::unique_ptr<AudioDeviceSettingsSerialization> serialization; |
| zx_status_t status = AudioDeviceSettingsSerializationImpl::Create(&serialization); |
| ASSERT_EQ(ZX_OK, status); |
| ASSERT_TRUE(serialization); |
| |
| WriteToFile( |
| R"JSON({ |
| "gain": { |
| "EXTRA_KEY": true, |
| "gain_db": 5.0, |
| "mute": true, |
| "agc": true |
| }, |
| "ignore_device": true, |
| "disallow_auto_routing": true |
| })JSON"); |
| |
| // Initialize AudioDeviceSettings from HwGainState. |
| AudioDeviceSettings settings(kTestUniqueId, kDefaultInitialHwGainState, false); |
| |
| // Deserialize should fail. |
| EXPECT_EQ(ZX_ERR_IO_DATA_INTEGRITY, serialization->Deserialize(fd(), &settings)); |
| } |
| |
| } // namespace |
| } // namespace media::audio |