Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79903fea authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Audio VTS: Improve stability, update config validation test

Major challenge: the configuration of HAL tests
depends on the APM XML configuration file which may be
invalid. The code that reads the configuration
has been updated to avoid crashes when the config
is invalid.

In CheckConfig_audioPolicyConfigurationValidation the
dependency on the config parser was removed. Previously,
a failure to parse the config by the config parser would
lead to the test being skipped, which isn't correct
as it must fail in this case.

Minor fixes to V7 tests to pass on a real life legacy HAL.

Bug: 36733185
Test: run VtsHalAudioV7_0TargetTest on a device with V6
Test: run VtsHalAudioV7_0TargetTest on a device with
      a side-loaded V7 and invalid APM config file
Test: run VtsHalAudioV7_0TargetTest on a device with
      a side-loaded V7
Change-Id: I746339ff69ab455dc64eef9a17827d047b357329
parent a9cfd015
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -140,20 +140,23 @@ TEST_P(AudioHidlDeviceTest, SetConnectedState) {
#if MAJOR_VERSION <= 6
    using AD = AudioDevice;
    for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
        SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType));
#elif MAJOR_VERSION >= 7
    using AD = xsd::AudioDevice;
    for (auto deviceType :
         {toString(AD::AUDIO_DEVICE_OUT_HDMI), toString(AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
          toString(AD::AUDIO_DEVICE_IN_USB_HEADSET)}) {
    for (auto deviceType : {AD::AUDIO_DEVICE_OUT_HDMI, AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
                            AD::AUDIO_DEVICE_IN_USB_HEADSET}) {
        SCOPED_TRACE("device=" + toString(deviceType));
#endif
        SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType));
        for (bool state : {true, false}) {
            SCOPED_TRACE("state=" + ::testing::PrintToString(state));
            DeviceAddress address = {};
#if MAJOR_VERSION <= 6
            address.device = deviceType;
#elif MAJOR_VERSION >= 7
            address.deviceType = deviceType;
            address.deviceType = toString(deviceType);
            if (deviceType == AD::AUDIO_DEVICE_IN_USB_HEADSET) {
                address.address.alsa({0, 0});
            }
#endif
            auto ret = getDevice()->setConnectedState(address, state);
            ASSERT_TRUE(ret.isOk());
+21 −13
Original line number Diff line number Diff line
@@ -44,14 +44,17 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
        for (const auto& device : getDeviceParameters()) {
            auto module =
                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
            if (!module || !module->getFirstMixPorts()) break;
            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
                if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
                std::vector<AudioInOutFlag> flags;
                bool isOffload = false;
                if (mixPort.hasFlags()) {
                    auto xsdFlags = mixPort.getFlags();
                const bool isOffload =
                    isOffload =
                            std::find(xsdFlags.begin(), xsdFlags.end(),
                                      xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
                            xsdFlags.end();
                std::vector<AudioInOutFlag> flags;
                    if (!isOffload) {
                        for (auto flag : xsdFlags) {
                            if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
@@ -61,6 +64,7 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
                    } else {
                        flags = offloadFlags;
                    }
                }
                for (const auto& profile : mixPort.getProfile()) {
                    auto configs =
                            combineAudioConfig(profile.getChannelMasks(),
@@ -94,11 +98,15 @@ const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
        for (const auto& device : getDeviceParameters()) {
            auto module =
                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
            if (!module || !module->getFirstMixPorts()) break;
            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
                if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
                std::vector<AudioInOutFlag> flags;
                std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(), flags.begin(),
                if (mixPort.hasFlags()) {
                    std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
                                   std::back_inserter(flags),
                                   [](auto flag) { return toString(flag); });
                }
                for (const auto& profile : mixPort.getProfile()) {
                    auto configs =
                            combineAudioConfig(profile.getChannelMasks(),
+13 −7
Original line number Diff line number Diff line
@@ -33,7 +33,9 @@ class PolicyConfig {
        if (mConfig) {
            mStatus = OK;
            mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
            if (mConfig->getFirstModules()) {
                for (const auto& module : mConfig->getFirstModules()->get_module()) {
                    if (module.getFirstAttachedDevices()) {
                        auto attachedDevices = module.getFirstAttachedDevices()->getItem();
                        if (!attachedDevices.empty()) {
                            mModulesWithDevicesNames.insert(module.getName());
@@ -41,6 +43,8 @@ class PolicyConfig {
                    }
                }
            }
        }
    }
    status_t getStatus() const { return mStatus; }
    std::string getError() const {
        if (mFilePath.empty()) {
@@ -52,7 +56,7 @@ class PolicyConfig {
    }
    const std::string& getFilePath() const { return mFilePath; }
    const xsd::Module* getModuleFromName(const std::string& name) const {
        if (mConfig) {
        if (mConfig && mConfig->getFirstModules()) {
            for (const auto& module : mConfig->getFirstModules()->get_module()) {
                if (module.getName() == name) return &module;
            }
@@ -65,9 +69,11 @@ class PolicyConfig {
    }
    bool haveInputProfilesInModule(const std::string& name) const {
        auto module = getModuleFromName(name);
        if (module && module->getFirstMixPorts()) {
            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
                if (mixPort.getRole() == xsd::Role::sink) return true;
            }
        }
        return false;
    }

+15 −15
Original line number Diff line number Diff line
@@ -156,6 +156,21 @@ const PolicyConfig& getCachedPolicyConfig() {
    return *policyConfig;
}

TEST(CheckConfig, audioPolicyConfigurationValidation) {
    const auto factories = ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
    if (factories.size() == 0) {
        GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no factory instances "
                        "are found.";
    }
    RecordProperty("description",
                   "Verify that the audio policy configuration file "
                   "is valid according to the schema");

    const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName,
                                            android::audio_get_configuration_paths(), xsd);
}

//////////////////////////////////////////////////////////////////////////////
//////////////////// Test parameter types and definitions ////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -231,21 +246,6 @@ class AudioHidlTestWithDeviceParameter : public HidlTest,
    }
};

TEST(CheckConfig, audioPolicyConfigurationValidation) {
    auto deviceParameters = getDeviceParametersForFactoryTests();
    if (deviceParameters.size() == 0) {
        GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no device parameter "
                        "is found.";
    }
    RecordProperty("description",
                   "Verify that the audio policy configuration file "
                   "is valid according to the schema");

    const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName,
                                            android::audio_get_configuration_paths(), xsd);
}

class AudioPolicyConfigTest : public AudioHidlTestWithDeviceParameter {
  public:
    void SetUp() override {