| // Copyright 2023 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 <fidl/fuchsia.hardware.audio/cpp/common_types.h> |
| #include <fidl/fuchsia.hardware.audio/cpp/natural_types.h> |
| #include <lib/zx/clock.h> |
| #include <lib/zx/time.h> |
| #include <zircon/errors.h> |
| |
| #include <cmath> |
| #include <cstdint> |
| #include <optional> |
| #include <set> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| #include "src/media/audio/services/device_registry/signal_processing_utils.h" |
| #include "src/media/audio/services/device_registry/signal_processing_utils_unittest.h" |
| #include "src/media/audio/services/device_registry/validate.h" |
| |
| // These cases unittest the Validate... functions with inputs that cause WARNING log output. |
| |
| namespace media_audio { |
| |
| // Negative-test ValidateStreamProperties |
| fuchsia_hardware_audio::StreamProperties ValidStreamProperties() { |
| return {{ |
| .is_input = false, |
| .min_gain_db = 0.0f, |
| .max_gain_db = 0.0f, |
| .gain_step_db = 0.0f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kCanAsyncNotify, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }}; |
| } |
| TEST(ValidateWarningTest, BadStreamProperties) { |
| auto stream_properties = ValidStreamProperties(); |
| ASSERT_TRUE(ValidateStreamProperties(stream_properties)) << "Baseline setup unsuccessful"; |
| |
| // missing is_input |
| stream_properties = ValidStreamProperties(); |
| stream_properties.is_input() = std::nullopt; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| |
| // missing min_gain_db |
| stream_properties = ValidStreamProperties(); |
| stream_properties.min_gain_db() = std::nullopt; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| // bad min_gain_db (NAN, inf) |
| stream_properties.min_gain_db() = NAN; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| stream_properties.min_gain_db() = -INFINITY; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| |
| // missing max_gain_db |
| stream_properties = ValidStreamProperties(); |
| stream_properties.max_gain_db() = std::nullopt; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| // bad max_gain_db (NAN, inf) |
| stream_properties.max_gain_db() = NAN; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| stream_properties.max_gain_db() = INFINITY; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| |
| // bad max_gain_db (below min_gain_db) |
| stream_properties = ValidStreamProperties(); |
| stream_properties.min_gain_db() = 0.0f; |
| stream_properties.max_gain_db() = -1.0f; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| |
| // missing gain_step_db |
| stream_properties = ValidStreamProperties(); |
| stream_properties.gain_step_db() = std::nullopt; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| // bad gain_step_db (NAN, inf) |
| stream_properties.gain_step_db() = NAN; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| stream_properties.gain_step_db() = INFINITY; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| // gain_step_db too large (max-min) |
| stream_properties.gain_step_db() = 1.0f; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| stream_properties = ValidStreamProperties(); |
| stream_properties.min_gain_db() = -42.0f; |
| stream_properties.max_gain_db() = 26.0f; |
| stream_properties.gain_step_db() = 68.1f; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| |
| // current mute state impossible (implicit) |
| stream_properties = ValidStreamProperties(); |
| EXPECT_FALSE(ValidateStreamProperties( |
| stream_properties, fuchsia_hardware_audio::GainState{{.muted = true, .gain_db = 0.0f}})); |
| // current mute state impossible (explicit) |
| stream_properties.can_mute() = false; |
| EXPECT_FALSE(ValidateStreamProperties( |
| stream_properties, fuchsia_hardware_audio::GainState{{.muted = true, .gain_db = 0.0f}})); |
| |
| // current agc state impossible (implicit) |
| stream_properties = ValidStreamProperties(); |
| EXPECT_FALSE(ValidateStreamProperties( |
| stream_properties, |
| fuchsia_hardware_audio::GainState{{.agc_enabled = true, .gain_db = 0.0f}})); |
| // current agc state impossible (explicit) |
| stream_properties.can_agc() = false; |
| EXPECT_FALSE(ValidateStreamProperties( |
| stream_properties, |
| fuchsia_hardware_audio::GainState{{.agc_enabled = true, .gain_db = 0.0f}})); |
| |
| // current gain_db out of range |
| stream_properties = ValidStreamProperties(); |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties, |
| fuchsia_hardware_audio::GainState{{.gain_db = -0.1f}})); |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties, |
| fuchsia_hardware_audio::GainState{{.gain_db = 0.1f}})); |
| |
| // missing plug_detect_capabilities |
| stream_properties = ValidStreamProperties(); |
| stream_properties.plug_detect_capabilities() = std::nullopt; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| |
| // current plug state impossible |
| stream_properties = ValidStreamProperties(); |
| stream_properties.plug_detect_capabilities() = |
| fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired; |
| EXPECT_FALSE(ValidateStreamProperties( |
| stream_properties, fuchsia_hardware_audio::GainState{{.gain_db = 0.0f}}, |
| fuchsia_hardware_audio::PlugState{{.plugged = false, .plug_state_time = 0}})); |
| |
| // missing clock_domain |
| stream_properties = ValidStreamProperties(); |
| stream_properties.clock_domain() = std::nullopt; |
| EXPECT_FALSE(ValidateStreamProperties(stream_properties)); |
| } |
| |
| // Negative-test ValidateRingBufferFormatSets |
| fuchsia_hardware_audio::SupportedFormats CompliantFormatSet() { |
| return fuchsia_hardware_audio::SupportedFormats{{ |
| .pcm_supported_formats = fuchsia_hardware_audio::PcmSupportedFormats{{ |
| .channel_sets = {{ |
| fuchsia_hardware_audio::ChannelSet{{ |
| .attributes = {{ |
| fuchsia_hardware_audio::ChannelAttributes{{ |
| .min_frequency = 20, |
| .max_frequency = 20000, |
| }}, |
| }}, |
| }}, |
| }}, |
| .sample_formats = {{fuchsia_hardware_audio::SampleFormat::kPcmSigned}}, |
| .bytes_per_sample = {{2}}, |
| .valid_bits_per_sample = {{16}}, |
| .frame_rates = {{48000}}, |
| }}, |
| }}; |
| } |
| TEST(ValidateWarningTest, BadSupportedFormats) { |
| std::vector<fuchsia_hardware_audio::SupportedFormats> supported_formats; |
| |
| // Empty top-level vector |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.push_back(CompliantFormatSet()); |
| EXPECT_TRUE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // No pcm_supported_formats (one supported_formats[] vector entry, but it is empty) |
| supported_formats.emplace_back(); |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| } |
| |
| // Negative-test ValidateRingBufferFormatSets for frame_rates |
| TEST(ValidateWarningTest, BadSupportedFormatsFrameRates) { |
| std::vector<fuchsia_hardware_audio::SupportedFormats> supported_formats{CompliantFormatSet()}; |
| |
| // Missing frame_rates |
| supported_formats.at(0).pcm_supported_formats()->frame_rates() = std::nullopt; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Empty frame_rates vector |
| supported_formats.at(0).pcm_supported_formats()->frame_rates() = {{}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Too low frame_rate |
| supported_formats.at(0).pcm_supported_formats()->frame_rates() = {{999}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Too high frame_rate |
| supported_formats.at(0).pcm_supported_formats()->frame_rates() = {{192001}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Out-of-order frame_rates |
| supported_formats.at(0).pcm_supported_formats()->frame_rates() = {{48000, 44100}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| } |
| |
| // Negative-test ValidateRingBufferFormatSets for channel_sets |
| TEST(ValidateWarningTest, BadSupportedFormatsChannelSets) { |
| std::vector<fuchsia_hardware_audio::SupportedFormats> supported_formats{CompliantFormatSet()}; |
| |
| // Missing channel_sets |
| supported_formats.at(0).pcm_supported_formats()->channel_sets() = std::nullopt; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Empty channel_sets vector |
| supported_formats.at(0).pcm_supported_formats()->channel_sets() = {{}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Missing attributes |
| supported_formats.at(0).pcm_supported_formats()->channel_sets() = {{ |
| {}, |
| }}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Empty attributes vector |
| supported_formats.at(0).pcm_supported_formats()->channel_sets() = {{ |
| { |
| .attributes = {{}}, |
| }, |
| }}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Duplicate channel_set lengths |
| // Two channel_sets entries - both with a single channel |
| supported_formats.at(0).pcm_supported_formats()->channel_sets() = {{ |
| {{ |
| .attributes = {{ |
| {}, |
| }}, |
| }}, |
| {{ |
| .attributes = {{ |
| {}, |
| }}, |
| }}, |
| }}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.at(0) |
| .pcm_supported_formats() |
| ->channel_sets() |
| ->at(0) |
| .attributes() |
| ->emplace_back(); |
| ASSERT_TRUE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Too high min_frequency |
| supported_formats.at(0).pcm_supported_formats()->channel_sets()->at(1).attributes()->at(0) = {{ |
| .min_frequency = 24001, |
| }}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Min > max |
| supported_formats.at(0).pcm_supported_formats()->channel_sets()->at(1).attributes()->at(0) = {{ |
| .min_frequency = 16001, |
| .max_frequency = 16000, |
| }}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Too high max_frequency (passes but emits WARNING, thus is in the "warning" suite) |
| supported_formats.at(0).pcm_supported_formats()->channel_sets()->at(1).attributes()->at(0) = {{ |
| .max_frequency = 192000, |
| }}; |
| EXPECT_TRUE(ValidateRingBufferFormatSets(supported_formats)); |
| } |
| |
| // Negative-test ValidateRingBufferFormatSets for sample_formats |
| TEST(ValidateWarningTest, BadSupportedFormatsSampleFormats) { |
| std::vector<fuchsia_hardware_audio::SupportedFormats> supported_formats{CompliantFormatSet()}; |
| // Missing sample_formats |
| supported_formats.at(0).pcm_supported_formats()->sample_formats() = std::nullopt; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Empty sample_formats vector |
| supported_formats.at(0).pcm_supported_formats()->sample_formats() = {{}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Duplicate sample_format |
| supported_formats.at(0).pcm_supported_formats()->sample_formats() = {{ |
| fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| }}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| } |
| |
| // Negative-test ValidateRingBufferFormatSets for bytes_per_sample |
| TEST(ValidateWarningTest, BadSupportedFormatsBytesPerSample) { |
| std::vector<fuchsia_hardware_audio::SupportedFormats> supported_formats{CompliantFormatSet()}; |
| |
| // Missing bytes_per_sample |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = std::nullopt; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Empty bytes_per_sample vector |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Out-of-order bytes_per_sample |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{4, 2}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Bad bytes_per_sample - unsigned |
| supported_formats.at(0).pcm_supported_formats()->sample_formats() = { |
| {fuchsia_hardware_audio::SampleFormat::kPcmUnsigned}}; |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{0, 1}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{1, 2}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Bad bytes_per_sample - signed |
| supported_formats.at(0).pcm_supported_formats()->sample_formats() = { |
| {fuchsia_hardware_audio::SampleFormat::kPcmSigned}}; |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{1, 2}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{3, 4}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{2, 8}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Bad bytes_per_sample - float |
| supported_formats.at(0).pcm_supported_formats()->sample_formats() = { |
| {fuchsia_hardware_audio::SampleFormat::kPcmFloat}}; |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{2, 4}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{6, 8}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| supported_formats.at(0).pcm_supported_formats()->bytes_per_sample() = {{4, 16}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| } |
| |
| // Negative-test ValidateRingBufferFormatSets for valid_bits_per_sample |
| TEST(ValidateWarningTest, BadSupportedFormatsValidBitsPerSample) { |
| std::vector<fuchsia_hardware_audio::SupportedFormats> supported_formats{CompliantFormatSet()}; |
| |
| // Missing valid_bits_per_sample |
| supported_formats.at(0).pcm_supported_formats()->valid_bits_per_sample() = std::nullopt; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Empty valid_bits_per_sample vector |
| supported_formats.at(0).pcm_supported_formats()->valid_bits_per_sample() = {{}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Out-of-order valid_bits_per_sample |
| supported_formats.at(0).pcm_supported_formats()->valid_bits_per_sample() = {{16, 15}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Too low valid_bits_per_sample |
| supported_formats.at(0).pcm_supported_formats()->valid_bits_per_sample() = {{0, 16}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| |
| // Too high valid_bits_per_sample |
| supported_formats.at(0).pcm_supported_formats()->valid_bits_per_sample() = {{16, 18}}; |
| EXPECT_FALSE(ValidateRingBufferFormatSets(supported_formats)); |
| } |
| |
| // Negative-test ValidateGainState |
| TEST(ValidateWarningTest, BadGainState) { |
| // empty |
| EXPECT_FALSE(ValidateGainState(fuchsia_hardware_audio::GainState{})); |
| |
| // missing gain_db |
| EXPECT_FALSE(ValidateGainState(fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = false, |
| }}, |
| std::nullopt)); |
| |
| // bad gain_db |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = false, |
| .gain_db = NAN, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = true, |
| .can_agc = true, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = false, |
| .gain_db = INFINITY, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = true, |
| .can_agc = true, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| |
| // gain_db out-of-range |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = false, |
| .gain_db = -12.1f, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = true, |
| .can_agc = true, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = false, |
| .gain_db = 12.1f, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = true, |
| .can_agc = true, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| |
| // bad muted (implicit) |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = true, |
| .agc_enabled = false, |
| .gain_db = 0.0f, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| // can_mute (optional) is missing: CANNOT mute |
| .can_agc = true, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| |
| // bad muted (explicit) |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = true, |
| .agc_enabled = false, |
| .gain_db = 0.0f, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = false, |
| .can_agc = true, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| |
| // bad agc_enabled (implicit) |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = true, |
| .gain_db = 0.0f, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = true, |
| // can_agc ia missing: CANNOT agc |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| |
| // bad agc_enabled (explicit) |
| EXPECT_FALSE(ValidateGainState( |
| fuchsia_hardware_audio::GainState{{ |
| .muted = false, |
| .agc_enabled = true, |
| .gain_db = 0.0f, |
| }}, |
| fuchsia_hardware_audio::StreamProperties{{ |
| .is_input = false, |
| .can_mute = true, |
| .can_agc = false, |
| .min_gain_db = -12.0f, |
| .max_gain_db = 12.0f, |
| .gain_step_db = 0.5f, |
| .plug_detect_capabilities = fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired, |
| .clock_domain = fuchsia_hardware_audio::kClockDomainMonotonic, |
| }})); |
| } |
| |
| // Negative-test ValidatePlugState |
| TEST(ValidateWarningTest, BadPlugState) { |
| // empty |
| EXPECT_FALSE(ValidatePlugState(fuchsia_hardware_audio::PlugState{})); |
| |
| // missing plugged |
| EXPECT_FALSE(ValidatePlugState(fuchsia_hardware_audio::PlugState{{ |
| // plugged (required) is missing |
| .plug_state_time = zx::clock::get_monotonic().get(), |
| }}, |
| fuchsia_hardware_audio::PlugDetectCapabilities::kCanAsyncNotify)); |
| |
| // bad plugged |
| EXPECT_FALSE(ValidatePlugState(fuchsia_hardware_audio::PlugState{{ |
| .plugged = false, |
| .plug_state_time = zx::clock::get_monotonic().get(), |
| }}, |
| fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired)); |
| |
| // missing plug_state_time |
| EXPECT_FALSE(ValidatePlugState(fuchsia_hardware_audio::PlugState{{ |
| .plugged = false, |
| // plug_state_time (required) is missing |
| }}, |
| fuchsia_hardware_audio::PlugDetectCapabilities::kCanAsyncNotify)); |
| |
| // bad plug_state_time |
| EXPECT_FALSE( |
| ValidatePlugState(fuchsia_hardware_audio::PlugState{{ |
| .plugged = true, |
| .plug_state_time = (zx::clock::get_monotonic() + zx::hour(6)).get(), |
| }}, |
| fuchsia_hardware_audio::PlugDetectCapabilities::kHardwired)); |
| } |
| |
| // TODO(https://fxbug.dev/42069012): Negative-test ValidateDeviceInfo |
| // TEST(ValidateWarningTest, BadDeviceInfo) {} |
| |
| // Negative-test ValidateRingBufferProperties |
| TEST(ValidateWarningTest, BadRingBufferProperties) { |
| // empty |
| EXPECT_FALSE(ValidateRingBufferProperties(fuchsia_hardware_audio::RingBufferProperties{})); |
| |
| // missing needs_cache_flush_or_invalidate |
| EXPECT_FALSE(ValidateRingBufferProperties(fuchsia_hardware_audio::RingBufferProperties{{ |
| .turn_on_delay = 125, |
| .driver_transfer_bytes = 128, |
| }})); |
| |
| // bad turn_on_delay |
| EXPECT_FALSE(ValidateRingBufferProperties(fuchsia_hardware_audio::RingBufferProperties{{ |
| .needs_cache_flush_or_invalidate = true, |
| .turn_on_delay = -1, |
| .driver_transfer_bytes = 128, |
| }})); |
| |
| // missing driver_transfer_bytes |
| EXPECT_FALSE(ValidateRingBufferProperties(fuchsia_hardware_audio::RingBufferProperties{{ |
| .needs_cache_flush_or_invalidate = true, |
| .turn_on_delay = 125, |
| }})); |
| |
| // TODO(b/311694769): Resolve driver_transfer_bytes lower limit: specifically is 0 allowed? |
| // bad driver_transfer_bytes (too small) |
| // EXPECT_FALSE(ValidateRingBufferProperties(fuchsia_hardware_audio::RingBufferProperties{{ |
| // .needs_cache_flush_or_invalidate = true, |
| // .turn_on_delay = 125, |
| // .driver_transfer_bytes = 0, |
| // }}), |
| // ZX_ERR_INVALID_ARGS); |
| |
| // TODO(b/311694769): Resolve driver_transfer_bytes upper limit: no limit? Soft guideline? |
| // bad driver_transfer_bytes (too large) |
| // EXPECT_FALSE(ValidateRingBufferProperties(fuchsia_hardware_audio::RingBufferProperties{{ |
| // .needs_cache_flush_or_invalidate = true, |
| // .turn_on_delay = 125, |
| // .driver_transfer_bytes = 0xFFFFFFFF, |
| // }}), |
| // ZX_ERR_INVALID_ARGS); |
| } |
| |
| // Negative-test ValidateRingBufferFormat |
| TEST(ValidateWarningTest, BadRingBufferFormat) { |
| // missing pcm_format |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{})); |
| |
| // bad value number_of_channels |
| // Is there an upper limit on number_of_channels? |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 0, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 2, |
| .valid_bits_per_sample = 16, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| |
| // bad value bytes_per_sample |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 0, |
| .valid_bits_per_sample = 16, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 5, |
| .valid_bits_per_sample = 16, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| |
| // bad value valid_bits_per_sample |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 2, |
| .valid_bits_per_sample = 0, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmUnsigned, |
| .bytes_per_sample = 1, |
| .valid_bits_per_sample = 9, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 2, |
| .valid_bits_per_sample = 17, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 4, |
| .valid_bits_per_sample = 33, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmFloat, |
| .bytes_per_sample = 4, |
| .valid_bits_per_sample = 33, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmFloat, |
| .bytes_per_sample = 8, |
| .valid_bits_per_sample = 65, |
| .frame_rate = 48000, |
| }}, |
| }})); |
| |
| // bad value frame_rate |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 2, |
| .valid_bits_per_sample = 16, |
| .frame_rate = 999, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateRingBufferFormat(fuchsia_hardware_audio::Format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = 2, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = 2, |
| .valid_bits_per_sample = 16, |
| .frame_rate = 192001, |
| }}, |
| }})); |
| } |
| |
| // Negative-test ValidateSampleFormatCompatibility |
| TEST(ValidateWarningTest, BadFormatCompatibility) { |
| const std::set<std::pair<uint8_t, fuchsia_hardware_audio::SampleFormat>> kAllowedFormats{ |
| {1, fuchsia_hardware_audio::SampleFormat::kPcmUnsigned}, |
| {2, fuchsia_hardware_audio::SampleFormat::kPcmSigned}, |
| {4, fuchsia_hardware_audio::SampleFormat::kPcmSigned}, |
| {4, fuchsia_hardware_audio::SampleFormat::kPcmFloat}, |
| {8, fuchsia_hardware_audio::SampleFormat::kPcmFloat}, |
| }; |
| const std::vector<uint8_t> kSampleSizesToTest{ |
| 0, 1, 2, 3, 4, 6, 8, |
| }; |
| const std::vector<fuchsia_hardware_audio::SampleFormat> kSampleFormatsToTest{ |
| fuchsia_hardware_audio::SampleFormat::kPcmUnsigned, |
| fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| fuchsia_hardware_audio::SampleFormat::kPcmFloat, |
| }; |
| |
| for (auto sample_size : kSampleSizesToTest) { |
| for (auto sample_format : kSampleFormatsToTest) { |
| if (kAllowedFormats.find({sample_size, sample_format}) == kAllowedFormats.end()) { |
| EXPECT_FALSE(ValidateSampleFormatCompatibility(sample_size, sample_format)); |
| } |
| } |
| } |
| } |
| |
| // Negative-test ValidateRingBufferVmo |
| TEST(ValidateWarningTest, BadRingBufferVmo) { |
| constexpr uint64_t kVmoContentSize = 8192; |
| zx::vmo vmo; |
| auto status = zx::vmo::create(kVmoContentSize, 0, &vmo); |
| ASSERT_EQ(status, ZX_OK) << "could not create VMO for test input"; |
| |
| constexpr uint8_t kChannelCount = 1; |
| constexpr uint8_t kSampleSize = 2; |
| fuchsia_hardware_audio::Format format{{ |
| .pcm_format = fuchsia_hardware_audio::PcmFormat{{ |
| .number_of_channels = kChannelCount, |
| .sample_format = fuchsia_hardware_audio::SampleFormat::kPcmSigned, |
| .bytes_per_sample = kSampleSize, |
| .valid_bits_per_sample = 16, |
| .frame_rate = 48000, |
| }}, |
| }}; |
| uint32_t num_frames = static_cast<uint32_t>(kVmoContentSize / kChannelCount / kSampleSize); |
| |
| // Bad VMO (get_size failed) |
| EXPECT_FALSE(ValidateRingBufferVmo(zx::vmo(), num_frames, format)); |
| |
| // bad num_frames (too large for VMO) |
| EXPECT_FALSE(ValidateRingBufferVmo(vmo, num_frames + 1, format)); |
| |
| // Bad format (flagged by the encapsulated ValidateRingBufferFormat) |
| format.pcm_format()->frame_rate() = 999; |
| EXPECT_FALSE(ValidateRingBufferVmo(vmo, num_frames, format)); |
| format.pcm_format()->frame_rate() = 192001; |
| EXPECT_FALSE(ValidateRingBufferVmo(vmo, num_frames, format)); |
| |
| // Bad format (flagged by the encapsulated ValidateSampleFormatCompatibility) |
| format.pcm_format()->frame_rate() = 48000; |
| format.pcm_format()->sample_format() = fuchsia_hardware_audio::SampleFormat::kPcmFloat; |
| EXPECT_FALSE(ValidateRingBufferVmo(vmo, num_frames, format)); |
| } |
| |
| // Negative-test ValidateDelayInfo for internal_delay |
| TEST(ValidateWarningTest, BadInternalDelayInfo) { |
| // empty |
| EXPECT_FALSE(ValidateDelayInfo(fuchsia_hardware_audio::DelayInfo{})); |
| |
| // missing internal_delay |
| EXPECT_FALSE(ValidateDelayInfo(fuchsia_hardware_audio::DelayInfo{{ |
| .external_delay = 0, |
| }})); |
| |
| // bad internal_delay |
| EXPECT_FALSE(ValidateDelayInfo(fuchsia_hardware_audio::DelayInfo{{ |
| .internal_delay = -1, |
| }})); |
| } |
| |
| // Negative-test ValidateDelayInfo for external_delay |
| TEST(ValidateWarningTest, BadExternalDelayInfo) { |
| // bad external_delay |
| EXPECT_FALSE(ValidateDelayInfo(fuchsia_hardware_audio::DelayInfo{{ |
| .internal_delay = 0, |
| .external_delay = -1, |
| }})); |
| } |
| |
| // Unittest ValidateCodecProperties -- the missing, minimal and maximal possibilities |
| TEST(ValidateWarningTest, BadCodecProperties) { |
| EXPECT_FALSE(ValidateCodecProperties(fuchsia_hardware_audio::CodecProperties{{ |
| .is_input = false, .manufacturer = "manufacturer", .product = "product", .unique_id = {{}}, |
| // plug_detect_capabilities missing |
| }})) << "missing plug_detect_capabilities"; |
| } |
| |
| // Unittest ValidateDaiFormatSets |
| TEST(ValidateWarningTest, BadDaiSupportedFormats) { |
| // Entirely empty |
| EXPECT_FALSE(ValidateDaiFormatSets(std::vector<fuchsia_hardware_audio::DaiSupportedFormats>{})); |
| |
| // each empty |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| {{ |
| // .number_of_channels = {1}, |
| .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| .frame_rates = {48000}, |
| .bits_per_slot = {32}, |
| .bits_per_sample = {16}, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| {{ |
| .number_of_channels = {1}, |
| // .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| .frame_rates = {48000}, |
| .bits_per_slot = {32}, |
| .bits_per_sample = {16}, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| {{ |
| .number_of_channels = {1}, |
| .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| // .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| // fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| .frame_rates = {48000}, |
| .bits_per_slot = {32}, |
| .bits_per_sample = {16}, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| {{ |
| .number_of_channels = {1}, |
| .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| // .frame_rates = {48000}, |
| .bits_per_slot = {32}, |
| .bits_per_sample = {16}, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| {{ |
| .number_of_channels = {1}, |
| .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| .frame_rates = {48000}, |
| // .bits_per_slot = {32}, |
| .bits_per_sample = {16}, |
| }}, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| {{ |
| .number_of_channels = {1}, |
| .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| .frame_rates = {48000}, |
| .bits_per_slot = {32}, |
| // .bits_per_sample = {16}, |
| }}, |
| }})); |
| |
| const fuchsia_hardware_audio::DaiSupportedFormats valid = {{ |
| .number_of_channels = {1}, |
| .sample_formats = {fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned}, |
| .frame_formats = {fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S)}, |
| .frame_rates = {48000}, |
| .bits_per_slot = {32}, |
| .bits_per_sample = {16}, |
| }}; |
| |
| // values too small |
| fuchsia_hardware_audio::DaiSupportedFormats fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.number_of_channels({0, 1, 2}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.frame_rates({0, 48000}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.bits_per_slot({0, 32}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.bits_per_sample({0, 16}), |
| }})); |
| |
| // values too large |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.number_of_channels({1, 2, 65}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.frame_rates({48000, 2'000'000'000}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.bits_per_slot({32, 65}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.bits_per_sample({16, 33}), |
| }})); |
| |
| // values out of order |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.number_of_channels({2, 1}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.frame_rates({48000, 44100}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.bits_per_slot({32, 16}), |
| }})); |
| fmts = valid; |
| EXPECT_FALSE(ValidateDaiFormatSets({{ |
| fmts.bits_per_sample({16, 8}), |
| }})); |
| } |
| |
| // Unittest ValidateDaiFormat |
| TEST(ValidateWarningTest, BadDaiFormat) { |
| // empty |
| EXPECT_FALSE(ValidateDaiFormat({{}})); |
| |
| // each missing |
| EXPECT_FALSE(ValidateDaiFormat({{ |
| // .number_of_channels = 2, |
| .channels_to_use_bitmask = 0x03, |
| .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| .frame_rate = 48000, |
| .bits_per_slot = 32, |
| .bits_per_sample = 16, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormat({{ |
| .number_of_channels = 2, |
| // .channels_to_use_bitmask = 0x03, |
| .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| .frame_rate = 48000, |
| .bits_per_slot = 32, |
| .bits_per_sample = 16, |
| }})); |
| |
| EXPECT_FALSE(ValidateDaiFormat({{ |
| .number_of_channels = 2, |
| .channels_to_use_bitmask = 0x03, |
| // .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| .frame_rate = 48000, |
| .bits_per_slot = 32, |
| .bits_per_sample = 16, |
| }})); |
| |
| // Missing FrameFormat is impossible since DaiFrameFormat (and thus DaiFormat) has a custom ctor. |
| |
| EXPECT_FALSE(ValidateDaiFormat({{ |
| .number_of_channels = 2, |
| .channels_to_use_bitmask = 0x03, |
| .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| // .frame_rate = 48000, |
| .bits_per_slot = 32, |
| .bits_per_sample = 16, |
| }})); |
| |
| EXPECT_FALSE(ValidateDaiFormat({{ |
| .number_of_channels = 2, |
| .channels_to_use_bitmask = 0x03, |
| .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| .frame_rate = 48000, |
| // .bits_per_slot = 32, |
| .bits_per_sample = 16, |
| }})); |
| EXPECT_FALSE(ValidateDaiFormat({{ |
| .number_of_channels = 2, |
| .channels_to_use_bitmask = 0x03, |
| .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| .frame_rate = 48000, |
| .bits_per_slot = 32, |
| // .bits_per_sample = 16, |
| }})); |
| |
| // Values too low |
| const fuchsia_hardware_audio::DaiFormat valid = {{ |
| .number_of_channels = 2, |
| .channels_to_use_bitmask = 0x03, |
| .sample_format = fuchsia_hardware_audio::DaiSampleFormat::kPcmSigned, |
| .frame_format = fuchsia_hardware_audio::DaiFrameFormat::WithFrameFormatStandard( |
| fuchsia_hardware_audio::DaiFrameFormatStandard::kI2S), |
| .frame_rate = 48000, |
| .bits_per_slot = 32, |
| .bits_per_sample = 16, |
| }}; |
| fuchsia_hardware_audio::DaiFormat fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.number_of_channels(0))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.channels_to_use_bitmask(0x00))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.frame_rate(0))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.bits_per_slot(0).bits_per_sample(0))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.bits_per_sample(0))); |
| |
| // values too large |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.number_of_channels(65))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.channels_to_use_bitmask(0x04))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.frame_rate(2'000'000'000))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.bits_per_slot(kMaxSupportedDaiFormatBitsPerSlot + 1))); |
| fmt = valid; |
| EXPECT_FALSE(ValidateDaiFormat(fmt.bits_per_sample(33))); |
| } |
| |
| // Unittest ValidateCodecFormatInfo |
| TEST(ValidateWarningTest, BadCodecFormatInfo) { |
| // These durations cannot be negative. |
| EXPECT_FALSE(ValidateCodecFormatInfo(fuchsia_hardware_audio::CodecFormatInfo{{ |
| .external_delay = -1, |
| }})); |
| EXPECT_FALSE(ValidateCodecFormatInfo(fuchsia_hardware_audio::CodecFormatInfo{{ |
| .turn_on_delay = -1, |
| }})); |
| EXPECT_FALSE(ValidateCodecFormatInfo(fuchsia_hardware_audio::CodecFormatInfo{{ |
| .turn_off_delay = -1, |
| }})); |
| // ...that includes INT64_MIN (check for erroneously treating it as unsigned). |
| EXPECT_FALSE(ValidateCodecFormatInfo(fuchsia_hardware_audio::CodecFormatInfo{{ |
| .external_delay = zx::time::infinite_past().get(), |
| }})); |
| EXPECT_FALSE(ValidateCodecFormatInfo(fuchsia_hardware_audio::CodecFormatInfo{{ |
| .turn_on_delay = zx::time::infinite_past().get(), |
| }})); |
| EXPECT_FALSE(ValidateCodecFormatInfo(fuchsia_hardware_audio::CodecFormatInfo{{ |
| .turn_off_delay = zx::time::infinite_past().get(), |
| }})); |
| } |
| |
| // signalprocessing functions |
| // |
| TEST(ValidateWarningTest, BadElement) { |
| // This element has no 'id'. |
| EXPECT_FALSE(ValidateElement(kElementNoId)); |
| |
| // This element has no 'type'. |
| EXPECT_FALSE(ValidateElement(kElementNoType)); |
| |
| // This element has no 'type_specific', but its 'type' requires one. |
| EXPECT_FALSE(ValidateElement(kElementNoRequiredTypeSpecific)); |
| |
| // This element contains a 'type_specific' that does not match its 'type'. |
| EXPECT_FALSE(ValidateElement(kElementWrongTypeSpecific)); |
| |
| // This element contains a 'description' that is an empty string. |
| EXPECT_FALSE(ValidateElement(kElementEmptyDescription)); |
| |
| // Test inconsistencies in certain type_specifics |
| // TODO(https://fxbug.dev/42069012): Negative-test ValidateElement |
| } |
| |
| TEST(ValidateWarningTest, BadElementList) { |
| EXPECT_FALSE(ValidateElements(kEmptyElements)); |
| |
| // List contains two elements with the same id. |
| EXPECT_FALSE(ValidateElements(kElementsDuplicateId)); |
| |
| // bad Elements: all the ValidateElement negative cases |
| EXPECT_FALSE(ValidateElements(kElementsWithNoId)); |
| EXPECT_FALSE(ValidateElements(kElementsWithNoType)); |
| EXPECT_FALSE(ValidateElements(kElementsWithNoRequiredTypeSpecific)); |
| EXPECT_FALSE(ValidateElements(kElementsWithWrongTypeSpecific)); |
| EXPECT_FALSE(ValidateElements(kElementsWithEmptyDescription)); |
| } |
| |
| TEST(ValidateWarningTest, BadTopology) { |
| // This topology has no 'id'. |
| EXPECT_FALSE(ValidateTopology(kTopologyMissingId, MapElements(kElements))); |
| |
| // This topology has no 'processing_elements_edge_pairs'. |
| EXPECT_FALSE(ValidateTopology(kTopologyMissingEdgePairs, MapElements(kElements))); |
| |
| // This topology has an 'processing_elements_edge_pairs' vector that is empty. |
| EXPECT_FALSE(ValidateTopology(kTopologyEmptyEdgePairs, MapElements(kElements))); |
| |
| // This topology references an element_id that is not included in the element_map. |
| EXPECT_FALSE(ValidateTopology(kTopologyUnknownElementId, MapElements(kElements))); |
| |
| // This topology includes an edge that connects one element_id to itself. |
| EXPECT_FALSE(ValidateTopology(kTopologyEdgePairLoop, MapElements(kElements))); |
| |
| // This topology has a terminal (source or destination) element that is not an Endpoint. |
| EXPECT_FALSE(ValidateTopology(kTopologyTerminalNotEndpoint, MapElements(kElements))); |
| |
| // empty element_map |
| EXPECT_FALSE(ValidateTopology(kTopology14, kEmptyElementMap)); |
| } |
| |
| TEST(ValidateWarningTest, BadTopologyList) { |
| EXPECT_FALSE(ValidateTopologies(kEmptyTopologies, MapElements(kElements))); |
| |
| // List contains two topologies with the same id. |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithDuplicateId, MapElements(kElements))); |
| |
| // There are elements that are not mentioned in at least one of the topologies. |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithoutAllElements, MapElements(kElements))); |
| |
| // Topology list with a bad Topology: all the ValidateTopology negative cases |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithMissingId, MapElements(kElements))); |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithMissingEdgePairs, MapElements(kElements))); |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithEmptyEdgePairs, MapElements(kElements))); |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithUnknownElementId, MapElements(kElements))); |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithLoop, MapElements(kElements))); |
| EXPECT_FALSE(ValidateTopologies(kTopologiesWithTerminalNotEndpoint, MapElements(kElements))); |
| |
| // empty element_map |
| EXPECT_FALSE(ValidateTopologies(kTopologies, kEmptyElementMap)); |
| } |
| |
| TEST(ValidateWarningTest, BadElementState) { |
| EXPECT_FALSE(ValidateElementState(kElementStateEmpty, kElement1)); |
| |
| // Add more negative-test cases here |
| } |
| |
| } // namespace media_audio |